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.
30 var debugDefine
= flag
.Bool("debug-define", false, "print relevant #defines")
31 var debugGcc
= flag
.Bool("debug-gcc", false, "print gcc invocations")
33 var nameToC
= map[string]string{
34 "schar": "signed char",
35 "uchar": "unsigned char",
36 "ushort": "unsigned short",
37 "uint": "unsigned int",
38 "ulong": "unsigned long",
39 "longlong": "long long",
40 "ulonglong": "unsigned long long",
41 "complexfloat": "float _Complex",
42 "complexdouble": "double _Complex",
45 // cname returns the C name to use for C.s.
46 // The expansions are listed in nameToC and also
47 // struct_foo becomes "struct foo", and similarly for
49 func cname(s
string) string {
50 if t
, ok
:= nameToC
[s
]; ok
{
54 if strings
.HasPrefix(s
, "struct_") {
55 return "struct " + s
[len("struct_"):]
57 if strings
.HasPrefix(s
, "union_") {
58 return "union " + s
[len("union_"):]
60 if strings
.HasPrefix(s
, "enum_") {
61 return "enum " + s
[len("enum_"):]
63 if strings
.HasPrefix(s
, "sizeof_") {
64 return "sizeof(" + cname(s
[len("sizeof_"):]) + ")"
69 // DiscardCgoDirectives processes the import C preamble, and discards
70 // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
71 // way into _cgo_export.h.
72 func (f
*File
) DiscardCgoDirectives() {
73 linesIn
:= strings
.Split(f
.Preamble
, "\n")
74 linesOut
:= make([]string, 0, len(linesIn
))
75 for _
, line
:= range linesIn
{
76 l
:= strings
.TrimSpace(line
)
77 if len(l
) < 5 || l
[:4] != "#cgo" ||
!unicode
.IsSpace(rune(l
[4])) {
78 linesOut
= append(linesOut
, line
)
80 linesOut
= append(linesOut
, "")
83 f
.Preamble
= strings
.Join(linesOut
, "\n")
86 // addToFlag appends args to flag. All flags are later written out onto the
87 // _cgo_flags file for the build system to use.
88 func (p
*Package
) addToFlag(flag
string, args
[]string) {
89 p
.CgoFlags
[flag
] = append(p
.CgoFlags
[flag
], args
...)
91 // We'll also need these when preprocessing for dwarf information.
92 p
.GccOptions
= append(p
.GccOptions
, args
...)
96 // splitQuoted splits the string s around each instance of one or more consecutive
97 // white space characters while taking into account quotes and escaping, and
98 // returns an array of substrings of s or an empty list if s contains only white space.
99 // Single quotes and double quotes are recognized to prevent splitting within the
100 // quoted region, and are removed from the resulting substrings. If a quote in s
101 // isn't closed err will be set and r will have the unclosed argument as the
102 // last element. The backslash is used for escaping.
104 // For example, the following string:
106 // `a b:"c d" 'e''f' "g\""`
108 // Would be parsed as:
110 // []string{"a", "b:c d", "ef", `g"`}
112 func splitQuoted(s
string) (r
[]string, err error
) {
114 arg
:= make([]rune
, len(s
))
119 for _
, r
:= range s
{
131 case r
== '"' || r
== '\'':
135 case unicode
.IsSpace(r
):
138 args
= append(args
, string(arg
[:i
]))
147 args
= append(args
, string(arg
[:i
]))
150 err
= errors
.New("unclosed quote")
152 err
= errors
.New("unfinished escaping")
157 // Translate rewrites f.AST, the original Go input, to remove
158 // references to the imported package C, replacing them with
159 // references to the equivalent Go types, functions, and variables.
160 func (p
*Package
) Translate(f
*File
) {
161 for _
, cref
:= range f
.Ref
{
162 // Convert C.ulong to C.unsigned long, etc.
163 cref
.Name
.C
= cname(cref
.Name
.Go
)
166 needType
:= p
.guessKinds(f
)
167 if len(needType
) > 0 {
168 p
.loadDWARF(f
, needType
)
170 if p
.rewriteCalls(f
) {
171 // Add `import _cgo_unsafe "unsafe"` as the first decl
172 // after the package statement.
177 Name
: ast
.NewIdent("_cgo_unsafe"),
185 f
.AST
.Decls
= append([]ast
.Decl
{imp
}, f
.AST
.Decls
...)
190 // loadDefines coerces gcc into spitting out the #defines in use
191 // in the file f and saves relevant renamings in f.Name[name].Define.
192 func (p
*Package
) loadDefines(f
*File
) {
194 b
.WriteString(f
.Preamble
)
195 b
.WriteString(builtinProlog
)
196 stdout
:= p
.gccDefines(b
.Bytes())
198 for _
, line
:= range strings
.Split(stdout
, "\n") {
199 if len(line
) < 9 || line
[0:7] != "#define" {
203 line
= strings
.TrimSpace(line
[8:])
206 spaceIndex
:= strings
.Index(line
, " ")
207 tabIndex
:= strings
.Index(line
, "\t")
209 if spaceIndex
== -1 && tabIndex
== -1 {
211 } else if tabIndex
== -1 ||
(spaceIndex
!= -1 && spaceIndex
< tabIndex
) {
212 key
= line
[0:spaceIndex
]
213 val
= strings
.TrimSpace(line
[spaceIndex
:])
215 key
= line
[0:tabIndex
]
216 val
= strings
.TrimSpace(line
[tabIndex
:])
219 if key
== "__clang__" {
223 if n
:= f
.Name
[key
]; n
!= nil {
225 fmt
.Fprintf(os
.Stderr
, "#define %s %s\n", key
, val
)
232 // guessKinds tricks gcc into revealing the kind of each
233 // name xxx for the references C.xxx in the Go input.
234 // The kind is either a constant, type, or variable.
235 func (p
*Package
) guessKinds(f
*File
) []*Name
{
236 // Determine kinds for names we already know about,
237 // like #defines or 'struct foo', before bothering with gcc.
238 var names
, needType
[]*Name
239 for _
, key
:= range nameKeys(f
.Name
) {
241 // If we've already found this name as a #define
242 // and we can translate it as a constant value, do so.
245 if _
, err
:= strconv
.Atoi(n
.Define
); err
== nil {
247 } else if n
.Define
[0] == '"' || n
.Define
[0] == '\'' {
248 if _
, err
:= parser
.ParseExpr(n
.Define
); err
== nil {
254 // Turn decimal into hex, just for consistency
255 // with enum-derived constants. Otherwise
256 // in the cgo -godefs output half the constants
257 // are in hex and half are in whatever the #define used.
258 i
, err
:= strconv
.ParseInt(n
.Define
, 0, 64)
260 n
.Const
= fmt
.Sprintf("%#x", i
)
267 if isName(n
.Define
) {
272 needType
= append(needType
, n
)
274 // If this is a struct, union, or enum type name, no need to guess the kind.
275 if strings
.HasPrefix(n
.C
, "struct ") || strings
.HasPrefix(n
.C
, "union ") || strings
.HasPrefix(n
.C
, "enum ") {
280 // Otherwise, we'll need to find out from gcc.
281 names
= append(names
, n
)
284 // Bypass gcc if there's nothing left to find out.
289 // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
290 // For names, find out whether they are integer constants.
291 // We used to look at specific warning or error messages here, but that tied the
292 // behavior too closely to specific versions of the compilers.
293 // Instead, arrange that we can infer what we need from only the presence or absence
294 // of an error on a specific line.
296 // For each name, we generate these lines, where xxx is the index in toSniff plus one.
298 // #line xxx "not-declared"
299 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
300 // #line xxx "not-type"
301 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
302 // #line xxx "not-const"
303 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
305 // If we see an error at not-declared:xxx, the corresponding name is not declared.
306 // If we see an error at not-type:xxx, the corresponding name is a type.
307 // If we see an error at not-const:xxx, the corresponding name is not an integer constant.
308 // If we see no errors, we assume the name is an expression but not a constant
309 // (so a variable or a function).
311 // The specific input forms are chosen so that they are valid C syntax regardless of
312 // whether name denotes a type or an expression.
315 b
.WriteString(f
.Preamble
)
316 b
.WriteString(builtinProlog
)
318 for i
, n
:= range names
{
319 fmt
.Fprintf(&b
, "#line %d \"not-declared\"\n"+
320 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
321 "#line %d \"not-type\"\n"+
322 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
323 "#line %d \"not-const\"\n"+
324 "void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n",
329 fmt
.Fprintf(&b
, "#line 1 \"completed\"\n"+
330 "int __cgo__1 = __cgo__2;\n")
332 stderr
:= p
.gccErrors(b
.Bytes())
334 fatalf("%s produced no output\non input:\n%s", p
.gccBaseCmd()[0], b
.Bytes())
338 sniff
:= make([]int, len(names
))
344 for _
, line
:= range strings
.Split(stderr
, "\n") {
345 if !strings
.Contains(line
, ": error:") {
346 // we only care about errors.
347 // we tried to turn off warnings on the command line, but one never knows.
351 c1
:= strings
.Index(line
, ":")
355 c2
:= strings
.Index(line
[c1
+1:], ":")
361 filename
:= line
[:c1
]
362 i
, _
:= strconv
.Atoi(line
[c1
+1 : c2
])
364 if i
< 0 || i
>= len(names
) {
370 // Strictly speaking, there is no guarantee that seeing the error at completed:1
371 // (at the end of the file) means we've seen all the errors from earlier in the file,
372 // but usually it does. Certainly if we don't see the completed:1 error, we did
373 // not get all the errors we expected.
377 sniff
[i
] |
= notDeclared
386 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p
.gccBaseCmd()[0], b
.Bytes(), stderr
)
389 for i
, n
:= range names
{
392 error_(token
.NoPos
, "could not determine kind of name for C.%s", fixGo(n
.Go
))
397 case notConst | notType
:
402 // Check if compiling the preamble by itself causes any errors,
403 // because the messages we've printed out so far aren't helpful
404 // to users debugging preamble mistakes. See issue 8442.
405 preambleErrors
:= p
.gccErrors([]byte(f
.Preamble
))
406 if len(preambleErrors
) > 0 {
407 error_(token
.NoPos
, "\n%s errors for preamble:\n%s", p
.gccBaseCmd()[0], preambleErrors
)
410 fatalf("unresolved names")
413 needType
= append(needType
, names
...)
417 // loadDWARF parses the DWARF debug information generated
418 // by gcc to learn the details of the constants, variables, and types
419 // being referred to as C.xxx.
420 func (p
*Package
) loadDWARF(f
*File
, names
[]*Name
) {
421 // Extract the types from the DWARF section of an object
422 // from a well-formed C program. Gcc only generates DWARF info
423 // for symbols in the object file, so it is not enough to print the
424 // preamble and hope the symbols we care about will be there.
426 // __typeof__(names[i]) *__cgo__i;
427 // for each entry in names and then dereference the type we
428 // learn for __cgo__i.
430 b
.WriteString(f
.Preamble
)
431 b
.WriteString(builtinProlog
)
432 b
.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
433 for i
, n
:= range names
{
434 fmt
.Fprintf(&b
, "__typeof__(%s) *__cgo__%d;\n", n
.C
, i
)
435 if n
.Kind
== "const" {
436 fmt
.Fprintf(&b
, "enum { __cgo_enum__%d = %s };\n", i
, n
.C
)
440 // Apple's LLVM-based gcc does not include the enumeration
441 // names and values in its DWARF debug output. In case we're
442 // using such a gcc, create a data block initialized with the values.
443 // We can read them out of the object file.
444 fmt
.Fprintf(&b
, "long long __cgodebug_data[] = {\n")
445 for _
, n
:= range names
{
446 if n
.Kind
== "const" {
447 fmt
.Fprintf(&b
, "\t%s,\n", n
.C
)
449 fmt
.Fprintf(&b
, "\t0,\n")
452 // for the last entry, we cannot use 0, otherwise
453 // in case all __cgodebug_data is zero initialized,
454 // LLVM-based gcc will place the it in the __DATA.__common
455 // zero-filled section (our debug/macho doesn't support
457 fmt
.Fprintf(&b
, "\t1\n")
458 fmt
.Fprintf(&b
, "};\n")
460 d
, bo
, debugData
:= p
.gccDebug(b
.Bytes())
461 enumVal
:= make([]int64, len(debugData
)/8)
462 for i
:= range enumVal
{
463 enumVal
[i
] = int64(bo
.Uint64(debugData
[i
*8:]))
466 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
467 types
:= make([]dwarf
.Type
, len(names
))
468 enums
:= make([]dwarf
.Offset
, len(names
))
469 nameToIndex
:= make(map[*Name
]int)
470 for i
, n
:= range names
{
473 nameToRef
:= make(map[*Name
]*Ref
)
474 for _
, ref
:= range f
.Ref
{
475 nameToRef
[ref
.Name
] = ref
481 fatalf("reading DWARF entry: %s", err
)
487 case dwarf
.TagEnumerationType
:
492 fatalf("reading DWARF entry: %s", err
)
497 if e
.Tag
== dwarf
.TagEnumerator
{
498 entryName
:= e
.Val(dwarf
.AttrName
).(string)
499 if strings
.HasPrefix(entryName
, "__cgo_enum__") {
500 n
, _
:= strconv
.Atoi(entryName
[len("__cgo_enum__"):])
501 if 0 <= n
&& n
< len(names
) {
507 case dwarf
.TagVariable
:
508 name
, _
:= e
.Val(dwarf
.AttrName
).(string)
509 typOff
, _
:= e
.Val(dwarf
.AttrType
).(dwarf
.Offset
)
510 if name
== "" || typOff
== 0 {
511 if e
.Val(dwarf
.AttrSpecification
) != nil {
512 // Since we are reading all the DWARF,
513 // assume we will see the variable elsewhere.
516 fatalf("malformed DWARF TagVariable entry")
518 if !strings
.HasPrefix(name
, "__cgo__") {
521 typ
, err
:= d
.Type(typOff
)
523 fatalf("loading DWARF type: %s", err
)
525 t
, ok
:= typ
.(*dwarf
.PtrType
)
527 fatalf("internal error: %s has non-pointer type", name
)
529 i
, err
:= strconv
.Atoi(name
[7:])
531 fatalf("malformed __cgo__ name: %s", name
)
534 t
, err
:= d
.Type(enums
[i
])
536 fatalf("loading DWARF type: %s", err
)
543 if e
.Tag
!= dwarf
.TagCompileUnit
{
548 // Record types and typedef information.
550 conv
.Init(p
.PtrSize
, p
.IntSize
)
551 for i
, n
:= range names
{
556 if ref
, ok
:= nameToRef
[n
]; ok
{
559 f
, fok
:= types
[i
].(*dwarf
.FuncType
)
560 if n
.Kind
!= "type" && fok
{
562 n
.FuncType
= conv
.FuncType(f
, pos
)
564 n
.Type
= conv
.Type(types
[i
], pos
)
565 if enums
[i
] != 0 && n
.Type
.EnumValues
!= nil {
566 k
:= fmt
.Sprintf("__cgo_enum__%d", i
)
568 n
.Const
= fmt
.Sprintf("%#x", n
.Type
.EnumValues
[k
])
569 // Remove injected enum to ensure the value will deep-compare
570 // equally in future loads of the same constant.
571 delete(n
.Type
.EnumValues
, k
)
573 // Prefer debug data over DWARF debug output, if we have it.
574 if n
.Kind
== "const" && i
< len(enumVal
) {
575 n
.Const
= fmt
.Sprintf("%#x", enumVal
[i
])
582 // mangleName does name mangling to translate names
583 // from the original Go source files to the names
584 // used in the final Go files generated by cgo.
585 func (p
*Package
) mangleName(n
*Name
) {
586 // When using gccgo variables have to be
587 // exported so that they become global symbols
588 // that the C code can refer to.
590 if *gccgo
&& n
.IsVar() {
593 n
.Mangle
= prefix
+ n
.Kind
+ "_" + n
.Go
596 // rewriteCalls rewrites all calls that pass pointers to check that
597 // they follow the rules for passing pointers between Go and C.
598 // This returns whether the package needs to import unsafe as _cgo_unsafe.
599 func (p
*Package
) rewriteCalls(f
*File
) bool {
601 for _
, call
:= range f
.Calls
{
602 // This is a call to C.xxx; set goname to "xxx".
603 goname
:= call
.Call
.Fun
.(*ast
.SelectorExpr
).Sel
.Name
604 if goname
== "malloc" {
607 name
:= f
.Name
[goname
]
608 if name
.Kind
!= "func" {
609 // Probably a type conversion.
612 if p
.rewriteCall(f
, call
, name
) {
619 // rewriteCall rewrites one call to add pointer checks.
620 // If any pointer checks are required, we rewrite the call into a
621 // function literal that calls _cgoCheckPointer for each pointer
622 // argument and then calls the original function.
623 // This returns whether the package needs to import unsafe as _cgo_unsafe.
624 func (p
*Package
) rewriteCall(f
*File
, call
*Call
, name
*Name
) bool {
625 // Avoid a crash if the number of arguments is
626 // less than the number of parameters.
627 // This will be caught when the generated file is compiled.
628 if len(call
.Call
.Args
) < len(name
.FuncType
.Params
) {
633 for i
, param
:= range name
.FuncType
.Params
{
634 if p
.needsPointerCheck(f
, param
.Go
, call
.Call
.Args
[i
]) {
643 // We need to rewrite this call.
645 // We are going to rewrite C.f(p) to
646 // func (_cgo0 ptype) {
647 // _cgoCheckPointer(_cgo0)
650 // Using a function literal like this lets us do correct
651 // argument type checking, and works correctly if the call is
654 params
:= make([]*ast
.Field
, len(name
.FuncType
.Params
))
655 nargs
:= make([]ast
.Expr
, len(name
.FuncType
.Params
))
657 for i
, param
:= range name
.FuncType
.Params
{
658 // params is going to become the parameters of the
660 // nargs is going to become the list of arguments made
661 // by the call within the function literal.
662 // nparam is the parameter of the function literal that
663 // corresponds to param.
665 origArg
:= call
.Call
.Args
[i
]
666 nparam
:= ast
.NewIdent(fmt
.Sprintf("_cgo%d", i
))
669 // The Go version of the C type might use unsafe.Pointer,
670 // but the file might not import unsafe.
671 // Rewrite the Go type if necessary to use _cgo_unsafe.
672 ptype
:= p
.rewriteUnsafe(param
.Go
)
673 if ptype
!= param
.Go
{
677 params
[i
] = &ast
.Field
{
678 Names
: []*ast
.Ident
{nparam
},
682 if !p
.needsPointerCheck(f
, param
.Go
, origArg
) {
686 // Run the cgo pointer checks on nparam.
688 // Change the function literal to call the real function
689 // with the parameter passed through _cgoCheckPointer.
691 Fun
: ast
.NewIdent("_cgoCheckPointer"),
697 // Add optional additional arguments for an address
699 c
.Args
= p
.checkAddrArgs(f
, c
.Args
, origArg
)
701 stmt
:= &ast
.ExprStmt
{
704 stmts
= append(stmts
, stmt
)
707 fcall
:= &ast
.CallExpr
{
711 ftype
:= &ast
.FuncType
{
712 Params
: &ast
.FieldList
{
716 if name
.FuncType
.Result
!= nil {
717 rtype
:= p
.rewriteUnsafe(name
.FuncType
.Result
.Go
)
718 if rtype
!= name
.FuncType
.Result
.Go
{
721 ftype
.Results
= &ast
.FieldList
{
730 // There is a Ref pointing to the old call.Call.Fun.
731 for _
, ref
:= range f
.Ref
{
732 if ref
.Expr
== &call
.Call
.Fun
{
733 ref
.Expr
= &fcall
.Fun
735 // If this call expects two results, we have to
736 // adjust the results of the function we generated.
737 if ref
.Context
== "call2" {
738 if ftype
.Results
== nil {
739 // An explicit void argument
740 // looks odd but it seems to
741 // be how cgo has worked historically.
742 ftype
.Results
= &ast
.FieldList
{
745 Type
: ast
.NewIdent("_Ctype_void"),
750 ftype
.Results
.List
= append(ftype
.Results
.List
,
752 Type
: ast
.NewIdent("error"),
759 if ftype
.Results
== nil {
760 fbody
= &ast
.ExprStmt
{
764 fbody
= &ast
.ReturnStmt
{
765 Results
: []ast
.Expr
{fcall
},
768 call
.Call
.Fun
= &ast
.FuncLit
{
770 Body
: &ast
.BlockStmt
{
771 List
: append(stmts
, fbody
),
774 call
.Call
.Lparen
= token
.NoPos
775 call
.Call
.Rparen
= token
.NoPos
780 // needsPointerCheck returns whether the type t needs a pointer check.
781 // This is true if t is a pointer and if the value to which it points
782 // might contain a pointer.
783 func (p
*Package
) needsPointerCheck(f
*File
, t ast
.Expr
, arg ast
.Expr
) bool {
784 // An untyped nil does not need a pointer check, and when
785 // _cgoCheckPointer returns the untyped nil the type assertion we
786 // are going to insert will fail. Easier to just skip nil arguments.
787 // TODO: Note that this fails if nil is shadowed.
788 if id
, ok
:= arg
.(*ast
.Ident
); ok
&& id
.Name
== "nil" {
792 return p
.hasPointer(f
, t
, true)
795 // hasPointer is used by needsPointerCheck. If top is true it returns
796 // whether t is or contains a pointer that might point to a pointer.
797 // If top is false it returns whether t is or contains a pointer.
799 func (p
*Package
) hasPointer(f
*File
, t ast
.Expr
, top
bool) bool {
800 switch t
:= t
.(type) {
806 return p
.hasPointer(f
, t
.Elt
, false)
808 return p
.hasPointer(f
, t
.Elt
, top
)
809 case *ast
.StructType
:
810 for _
, field
:= range t
.Fields
.List
{
811 if p
.hasPointer(f
, field
.Type
, top
) {
816 case *ast
.StarExpr
: // Pointer type.
820 // Check whether this is a pointer to a C union (or class)
821 // type that contains a pointer.
822 if unionWithPointer
[t
.X
] {
825 return p
.hasPointer(f
, t
.X
, false)
826 case *ast
.FuncType
, *ast
.InterfaceType
, *ast
.MapType
, *ast
.ChanType
:
829 // TODO: Handle types defined within function.
830 for _
, d
:= range p
.Decl
{
831 gd
, ok
:= d
.(*ast
.GenDecl
)
832 if !ok || gd
.Tok
!= token
.TYPE
{
835 for _
, spec
:= range gd
.Specs
{
836 ts
, ok
:= spec
.(*ast
.TypeSpec
)
840 if ts
.Name
.Name
== t
.Name
{
841 return p
.hasPointer(f
, ts
.Type
, top
)
845 if def
:= typedef
[t
.Name
]; def
!= nil {
846 return p
.hasPointer(f
, def
.Go
, top
)
848 if t
.Name
== "string" {
851 if t
.Name
== "error" {
854 if goTypes
[t
.Name
] != nil {
857 // We can't figure out the type. Conservative
858 // approach is to assume it has a pointer.
860 case *ast
.SelectorExpr
:
861 if l
, ok
:= t
.X
.(*ast
.Ident
); !ok || l
.Name
!= "C" {
862 // Type defined in a different package.
863 // Conservative approach is to assume it has a
868 // Conservative approach: assume pointer.
871 name
:= f
.Name
[t
.Sel
.Name
]
872 if name
!= nil && name
.Kind
== "type" && name
.Type
!= nil && name
.Type
.Go
!= nil {
873 return p
.hasPointer(f
, name
.Type
.Go
, top
)
875 // We can't figure out the type. Conservative
876 // approach is to assume it has a pointer.
879 error_(t
.Pos(), "could not understand type %s", gofmt(t
))
884 // checkAddrArgs tries to add arguments to the call of
885 // _cgoCheckPointer when the argument is an address expression. We
886 // pass true to mean that the argument is an address operation of
887 // something other than a slice index, which means that it's only
888 // necessary to check the specific element pointed to, not the entire
889 // object. This is for &s.f, where f is a field in a struct. We can
890 // pass a slice or array, meaning that we should check the entire
891 // slice or array but need not check any other part of the object.
892 // This is for &s.a[i], where we need to check all of a. However, we
893 // only pass the slice or array if we can refer to it without side
895 func (p
*Package
) checkAddrArgs(f
*File
, args
[]ast
.Expr
, x ast
.Expr
) []ast
.Expr
{
896 // Strip type conversions.
898 c
, ok
:= x
.(*ast
.CallExpr
)
899 if !ok ||
len(c
.Args
) != 1 ||
!p
.isType(c
.Fun
) {
904 u
, ok
:= x
.(*ast
.UnaryExpr
)
905 if !ok || u
.Op
!= token
.AND
{
908 index
, ok
:= u
.X
.(*ast
.IndexExpr
)
910 // This is the address of something that is not an
911 // index expression. We only need to examine the
912 // single value to which it points.
913 // TODO: what if true is shadowed?
914 return append(args
, ast
.NewIdent("true"))
916 if !p
.hasSideEffects(f
, index
.X
) {
917 // Examine the entire slice.
918 return append(args
, index
.X
)
920 // Treat the pointer as unknown.
924 // hasSideEffects returns whether the expression x has any side
925 // effects. x is an expression, not a statement, so the only side
926 // effect is a function call.
927 func (p
*Package
) hasSideEffects(f
*File
, x ast
.Expr
) bool {
930 func(f
*File
, x
interface{}, context
string) {
939 // isType returns whether the expression is definitely a type.
940 // This is conservative--it returns false for an unknown identifier.
941 func (p
*Package
) isType(t ast
.Expr
) bool {
942 switch t
:= t
.(type) {
943 case *ast
.SelectorExpr
:
944 id
, ok
:= t
.X
.(*ast
.Ident
)
948 if id
.Name
== "unsafe" && t
.Sel
.Name
== "Pointer" {
951 if id
.Name
== "C" && typedef
["_Ctype_"+t
.Sel
.Name
] != nil {
956 // TODO: This ignores shadowing.
958 case "unsafe.Pointer", "bool", "byte",
959 "complex64", "complex128",
961 "float32", "float64",
962 "int", "int8", "int16", "int32", "int64",
964 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
970 case *ast
.ArrayType
, *ast
.StructType
, *ast
.FuncType
, *ast
.InterfaceType
,
971 *ast
.MapType
, *ast
.ChanType
:
978 // rewriteUnsafe returns a version of t with references to unsafe.Pointer
979 // rewritten to use _cgo_unsafe.Pointer instead.
980 func (p
*Package
) rewriteUnsafe(t ast
.Expr
) ast
.Expr
{
981 switch t
:= t
.(type) {
983 // We don't see a SelectorExpr for unsafe.Pointer;
984 // this is created by code in this file.
985 if t
.Name
== "unsafe.Pointer" {
986 return ast
.NewIdent("_cgo_unsafe.Pointer")
989 t1
:= p
.rewriteUnsafe(t
.Elt
)
995 case *ast
.StructType
:
999 for _
, f
:= range t
.Fields
.List
{
1000 ft
:= p
.rewriteUnsafe(f
.Type
)
1002 fields
.List
= append(fields
.List
, f
)
1006 fields
.List
= append(fields
.List
, &fn
)
1015 case *ast
.StarExpr
: // Pointer type.
1016 x1
:= p
.rewriteUnsafe(t
.X
)
1026 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1027 // Go equivalents, now that we have figured out the meaning of all
1028 // the xxx. In *godefs mode, rewriteRef replaces the names
1029 // with full definitions instead of mangled names.
1030 func (p
*Package
) rewriteRef(f
*File
) {
1031 // Keep a list of all the functions, to remove the ones
1032 // only used as expressions and avoid generating bridge
1034 functions
:= make(map[string]bool)
1036 // Assign mangled names.
1037 for _
, n
:= range f
.Name
{
1038 if n
.Kind
== "not-type" {
1044 if n
.Kind
== "func" {
1045 functions
[n
.Go
] = false
1049 // Now that we have all the name types filled in,
1050 // scan through the Refs to identify the ones that
1051 // are trying to do a ,err call. Also check that
1052 // functions are only used in calls.
1053 for _
, r
:= range f
.Ref
{
1054 if r
.Name
.Kind
== "const" && r
.Name
.Const
== "" {
1055 error_(r
.Pos(), "unable to find value of constant C.%s", fixGo(r
.Name
.Go
))
1057 var expr ast
.Expr
= ast
.NewIdent(r
.Name
.Mangle
) // default
1059 case "call", "call2":
1060 if r
.Name
.Kind
!= "func" {
1061 if r
.Name
.Kind
== "type" {
1063 if r
.Name
.Type
== nil {
1064 error_(r
.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r
.Name
.Go
), r
.Name
.C
)
1067 expr
= r
.Name
.Type
.Go
1070 error_(r
.Pos(), "call of non-function C.%s", fixGo(r
.Name
.Go
))
1073 functions
[r
.Name
.Go
] = true
1074 if r
.Context
== "call2" {
1075 if r
.Name
.Go
== "_CMalloc" {
1076 error_(r
.Pos(), "no two-result form for C.malloc")
1079 // Invent new Name for the two-result function.
1080 n
:= f
.Name
["2"+r
.Name
.Go
]
1085 n
.Mangle
= "_C2func_" + n
.Go
1086 f
.Name
["2"+r
.Name
.Go
] = n
1088 expr
= ast
.NewIdent(n
.Mangle
)
1093 if r
.Name
.Kind
== "func" {
1094 // Function is being used in an expression, to e.g. pass around a C function pointer.
1095 // Create a new Name for this Ref which causes the variable to be declared in Go land.
1096 fpName
:= "fp_" + r
.Name
.Go
1097 name
:= f
.Name
[fpName
]
1103 Type
: &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("void*"), Go
: ast
.NewIdent("unsafe.Pointer")},
1106 f
.Name
[fpName
] = name
1109 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1110 // function is defined in out.go and simply returns its argument. See
1112 expr
= &ast
.CallExpr
{
1113 Fun
: &ast
.Ident
{NamePos
: (*r
.Expr
).Pos(), Name
: "_Cgo_ptr"},
1114 Args
: []ast
.Expr
{ast
.NewIdent(name
.Mangle
)},
1116 } else if r
.Name
.Kind
== "type" {
1117 // Okay - might be new(T)
1118 if r
.Name
.Type
== nil {
1119 error_(r
.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r
.Name
.Go
), r
.Name
.C
)
1122 expr
= r
.Name
.Type
.Go
1123 } else if r
.Name
.Kind
== "var" {
1124 expr
= &ast
.StarExpr
{Star
: (*r
.Expr
).Pos(), X
: expr
}
1128 if r
.Name
.Kind
== "var" {
1129 expr
= &ast
.StarExpr
{Star
: (*r
.Expr
).Pos(), X
: expr
}
1131 error_(r
.Pos(), "only C variables allowed in selector expression %s", fixGo(r
.Name
.Go
))
1135 if r
.Name
.Kind
!= "type" {
1136 error_(r
.Pos(), "expression C.%s used as type", fixGo(r
.Name
.Go
))
1137 } else if r
.Name
.Type
== nil {
1138 // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1139 // GCC won't raise an error when using pointers to such unknown types.
1140 error_(r
.Pos(), "type C.%s: undefined C type '%s'", fixGo(r
.Name
.Go
), r
.Name
.C
)
1142 expr
= r
.Name
.Type
.Go
1145 if r
.Name
.Kind
== "func" {
1146 error_(r
.Pos(), "must call C.%s", fixGo(r
.Name
.Go
))
1150 // Substitute definition for mangled type name.
1151 if id
, ok
:= expr
.(*ast
.Ident
); ok
{
1152 if t
:= typedef
[id
.Name
]; t
!= nil {
1155 if id
.Name
== r
.Name
.Mangle
&& r
.Name
.Const
!= "" {
1156 expr
= ast
.NewIdent(r
.Name
.Const
)
1161 // Copy position information from old expr into new expr,
1162 // in case expression being replaced is first on line.
1163 // See golang.org/issue/6563.
1164 pos
:= (*r
.Expr
).Pos()
1165 switch x
:= expr
.(type) {
1167 expr
= &ast
.Ident
{NamePos
: pos
, Name
: x
.Name
}
1173 // Remove functions only used as expressions, so their respective
1174 // bridge functions are not generated.
1175 for name
, used
:= range functions
{
1177 delete(f
.Name
, name
)
1182 // gccBaseCmd returns the start of the compiler command line.
1183 // It uses $CC if set, or else $GCC, or else the compiler recorded
1184 // during the initial build as defaultCC.
1185 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1186 func (p
*Package
) gccBaseCmd() []string {
1187 // Use $CC if set, since that's what the build uses.
1188 if ret
:= strings
.Fields(os
.Getenv("CC")); len(ret
) > 0 {
1191 // Try $GCC if set, since that's what we used to use.
1192 if ret
:= strings
.Fields(os
.Getenv("GCC")); len(ret
) > 0 {
1195 return strings
.Fields(defaultCC
)
1198 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1199 func (p
*Package
) gccMachine() []string {
1202 return []string{"-m64"}
1204 return []string{"-m32"}
1206 return []string{"-marm"} // not thumb
1208 return []string{"-m31"}
1210 return []string{"-m64"}
1211 case "mips64", "mips64le":
1212 return []string{"-mabi=64"}
1213 case "mips", "mipsle":
1214 return []string{"-mabi=32"}
1219 func gccTmp() string {
1220 return *objDir
+ "_cgo_.o"
1223 // gccCmd returns the gcc command line to use for compiling
1225 func (p
*Package
) gccCmd() []string {
1226 c
:= append(p
.gccBaseCmd(),
1227 "-w", // no warnings
1228 "-Wno-error", // warnings are not errors
1229 "-o"+gccTmp(), // write object to tmp
1230 "-gdwarf-2", // generate DWARF v2 debugging symbols
1231 "-c", // do not link
1232 "-xc", // input language is C
1237 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1238 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1239 // flag to disable the warning. Yes, really good diagnostics, clang.
1240 "-Wno-unknown-warning-option",
1241 "-Wno-unneeded-internal-declaration",
1242 "-Wno-unused-function",
1243 "-Qunused-arguments",
1244 // Clang embeds prototypes for some builtin functions,
1245 // like malloc and calloc, but all size_t parameters are
1246 // incorrectly typed unsigned long. We work around that
1247 // by disabling the builtin functions (this is safe as
1248 // it won't affect the actual compilation of the C code).
1249 // See: https://golang.org/issue/6506.
1254 c
= append(c
, p
.GccOptions
...)
1255 c
= append(c
, p
.gccMachine()...)
1256 c
= append(c
, "-") //read input from standard input
1260 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
1261 // returns the corresponding DWARF data and, if present, debug data block.
1262 func (p
*Package
) gccDebug(stdin
[]byte) (*dwarf
.Data
, binary
.ByteOrder
, []byte) {
1263 runGcc(stdin
, p
.gccCmd())
1265 isDebugData
:= func(s
string) bool {
1266 // Some systems use leading _ to denote non-assembly symbols.
1267 return s
== "__cgodebug_data" || s
== "___cgodebug_data"
1270 if f
, err
:= macho
.Open(gccTmp()); err
== nil {
1274 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1277 if f
.Symtab
!= nil {
1278 for i
:= range f
.Symtab
.Syms
{
1279 s
:= &f
.Symtab
.Syms
[i
]
1280 if isDebugData(s
.Name
) {
1281 // Found it. Now find data section.
1282 if i
:= int(s
.Sect
) - 1; 0 <= i
&& i
< len(f
.Sections
) {
1283 sect
:= f
.Sections
[i
]
1284 if sect
.Addr
<= s
.Value
&& s
.Value
< sect
.Addr
+sect
.Size
{
1285 if sdat
, err
:= sect
.Data(); err
== nil {
1286 data
= sdat
[s
.Value
-sect
.Addr
:]
1293 return d
, f
.ByteOrder
, data
1296 if f
, err
:= elf
.Open(gccTmp()); err
== nil {
1300 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1303 symtab
, err
:= f
.Symbols()
1305 for i
:= range symtab
{
1307 if isDebugData(s
.Name
) {
1308 // Found it. Now find data section.
1309 if i
:= int(s
.Section
); 0 <= i
&& i
< len(f
.Sections
) {
1310 sect
:= f
.Sections
[i
]
1311 if sect
.Addr
<= s
.Value
&& s
.Value
< sect
.Addr
+sect
.Size
{
1312 if sdat
, err
:= sect
.Data(); err
== nil {
1313 data
= sdat
[s
.Value
-sect
.Addr
:]
1320 return d
, f
.ByteOrder
, data
1323 if f
, err
:= pe
.Open(gccTmp()); err
== nil {
1327 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1330 for _
, s
:= range f
.Symbols
{
1331 if isDebugData(s
.Name
) {
1332 if i
:= int(s
.SectionNumber
) - 1; 0 <= i
&& i
< len(f
.Sections
) {
1333 sect
:= f
.Sections
[i
]
1334 if s
.Value
< sect
.Size
{
1335 if sdat
, err
:= sect
.Data(); err
== nil {
1336 data
= sdat
[s
.Value
:]
1342 return d
, binary
.LittleEndian
, data
1345 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
1346 panic("not reached")
1349 // gccDefines runs gcc -E -dM -xc - over the C program stdin
1350 // and returns the corresponding standard output, which is the
1351 // #defines that gcc encountered while processing the input
1352 // and its included files.
1353 func (p
*Package
) gccDefines(stdin
[]byte) string {
1354 base
:= append(p
.gccBaseCmd(), "-E", "-dM", "-xc")
1355 base
= append(base
, p
.gccMachine()...)
1356 stdout
, _
:= runGcc(stdin
, append(append(base
, p
.GccOptions
...), "-"))
1360 // gccErrors runs gcc over the C program stdin and returns
1361 // the errors that gcc prints. That is, this function expects
1363 func (p
*Package
) gccErrors(stdin
[]byte) string {
1364 // TODO(rsc): require failure
1367 // Optimization options can confuse the error messages; remove them.
1368 nargs
:= make([]string, 0, len(args
))
1369 for _
, arg
:= range args
{
1370 if !strings
.HasPrefix(arg
, "-O") {
1371 nargs
= append(nargs
, arg
)
1376 fmt
.Fprintf(os
.Stderr
, "$ %s <<EOF\n", strings
.Join(nargs
, " "))
1377 os
.Stderr
.Write(stdin
)
1378 fmt
.Fprint(os
.Stderr
, "EOF\n")
1380 stdout
, stderr
, _
:= run(stdin
, nargs
)
1382 os
.Stderr
.Write(stdout
)
1383 os
.Stderr
.Write(stderr
)
1385 return string(stderr
)
1388 // runGcc runs the gcc command line args with stdin on standard input.
1389 // If the command exits with a non-zero exit status, runGcc prints
1390 // details about what was run and exits.
1391 // Otherwise runGcc returns the data written to standard output and standard error.
1392 // Note that for some of the uses we expect useful data back
1393 // on standard error, but for those uses gcc must still exit 0.
1394 func runGcc(stdin
[]byte, args
[]string) (string, string) {
1396 fmt
.Fprintf(os
.Stderr
, "$ %s <<EOF\n", strings
.Join(args
, " "))
1397 os
.Stderr
.Write(stdin
)
1398 fmt
.Fprint(os
.Stderr
, "EOF\n")
1400 stdout
, stderr
, ok
:= run(stdin
, args
)
1402 os
.Stderr
.Write(stdout
)
1403 os
.Stderr
.Write(stderr
)
1406 os
.Stderr
.Write(stderr
)
1409 return string(stdout
), string(stderr
)
1412 // A typeConv is a translator from dwarf types to Go types
1413 // with equivalent memory layout.
1414 type typeConv
struct {
1415 // Cache of already-translated or in-progress types.
1416 m
map[dwarf
.Type
]*Type
1418 // Map from types to incomplete pointers to those types.
1419 ptrs
map[dwarf
.Type
][]*Type
1420 // Keys of ptrs in insertion order (deterministic worklist)
1421 ptrKeys
[]dwarf
.Type
1423 // Predeclared types.
1425 byte ast
.Expr
// denotes padding
1426 int8, int16, int32, int64 ast
.Expr
1427 uint8, uint16, uint32, uint64, uintptr ast
.Expr
1428 float32, float64 ast
.Expr
1429 complex64
, complex128 ast
.Expr
1432 goVoid ast
.Expr
// _Ctype_void, denotes C's void
1433 goVoidPtr ast
.Expr
// unsafe.Pointer or *byte
1440 var typedef
= make(map[string]*Type
)
1441 var goIdent
= make(map[string]*ast
.Ident
)
1443 // unionWithPointer is true for a Go type that represents a C union (or class)
1444 // that may contain a pointer. This is used for cgo pointer checking.
1445 var unionWithPointer
= make(map[ast
.Expr
]bool)
1447 func (c
*typeConv
) Init(ptrSize
, intSize
int64) {
1450 c
.m
= make(map[dwarf
.Type
]*Type
)
1451 c
.ptrs
= make(map[dwarf
.Type
][]*Type
)
1452 c
.bool = c
.Ident("bool")
1453 c
.byte = c
.Ident("byte")
1454 c
.int8 = c
.Ident("int8")
1455 c
.int16 = c
.Ident("int16")
1456 c
.int32 = c
.Ident("int32")
1457 c
.int64 = c
.Ident("int64")
1458 c
.uint8 = c
.Ident("uint8")
1459 c
.uint16 = c
.Ident("uint16")
1460 c
.uint32 = c
.Ident("uint32")
1461 c
.uint64 = c
.Ident("uint64")
1462 c
.uintptr = c
.Ident("uintptr")
1463 c
.float32 = c
.Ident("float32")
1464 c
.float64 = c
.Ident("float64")
1465 c
.complex64
= c
.Ident("complex64")
1466 c
.complex128
= c
.Ident("complex128")
1467 c
.void
= c
.Ident("void")
1468 c
.string = c
.Ident("string")
1469 c
.goVoid
= c
.Ident("_Ctype_void")
1471 // Normally cgo translates void* to unsafe.Pointer,
1472 // but for historical reasons -godefs uses *byte instead.
1474 c
.goVoidPtr
= &ast
.StarExpr
{X
: c
.byte}
1476 c
.goVoidPtr
= c
.Ident("unsafe.Pointer")
1480 // base strips away qualifiers and typedefs to get the underlying type
1481 func base(dt dwarf
.Type
) dwarf
.Type
{
1483 if d
, ok
:= dt
.(*dwarf
.QualType
); ok
{
1487 if d
, ok
:= dt
.(*dwarf
.TypedefType
); ok
{
1496 // unqual strips away qualifiers from a DWARF type.
1497 // In general we don't care about top-level qualifiers.
1498 func unqual(dt dwarf
.Type
) dwarf
.Type
{
1500 if d
, ok
:= dt
.(*dwarf
.QualType
); ok
{
1509 // Map from dwarf text names to aliases we use in package "C".
1510 var dwarfToName
= map[string]string{
1512 "long unsigned int": "ulong",
1513 "unsigned int": "uint",
1514 "short unsigned int": "ushort",
1515 "unsigned short": "ushort", // Used by Clang; issue 13129.
1516 "short int": "short",
1517 "long long int": "longlong",
1518 "long long unsigned int": "ulonglong",
1519 "signed char": "schar",
1520 "unsigned char": "uchar",
1523 const signedDelta
= 64
1525 // String returns the current type representation. Format arguments
1526 // are assembled within this method so that any changes in mutable
1527 // values are taken into account.
1528 func (tr
*TypeRepr
) String() string {
1529 if len(tr
.Repr
) == 0 {
1532 if len(tr
.FormatArgs
) == 0 {
1535 return fmt
.Sprintf(tr
.Repr
, tr
.FormatArgs
...)
1538 // Empty reports whether the result of String would be "".
1539 func (tr
*TypeRepr
) Empty() bool {
1540 return len(tr
.Repr
) == 0
1543 // Set modifies the type representation.
1544 // If fargs are provided, repr is used as a format for fmt.Sprintf.
1545 // Otherwise, repr is used unprocessed as the type representation.
1546 func (tr
*TypeRepr
) Set(repr
string, fargs
...interface{}) {
1548 tr
.FormatArgs
= fargs
1551 // FinishType completes any outstanding type mapping work.
1552 // In particular, it resolves incomplete pointer types.
1553 func (c
*typeConv
) FinishType(pos token
.Pos
) {
1554 // Completing one pointer type might produce more to complete.
1555 // Keep looping until they're all done.
1556 for len(c
.ptrKeys
) > 0 {
1557 dtype
:= c
.ptrKeys
[0]
1558 c
.ptrKeys
= c
.ptrKeys
[1:]
1560 // Note Type might invalidate c.ptrs[dtype].
1561 t
:= c
.Type(dtype
, pos
)
1562 for _
, ptr
:= range c
.ptrs
[dtype
] {
1563 ptr
.Go
.(*ast
.StarExpr
).X
= t
.Go
1564 ptr
.C
.Set("%s*", t
.C
)
1566 c
.ptrs
[dtype
] = nil // retain the map key
1570 // Type returns a *Type with the same memory layout as
1571 // dtype when used as the type of a variable or a struct field.
1572 func (c
*typeConv
) Type(dtype dwarf
.Type
, pos token
.Pos
) *Type
{
1573 if t
, ok
:= c
.m
[dtype
]; ok
{
1575 fatalf("%s: type conversion loop at %s", lineno(pos
), dtype
)
1581 t
.Size
= dtype
.Size() // note: wrong for array of pointers, corrected below
1583 t
.C
= &TypeRepr
{Repr
: dtype
.Common().Name
}
1586 switch dt
:= dtype
.(type) {
1588 fatalf("%s: unexpected type: %s", lineno(pos
), dtype
)
1590 case *dwarf
.AddrType
:
1591 if t
.Size
!= c
.ptrSize
{
1592 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos
), t
.Size
, dtype
)
1597 case *dwarf
.ArrayType
:
1598 if dt
.StrideBitSize
> 0 {
1599 // Cannot represent bit-sized elements in Go.
1600 t
.Go
= c
.Opaque(t
.Size
)
1605 // Indicates flexible array member, which Go doesn't support.
1606 // Translate to zero-length array instead.
1609 sub
:= c
.Type(dt
.Type
, pos
)
1611 t
.Go
= &ast
.ArrayType
{
1612 Len
: c
.intExpr(count
),
1615 // Recalculate t.Size now that we know sub.Size.
1616 t
.Size
= count
* sub
.Size
1617 t
.C
.Set("__typeof__(%s[%d])", sub
.C
, dt
.Count
)
1619 case *dwarf
.BoolType
:
1623 case *dwarf
.CharType
:
1625 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos
), t
.Size
, dtype
)
1630 case *dwarf
.EnumType
:
1631 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
1634 t
.C
.Set("enum " + dt
.EnumName
)
1636 t
.EnumValues
= make(map[string]int64)
1637 for _
, ev
:= range dt
.Val
{
1638 t
.EnumValues
[ev
.Name
] = ev
.Val
1640 signed
= signedDelta
1643 switch t
.Size
+ int64(signed
) {
1645 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos
), t
.Size
, dtype
)
1654 case 1 + signedDelta
:
1656 case 2 + signedDelta
:
1658 case 4 + signedDelta
:
1660 case 8 + signedDelta
:
1664 case *dwarf
.FloatType
:
1667 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos
), t
.Size
, dtype
)
1673 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
1677 case *dwarf
.ComplexType
:
1680 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos
), t
.Size
, dtype
)
1686 if t
.Align
= t
.Size
/ 2; t
.Align
>= c
.ptrSize
{
1690 case *dwarf
.FuncType
:
1691 // No attempt at translation: would enable calls
1692 // directly between worlds, but we need to moderate those.
1696 case *dwarf
.IntType
:
1698 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos
), dt
.BitSize
, dtype
)
1702 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos
), t
.Size
, dtype
)
1712 t
.Go
= &ast
.ArrayType
{
1713 Len
: c
.intExpr(t
.Size
),
1717 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
1721 case *dwarf
.PtrType
:
1722 // Clang doesn't emit DW_AT_byte_size for pointer types.
1723 if t
.Size
!= c
.ptrSize
&& t
.Size
!= -1 {
1724 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos
), t
.Size
, dtype
)
1729 if _
, ok
:= base(dt
.Type
).(*dwarf
.VoidType
); ok
{
1734 if d
, ok
:= dq
.(*dwarf
.QualType
); ok
{
1735 t
.C
.Set(d
.Qual
+ " " + t
.C
.String())
1744 // Placeholder initialization; completed in FinishType.
1745 t
.Go
= &ast
.StarExpr
{}
1746 t
.C
.Set("<incomplete>*")
1747 if _
, ok
:= c
.ptrs
[dt
.Type
]; !ok
{
1748 c
.ptrKeys
= append(c
.ptrKeys
, dt
.Type
)
1750 c
.ptrs
[dt
.Type
] = append(c
.ptrs
[dt
.Type
], t
)
1752 case *dwarf
.QualType
:
1753 t1
:= c
.Type(dt
.Type
, pos
)
1757 if unionWithPointer
[t1
.Go
] {
1758 unionWithPointer
[t
.Go
] = true
1762 t
.C
.Set("%s "+dt
.Qual
, t1
.C
)
1765 case *dwarf
.StructType
:
1766 // Convert to Go struct, being careful about alignment.
1767 // Have to give it a name to simulate C "struct foo" references.
1768 tag
:= dt
.StructName
1769 if dt
.ByteSize
< 0 && tag
== "" { // opaque unnamed struct - should not be possible
1773 tag
= "__" + strconv
.Itoa(tagGen
)
1775 } else if t
.C
.Empty() {
1776 t
.C
.Set(dt
.Kind
+ " " + tag
)
1778 name
:= c
.Ident("_Ctype_" + dt
.Kind
+ "_" + tag
)
1779 t
.Go
= name
// publish before recursive calls
1780 goIdent
[name
.Name
] = name
1781 if dt
.ByteSize
< 0 {
1782 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
1783 // so execute the basic things that the struct case would do
1784 // other than try to determine a Go representation.
1786 tt
.C
= &TypeRepr
{"%s %s", []interface{}{dt
.Kind
, tag
}}
1787 tt
.Go
= c
.Ident("struct{}")
1788 typedef
[name
.Name
] = &tt
1792 case "class", "union":
1793 t
.Go
= c
.Opaque(t
.Size
)
1794 if c
.dwarfHasPointer(dt
, pos
) {
1795 unionWithPointer
[t
.Go
] = true
1798 t
.C
.Set("__typeof__(unsigned char[%d])", t
.Size
)
1800 t
.Align
= 1 // TODO: should probably base this on field alignment.
1801 typedef
[name
.Name
] = t
1803 g
, csyntax
, align
:= c
.Struct(dt
, pos
)
1810 tt
.C
= &TypeRepr
{"struct %s", []interface{}{tag
}}
1813 typedef
[name
.Name
] = &tt
1816 case *dwarf
.TypedefType
:
1817 // Record typedef for printing.
1818 if dt
.Name
== "_GoString_" {
1819 // Special C name for Go string type.
1820 // Knows string layout used by compilers: pointer plus length,
1821 // which rounds up to 2 pointers after alignment.
1823 t
.Size
= c
.ptrSize
* 2
1827 if dt
.Name
== "_GoBytes_" {
1828 // Special C name for Go []byte type.
1829 // Knows slice layout used by compilers: pointer, length, cap.
1830 t
.Go
= c
.Ident("[]byte")
1831 t
.Size
= c
.ptrSize
+ 4 + 4
1835 name
:= c
.Ident("_Ctype_" + dt
.Name
)
1836 goIdent
[name
.Name
] = name
1837 sub
:= c
.Type(dt
.Type
, pos
)
1839 if unionWithPointer
[sub
.Go
] {
1840 unionWithPointer
[t
.Go
] = true
1844 oldType
:= typedef
[name
.Name
]
1848 typedef
[name
.Name
] = &tt
1851 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
1852 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
1853 // with the base type.
1854 // In -godefs mode, do this for all typedefs.
1855 if isStructUnionClass(sub
.Go
) ||
*godefs
{
1858 if isStructUnionClass(sub
.Go
) {
1859 // Use the typedef name for C code.
1860 typedef
[sub
.Go
.(*ast
.Ident
).Name
].C
= t
.C
1863 // If we've seen this typedef before, and it
1864 // was an anonymous struct/union/class before
1865 // too, use the old definition.
1866 // TODO: it would be safer to only do this if
1867 // we verify that the types are the same.
1868 if oldType
!= nil && isStructUnionClass(oldType
.Go
) {
1873 case *dwarf
.UcharType
:
1875 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos
), t
.Size
, dtype
)
1880 case *dwarf
.UintType
:
1882 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos
), dt
.BitSize
, dtype
)
1886 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos
), t
.Size
, dtype
)
1896 t
.Go
= &ast
.ArrayType
{
1897 Len
: c
.intExpr(t
.Size
),
1901 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
1905 case *dwarf
.VoidType
:
1911 switch dtype
.(type) {
1912 case *dwarf
.AddrType
, *dwarf
.BoolType
, *dwarf
.CharType
, *dwarf
.ComplexType
, *dwarf
.IntType
, *dwarf
.FloatType
, *dwarf
.UcharType
, *dwarf
.UintType
:
1913 s
:= dtype
.Common().Name
1915 if ss
, ok
:= dwarfToName
[s
]; ok
{
1918 s
= strings
.Join(strings
.Split(s
, " "), "") // strip spaces
1919 name
:= c
.Ident("_Ctype_" + s
)
1921 typedef
[name
.Name
] = &tt
1929 // Unsized types are [0]byte, unless they're typedefs of other types
1930 // or structs with tags.
1931 // if so, use the name we've already defined.
1933 switch dt
:= dtype
.(type) {
1934 case *dwarf
.TypedefType
:
1936 case *dwarf
.StructType
:
1937 if dt
.StructName
!= "" {
1950 fatalf("%s: internal error: did not create C name for %s", lineno(pos
), dtype
)
1956 // isStructUnionClass reports whether the type described by the Go syntax x
1957 // is a struct, union, or class with a tag.
1958 func isStructUnionClass(x ast
.Expr
) bool {
1959 id
, ok
:= x
.(*ast
.Ident
)
1964 return strings
.HasPrefix(name
, "_Ctype_struct_") ||
1965 strings
.HasPrefix(name
, "_Ctype_union_") ||
1966 strings
.HasPrefix(name
, "_Ctype_class_")
1969 // FuncArg returns a Go type with the same memory layout as
1970 // dtype when used as the type of a C function argument.
1971 func (c
*typeConv
) FuncArg(dtype dwarf
.Type
, pos token
.Pos
) *Type
{
1972 t
:= c
.Type(unqual(dtype
), pos
)
1973 switch dt
:= dtype
.(type) {
1974 case *dwarf
.ArrayType
:
1975 // Arrays are passed implicitly as pointers in C.
1976 // In Go, we must be explicit.
1982 Go
: &ast
.StarExpr
{X
: t
.Go
},
1985 case *dwarf
.TypedefType
:
1986 // C has much more relaxed rules than Go for
1987 // implicit type conversions. When the parameter
1988 // is type T defined as *X, simulate a little of the
1989 // laxness of C by making the argument *X instead of T.
1990 if ptr
, ok
:= base(dt
.Type
).(*dwarf
.PtrType
); ok
{
1991 // Unless the typedef happens to point to void* since
1992 // Go has special rules around using unsafe.Pointer.
1993 if _
, void
:= base(ptr
.Type
).(*dwarf
.VoidType
); void
{
1997 t
= c
.Type(ptr
, pos
)
2002 // For a struct/union/class, remember the C spelling,
2003 // in case it has __attribute__((unavailable)).
2005 if isStructUnionClass(t
.Go
) {
2013 // FuncType returns the Go type analogous to dtype.
2014 // There is no guarantee about matching memory layout.
2015 func (c
*typeConv
) FuncType(dtype
*dwarf
.FuncType
, pos token
.Pos
) *FuncType
{
2016 p
:= make([]*Type
, len(dtype
.ParamType
))
2017 gp
:= make([]*ast
.Field
, len(dtype
.ParamType
))
2018 for i
, f
:= range dtype
.ParamType
{
2019 // gcc's DWARF generator outputs a single DotDotDotType parameter for
2020 // function pointers that specify no parameters (e.g. void
2021 // (*__cgo_0)()). Treat this special case as void. This case is
2022 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2024 if _
, ok
:= f
.(*dwarf
.DotDotDotType
); ok
&& i
== 0 {
2028 p
[i
] = c
.FuncArg(f
, pos
)
2029 gp
[i
] = &ast
.Field
{Type
: p
[i
].Go
}
2033 if _
, ok
:= dtype
.ReturnType
.(*dwarf
.VoidType
); ok
{
2034 gr
= []*ast
.Field
{{Type
: c
.goVoid
}}
2035 } else if dtype
.ReturnType
!= nil {
2036 r
= c
.Type(unqual(dtype
.ReturnType
), pos
)
2037 gr
= []*ast
.Field
{{Type
: r
.Go
}}
2043 Params
: &ast
.FieldList
{List
: gp
},
2044 Results
: &ast
.FieldList
{List
: gr
},
2050 func (c
*typeConv
) Ident(s
string) *ast
.Ident
{
2051 return ast
.NewIdent(s
)
2054 // Opaque type of n bytes.
2055 func (c
*typeConv
) Opaque(n
int64) ast
.Expr
{
2056 return &ast
.ArrayType
{
2062 // Expr for integer n.
2063 func (c
*typeConv
) intExpr(n
int64) ast
.Expr
{
2064 return &ast
.BasicLit
{
2066 Value
: strconv
.FormatInt(n
, 10),
2070 // Add padding of given size to fld.
2071 func (c
*typeConv
) pad(fld
[]*ast
.Field
, sizes
[]int64, size
int64) ([]*ast
.Field
, []int64) {
2074 fld
[n
] = &ast
.Field
{Names
: []*ast
.Ident
{c
.Ident("_")}, Type
: c
.Opaque(size
)}
2075 sizes
= sizes
[0 : n
+1]
2080 // Struct conversion: return Go and (gc) C syntax for type.
2081 func (c
*typeConv
) Struct(dt
*dwarf
.StructType
, pos token
.Pos
) (expr
*ast
.StructType
, csyntax
string, align
int64) {
2082 // Minimum alignment for a struct is 1 byte.
2085 var buf bytes
.Buffer
2086 buf
.WriteString("struct {")
2087 fld
:= make([]*ast
.Field
, 0, 2*len(dt
.Field
)+1) // enough for padding around every field
2088 sizes
:= make([]int64, 0, 2*len(dt
.Field
)+1)
2091 // Rename struct fields that happen to be named Go keywords into
2092 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will
2093 // be mangled. Any existing identifier that already has the same name on
2094 // the C-side will cause the Go-mangled version to be prefixed with _.
2095 // (e.g. in a struct with fields '_type' and 'type', the latter would be
2096 // rendered as '__type' in Go).
2097 ident
:= make(map[string]string)
2098 used
:= make(map[string]bool)
2099 for _
, f
:= range dt
.Field
{
2100 ident
[f
.Name
] = f
.Name
2105 for cid
, goid
:= range ident
{
2106 if token
.Lookup(goid
).IsKeyword() {
2110 // Also avoid existing fields
2111 for _
, exist
:= used
[goid
]; exist
; _
, exist
= used
[goid
] {
2122 for _
, f
:= range dt
.Field
{
2123 if f
.ByteOffset
> off
{
2124 fld
, sizes
= c
.pad(fld
, sizes
, f
.ByteOffset
-off
)
2131 // In godefs mode, if this field is a C11
2132 // anonymous union then treat the first field in the
2133 // union as the field in the struct. This handles
2134 // cases like the glibc <sys/resource.h> file; see
2137 if st
, ok
:= f
.Type
.(*dwarf
.StructType
); ok
&& name
== "" && st
.Kind
== "union" && len(st
.Field
) > 0 && !used
[st
.Field
[0].Name
] {
2138 name
= st
.Field
[0].Name
2140 ft
= st
.Field
[0].Type
2144 // TODO: Handle fields that are anonymous structs by
2145 // promoting the fields of the inner struct.
2147 t
:= c
.Type(ft
, pos
)
2152 if f
.BitSize%8
!= 0 {
2155 size
= f
.BitSize
/ 8
2156 name
:= tgo
.(*ast
.Ident
).String()
2157 if strings
.HasPrefix(name
, "int") {
2162 tgo
= ast
.NewIdent(name
+ fmt
.Sprint(f
.BitSize
))
2166 if talign
> 0 && f
.ByteOffset%talign
!= 0 {
2167 // Drop misaligned fields, the same way we drop integer bit fields.
2168 // The goal is to make available what can be made available.
2169 // Otherwise one bad and unneeded field in an otherwise okay struct
2170 // makes the whole program not compile. Much of the time these
2171 // structs are in system headers that cannot be corrected.
2177 name
= fmt
.Sprintf("anon%d", anon
)
2181 fld
[n
] = &ast
.Field
{Names
: []*ast
.Ident
{c
.Ident(ident
[name
])}, Type
: tgo
}
2182 sizes
= sizes
[0 : n
+1]
2185 buf
.WriteString(t
.C
.String())
2186 buf
.WriteString(" ")
2187 buf
.WriteString(name
)
2188 buf
.WriteString("; ")
2193 if off
< dt
.ByteSize
{
2194 fld
, sizes
= c
.pad(fld
, sizes
, dt
.ByteSize
-off
)
2198 // If the last field in a non-zero-sized struct is zero-sized
2199 // the compiler is going to pad it by one (see issue 9401).
2200 // We can't permit that, because then the size of the Go
2201 // struct will not be the same as the size of the C struct.
2202 // Our only option in such a case is to remove the field,
2203 // which means that it cannot be referenced from Go.
2204 for off
> 0 && sizes
[len(sizes
)-1] == 0 {
2207 sizes
= sizes
[0 : n
-1]
2210 if off
!= dt
.ByteSize
{
2211 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos
), off
, dt
.ByteSize
)
2213 buf
.WriteString("}")
2214 csyntax
= buf
.String()
2219 expr
= &ast
.StructType
{Fields
: &ast
.FieldList
{List
: fld
}}
2223 // dwarfHasPointer returns whether the DWARF type dt contains a pointer.
2224 func (c
*typeConv
) dwarfHasPointer(dt dwarf
.Type
, pos token
.Pos
) bool {
2225 switch dt
:= dt
.(type) {
2227 fatalf("%s: unexpected type: %s", lineno(pos
), dt
)
2230 case *dwarf
.AddrType
, *dwarf
.BoolType
, *dwarf
.CharType
, *dwarf
.EnumType
,
2231 *dwarf
.FloatType
, *dwarf
.ComplexType
, *dwarf
.FuncType
,
2232 *dwarf
.IntType
, *dwarf
.UcharType
, *dwarf
.UintType
, *dwarf
.VoidType
:
2236 case *dwarf
.ArrayType
:
2237 return c
.dwarfHasPointer(dt
.Type
, pos
)
2239 case *dwarf
.PtrType
:
2242 case *dwarf
.QualType
:
2243 return c
.dwarfHasPointer(dt
.Type
, pos
)
2245 case *dwarf
.StructType
:
2246 for _
, f
:= range dt
.Field
{
2247 if c
.dwarfHasPointer(f
.Type
, pos
) {
2253 case *dwarf
.TypedefType
:
2254 if dt
.Name
== "_GoString_" || dt
.Name
== "_GoBytes_" {
2257 return c
.dwarfHasPointer(dt
.Type
, pos
)
2261 func upper(s
string) string {
2265 r
, size
:= utf8
.DecodeRuneInString(s
)
2269 return string(unicode
.ToUpper(r
)) + s
[size
:]
2272 // godefsFields rewrites field names for use in Go or C definitions.
2273 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2274 // converts names to upper case, and rewrites _ into Pad_godefs_n,
2275 // so that all fields are exported.
2276 func godefsFields(fld
[]*ast
.Field
) {
2277 prefix
:= fieldPrefix(fld
)
2279 for _
, f
:= range fld
{
2280 for _
, n
:= range f
.Names
{
2281 if n
.Name
!= prefix
{
2282 n
.Name
= strings
.TrimPrefix(n
.Name
, prefix
)
2285 // Use exported name instead.
2286 n
.Name
= "Pad_cgo_" + strconv
.Itoa(npad
)
2289 n
.Name
= upper(n
.Name
)
2294 // fieldPrefix returns the prefix that should be removed from all the
2295 // field names when generating the C or Go code. For generated
2296 // C, we leave the names as is (tv_sec, tv_usec), since that's what
2297 // people are used to seeing in C. For generated Go code, such as
2298 // package syscall's data structures, we drop a common prefix
2299 // (so sec, usec, which will get turned into Sec, Usec for exporting).
2300 func fieldPrefix(fld
[]*ast
.Field
) string {
2302 for _
, f
:= range fld
{
2303 for _
, n
:= range f
.Names
{
2304 // Ignore field names that don't have the prefix we're
2305 // looking for. It is common in C headers to have fields
2306 // named, say, _pad in an otherwise prefixed header.
2307 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
2308 // still want to remove the tv_ prefix.
2309 // The check for "orig_" here handles orig_eax in the
2310 // x86 ptrace register sets, which otherwise have all fields
2311 // with reg_ prefixes.
2312 if strings
.HasPrefix(n
.Name
, "orig_") || strings
.HasPrefix(n
.Name
, "_") {
2315 i
:= strings
.Index(n
.Name
, "_")
2320 prefix
= n
.Name
[:i
+1]
2321 } else if prefix
!= n
.Name
[:i
+1] {