libgo: update to Go 1.14.4 release
[official-gcc.git] / libgo / go / cmd / cgo / gcc.go
blobe38972913be2df18324e6704b85e0807d3fbb0c1
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Annotate Ref in Prog with C types by parsing gcc debug output.
6 // Conversion of debug output to Go types.
8 package main
10 import (
11 "bytes"
12 "debug/dwarf"
13 "debug/elf"
14 "debug/macho"
15 "debug/pe"
16 "encoding/binary"
17 "errors"
18 "flag"
19 "fmt"
20 "go/ast"
21 "go/parser"
22 "go/token"
23 "internal/xcoff"
24 "math"
25 "os"
26 "strconv"
27 "strings"
28 "unicode"
29 "unicode/utf8"
32 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
33 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
35 var nameToC = map[string]string{
36 "schar": "signed char",
37 "uchar": "unsigned char",
38 "ushort": "unsigned short",
39 "uint": "unsigned int",
40 "ulong": "unsigned long",
41 "longlong": "long long",
42 "ulonglong": "unsigned long long",
43 "complexfloat": "float _Complex",
44 "complexdouble": "double _Complex",
47 // cname returns the C name to use for C.s.
48 // The expansions are listed in nameToC and also
49 // struct_foo becomes "struct foo", and similarly for
50 // union and enum.
51 func cname(s string) string {
52 if t, ok := nameToC[s]; ok {
53 return t
56 if strings.HasPrefix(s, "struct_") {
57 return "struct " + s[len("struct_"):]
59 if strings.HasPrefix(s, "union_") {
60 return "union " + s[len("union_"):]
62 if strings.HasPrefix(s, "enum_") {
63 return "enum " + s[len("enum_"):]
65 if strings.HasPrefix(s, "sizeof_") {
66 return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
68 return s
71 // DiscardCgoDirectives processes the import C preamble, and discards
72 // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
73 // way into _cgo_export.h.
74 func (f *File) DiscardCgoDirectives() {
75 linesIn := strings.Split(f.Preamble, "\n")
76 linesOut := make([]string, 0, len(linesIn))
77 for _, line := range linesIn {
78 l := strings.TrimSpace(line)
79 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
80 linesOut = append(linesOut, line)
81 } else {
82 linesOut = append(linesOut, "")
85 f.Preamble = strings.Join(linesOut, "\n")
88 // addToFlag appends args to flag. All flags are later written out onto the
89 // _cgo_flags file for the build system to use.
90 func (p *Package) addToFlag(flag string, args []string) {
91 if flag == "CFLAGS" {
92 // We'll also need these when preprocessing for dwarf information.
93 // However, discard any -g options: we need to be able
94 // to parse the debug info, so stick to what we expect.
95 for _, arg := range args {
96 if !strings.HasPrefix(arg, "-g") {
97 p.GccOptions = append(p.GccOptions, arg)
102 skip := false
103 for i, arg := range args {
104 // The go tool will pass us a -I option pointing to objdir;
105 // we don't need to record that for later, as the objdir
106 // will disappear anyhow.
107 if skip {
108 // Discard argument in "-I objdir" case.
109 skip = false
110 } else if strings.HasPrefix(arg, "-I") && strings.HasPrefix(arg[2:], *objDir) {
111 // This is -Iobjdir. Don't save this argument.
112 } else if arg == "-I" && i+1 < len(args) && strings.HasPrefix(args[i+1], *objDir) {
113 // This is -I objdir. Don't save this argument
114 // or the next one.
115 skip = true
116 } else {
117 p.CgoFlags[flag] = append(p.CgoFlags[flag], arg)
122 // splitQuoted splits the string s around each instance of one or more consecutive
123 // white space characters while taking into account quotes and escaping, and
124 // returns an array of substrings of s or an empty list if s contains only white space.
125 // Single quotes and double quotes are recognized to prevent splitting within the
126 // quoted region, and are removed from the resulting substrings. If a quote in s
127 // isn't closed err will be set and r will have the unclosed argument as the
128 // last element. The backslash is used for escaping.
130 // For example, the following string:
132 // `a b:"c d" 'e''f' "g\""`
134 // Would be parsed as:
136 // []string{"a", "b:c d", "ef", `g"`}
138 func splitQuoted(s string) (r []string, err error) {
139 var args []string
140 arg := make([]rune, len(s))
141 escaped := false
142 quoted := false
143 quote := '\x00'
144 i := 0
145 for _, r := range s {
146 switch {
147 case escaped:
148 escaped = false
149 case r == '\\':
150 escaped = true
151 continue
152 case quote != 0:
153 if r == quote {
154 quote = 0
155 continue
157 case r == '"' || r == '\'':
158 quoted = true
159 quote = r
160 continue
161 case unicode.IsSpace(r):
162 if quoted || i > 0 {
163 quoted = false
164 args = append(args, string(arg[:i]))
165 i = 0
167 continue
169 arg[i] = r
172 if quoted || i > 0 {
173 args = append(args, string(arg[:i]))
175 if quote != 0 {
176 err = errors.New("unclosed quote")
177 } else if escaped {
178 err = errors.New("unfinished escaping")
180 return args, err
183 // Translate rewrites f.AST, the original Go input, to remove
184 // references to the imported package C, replacing them with
185 // references to the equivalent Go types, functions, and variables.
186 func (p *Package) Translate(f *File) {
187 for _, cref := range f.Ref {
188 // Convert C.ulong to C.unsigned long, etc.
189 cref.Name.C = cname(cref.Name.Go)
192 var conv typeConv
193 conv.Init(p.PtrSize, p.IntSize)
195 p.loadDefines(f)
196 p.typedefs = map[string]bool{}
197 p.typedefList = nil
198 numTypedefs := -1
199 for len(p.typedefs) > numTypedefs {
200 numTypedefs = len(p.typedefs)
201 // Also ask about any typedefs we've seen so far.
202 for _, info := range p.typedefList {
203 n := &Name{
204 Go: info.typedef,
205 C: info.typedef,
207 f.Name[info.typedef] = n
208 f.NamePos[n] = info.pos
210 needType := p.guessKinds(f)
211 if len(needType) > 0 {
212 p.loadDWARF(f, &conv, needType)
215 // In godefs mode we're OK with the typedefs, which
216 // will presumably also be defined in the file, we
217 // don't want to resolve them to their base types.
218 if *godefs {
219 break
222 p.prepareNames(f)
223 if p.rewriteCalls(f) {
224 // Add `import _cgo_unsafe "unsafe"` after the package statement.
225 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
227 p.rewriteRef(f)
230 // loadDefines coerces gcc into spitting out the #defines in use
231 // in the file f and saves relevant renamings in f.Name[name].Define.
232 func (p *Package) loadDefines(f *File) {
233 var b bytes.Buffer
234 b.WriteString(builtinProlog)
235 b.WriteString(f.Preamble)
236 stdout := p.gccDefines(b.Bytes())
238 for _, line := range strings.Split(stdout, "\n") {
239 if len(line) < 9 || line[0:7] != "#define" {
240 continue
243 line = strings.TrimSpace(line[8:])
245 var key, val string
246 spaceIndex := strings.Index(line, " ")
247 tabIndex := strings.Index(line, "\t")
249 if spaceIndex == -1 && tabIndex == -1 {
250 continue
251 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
252 key = line[0:spaceIndex]
253 val = strings.TrimSpace(line[spaceIndex:])
254 } else {
255 key = line[0:tabIndex]
256 val = strings.TrimSpace(line[tabIndex:])
259 if key == "__clang__" {
260 p.GccIsClang = true
263 if n := f.Name[key]; n != nil {
264 if *debugDefine {
265 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
267 n.Define = val
272 // guessKinds tricks gcc into revealing the kind of each
273 // name xxx for the references C.xxx in the Go input.
274 // The kind is either a constant, type, or variable.
275 func (p *Package) guessKinds(f *File) []*Name {
276 // Determine kinds for names we already know about,
277 // like #defines or 'struct foo', before bothering with gcc.
278 var names, needType []*Name
279 optional := map[*Name]bool{}
280 for _, key := range nameKeys(f.Name) {
281 n := f.Name[key]
282 // If we've already found this name as a #define
283 // and we can translate it as a constant value, do so.
284 if n.Define != "" {
285 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
286 n.Kind = "iconst"
287 // Turn decimal into hex, just for consistency
288 // with enum-derived constants. Otherwise
289 // in the cgo -godefs output half the constants
290 // are in hex and half are in whatever the #define used.
291 n.Const = fmt.Sprintf("%#x", i)
292 } else if n.Define[0] == '\'' {
293 if _, err := parser.ParseExpr(n.Define); err == nil {
294 n.Kind = "iconst"
295 n.Const = n.Define
297 } else if n.Define[0] == '"' {
298 if _, err := parser.ParseExpr(n.Define); err == nil {
299 n.Kind = "sconst"
300 n.Const = n.Define
304 if n.IsConst() {
305 continue
309 // If this is a struct, union, or enum type name, no need to guess the kind.
310 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
311 n.Kind = "type"
312 needType = append(needType, n)
313 continue
316 if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
317 // For FooRef, find out if FooGetTypeID exists.
318 s := n.C[:len(n.C)-3] + "GetTypeID"
319 n := &Name{Go: s, C: s}
320 names = append(names, n)
321 optional[n] = true
324 // Otherwise, we'll need to find out from gcc.
325 names = append(names, n)
328 // Bypass gcc if there's nothing left to find out.
329 if len(names) == 0 {
330 return needType
333 // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
334 // For names, find out whether they are integer constants.
335 // We used to look at specific warning or error messages here, but that tied the
336 // behavior too closely to specific versions of the compilers.
337 // Instead, arrange that we can infer what we need from only the presence or absence
338 // of an error on a specific line.
340 // For each name, we generate these lines, where xxx is the index in toSniff plus one.
342 // #line xxx "not-declared"
343 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
344 // #line xxx "not-type"
345 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
346 // #line xxx "not-int-const"
347 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
348 // #line xxx "not-num-const"
349 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
350 // #line xxx "not-str-lit"
351 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
353 // If we see an error at not-declared:xxx, the corresponding name is not declared.
354 // If we see an error at not-type:xxx, the corresponding name is a type.
355 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
356 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
357 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
359 // The specific input forms are chosen so that they are valid C syntax regardless of
360 // whether name denotes a type or an expression.
362 var b bytes.Buffer
363 b.WriteString(builtinProlog)
364 b.WriteString(f.Preamble)
366 for i, n := range names {
367 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
368 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
369 "#line %d \"not-type\"\n"+
370 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
371 "#line %d \"not-int-const\"\n"+
372 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
373 "#line %d \"not-num-const\"\n"+
374 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
375 "#line %d \"not-str-lit\"\n"+
376 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
377 i+1, i+1, n.C,
378 i+1, i+1, n.C,
379 i+1, i+1, n.C,
380 i+1, i+1, n.C,
381 i+1, i+1, n.C,
384 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
385 "int __cgo__1 = __cgo__2;\n")
387 stderr := p.gccErrors(b.Bytes())
388 if stderr == "" {
389 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
392 completed := false
393 sniff := make([]int, len(names))
394 const (
395 notType = 1 << iota
396 notIntConst
397 notNumConst
398 notStrLiteral
399 notDeclared
401 sawUnmatchedErrors := false
402 for _, line := range strings.Split(stderr, "\n") {
403 // Ignore warnings and random comments, with one
404 // exception: newer GCC versions will sometimes emit
405 // an error on a macro #define with a note referring
406 // to where the expansion occurs. We care about where
407 // the expansion occurs, so in that case treat the note
408 // as an error.
409 isError := strings.Contains(line, ": error:")
410 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
411 if !isError && !isErrorNote {
412 continue
415 c1 := strings.Index(line, ":")
416 if c1 < 0 {
417 continue
419 c2 := strings.Index(line[c1+1:], ":")
420 if c2 < 0 {
421 continue
423 c2 += c1 + 1
425 filename := line[:c1]
426 i, _ := strconv.Atoi(line[c1+1 : c2])
428 if i < 0 || i >= len(names) {
429 if isError {
430 sawUnmatchedErrors = true
432 continue
435 switch filename {
436 case "completed":
437 // Strictly speaking, there is no guarantee that seeing the error at completed:1
438 // (at the end of the file) means we've seen all the errors from earlier in the file,
439 // but usually it does. Certainly if we don't see the completed:1 error, we did
440 // not get all the errors we expected.
441 completed = true
443 case "not-declared":
444 sniff[i] |= notDeclared
445 case "not-type":
446 sniff[i] |= notType
447 case "not-int-const":
448 sniff[i] |= notIntConst
449 case "not-num-const":
450 sniff[i] |= notNumConst
451 case "not-str-lit":
452 sniff[i] |= notStrLiteral
453 default:
454 if isError {
455 sawUnmatchedErrors = true
457 continue
460 sawUnmatchedErrors = false
463 if !completed {
464 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
467 for i, n := range names {
468 switch sniff[i] {
469 default:
470 if sniff[i]&notDeclared != 0 && optional[n] {
471 // Ignore optional undeclared identifiers.
472 // Don't report an error, and skip adding n to the needType array.
473 continue
475 error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
476 case notStrLiteral | notType:
477 n.Kind = "iconst"
478 case notIntConst | notStrLiteral | notType:
479 n.Kind = "fconst"
480 case notIntConst | notNumConst | notType:
481 n.Kind = "sconst"
482 case notIntConst | notNumConst | notStrLiteral:
483 n.Kind = "type"
484 case notIntConst | notNumConst | notStrLiteral | notType:
485 n.Kind = "not-type"
487 needType = append(needType, n)
489 if nerrors > 0 {
490 // Check if compiling the preamble by itself causes any errors,
491 // because the messages we've printed out so far aren't helpful
492 // to users debugging preamble mistakes. See issue 8442.
493 preambleErrors := p.gccErrors([]byte(f.Preamble))
494 if len(preambleErrors) > 0 {
495 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
498 fatalf("unresolved names")
501 return needType
504 // loadDWARF parses the DWARF debug information generated
505 // by gcc to learn the details of the constants, variables, and types
506 // being referred to as C.xxx.
507 func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
508 // Extract the types from the DWARF section of an object
509 // from a well-formed C program. Gcc only generates DWARF info
510 // for symbols in the object file, so it is not enough to print the
511 // preamble and hope the symbols we care about will be there.
512 // Instead, emit
513 // __typeof__(names[i]) *__cgo__i;
514 // for each entry in names and then dereference the type we
515 // learn for __cgo__i.
516 var b bytes.Buffer
517 b.WriteString(builtinProlog)
518 b.WriteString(f.Preamble)
519 b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
520 for i, n := range names {
521 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
522 if n.Kind == "iconst" {
523 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
527 // We create a data block initialized with the values,
528 // so we can read them out of the object file.
529 fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
530 for _, n := range names {
531 if n.Kind == "iconst" {
532 fmt.Fprintf(&b, "\t%s,\n", n.C)
533 } else {
534 fmt.Fprintf(&b, "\t0,\n")
537 // for the last entry, we cannot use 0, otherwise
538 // in case all __cgodebug_data is zero initialized,
539 // LLVM-based gcc will place the it in the __DATA.__common
540 // zero-filled section (our debug/macho doesn't support
541 // this)
542 fmt.Fprintf(&b, "\t1\n")
543 fmt.Fprintf(&b, "};\n")
545 // do the same work for floats.
546 fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n")
547 for _, n := range names {
548 if n.Kind == "fconst" {
549 fmt.Fprintf(&b, "\t%s,\n", n.C)
550 } else {
551 fmt.Fprintf(&b, "\t0,\n")
554 fmt.Fprintf(&b, "\t1\n")
555 fmt.Fprintf(&b, "};\n")
557 // do the same work for strings.
558 for i, n := range names {
559 if n.Kind == "sconst" {
560 fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C)
561 fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C)
565 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
567 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
568 types := make([]dwarf.Type, len(names))
569 r := d.Reader()
570 for {
571 e, err := r.Next()
572 if err != nil {
573 fatalf("reading DWARF entry: %s", err)
575 if e == nil {
576 break
578 switch e.Tag {
579 case dwarf.TagVariable:
580 name, _ := e.Val(dwarf.AttrName).(string)
581 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
582 if name == "" || typOff == 0 {
583 if e.Val(dwarf.AttrSpecification) != nil {
584 // Since we are reading all the DWARF,
585 // assume we will see the variable elsewhere.
586 break
588 fatalf("malformed DWARF TagVariable entry")
590 if !strings.HasPrefix(name, "__cgo__") {
591 break
593 typ, err := d.Type(typOff)
594 if err != nil {
595 fatalf("loading DWARF type: %s", err)
597 t, ok := typ.(*dwarf.PtrType)
598 if !ok || t == nil {
599 fatalf("internal error: %s has non-pointer type", name)
601 i, err := strconv.Atoi(name[7:])
602 if err != nil {
603 fatalf("malformed __cgo__ name: %s", name)
605 types[i] = t.Type
606 p.recordTypedefs(t.Type, f.NamePos[names[i]])
608 if e.Tag != dwarf.TagCompileUnit {
609 r.SkipChildren()
613 // Record types and typedef information.
614 for i, n := range names {
615 if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
616 conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
619 for i, n := range names {
620 if types[i] == nil {
621 continue
623 pos := f.NamePos[n]
624 f, fok := types[i].(*dwarf.FuncType)
625 if n.Kind != "type" && fok {
626 n.Kind = "func"
627 n.FuncType = conv.FuncType(f, pos)
628 } else {
629 n.Type = conv.Type(types[i], pos)
630 switch n.Kind {
631 case "iconst":
632 if i < len(ints) {
633 if _, ok := types[i].(*dwarf.UintType); ok {
634 n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
635 } else {
636 n.Const = fmt.Sprintf("%#x", ints[i])
639 case "fconst":
640 if i >= len(floats) {
641 break
643 switch base(types[i]).(type) {
644 case *dwarf.IntType, *dwarf.UintType:
645 // This has an integer type so it's
646 // not really a floating point
647 // constant. This can happen when the
648 // C compiler complains about using
649 // the value as an integer constant,
650 // but not as a general constant.
651 // Treat this as a variable of the
652 // appropriate type, not a constant,
653 // to get C-style type handling,
654 // avoiding the problem that C permits
655 // uint64(-1) but Go does not.
656 // See issue 26066.
657 n.Kind = "var"
658 default:
659 n.Const = fmt.Sprintf("%f", floats[i])
661 case "sconst":
662 if i < len(strs) {
663 n.Const = fmt.Sprintf("%q", strs[i])
667 conv.FinishType(pos)
671 // recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
672 func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
673 p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
676 func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
677 if dtype == nil {
678 return
680 if visited[dtype] {
681 return
683 visited[dtype] = true
684 switch dt := dtype.(type) {
685 case *dwarf.TypedefType:
686 if strings.HasPrefix(dt.Name, "__builtin") {
687 // Don't look inside builtin types. There be dragons.
688 return
690 if !p.typedefs[dt.Name] {
691 p.typedefs[dt.Name] = true
692 p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
693 p.recordTypedefs1(dt.Type, pos, visited)
695 case *dwarf.PtrType:
696 p.recordTypedefs1(dt.Type, pos, visited)
697 case *dwarf.ArrayType:
698 p.recordTypedefs1(dt.Type, pos, visited)
699 case *dwarf.QualType:
700 p.recordTypedefs1(dt.Type, pos, visited)
701 case *dwarf.FuncType:
702 p.recordTypedefs1(dt.ReturnType, pos, visited)
703 for _, a := range dt.ParamType {
704 p.recordTypedefs1(a, pos, visited)
706 case *dwarf.StructType:
707 for _, f := range dt.Field {
708 p.recordTypedefs1(f.Type, pos, visited)
713 // prepareNames finalizes the Kind field of not-type names and sets
714 // the mangled name of all names.
715 func (p *Package) prepareNames(f *File) {
716 for _, n := range f.Name {
717 if n.Kind == "not-type" {
718 if n.Define == "" {
719 n.Kind = "var"
720 } else {
721 n.Kind = "macro"
722 n.FuncType = &FuncType{
723 Result: n.Type,
724 Go: &ast.FuncType{
725 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
730 p.mangleName(n)
734 // mangleName does name mangling to translate names
735 // from the original Go source files to the names
736 // used in the final Go files generated by cgo.
737 func (p *Package) mangleName(n *Name) {
738 // When using gccgo variables have to be
739 // exported so that they become global symbols
740 // that the C code can refer to.
741 prefix := "_C"
742 if *gccgo && n.IsVar() {
743 prefix = "C"
745 n.Mangle = prefix + n.Kind + "_" + n.Go
748 func (f *File) isMangledName(s string) bool {
749 prefix := "_C"
750 if strings.HasPrefix(s, prefix) {
751 t := s[len(prefix):]
752 for _, k := range nameKinds {
753 if strings.HasPrefix(t, k+"_") {
754 return true
758 return false
761 // rewriteCalls rewrites all calls that pass pointers to check that
762 // they follow the rules for passing pointers between Go and C.
763 // This reports whether the package needs to import unsafe as _cgo_unsafe.
764 func (p *Package) rewriteCalls(f *File) bool {
765 needsUnsafe := false
766 // Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first.
767 for _, call := range f.Calls {
768 if call.Done {
769 continue
771 start := f.offset(call.Call.Pos())
772 end := f.offset(call.Call.End())
773 str, nu := p.rewriteCall(f, call)
774 if str != "" {
775 f.Edit.Replace(start, end, str)
776 if nu {
777 needsUnsafe = true
781 return needsUnsafe
784 // rewriteCall rewrites one call to add pointer checks.
785 // If any pointer checks are required, we rewrite the call into a
786 // function literal that calls _cgoCheckPointer for each pointer
787 // argument and then calls the original function.
788 // This returns the rewritten call and whether the package needs to
789 // import unsafe as _cgo_unsafe.
790 // If it returns the empty string, the call did not need to be rewritten.
791 func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
792 // This is a call to C.xxx; set goname to "xxx".
793 // It may have already been mangled by rewriteName.
794 var goname string
795 switch fun := call.Call.Fun.(type) {
796 case *ast.SelectorExpr:
797 goname = fun.Sel.Name
798 case *ast.Ident:
799 goname = strings.TrimPrefix(fun.Name, "_C2func_")
800 goname = strings.TrimPrefix(goname, "_Cfunc_")
802 if goname == "" || goname == "malloc" {
803 return "", false
805 name := f.Name[goname]
806 if name == nil || name.Kind != "func" {
807 // Probably a type conversion.
808 return "", false
811 params := name.FuncType.Params
812 args := call.Call.Args
814 // Avoid a crash if the number of arguments doesn't match
815 // the number of parameters.
816 // This will be caught when the generated file is compiled.
817 if len(args) != len(params) {
818 return "", false
821 any := false
822 for i, param := range params {
823 if p.needsPointerCheck(f, param.Go, args[i]) {
824 any = true
825 break
828 if !any {
829 return "", false
832 // We need to rewrite this call.
834 // Rewrite C.f(p) to
835 // func() {
836 // _cgo0 := p
837 // _cgoCheckPointer(_cgo0, nil)
838 // C.f(_cgo0)
839 // }()
840 // Using a function literal like this lets us evaluate the
841 // function arguments only once while doing pointer checks.
842 // This is particularly useful when passing additional arguments
843 // to _cgoCheckPointer, as done in checkIndex and checkAddr.
845 // When the function argument is a conversion to unsafe.Pointer,
846 // we unwrap the conversion before checking the pointer,
847 // and then wrap again when calling C.f. This lets us check
848 // the real type of the pointer in some cases. See issue #25941.
850 // When the call to C.f is deferred, we use an additional function
851 // literal to evaluate the arguments at the right time.
852 // defer func() func() {
853 // _cgo0 := p
854 // return func() {
855 // _cgoCheckPointer(_cgo0, nil)
856 // C.f(_cgo0)
857 // }
858 // }()()
859 // This works because the defer statement evaluates the first
860 // function literal in order to get the function to call.
862 var sb bytes.Buffer
863 sb.WriteString("func() ")
864 if call.Deferred {
865 sb.WriteString("func() ")
868 needsUnsafe := false
869 result := false
870 twoResults := false
871 if !call.Deferred {
872 // Check whether this call expects two results.
873 for _, ref := range f.Ref {
874 if ref.Expr != &call.Call.Fun {
875 continue
877 if ref.Context == ctxCall2 {
878 sb.WriteString("(")
879 result = true
880 twoResults = true
882 break
885 // Add the result type, if any.
886 if name.FuncType.Result != nil {
887 rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
888 if rtype != name.FuncType.Result.Go {
889 needsUnsafe = true
891 sb.WriteString(gofmtLine(rtype))
892 result = true
895 // Add the second result type, if any.
896 if twoResults {
897 if name.FuncType.Result == nil {
898 // An explicit void result looks odd but it
899 // seems to be how cgo has worked historically.
900 sb.WriteString("_Ctype_void")
902 sb.WriteString(", error)")
906 sb.WriteString("{ ")
908 // Define _cgoN for each argument value.
909 // Write _cgoCheckPointer calls to sbCheck.
910 var sbCheck bytes.Buffer
911 for i, param := range params {
912 origArg := args[i]
913 arg, nu := p.mangle(f, &args[i])
914 if nu {
915 needsUnsafe = true
918 // Use "var x T = ..." syntax to explicitly convert untyped
919 // constants to the parameter type, to avoid a type mismatch.
920 ptype := p.rewriteUnsafe(param.Go)
922 if !p.needsPointerCheck(f, param.Go, args[i]) || param.BadPointer {
923 if ptype != param.Go {
924 needsUnsafe = true
926 fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i,
927 gofmtLine(ptype), gofmtPos(arg, origArg.Pos()))
928 continue
931 // Check for &a[i].
932 if p.checkIndex(&sb, &sbCheck, arg, i) {
933 continue
936 // Check for &x.
937 if p.checkAddr(&sb, &sbCheck, arg, i) {
938 continue
941 fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
942 fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i)
945 if call.Deferred {
946 sb.WriteString("return func() { ")
949 // Write out the calls to _cgoCheckPointer.
950 sb.WriteString(sbCheck.String())
952 if result {
953 sb.WriteString("return ")
956 m, nu := p.mangle(f, &call.Call.Fun)
957 if nu {
958 needsUnsafe = true
960 sb.WriteString(gofmtLine(m))
962 sb.WriteString("(")
963 for i := range params {
964 if i > 0 {
965 sb.WriteString(", ")
967 fmt.Fprintf(&sb, "_cgo%d", i)
969 sb.WriteString("); ")
970 if call.Deferred {
971 sb.WriteString("}")
973 sb.WriteString("}")
974 if call.Deferred {
975 sb.WriteString("()")
977 sb.WriteString("()")
979 return sb.String(), needsUnsafe
982 // needsPointerCheck reports whether the type t needs a pointer check.
983 // This is true if t is a pointer and if the value to which it points
984 // might contain a pointer.
985 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
986 // An untyped nil does not need a pointer check, and when
987 // _cgoCheckPointer returns the untyped nil the type assertion we
988 // are going to insert will fail. Easier to just skip nil arguments.
989 // TODO: Note that this fails if nil is shadowed.
990 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
991 return false
994 return p.hasPointer(f, t, true)
997 // hasPointer is used by needsPointerCheck. If top is true it returns
998 // whether t is or contains a pointer that might point to a pointer.
999 // If top is false it reports whether t is or contains a pointer.
1000 // f may be nil.
1001 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
1002 switch t := t.(type) {
1003 case *ast.ArrayType:
1004 if t.Len == nil {
1005 if !top {
1006 return true
1008 return p.hasPointer(f, t.Elt, false)
1010 return p.hasPointer(f, t.Elt, top)
1011 case *ast.StructType:
1012 for _, field := range t.Fields.List {
1013 if p.hasPointer(f, field.Type, top) {
1014 return true
1017 return false
1018 case *ast.StarExpr: // Pointer type.
1019 if !top {
1020 return true
1022 // Check whether this is a pointer to a C union (or class)
1023 // type that contains a pointer.
1024 if unionWithPointer[t.X] {
1025 return true
1027 return p.hasPointer(f, t.X, false)
1028 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
1029 return true
1030 case *ast.Ident:
1031 // TODO: Handle types defined within function.
1032 for _, d := range p.Decl {
1033 gd, ok := d.(*ast.GenDecl)
1034 if !ok || gd.Tok != token.TYPE {
1035 continue
1037 for _, spec := range gd.Specs {
1038 ts, ok := spec.(*ast.TypeSpec)
1039 if !ok {
1040 continue
1042 if ts.Name.Name == t.Name {
1043 return p.hasPointer(f, ts.Type, top)
1047 if def := typedef[t.Name]; def != nil {
1048 return p.hasPointer(f, def.Go, top)
1050 if t.Name == "string" {
1051 return !top
1053 if t.Name == "error" {
1054 return true
1056 if goTypes[t.Name] != nil {
1057 return false
1059 // We can't figure out the type. Conservative
1060 // approach is to assume it has a pointer.
1061 return true
1062 case *ast.SelectorExpr:
1063 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
1064 // Type defined in a different package.
1065 // Conservative approach is to assume it has a
1066 // pointer.
1067 return true
1069 if f == nil {
1070 // Conservative approach: assume pointer.
1071 return true
1073 name := f.Name[t.Sel.Name]
1074 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
1075 return p.hasPointer(f, name.Type.Go, top)
1077 // We can't figure out the type. Conservative
1078 // approach is to assume it has a pointer.
1079 return true
1080 default:
1081 error_(t.Pos(), "could not understand type %s", gofmt(t))
1082 return true
1086 // mangle replaces references to C names in arg with the mangled names,
1087 // rewriting calls when it finds them.
1088 // It removes the corresponding references in f.Ref and f.Calls, so that we
1089 // don't try to do the replacement again in rewriteRef or rewriteCall.
1090 func (p *Package) mangle(f *File, arg *ast.Expr) (ast.Expr, bool) {
1091 needsUnsafe := false
1092 f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) {
1093 px, ok := arg.(*ast.Expr)
1094 if !ok {
1095 return
1097 sel, ok := (*px).(*ast.SelectorExpr)
1098 if ok {
1099 if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
1100 return
1103 for _, r := range f.Ref {
1104 if r.Expr == px {
1105 *px = p.rewriteName(f, r)
1106 r.Done = true
1107 break
1111 return
1114 call, ok := (*px).(*ast.CallExpr)
1115 if !ok {
1116 return
1119 for _, c := range f.Calls {
1120 if !c.Done && c.Call.Lparen == call.Lparen {
1121 cstr, nu := p.rewriteCall(f, c)
1122 if cstr != "" {
1123 // Smuggle the rewritten call through an ident.
1124 *px = ast.NewIdent(cstr)
1125 if nu {
1126 needsUnsafe = true
1128 c.Done = true
1133 return *arg, needsUnsafe
1136 // checkIndex checks whether arg has the form &a[i], possibly inside
1137 // type conversions. If so, then in the general case it writes
1138 // _cgoIndexNN := a
1139 // _cgoNN := &cgoIndexNN[i] // with type conversions, if any
1140 // to sb, and writes
1141 // _cgoCheckPointer(_cgoNN, _cgoIndexNN)
1142 // to sbCheck, and returns true. If a is a simple variable or field reference,
1143 // it writes
1144 // _cgoIndexNN := &a
1145 // and dereferences the uses of _cgoIndexNN. Taking the address avoids
1146 // making a copy of an array.
1148 // This tells _cgoCheckPointer to check the complete contents of the
1149 // slice or array being indexed, but no other part of the memory allocation.
1150 func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1151 // Strip type conversions.
1152 x := arg
1153 for {
1154 c, ok := x.(*ast.CallExpr)
1155 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
1156 break
1158 x = c.Args[0]
1160 u, ok := x.(*ast.UnaryExpr)
1161 if !ok || u.Op != token.AND {
1162 return false
1164 index, ok := u.X.(*ast.IndexExpr)
1165 if !ok {
1166 return false
1169 addr := ""
1170 deref := ""
1171 if p.isVariable(index.X) {
1172 addr = "&"
1173 deref = "*"
1176 fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos()))
1177 origX := index.X
1178 index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
1179 if deref == "*" {
1180 index.X = &ast.StarExpr{X: index.X}
1182 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1183 index.X = origX
1185 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
1187 return true
1190 // checkAddr checks whether arg has the form &x, possibly inside type
1191 // conversions. If so, it writes
1192 // _cgoBaseNN := &x
1193 // _cgoNN := _cgoBaseNN // with type conversions, if any
1194 // to sb, and writes
1195 // _cgoCheckPointer(_cgoBaseNN, true)
1196 // to sbCheck, and returns true. This tells _cgoCheckPointer to check
1197 // just the contents of the pointer being passed, not any other part
1198 // of the memory allocation. This is run after checkIndex, which looks
1199 // for the special case of &a[i], which requires different checks.
1200 func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1201 // Strip type conversions.
1202 px := &arg
1203 for {
1204 c, ok := (*px).(*ast.CallExpr)
1205 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
1206 break
1208 px = &c.Args[0]
1210 if u, ok := (*px).(*ast.UnaryExpr); !ok || u.Op != token.AND {
1211 return false
1214 fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
1216 origX := *px
1217 *px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
1218 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1219 *px = origX
1221 // Use "0 == 0" to do the right thing in the unlikely event
1222 // that "true" is shadowed.
1223 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoBase%d, 0 == 0); ", i)
1225 return true
1228 // isType reports whether the expression is definitely a type.
1229 // This is conservative--it returns false for an unknown identifier.
1230 func (p *Package) isType(t ast.Expr) bool {
1231 switch t := t.(type) {
1232 case *ast.SelectorExpr:
1233 id, ok := t.X.(*ast.Ident)
1234 if !ok {
1235 return false
1237 if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
1238 return true
1240 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
1241 return true
1243 return false
1244 case *ast.Ident:
1245 // TODO: This ignores shadowing.
1246 switch t.Name {
1247 case "unsafe.Pointer", "bool", "byte",
1248 "complex64", "complex128",
1249 "error",
1250 "float32", "float64",
1251 "int", "int8", "int16", "int32", "int64",
1252 "rune", "string",
1253 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1255 return true
1257 if strings.HasPrefix(t.Name, "_Ctype_") {
1258 return true
1260 case *ast.ParenExpr:
1261 return p.isType(t.X)
1262 case *ast.StarExpr:
1263 return p.isType(t.X)
1264 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
1265 *ast.MapType, *ast.ChanType:
1267 return true
1269 return false
1272 // isVariable reports whether x is a variable, possibly with field references.
1273 func (p *Package) isVariable(x ast.Expr) bool {
1274 switch x := x.(type) {
1275 case *ast.Ident:
1276 return true
1277 case *ast.SelectorExpr:
1278 return p.isVariable(x.X)
1279 case *ast.IndexExpr:
1280 return true
1282 return false
1285 // rewriteUnsafe returns a version of t with references to unsafe.Pointer
1286 // rewritten to use _cgo_unsafe.Pointer instead.
1287 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
1288 switch t := t.(type) {
1289 case *ast.Ident:
1290 // We don't see a SelectorExpr for unsafe.Pointer;
1291 // this is created by code in this file.
1292 if t.Name == "unsafe.Pointer" {
1293 return ast.NewIdent("_cgo_unsafe.Pointer")
1295 case *ast.ArrayType:
1296 t1 := p.rewriteUnsafe(t.Elt)
1297 if t1 != t.Elt {
1298 r := *t
1299 r.Elt = t1
1300 return &r
1302 case *ast.StructType:
1303 changed := false
1304 fields := *t.Fields
1305 fields.List = nil
1306 for _, f := range t.Fields.List {
1307 ft := p.rewriteUnsafe(f.Type)
1308 if ft == f.Type {
1309 fields.List = append(fields.List, f)
1310 } else {
1311 fn := *f
1312 fn.Type = ft
1313 fields.List = append(fields.List, &fn)
1314 changed = true
1317 if changed {
1318 r := *t
1319 r.Fields = &fields
1320 return &r
1322 case *ast.StarExpr: // Pointer type.
1323 x1 := p.rewriteUnsafe(t.X)
1324 if x1 != t.X {
1325 r := *t
1326 r.X = x1
1327 return &r
1330 return t
1333 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1334 // Go equivalents, now that we have figured out the meaning of all
1335 // the xxx. In *godefs mode, rewriteRef replaces the names
1336 // with full definitions instead of mangled names.
1337 func (p *Package) rewriteRef(f *File) {
1338 // Keep a list of all the functions, to remove the ones
1339 // only used as expressions and avoid generating bridge
1340 // code for them.
1341 functions := make(map[string]bool)
1343 for _, n := range f.Name {
1344 if n.Kind == "func" {
1345 functions[n.Go] = false
1349 // Now that we have all the name types filled in,
1350 // scan through the Refs to identify the ones that
1351 // are trying to do a ,err call. Also check that
1352 // functions are only used in calls.
1353 for _, r := range f.Ref {
1354 if r.Name.IsConst() && r.Name.Const == "" {
1355 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1358 if r.Name.Kind == "func" {
1359 switch r.Context {
1360 case ctxCall, ctxCall2:
1361 functions[r.Name.Go] = true
1365 expr := p.rewriteName(f, r)
1367 if *godefs {
1368 // Substitute definition for mangled type name.
1369 if id, ok := expr.(*ast.Ident); ok {
1370 if t := typedef[id.Name]; t != nil {
1371 expr = t.Go
1373 if id.Name == r.Name.Mangle && r.Name.Const != "" {
1374 expr = ast.NewIdent(r.Name.Const)
1379 // Copy position information from old expr into new expr,
1380 // in case expression being replaced is first on line.
1381 // See golang.org/issue/6563.
1382 pos := (*r.Expr).Pos()
1383 if x, ok := expr.(*ast.Ident); ok {
1384 expr = &ast.Ident{NamePos: pos, Name: x.Name}
1387 // Change AST, because some later processing depends on it,
1388 // and also because -godefs mode still prints the AST.
1389 old := *r.Expr
1390 *r.Expr = expr
1392 // Record source-level edit for cgo output.
1393 if !r.Done {
1394 // Prepend a space in case the earlier code ends
1395 // with '/', which would give us a "//" comment.
1396 repl := " " + gofmtPos(expr, old.Pos())
1397 end := fset.Position(old.End())
1398 // Subtract 1 from the column if we are going to
1399 // append a close parenthesis. That will set the
1400 // correct column for the following characters.
1401 sub := 0
1402 if r.Name.Kind != "type" {
1403 sub = 1
1405 if end.Column > sub {
1406 repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub)
1408 if r.Name.Kind != "type" {
1409 repl = "(" + repl + ")"
1411 f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
1415 // Remove functions only used as expressions, so their respective
1416 // bridge functions are not generated.
1417 for name, used := range functions {
1418 if !used {
1419 delete(f.Name, name)
1424 // rewriteName returns the expression used to rewrite a reference.
1425 func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
1426 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
1427 switch r.Context {
1428 case ctxCall, ctxCall2:
1429 if r.Name.Kind != "func" {
1430 if r.Name.Kind == "type" {
1431 r.Context = ctxType
1432 if r.Name.Type == nil {
1433 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1434 break
1436 expr = r.Name.Type.Go
1437 break
1439 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1440 break
1442 if r.Context == ctxCall2 {
1443 if r.Name.Go == "_CMalloc" {
1444 error_(r.Pos(), "no two-result form for C.malloc")
1445 break
1447 // Invent new Name for the two-result function.
1448 n := f.Name["2"+r.Name.Go]
1449 if n == nil {
1450 n = new(Name)
1451 *n = *r.Name
1452 n.AddError = true
1453 n.Mangle = "_C2func_" + n.Go
1454 f.Name["2"+r.Name.Go] = n
1456 expr = ast.NewIdent(n.Mangle)
1457 r.Name = n
1458 break
1460 case ctxExpr:
1461 switch r.Name.Kind {
1462 case "func":
1463 if builtinDefs[r.Name.C] != "" {
1464 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
1467 // Function is being used in an expression, to e.g. pass around a C function pointer.
1468 // Create a new Name for this Ref which causes the variable to be declared in Go land.
1469 fpName := "fp_" + r.Name.Go
1470 name := f.Name[fpName]
1471 if name == nil {
1472 name = &Name{
1473 Go: fpName,
1474 C: r.Name.C,
1475 Kind: "fpvar",
1476 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1478 p.mangleName(name)
1479 f.Name[fpName] = name
1481 r.Name = name
1482 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1483 // function is defined in out.go and simply returns its argument. See
1484 // issue 7757.
1485 expr = &ast.CallExpr{
1486 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1487 Args: []ast.Expr{ast.NewIdent(name.Mangle)},
1489 case "type":
1490 // Okay - might be new(T)
1491 if r.Name.Type == nil {
1492 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1493 break
1495 expr = r.Name.Type.Go
1496 case "var":
1497 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1498 case "macro":
1499 expr = &ast.CallExpr{Fun: expr}
1501 case ctxSelector:
1502 if r.Name.Kind == "var" {
1503 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1504 } else {
1505 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
1507 case ctxType:
1508 if r.Name.Kind != "type" {
1509 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1510 } else if r.Name.Type == nil {
1511 // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1512 // GCC won't raise an error when using pointers to such unknown types.
1513 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1514 } else {
1515 expr = r.Name.Type.Go
1517 default:
1518 if r.Name.Kind == "func" {
1519 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1522 return expr
1525 // gofmtPos returns the gofmt-formatted string for an AST node,
1526 // with a comment setting the position before the node.
1527 func gofmtPos(n ast.Expr, pos token.Pos) string {
1528 s := gofmtLine(n)
1529 p := fset.Position(pos)
1530 if p.Column == 0 {
1531 return s
1533 return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
1536 // gccBaseCmd returns the start of the compiler command line.
1537 // It uses $CC if set, or else $GCC, or else the compiler recorded
1538 // during the initial build as defaultCC.
1539 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1540 func (p *Package) gccBaseCmd() []string {
1541 // Use $CC if set, since that's what the build uses.
1542 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
1543 return ret
1545 // Try $GCC if set, since that's what we used to use.
1546 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
1547 return ret
1549 return strings.Fields(defaultCC(goos, goarch))
1552 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1553 func (p *Package) gccMachine() []string {
1554 switch goarch {
1555 case "amd64":
1556 return []string{"-m64"}
1557 case "386":
1558 return []string{"-m32"}
1559 case "arm":
1560 return []string{"-marm"} // not thumb
1561 case "s390":
1562 return []string{"-m31"}
1563 case "s390x":
1564 return []string{"-m64"}
1565 case "mips64", "mips64le":
1566 return []string{"-mabi=64"}
1567 case "mips", "mipsle":
1568 return []string{"-mabi=32"}
1569 case "ppc64":
1570 if goos == "aix" {
1571 return []string{"-maix64"}
1574 return nil
1577 func gccTmp() string {
1578 return *objDir + "_cgo_.o"
1581 // gccCmd returns the gcc command line to use for compiling
1582 // the input.
1583 func (p *Package) gccCmd() []string {
1584 c := append(p.gccBaseCmd(),
1585 "-w", // no warnings
1586 "-Wno-error", // warnings are not errors
1587 "-o"+gccTmp(), // write object to tmp
1588 "-gdwarf-2", // generate DWARF v2 debugging symbols
1589 "-c", // do not link
1590 "-xc", // input language is C
1592 if p.GccIsClang {
1593 c = append(c,
1594 "-ferror-limit=0",
1595 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1596 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1597 // flag to disable the warning. Yes, really good diagnostics, clang.
1598 "-Wno-unknown-warning-option",
1599 "-Wno-unneeded-internal-declaration",
1600 "-Wno-unused-function",
1601 "-Qunused-arguments",
1602 // Clang embeds prototypes for some builtin functions,
1603 // like malloc and calloc, but all size_t parameters are
1604 // incorrectly typed unsigned long. We work around that
1605 // by disabling the builtin functions (this is safe as
1606 // it won't affect the actual compilation of the C code).
1607 // See: https://golang.org/issue/6506.
1608 "-fno-builtin",
1612 c = append(c, p.GccOptions...)
1613 c = append(c, p.gccMachine()...)
1614 if goos == "aix" {
1615 c = append(c, "-maix64")
1616 c = append(c, "-mcmodel=large")
1618 c = append(c, "-") //read input from standard input
1619 return c
1622 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
1623 // returns the corresponding DWARF data and, if present, debug data block.
1624 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1625 runGcc(stdin, p.gccCmd())
1627 isDebugInts := func(s string) bool {
1628 // Some systems use leading _ to denote non-assembly symbols.
1629 return s == "__cgodebug_ints" || s == "___cgodebug_ints"
1631 isDebugFloats := func(s string) bool {
1632 // Some systems use leading _ to denote non-assembly symbols.
1633 return s == "__cgodebug_floats" || s == "___cgodebug_floats"
1635 indexOfDebugStr := func(s string) int {
1636 // Some systems use leading _ to denote non-assembly symbols.
1637 if strings.HasPrefix(s, "___") {
1638 s = s[1:]
1640 if strings.HasPrefix(s, "__cgodebug_str__") {
1641 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
1642 return n
1645 return -1
1647 indexOfDebugStrlen := func(s string) int {
1648 // Some systems use leading _ to denote non-assembly symbols.
1649 if strings.HasPrefix(s, "___") {
1650 s = s[1:]
1652 if strings.HasPrefix(s, "__cgodebug_strlen__") {
1653 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
1654 return n
1657 return -1
1660 strs = make([]string, nnames)
1662 strdata := make(map[int]string, nnames)
1663 strlens := make(map[int]int, nnames)
1665 buildStrings := func() {
1666 for n, strlen := range strlens {
1667 data := strdata[n]
1668 if len(data) <= strlen {
1669 fatalf("invalid string literal")
1671 strs[n] = data[:strlen]
1675 if f, err := macho.Open(gccTmp()); err == nil {
1676 defer f.Close()
1677 d, err := f.DWARF()
1678 if err != nil {
1679 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1681 bo := f.ByteOrder
1682 if f.Symtab != nil {
1683 for i := range f.Symtab.Syms {
1684 s := &f.Symtab.Syms[i]
1685 switch {
1686 case isDebugInts(s.Name):
1687 // Found it. Now find data section.
1688 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1689 sect := f.Sections[i]
1690 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1691 if sdat, err := sect.Data(); err == nil {
1692 data := sdat[s.Value-sect.Addr:]
1693 ints = make([]int64, len(data)/8)
1694 for i := range ints {
1695 ints[i] = int64(bo.Uint64(data[i*8:]))
1700 case isDebugFloats(s.Name):
1701 // Found it. Now find data section.
1702 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1703 sect := f.Sections[i]
1704 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1705 if sdat, err := sect.Data(); err == nil {
1706 data := sdat[s.Value-sect.Addr:]
1707 floats = make([]float64, len(data)/8)
1708 for i := range floats {
1709 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1714 default:
1715 if n := indexOfDebugStr(s.Name); n != -1 {
1716 // Found it. Now find data section.
1717 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1718 sect := f.Sections[i]
1719 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1720 if sdat, err := sect.Data(); err == nil {
1721 data := sdat[s.Value-sect.Addr:]
1722 strdata[n] = string(data)
1726 break
1728 if n := indexOfDebugStrlen(s.Name); n != -1 {
1729 // Found it. Now find data section.
1730 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1731 sect := f.Sections[i]
1732 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1733 if sdat, err := sect.Data(); err == nil {
1734 data := sdat[s.Value-sect.Addr:]
1735 strlen := bo.Uint64(data[:8])
1736 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1737 fatalf("string literal too big")
1739 strlens[n] = int(strlen)
1743 break
1748 buildStrings()
1750 return d, ints, floats, strs
1753 if f, err := elf.Open(gccTmp()); err == nil {
1754 defer f.Close()
1755 d, err := f.DWARF()
1756 if err != nil {
1757 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1759 bo := f.ByteOrder
1760 symtab, err := f.Symbols()
1761 if err == nil {
1762 for i := range symtab {
1763 s := &symtab[i]
1764 switch {
1765 case isDebugInts(s.Name):
1766 // Found it. Now find data section.
1767 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1768 sect := f.Sections[i]
1769 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1770 if sdat, err := sect.Data(); err == nil {
1771 data := sdat[s.Value-sect.Addr:]
1772 ints = make([]int64, len(data)/8)
1773 for i := range ints {
1774 ints[i] = int64(bo.Uint64(data[i*8:]))
1779 case isDebugFloats(s.Name):
1780 // Found it. Now find data section.
1781 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1782 sect := f.Sections[i]
1783 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1784 if sdat, err := sect.Data(); err == nil {
1785 data := sdat[s.Value-sect.Addr:]
1786 floats = make([]float64, len(data)/8)
1787 for i := range floats {
1788 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1793 default:
1794 if n := indexOfDebugStr(s.Name); n != -1 {
1795 // Found it. Now find data section.
1796 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1797 sect := f.Sections[i]
1798 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1799 if sdat, err := sect.Data(); err == nil {
1800 data := sdat[s.Value-sect.Addr:]
1801 strdata[n] = string(data)
1805 break
1807 if n := indexOfDebugStrlen(s.Name); n != -1 {
1808 // Found it. Now find data section.
1809 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1810 sect := f.Sections[i]
1811 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1812 if sdat, err := sect.Data(); err == nil {
1813 data := sdat[s.Value-sect.Addr:]
1814 strlen := bo.Uint64(data[:8])
1815 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1816 fatalf("string literal too big")
1818 strlens[n] = int(strlen)
1822 break
1827 buildStrings()
1829 return d, ints, floats, strs
1832 if f, err := pe.Open(gccTmp()); err == nil {
1833 defer f.Close()
1834 d, err := f.DWARF()
1835 if err != nil {
1836 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1838 bo := binary.LittleEndian
1839 for _, s := range f.Symbols {
1840 switch {
1841 case isDebugInts(s.Name):
1842 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1843 sect := f.Sections[i]
1844 if s.Value < sect.Size {
1845 if sdat, err := sect.Data(); err == nil {
1846 data := sdat[s.Value:]
1847 ints = make([]int64, len(data)/8)
1848 for i := range ints {
1849 ints[i] = int64(bo.Uint64(data[i*8:]))
1854 case isDebugFloats(s.Name):
1855 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1856 sect := f.Sections[i]
1857 if s.Value < sect.Size {
1858 if sdat, err := sect.Data(); err == nil {
1859 data := sdat[s.Value:]
1860 floats = make([]float64, len(data)/8)
1861 for i := range floats {
1862 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1867 default:
1868 if n := indexOfDebugStr(s.Name); n != -1 {
1869 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1870 sect := f.Sections[i]
1871 if s.Value < sect.Size {
1872 if sdat, err := sect.Data(); err == nil {
1873 data := sdat[s.Value:]
1874 strdata[n] = string(data)
1878 break
1880 if n := indexOfDebugStrlen(s.Name); n != -1 {
1881 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1882 sect := f.Sections[i]
1883 if s.Value < sect.Size {
1884 if sdat, err := sect.Data(); err == nil {
1885 data := sdat[s.Value:]
1886 strlen := bo.Uint64(data[:8])
1887 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1888 fatalf("string literal too big")
1890 strlens[n] = int(strlen)
1894 break
1899 buildStrings()
1901 return d, ints, floats, strs
1904 if f, err := xcoff.Open(gccTmp()); err == nil {
1905 defer f.Close()
1906 d, err := f.DWARF()
1907 if err != nil {
1908 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1910 bo := binary.BigEndian
1911 for _, s := range f.Symbols {
1912 switch {
1913 case isDebugInts(s.Name):
1914 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1915 sect := f.Sections[i]
1916 if s.Value < sect.Size {
1917 if sdat, err := sect.Data(); err == nil {
1918 data := sdat[s.Value:]
1919 ints = make([]int64, len(data)/8)
1920 for i := range ints {
1921 ints[i] = int64(bo.Uint64(data[i*8:]))
1926 case isDebugFloats(s.Name):
1927 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1928 sect := f.Sections[i]
1929 if s.Value < sect.Size {
1930 if sdat, err := sect.Data(); err == nil {
1931 data := sdat[s.Value:]
1932 floats = make([]float64, len(data)/8)
1933 for i := range floats {
1934 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1939 default:
1940 if n := indexOfDebugStr(s.Name); n != -1 {
1941 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1942 sect := f.Sections[i]
1943 if s.Value < sect.Size {
1944 if sdat, err := sect.Data(); err == nil {
1945 data := sdat[s.Value:]
1946 strdata[n] = string(data)
1950 break
1952 if n := indexOfDebugStrlen(s.Name); n != -1 {
1953 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1954 sect := f.Sections[i]
1955 if s.Value < sect.Size {
1956 if sdat, err := sect.Data(); err == nil {
1957 data := sdat[s.Value:]
1958 strlen := bo.Uint64(data[:8])
1959 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1960 fatalf("string literal too big")
1962 strlens[n] = int(strlen)
1966 break
1971 buildStrings()
1972 return d, ints, floats, strs
1974 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
1975 panic("not reached")
1978 // gccDefines runs gcc -E -dM -xc - over the C program stdin
1979 // and returns the corresponding standard output, which is the
1980 // #defines that gcc encountered while processing the input
1981 // and its included files.
1982 func (p *Package) gccDefines(stdin []byte) string {
1983 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
1984 base = append(base, p.gccMachine()...)
1985 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
1986 return stdout
1989 // gccErrors runs gcc over the C program stdin and returns
1990 // the errors that gcc prints. That is, this function expects
1991 // gcc to fail.
1992 func (p *Package) gccErrors(stdin []byte) string {
1993 // TODO(rsc): require failure
1994 args := p.gccCmd()
1996 // Optimization options can confuse the error messages; remove them.
1997 nargs := make([]string, 0, len(args))
1998 for _, arg := range args {
1999 if !strings.HasPrefix(arg, "-O") {
2000 nargs = append(nargs, arg)
2004 // Force -O0 optimization but keep the trailing "-" at the end.
2005 nargs = append(nargs, "-O0")
2006 nl := len(nargs)
2007 nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
2009 if *debugGcc {
2010 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
2011 os.Stderr.Write(stdin)
2012 fmt.Fprint(os.Stderr, "EOF\n")
2014 stdout, stderr, _ := run(stdin, nargs)
2015 if *debugGcc {
2016 os.Stderr.Write(stdout)
2017 os.Stderr.Write(stderr)
2019 return string(stderr)
2022 // runGcc runs the gcc command line args with stdin on standard input.
2023 // If the command exits with a non-zero exit status, runGcc prints
2024 // details about what was run and exits.
2025 // Otherwise runGcc returns the data written to standard output and standard error.
2026 // Note that for some of the uses we expect useful data back
2027 // on standard error, but for those uses gcc must still exit 0.
2028 func runGcc(stdin []byte, args []string) (string, string) {
2029 if *debugGcc {
2030 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
2031 os.Stderr.Write(stdin)
2032 fmt.Fprint(os.Stderr, "EOF\n")
2034 stdout, stderr, ok := run(stdin, args)
2035 if *debugGcc {
2036 os.Stderr.Write(stdout)
2037 os.Stderr.Write(stderr)
2039 if !ok {
2040 os.Stderr.Write(stderr)
2041 os.Exit(2)
2043 return string(stdout), string(stderr)
2046 // A typeConv is a translator from dwarf types to Go types
2047 // with equivalent memory layout.
2048 type typeConv struct {
2049 // Cache of already-translated or in-progress types.
2050 m map[string]*Type
2052 // Map from types to incomplete pointers to those types.
2053 ptrs map[string][]*Type
2054 // Keys of ptrs in insertion order (deterministic worklist)
2055 // ptrKeys contains exactly the keys in ptrs.
2056 ptrKeys []dwarf.Type
2058 // Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
2059 getTypeIDs map[string]bool
2061 // Predeclared types.
2062 bool ast.Expr
2063 byte ast.Expr // denotes padding
2064 int8, int16, int32, int64 ast.Expr
2065 uint8, uint16, uint32, uint64, uintptr ast.Expr
2066 float32, float64 ast.Expr
2067 complex64, complex128 ast.Expr
2068 void ast.Expr
2069 string ast.Expr
2070 goVoid ast.Expr // _Ctype_void, denotes C's void
2071 goVoidPtr ast.Expr // unsafe.Pointer or *byte
2073 ptrSize int64
2074 intSize int64
2077 var tagGen int
2078 var typedef = make(map[string]*Type)
2079 var goIdent = make(map[string]*ast.Ident)
2081 // unionWithPointer is true for a Go type that represents a C union (or class)
2082 // that may contain a pointer. This is used for cgo pointer checking.
2083 var unionWithPointer = make(map[ast.Expr]bool)
2085 // anonymousStructTag provides a consistent tag for an anonymous struct.
2086 // The same dwarf.StructType pointer will always get the same tag.
2087 var anonymousStructTag = make(map[*dwarf.StructType]string)
2089 func (c *typeConv) Init(ptrSize, intSize int64) {
2090 c.ptrSize = ptrSize
2091 c.intSize = intSize
2092 c.m = make(map[string]*Type)
2093 c.ptrs = make(map[string][]*Type)
2094 c.getTypeIDs = make(map[string]bool)
2095 c.bool = c.Ident("bool")
2096 c.byte = c.Ident("byte")
2097 c.int8 = c.Ident("int8")
2098 c.int16 = c.Ident("int16")
2099 c.int32 = c.Ident("int32")
2100 c.int64 = c.Ident("int64")
2101 c.uint8 = c.Ident("uint8")
2102 c.uint16 = c.Ident("uint16")
2103 c.uint32 = c.Ident("uint32")
2104 c.uint64 = c.Ident("uint64")
2105 c.uintptr = c.Ident("uintptr")
2106 c.float32 = c.Ident("float32")
2107 c.float64 = c.Ident("float64")
2108 c.complex64 = c.Ident("complex64")
2109 c.complex128 = c.Ident("complex128")
2110 c.void = c.Ident("void")
2111 c.string = c.Ident("string")
2112 c.goVoid = c.Ident("_Ctype_void")
2114 // Normally cgo translates void* to unsafe.Pointer,
2115 // but for historical reasons -godefs uses *byte instead.
2116 if *godefs {
2117 c.goVoidPtr = &ast.StarExpr{X: c.byte}
2118 } else {
2119 c.goVoidPtr = c.Ident("unsafe.Pointer")
2123 // base strips away qualifiers and typedefs to get the underlying type
2124 func base(dt dwarf.Type) dwarf.Type {
2125 for {
2126 if d, ok := dt.(*dwarf.QualType); ok {
2127 dt = d.Type
2128 continue
2130 if d, ok := dt.(*dwarf.TypedefType); ok {
2131 dt = d.Type
2132 continue
2134 break
2136 return dt
2139 // unqual strips away qualifiers from a DWARF type.
2140 // In general we don't care about top-level qualifiers.
2141 func unqual(dt dwarf.Type) dwarf.Type {
2142 for {
2143 if d, ok := dt.(*dwarf.QualType); ok {
2144 dt = d.Type
2145 } else {
2146 break
2149 return dt
2152 // Map from dwarf text names to aliases we use in package "C".
2153 var dwarfToName = map[string]string{
2154 "long int": "long",
2155 "long unsigned int": "ulong",
2156 "unsigned int": "uint",
2157 "short unsigned int": "ushort",
2158 "unsigned short": "ushort", // Used by Clang; issue 13129.
2159 "short int": "short",
2160 "long long int": "longlong",
2161 "long long unsigned int": "ulonglong",
2162 "signed char": "schar",
2163 "unsigned char": "uchar",
2166 const signedDelta = 64
2168 // String returns the current type representation. Format arguments
2169 // are assembled within this method so that any changes in mutable
2170 // values are taken into account.
2171 func (tr *TypeRepr) String() string {
2172 if len(tr.Repr) == 0 {
2173 return ""
2175 if len(tr.FormatArgs) == 0 {
2176 return tr.Repr
2178 return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
2181 // Empty reports whether the result of String would be "".
2182 func (tr *TypeRepr) Empty() bool {
2183 return len(tr.Repr) == 0
2186 // Set modifies the type representation.
2187 // If fargs are provided, repr is used as a format for fmt.Sprintf.
2188 // Otherwise, repr is used unprocessed as the type representation.
2189 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
2190 tr.Repr = repr
2191 tr.FormatArgs = fargs
2194 // FinishType completes any outstanding type mapping work.
2195 // In particular, it resolves incomplete pointer types.
2196 func (c *typeConv) FinishType(pos token.Pos) {
2197 // Completing one pointer type might produce more to complete.
2198 // Keep looping until they're all done.
2199 for len(c.ptrKeys) > 0 {
2200 dtype := c.ptrKeys[0]
2201 dtypeKey := dtype.String()
2202 c.ptrKeys = c.ptrKeys[1:]
2203 ptrs := c.ptrs[dtypeKey]
2204 delete(c.ptrs, dtypeKey)
2206 // Note Type might invalidate c.ptrs[dtypeKey].
2207 t := c.Type(dtype, pos)
2208 for _, ptr := range ptrs {
2209 ptr.Go.(*ast.StarExpr).X = t.Go
2210 ptr.C.Set("%s*", t.C)
2215 // Type returns a *Type with the same memory layout as
2216 // dtype when used as the type of a variable or a struct field.
2217 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
2218 return c.loadType(dtype, pos, "")
2221 // loadType recursively loads the requested dtype and its dependency graph.
2222 func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type {
2223 // Always recompute bad pointer typedefs, as the set of such
2224 // typedefs changes as we see more types.
2225 checkCache := true
2226 if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) {
2227 checkCache = false
2230 // The cache key should be relative to its parent.
2231 // See issue https://golang.org/issue/31891
2232 key := parent + " > " + dtype.String()
2234 if checkCache {
2235 if t, ok := c.m[key]; ok {
2236 if t.Go == nil {
2237 fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
2239 return t
2243 t := new(Type)
2244 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
2245 t.Align = -1
2246 t.C = &TypeRepr{Repr: dtype.Common().Name}
2247 c.m[key] = t
2249 switch dt := dtype.(type) {
2250 default:
2251 fatalf("%s: unexpected type: %s", lineno(pos), dtype)
2253 case *dwarf.AddrType:
2254 if t.Size != c.ptrSize {
2255 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
2257 t.Go = c.uintptr
2258 t.Align = t.Size
2260 case *dwarf.ArrayType:
2261 if dt.StrideBitSize > 0 {
2262 // Cannot represent bit-sized elements in Go.
2263 t.Go = c.Opaque(t.Size)
2264 break
2266 count := dt.Count
2267 if count == -1 {
2268 // Indicates flexible array member, which Go doesn't support.
2269 // Translate to zero-length array instead.
2270 count = 0
2272 sub := c.Type(dt.Type, pos)
2273 t.Align = sub.Align
2274 t.Go = &ast.ArrayType{
2275 Len: c.intExpr(count),
2276 Elt: sub.Go,
2278 // Recalculate t.Size now that we know sub.Size.
2279 t.Size = count * sub.Size
2280 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
2282 case *dwarf.BoolType:
2283 t.Go = c.bool
2284 t.Align = 1
2286 case *dwarf.CharType:
2287 if t.Size != 1 {
2288 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
2290 t.Go = c.int8
2291 t.Align = 1
2293 case *dwarf.EnumType:
2294 if t.Align = t.Size; t.Align >= c.ptrSize {
2295 t.Align = c.ptrSize
2297 t.C.Set("enum " + dt.EnumName)
2298 signed := 0
2299 t.EnumValues = make(map[string]int64)
2300 for _, ev := range dt.Val {
2301 t.EnumValues[ev.Name] = ev.Val
2302 if ev.Val < 0 {
2303 signed = signedDelta
2306 switch t.Size + int64(signed) {
2307 default:
2308 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
2309 case 1:
2310 t.Go = c.uint8
2311 case 2:
2312 t.Go = c.uint16
2313 case 4:
2314 t.Go = c.uint32
2315 case 8:
2316 t.Go = c.uint64
2317 case 1 + signedDelta:
2318 t.Go = c.int8
2319 case 2 + signedDelta:
2320 t.Go = c.int16
2321 case 4 + signedDelta:
2322 t.Go = c.int32
2323 case 8 + signedDelta:
2324 t.Go = c.int64
2327 case *dwarf.FloatType:
2328 switch t.Size {
2329 default:
2330 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
2331 case 4:
2332 t.Go = c.float32
2333 case 8:
2334 t.Go = c.float64
2336 if t.Align = t.Size; t.Align >= c.ptrSize {
2337 t.Align = c.ptrSize
2340 case *dwarf.ComplexType:
2341 switch t.Size {
2342 default:
2343 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
2344 case 8:
2345 t.Go = c.complex64
2346 case 16:
2347 t.Go = c.complex128
2349 if t.Align = t.Size / 2; t.Align >= c.ptrSize {
2350 t.Align = c.ptrSize
2353 case *dwarf.FuncType:
2354 // No attempt at translation: would enable calls
2355 // directly between worlds, but we need to moderate those.
2356 t.Go = c.uintptr
2357 t.Align = c.ptrSize
2359 case *dwarf.IntType:
2360 if dt.BitSize > 0 {
2361 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
2363 switch t.Size {
2364 default:
2365 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2366 case 1:
2367 t.Go = c.int8
2368 case 2:
2369 t.Go = c.int16
2370 case 4:
2371 t.Go = c.int32
2372 case 8:
2373 t.Go = c.int64
2374 case 16:
2375 t.Go = &ast.ArrayType{
2376 Len: c.intExpr(t.Size),
2377 Elt: c.uint8,
2380 if t.Align = t.Size; t.Align >= c.ptrSize {
2381 t.Align = c.ptrSize
2384 case *dwarf.PtrType:
2385 // Clang doesn't emit DW_AT_byte_size for pointer types.
2386 if t.Size != c.ptrSize && t.Size != -1 {
2387 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2389 t.Size = c.ptrSize
2390 t.Align = c.ptrSize
2392 if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2393 t.Go = c.goVoidPtr
2394 t.C.Set("void*")
2395 dq := dt.Type
2396 for {
2397 if d, ok := dq.(*dwarf.QualType); ok {
2398 t.C.Set(d.Qual + " " + t.C.String())
2399 dq = d.Type
2400 } else {
2401 break
2404 break
2407 // Placeholder initialization; completed in FinishType.
2408 t.Go = &ast.StarExpr{}
2409 t.C.Set("<incomplete>*")
2410 key := dt.Type.String()
2411 if _, ok := c.ptrs[key]; !ok {
2412 c.ptrKeys = append(c.ptrKeys, dt.Type)
2414 c.ptrs[key] = append(c.ptrs[key], t)
2416 case *dwarf.QualType:
2417 t1 := c.Type(dt.Type, pos)
2418 t.Size = t1.Size
2419 t.Align = t1.Align
2420 t.Go = t1.Go
2421 if unionWithPointer[t1.Go] {
2422 unionWithPointer[t.Go] = true
2424 t.EnumValues = nil
2425 t.Typedef = ""
2426 t.C.Set("%s "+dt.Qual, t1.C)
2427 return t
2429 case *dwarf.StructType:
2430 // Convert to Go struct, being careful about alignment.
2431 // Have to give it a name to simulate C "struct foo" references.
2432 tag := dt.StructName
2433 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2434 break
2436 if tag == "" {
2437 tag = anonymousStructTag[dt]
2438 if tag == "" {
2439 tag = "__" + strconv.Itoa(tagGen)
2440 tagGen++
2441 anonymousStructTag[dt] = tag
2443 } else if t.C.Empty() {
2444 t.C.Set(dt.Kind + " " + tag)
2446 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2447 t.Go = name // publish before recursive calls
2448 goIdent[name.Name] = name
2449 if dt.ByteSize < 0 {
2450 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2451 // so execute the basic things that the struct case would do
2452 // other than try to determine a Go representation.
2453 tt := *t
2454 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2455 tt.Go = c.Ident("struct{}")
2456 typedef[name.Name] = &tt
2457 break
2459 switch dt.Kind {
2460 case "class", "union":
2461 t.Go = c.Opaque(t.Size)
2462 if c.dwarfHasPointer(dt, pos) {
2463 unionWithPointer[t.Go] = true
2465 if t.C.Empty() {
2466 t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2468 t.Align = 1 // TODO: should probably base this on field alignment.
2469 typedef[name.Name] = t
2470 case "struct":
2471 g, csyntax, align := c.Struct(dt, pos)
2472 if t.C.Empty() {
2473 t.C.Set(csyntax)
2475 t.Align = align
2476 tt := *t
2477 if tag != "" {
2478 tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2480 tt.Go = g
2481 typedef[name.Name] = &tt
2484 case *dwarf.TypedefType:
2485 // Record typedef for printing.
2486 if dt.Name == "_GoString_" {
2487 // Special C name for Go string type.
2488 // Knows string layout used by compilers: pointer plus length,
2489 // which rounds up to 2 pointers after alignment.
2490 t.Go = c.string
2491 t.Size = c.ptrSize * 2
2492 t.Align = c.ptrSize
2493 break
2495 if dt.Name == "_GoBytes_" {
2496 // Special C name for Go []byte type.
2497 // Knows slice layout used by compilers: pointer, length, cap.
2498 t.Go = c.Ident("[]byte")
2499 t.Size = c.ptrSize + 4 + 4
2500 t.Align = c.ptrSize
2501 break
2503 name := c.Ident("_Ctype_" + dt.Name)
2504 goIdent[name.Name] = name
2505 akey := ""
2506 if c.anonymousStructTypedef(dt) {
2507 // only load type recursively for typedefs of anonymous
2508 // structs, see issues 37479 and 37621.
2509 akey = key
2511 sub := c.loadType(dt.Type, pos, akey)
2512 if c.badPointerTypedef(dt) {
2513 // Treat this typedef as a uintptr.
2514 s := *sub
2515 s.Go = c.uintptr
2516 s.BadPointer = true
2517 sub = &s
2518 // Make sure we update any previously computed type.
2519 if oldType := typedef[name.Name]; oldType != nil {
2520 oldType.Go = sub.Go
2521 oldType.BadPointer = true
2524 t.Go = name
2525 t.BadPointer = sub.BadPointer
2526 if unionWithPointer[sub.Go] {
2527 unionWithPointer[t.Go] = true
2529 t.Size = sub.Size
2530 t.Align = sub.Align
2531 oldType := typedef[name.Name]
2532 if oldType == nil {
2533 tt := *t
2534 tt.Go = sub.Go
2535 tt.BadPointer = sub.BadPointer
2536 typedef[name.Name] = &tt
2539 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2540 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
2541 // with the base type.
2542 // In -godefs mode, do this for all typedefs.
2543 if isStructUnionClass(sub.Go) || *godefs {
2544 t.Go = sub.Go
2546 if isStructUnionClass(sub.Go) {
2547 // Use the typedef name for C code.
2548 typedef[sub.Go.(*ast.Ident).Name].C = t.C
2551 // If we've seen this typedef before, and it
2552 // was an anonymous struct/union/class before
2553 // too, use the old definition.
2554 // TODO: it would be safer to only do this if
2555 // we verify that the types are the same.
2556 if oldType != nil && isStructUnionClass(oldType.Go) {
2557 t.Go = oldType.Go
2561 case *dwarf.UcharType:
2562 if t.Size != 1 {
2563 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2565 t.Go = c.uint8
2566 t.Align = 1
2568 case *dwarf.UintType:
2569 if dt.BitSize > 0 {
2570 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2572 switch t.Size {
2573 default:
2574 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2575 case 1:
2576 t.Go = c.uint8
2577 case 2:
2578 t.Go = c.uint16
2579 case 4:
2580 t.Go = c.uint32
2581 case 8:
2582 t.Go = c.uint64
2583 case 16:
2584 t.Go = &ast.ArrayType{
2585 Len: c.intExpr(t.Size),
2586 Elt: c.uint8,
2589 if t.Align = t.Size; t.Align >= c.ptrSize {
2590 t.Align = c.ptrSize
2593 case *dwarf.VoidType:
2594 t.Go = c.goVoid
2595 t.C.Set("void")
2596 t.Align = 1
2599 switch dtype.(type) {
2600 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2601 s := dtype.Common().Name
2602 if s != "" {
2603 if ss, ok := dwarfToName[s]; ok {
2604 s = ss
2606 s = strings.Replace(s, " ", "", -1)
2607 name := c.Ident("_Ctype_" + s)
2608 tt := *t
2609 typedef[name.Name] = &tt
2610 if !*godefs {
2611 t.Go = name
2616 if t.Size < 0 {
2617 // Unsized types are [0]byte, unless they're typedefs of other types
2618 // or structs with tags.
2619 // if so, use the name we've already defined.
2620 t.Size = 0
2621 switch dt := dtype.(type) {
2622 case *dwarf.TypedefType:
2623 // ok
2624 case *dwarf.StructType:
2625 if dt.StructName != "" {
2626 break
2628 t.Go = c.Opaque(0)
2629 default:
2630 t.Go = c.Opaque(0)
2632 if t.C.Empty() {
2633 t.C.Set("void")
2637 if t.C.Empty() {
2638 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2641 return t
2644 // isStructUnionClass reports whether the type described by the Go syntax x
2645 // is a struct, union, or class with a tag.
2646 func isStructUnionClass(x ast.Expr) bool {
2647 id, ok := x.(*ast.Ident)
2648 if !ok {
2649 return false
2651 name := id.Name
2652 return strings.HasPrefix(name, "_Ctype_struct_") ||
2653 strings.HasPrefix(name, "_Ctype_union_") ||
2654 strings.HasPrefix(name, "_Ctype_class_")
2657 // FuncArg returns a Go type with the same memory layout as
2658 // dtype when used as the type of a C function argument.
2659 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2660 t := c.Type(unqual(dtype), pos)
2661 switch dt := dtype.(type) {
2662 case *dwarf.ArrayType:
2663 // Arrays are passed implicitly as pointers in C.
2664 // In Go, we must be explicit.
2665 tr := &TypeRepr{}
2666 tr.Set("%s*", t.C)
2667 return &Type{
2668 Size: c.ptrSize,
2669 Align: c.ptrSize,
2670 Go: &ast.StarExpr{X: t.Go},
2671 C: tr,
2673 case *dwarf.TypedefType:
2674 // C has much more relaxed rules than Go for
2675 // implicit type conversions. When the parameter
2676 // is type T defined as *X, simulate a little of the
2677 // laxness of C by making the argument *X instead of T.
2678 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2679 // Unless the typedef happens to point to void* since
2680 // Go has special rules around using unsafe.Pointer.
2681 if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2682 break
2684 // ...or the typedef is one in which we expect bad pointers.
2685 // It will be a uintptr instead of *X.
2686 if c.baseBadPointerTypedef(dt) {
2687 break
2690 t = c.Type(ptr, pos)
2691 if t == nil {
2692 return nil
2695 // For a struct/union/class, remember the C spelling,
2696 // in case it has __attribute__((unavailable)).
2697 // See issue 2888.
2698 if isStructUnionClass(t.Go) {
2699 t.Typedef = dt.Name
2703 return t
2706 // FuncType returns the Go type analogous to dtype.
2707 // There is no guarantee about matching memory layout.
2708 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2709 p := make([]*Type, len(dtype.ParamType))
2710 gp := make([]*ast.Field, len(dtype.ParamType))
2711 for i, f := range dtype.ParamType {
2712 // gcc's DWARF generator outputs a single DotDotDotType parameter for
2713 // function pointers that specify no parameters (e.g. void
2714 // (*__cgo_0)()). Treat this special case as void. This case is
2715 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2716 // legal).
2717 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2718 p, gp = nil, nil
2719 break
2721 p[i] = c.FuncArg(f, pos)
2722 gp[i] = &ast.Field{Type: p[i].Go}
2724 var r *Type
2725 var gr []*ast.Field
2726 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2727 gr = []*ast.Field{{Type: c.goVoid}}
2728 } else if dtype.ReturnType != nil {
2729 r = c.Type(unqual(dtype.ReturnType), pos)
2730 gr = []*ast.Field{{Type: r.Go}}
2732 return &FuncType{
2733 Params: p,
2734 Result: r,
2735 Go: &ast.FuncType{
2736 Params: &ast.FieldList{List: gp},
2737 Results: &ast.FieldList{List: gr},
2742 // Identifier
2743 func (c *typeConv) Ident(s string) *ast.Ident {
2744 return ast.NewIdent(s)
2747 // Opaque type of n bytes.
2748 func (c *typeConv) Opaque(n int64) ast.Expr {
2749 return &ast.ArrayType{
2750 Len: c.intExpr(n),
2751 Elt: c.byte,
2755 // Expr for integer n.
2756 func (c *typeConv) intExpr(n int64) ast.Expr {
2757 return &ast.BasicLit{
2758 Kind: token.INT,
2759 Value: strconv.FormatInt(n, 10),
2763 // Add padding of given size to fld.
2764 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
2765 n := len(fld)
2766 fld = fld[0 : n+1]
2767 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
2768 sizes = sizes[0 : n+1]
2769 sizes[n] = size
2770 return fld, sizes
2773 // Struct conversion: return Go and (gc) C syntax for type.
2774 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
2775 // Minimum alignment for a struct is 1 byte.
2776 align = 1
2778 var buf bytes.Buffer
2779 buf.WriteString("struct {")
2780 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
2781 sizes := make([]int64, 0, 2*len(dt.Field)+1)
2782 off := int64(0)
2784 // Rename struct fields that happen to be named Go keywords into
2785 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will
2786 // be mangled. Any existing identifier that already has the same name on
2787 // the C-side will cause the Go-mangled version to be prefixed with _.
2788 // (e.g. in a struct with fields '_type' and 'type', the latter would be
2789 // rendered as '__type' in Go).
2790 ident := make(map[string]string)
2791 used := make(map[string]bool)
2792 for _, f := range dt.Field {
2793 ident[f.Name] = f.Name
2794 used[f.Name] = true
2797 if !*godefs {
2798 for cid, goid := range ident {
2799 if token.Lookup(goid).IsKeyword() {
2800 // Avoid keyword
2801 goid = "_" + goid
2803 // Also avoid existing fields
2804 for _, exist := used[goid]; exist; _, exist = used[goid] {
2805 goid = "_" + goid
2808 used[goid] = true
2809 ident[cid] = goid
2814 anon := 0
2815 for _, f := range dt.Field {
2816 name := f.Name
2817 ft := f.Type
2819 // In godefs mode, if this field is a C11
2820 // anonymous union then treat the first field in the
2821 // union as the field in the struct. This handles
2822 // cases like the glibc <sys/resource.h> file; see
2823 // issue 6677.
2824 if *godefs {
2825 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
2826 name = st.Field[0].Name
2827 ident[name] = name
2828 ft = st.Field[0].Type
2832 // TODO: Handle fields that are anonymous structs by
2833 // promoting the fields of the inner struct.
2835 t := c.Type(ft, pos)
2836 tgo := t.Go
2837 size := t.Size
2838 talign := t.Align
2839 if f.BitSize > 0 {
2840 switch f.BitSize {
2841 case 8, 16, 32, 64:
2842 default:
2843 continue
2845 size = f.BitSize / 8
2846 name := tgo.(*ast.Ident).String()
2847 if strings.HasPrefix(name, "int") {
2848 name = "int"
2849 } else {
2850 name = "uint"
2852 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
2853 talign = size
2856 if talign > 0 && f.ByteOffset%talign != 0 {
2857 // Drop misaligned fields, the same way we drop integer bit fields.
2858 // The goal is to make available what can be made available.
2859 // Otherwise one bad and unneeded field in an otherwise okay struct
2860 // makes the whole program not compile. Much of the time these
2861 // structs are in system headers that cannot be corrected.
2862 continue
2865 // Round off up to talign, assumed to be a power of 2.
2866 off = (off + talign - 1) &^ (talign - 1)
2868 if f.ByteOffset > off {
2869 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
2870 off = f.ByteOffset
2872 if f.ByteOffset < off {
2873 // Drop a packed field that we can't represent.
2874 continue
2877 n := len(fld)
2878 fld = fld[0 : n+1]
2879 if name == "" {
2880 name = fmt.Sprintf("anon%d", anon)
2881 anon++
2882 ident[name] = name
2884 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
2885 sizes = sizes[0 : n+1]
2886 sizes[n] = size
2887 off += size
2888 buf.WriteString(t.C.String())
2889 buf.WriteString(" ")
2890 buf.WriteString(name)
2891 buf.WriteString("; ")
2892 if talign > align {
2893 align = talign
2896 if off < dt.ByteSize {
2897 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
2898 off = dt.ByteSize
2901 // If the last field in a non-zero-sized struct is zero-sized
2902 // the compiler is going to pad it by one (see issue 9401).
2903 // We can't permit that, because then the size of the Go
2904 // struct will not be the same as the size of the C struct.
2905 // Our only option in such a case is to remove the field,
2906 // which means that it cannot be referenced from Go.
2907 for off > 0 && sizes[len(sizes)-1] == 0 {
2908 n := len(sizes)
2909 fld = fld[0 : n-1]
2910 sizes = sizes[0 : n-1]
2913 if off != dt.ByteSize {
2914 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
2916 buf.WriteString("}")
2917 csyntax = buf.String()
2919 if *godefs {
2920 godefsFields(fld)
2922 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
2923 return
2926 // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
2927 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
2928 switch dt := dt.(type) {
2929 default:
2930 fatalf("%s: unexpected type: %s", lineno(pos), dt)
2931 return false
2933 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
2934 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
2935 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
2937 return false
2939 case *dwarf.ArrayType:
2940 return c.dwarfHasPointer(dt.Type, pos)
2942 case *dwarf.PtrType:
2943 return true
2945 case *dwarf.QualType:
2946 return c.dwarfHasPointer(dt.Type, pos)
2948 case *dwarf.StructType:
2949 for _, f := range dt.Field {
2950 if c.dwarfHasPointer(f.Type, pos) {
2951 return true
2954 return false
2956 case *dwarf.TypedefType:
2957 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
2958 return true
2960 return c.dwarfHasPointer(dt.Type, pos)
2964 func upper(s string) string {
2965 if s == "" {
2966 return ""
2968 r, size := utf8.DecodeRuneInString(s)
2969 if r == '_' {
2970 return "X" + s
2972 return string(unicode.ToUpper(r)) + s[size:]
2975 // godefsFields rewrites field names for use in Go or C definitions.
2976 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2977 // converts names to upper case, and rewrites _ into Pad_godefs_n,
2978 // so that all fields are exported.
2979 func godefsFields(fld []*ast.Field) {
2980 prefix := fieldPrefix(fld)
2981 npad := 0
2982 for _, f := range fld {
2983 for _, n := range f.Names {
2984 if n.Name != prefix {
2985 n.Name = strings.TrimPrefix(n.Name, prefix)
2987 if n.Name == "_" {
2988 // Use exported name instead.
2989 n.Name = "Pad_cgo_" + strconv.Itoa(npad)
2990 npad++
2992 n.Name = upper(n.Name)
2997 // fieldPrefix returns the prefix that should be removed from all the
2998 // field names when generating the C or Go code. For generated
2999 // C, we leave the names as is (tv_sec, tv_usec), since that's what
3000 // people are used to seeing in C. For generated Go code, such as
3001 // package syscall's data structures, we drop a common prefix
3002 // (so sec, usec, which will get turned into Sec, Usec for exporting).
3003 func fieldPrefix(fld []*ast.Field) string {
3004 prefix := ""
3005 for _, f := range fld {
3006 for _, n := range f.Names {
3007 // Ignore field names that don't have the prefix we're
3008 // looking for. It is common in C headers to have fields
3009 // named, say, _pad in an otherwise prefixed header.
3010 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
3011 // still want to remove the tv_ prefix.
3012 // The check for "orig_" here handles orig_eax in the
3013 // x86 ptrace register sets, which otherwise have all fields
3014 // with reg_ prefixes.
3015 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
3016 continue
3018 i := strings.Index(n.Name, "_")
3019 if i < 0 {
3020 continue
3022 if prefix == "" {
3023 prefix = n.Name[:i+1]
3024 } else if prefix != n.Name[:i+1] {
3025 return ""
3029 return prefix
3032 // anonymousStructTypedef reports whether dt is a C typedef for an anonymous
3033 // struct.
3034 func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
3035 st, ok := dt.Type.(*dwarf.StructType)
3036 return ok && st.StructName == ""
3039 // badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
3040 // A typedef is bad if C code sometimes stores non-pointers in this type.
3041 // TODO: Currently our best solution is to find these manually and list them as
3042 // they come up. A better solution is desired.
3043 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
3044 if c.badCFType(dt) {
3045 return true
3047 if c.badJNI(dt) {
3048 return true
3050 if c.badEGLDisplay(dt) {
3051 return true
3053 return false
3056 // baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
3057 // as badPointerTypedef reports.
3058 func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
3059 for {
3060 if t, ok := dt.Type.(*dwarf.TypedefType); ok {
3061 dt = t
3062 continue
3064 break
3066 return c.badPointerTypedef(dt)
3069 func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
3070 // The real bad types are CFNumberRef and CFDateRef.
3071 // Sometimes non-pointers are stored in these types.
3072 // CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
3073 // We return true for the other *Ref types just so casting between them is easier.
3074 // We identify the correct set of types as those ending in Ref and for which
3075 // there exists a corresponding GetTypeID function.
3076 // See comment below for details about the bad pointers.
3077 if goos != "darwin" {
3078 return false
3080 s := dt.Name
3081 if !strings.HasSuffix(s, "Ref") {
3082 return false
3084 s = s[:len(s)-3]
3085 if s == "CFType" {
3086 return true
3088 if c.getTypeIDs[s] {
3089 return true
3091 if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
3092 // Mutable and immutable variants share a type ID.
3093 return true
3095 return false
3098 // Comment from Darwin's CFInternal.h
3100 // Tagged pointer support
3101 // Low-bit set means tagged object, next 3 bits (currently)
3102 // define the tagged object class, next 4 bits are for type
3103 // information for the specific tagged object class. Thus,
3104 // the low byte is for type info, and the rest of a pointer
3105 // (32 or 64-bit) is for payload, whatever the tagged class.
3107 // Note that the specific integers used to identify the
3108 // specific tagged classes can and will change from release
3109 // to release (that's why this stuff is in CF*Internal*.h),
3110 // as can the definition of type info vs payload above.
3112 #if __LP64__
3113 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
3114 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
3115 #else
3116 #define CF_IS_TAGGED_OBJ(PTR) 0
3117 #define CF_TAGGED_OBJ_TYPE(PTR) 0
3118 #endif
3120 enum {
3121 kCFTaggedObjectID_Invalid = 0,
3122 kCFTaggedObjectID_Atom = (0 << 1) + 1,
3123 kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
3124 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
3125 kCFTaggedObjectID_Integer = (3 << 1) + 1,
3126 kCFTaggedObjectID_DateTS = (4 << 1) + 1,
3127 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
3128 kCFTaggedObjectID_Date = (6 << 1) + 1,
3129 kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
3133 func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
3134 // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
3135 // property that it is sometimes (always?) a small integer instead of a real pointer.
3136 // Note: although only the android JVMs are bad in this respect, we declare the JNI types
3137 // bad regardless of platform, so the same Go code compiles on both android and non-android.
3138 if parent, ok := jniTypes[dt.Name]; ok {
3139 // Try to make sure we're talking about a JNI type, not just some random user's
3140 // type that happens to use the same name.
3141 // C doesn't have the notion of a package, so it's hard to be certain.
3143 // Walk up to jobject, checking each typedef on the way.
3144 w := dt
3145 for parent != "" {
3146 t, ok := w.Type.(*dwarf.TypedefType)
3147 if !ok || t.Name != parent {
3148 return false
3150 w = t
3151 parent, ok = jniTypes[w.Name]
3152 if !ok {
3153 return false
3157 // Check that the typedef is either:
3158 // 1:
3159 // struct _jobject;
3160 // typedef struct _jobject *jobject;
3161 // 2: (in NDK16 in C++)
3162 // class _jobject {};
3163 // typedef _jobject* jobject;
3164 // 3: (in NDK16 in C)
3165 // typedef void* jobject;
3166 if ptr, ok := w.Type.(*dwarf.PtrType); ok {
3167 switch v := ptr.Type.(type) {
3168 case *dwarf.VoidType:
3169 return true
3170 case *dwarf.StructType:
3171 if v.StructName == "_jobject" && len(v.Field) == 0 {
3172 switch v.Kind {
3173 case "struct":
3174 if v.Incomplete {
3175 return true
3177 case "class":
3178 if !v.Incomplete {
3179 return true
3186 return false
3189 func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool {
3190 if dt.Name != "EGLDisplay" {
3191 return false
3193 // Check that the typedef is "typedef void *EGLDisplay".
3194 if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3195 if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3196 return true
3199 return false
3202 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
3203 // they are mapped. The base "jobject" maps to the empty string.
3204 var jniTypes = map[string]string{
3205 "jobject": "",
3206 "jclass": "jobject",
3207 "jthrowable": "jobject",
3208 "jstring": "jobject",
3209 "jarray": "jobject",
3210 "jbooleanArray": "jarray",
3211 "jbyteArray": "jarray",
3212 "jcharArray": "jarray",
3213 "jshortArray": "jarray",
3214 "jintArray": "jarray",
3215 "jlongArray": "jarray",
3216 "jfloatArray": "jarray",
3217 "jdoubleArray": "jarray",
3218 "jobjectArray": "jarray",
3219 "jweak": "jobject",