]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/cmd/cgo/gcc.go
libgo: update to go1.7rc3
[thirdparty/gcc.git] / libgo / go / cmd / cgo / gcc.go
CommitLineData
22b955cc 1// Copyright 2009 The Go Authors. All rights reserved.
7d7d64c1
ILT
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Annotate Ref in Prog with C types by parsing gcc debug output.
6// Conversion of debug output to Go types.
7
8package main
9
10import (
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 "os"
24 "strconv"
25 "strings"
26 "unicode"
27 "unicode/utf8"
28)
29
30var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
31var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
32
33var 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",
f98dd1a3
ILT
41 "complexfloat": "float _Complex",
42 "complexdouble": "double _Complex",
7d7d64c1
ILT
43}
44
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
48// union and enum.
49func cname(s string) string {
50 if t, ok := nameToC[s]; ok {
51 return t
52 }
53
54 if strings.HasPrefix(s, "struct_") {
55 return "struct " + s[len("struct_"):]
56 }
57 if strings.HasPrefix(s, "union_") {
58 return "union " + s[len("union_"):]
59 }
60 if strings.HasPrefix(s, "enum_") {
61 return "enum " + s[len("enum_"):]
62 }
63 if strings.HasPrefix(s, "sizeof_") {
64 return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
65 }
66 return s
67}
68
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.
72func (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)
79 } else {
80 linesOut = append(linesOut, "")
81 }
82 }
83 f.Preamble = strings.Join(linesOut, "\n")
84}
85
22b955cc 86// addToFlag appends args to flag. All flags are later written out onto the
7d7d64c1
ILT
87// _cgo_flags file for the build system to use.
88func (p *Package) addToFlag(flag string, args []string) {
89 p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
90 if flag == "CFLAGS" {
91 // We'll also need these when preprocessing for dwarf information.
92 p.GccOptions = append(p.GccOptions, args...)
93 }
94}
95
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
22b955cc 102// last element. The backslash is used for escaping.
7d7d64c1
ILT
103//
104// For example, the following string:
105//
106// `a b:"c d" 'e''f' "g\""`
107//
108// Would be parsed as:
109//
110// []string{"a", "b:c d", "ef", `g"`}
111//
112func splitQuoted(s string) (r []string, err error) {
113 var args []string
114 arg := make([]rune, len(s))
115 escaped := false
116 quoted := false
117 quote := '\x00'
118 i := 0
119 for _, r := range s {
120 switch {
121 case escaped:
122 escaped = false
123 case r == '\\':
124 escaped = true
125 continue
126 case quote != 0:
127 if r == quote {
128 quote = 0
129 continue
130 }
131 case r == '"' || r == '\'':
132 quoted = true
133 quote = r
134 continue
135 case unicode.IsSpace(r):
136 if quoted || i > 0 {
137 quoted = false
138 args = append(args, string(arg[:i]))
139 i = 0
140 }
141 continue
142 }
143 arg[i] = r
144 i++
145 }
146 if quoted || i > 0 {
147 args = append(args, string(arg[:i]))
148 }
149 if quote != 0 {
150 err = errors.New("unclosed quote")
151 } else if escaped {
152 err = errors.New("unfinished escaping")
153 }
154 return args, err
155}
156
7d7d64c1
ILT
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.
160func (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)
164 }
165 p.loadDefines(f)
166 needType := p.guessKinds(f)
167 if len(needType) > 0 {
168 p.loadDWARF(f, needType)
169 }
f98dd1a3 170 p.rewriteCalls(f)
7d7d64c1
ILT
171 p.rewriteRef(f)
172}
173
174// loadDefines coerces gcc into spitting out the #defines in use
175// in the file f and saves relevant renamings in f.Name[name].Define.
176func (p *Package) loadDefines(f *File) {
177 var b bytes.Buffer
178 b.WriteString(f.Preamble)
179 b.WriteString(builtinProlog)
180 stdout := p.gccDefines(b.Bytes())
181
182 for _, line := range strings.Split(stdout, "\n") {
183 if len(line) < 9 || line[0:7] != "#define" {
184 continue
185 }
186
187 line = strings.TrimSpace(line[8:])
188
189 var key, val string
190 spaceIndex := strings.Index(line, " ")
191 tabIndex := strings.Index(line, "\t")
192
193 if spaceIndex == -1 && tabIndex == -1 {
194 continue
195 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
196 key = line[0:spaceIndex]
197 val = strings.TrimSpace(line[spaceIndex:])
198 } else {
199 key = line[0:tabIndex]
200 val = strings.TrimSpace(line[tabIndex:])
201 }
202
af146490
ILT
203 if key == "__clang__" {
204 p.GccIsClang = true
205 }
206
7d7d64c1
ILT
207 if n := f.Name[key]; n != nil {
208 if *debugDefine {
209 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
210 }
211 n.Define = val
212 }
213 }
214}
215
216// guessKinds tricks gcc into revealing the kind of each
217// name xxx for the references C.xxx in the Go input.
218// The kind is either a constant, type, or variable.
219func (p *Package) guessKinds(f *File) []*Name {
220 // Determine kinds for names we already know about,
221 // like #defines or 'struct foo', before bothering with gcc.
222 var names, needType []*Name
f8d9fa9e
ILT
223 for _, key := range nameKeys(f.Name) {
224 n := f.Name[key]
7d7d64c1
ILT
225 // If we've already found this name as a #define
226 // and we can translate it as a constant value, do so.
227 if n.Define != "" {
228 isConst := false
229 if _, err := strconv.Atoi(n.Define); err == nil {
230 isConst = true
231 } else if n.Define[0] == '"' || n.Define[0] == '\'' {
232 if _, err := parser.ParseExpr(n.Define); err == nil {
233 isConst = true
234 }
235 }
236 if isConst {
237 n.Kind = "const"
238 // Turn decimal into hex, just for consistency
22b955cc 239 // with enum-derived constants. Otherwise
7d7d64c1
ILT
240 // in the cgo -godefs output half the constants
241 // are in hex and half are in whatever the #define used.
242 i, err := strconv.ParseInt(n.Define, 0, 64)
243 if err == nil {
244 n.Const = fmt.Sprintf("%#x", i)
245 } else {
246 n.Const = n.Define
247 }
248 continue
249 }
250
251 if isName(n.Define) {
252 n.C = n.Define
253 }
254 }
255
256 needType = append(needType, n)
257
258 // If this is a struct, union, or enum type name, no need to guess the kind.
259 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
260 n.Kind = "type"
261 continue
262 }
263
264 // Otherwise, we'll need to find out from gcc.
265 names = append(names, n)
266 }
267
268 // Bypass gcc if there's nothing left to find out.
269 if len(names) == 0 {
270 return needType
271 }
272
273 // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
274 // For names, find out whether they are integer constants.
275 // We used to look at specific warning or error messages here, but that tied the
276 // behavior too closely to specific versions of the compilers.
277 // Instead, arrange that we can infer what we need from only the presence or absence
278 // of an error on a specific line.
279 //
280 // For each name, we generate these lines, where xxx is the index in toSniff plus one.
281 //
282 // #line xxx "not-declared"
283 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
284 // #line xxx "not-type"
285 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
286 // #line xxx "not-const"
287 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
288 //
289 // If we see an error at not-declared:xxx, the corresponding name is not declared.
290 // If we see an error at not-type:xxx, the corresponding name is a type.
291 // If we see an error at not-const:xxx, the corresponding name is not an integer constant.
292 // If we see no errors, we assume the name is an expression but not a constant
293 // (so a variable or a function).
294 //
295 // The specific input forms are chosen so that they are valid C syntax regardless of
296 // whether name denotes a type or an expression.
297
298 var b bytes.Buffer
299 b.WriteString(f.Preamble)
300 b.WriteString(builtinProlog)
301
302 for i, n := range names {
303 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
304 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
305 "#line %d \"not-type\"\n"+
306 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
307 "#line %d \"not-const\"\n"+
308 "void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n",
309 i+1, i+1, n.C,
310 i+1, i+1, n.C,
311 i+1, i+1, n.C)
312 }
313 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
314 "int __cgo__1 = __cgo__2;\n")
315
316 stderr := p.gccErrors(b.Bytes())
317 if stderr == "" {
318 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
319 }
320
321 completed := false
322 sniff := make([]int, len(names))
323 const (
324 notType = 1 << iota
325 notConst
f8d9fa9e 326 notDeclared
7d7d64c1
ILT
327 )
328 for _, line := range strings.Split(stderr, "\n") {
329 if !strings.Contains(line, ": error:") {
330 // we only care about errors.
331 // we tried to turn off warnings on the command line, but one never knows.
332 continue
333 }
334
335 c1 := strings.Index(line, ":")
336 if c1 < 0 {
337 continue
338 }
339 c2 := strings.Index(line[c1+1:], ":")
340 if c2 < 0 {
341 continue
342 }
343 c2 += c1 + 1
344
345 filename := line[:c1]
346 i, _ := strconv.Atoi(line[c1+1 : c2])
347 i--
348 if i < 0 || i >= len(names) {
349 continue
350 }
351
352 switch filename {
353 case "completed":
354 // Strictly speaking, there is no guarantee that seeing the error at completed:1
355 // (at the end of the file) means we've seen all the errors from earlier in the file,
356 // but usually it does. Certainly if we don't see the completed:1 error, we did
357 // not get all the errors we expected.
358 completed = true
359
360 case "not-declared":
f8d9fa9e 361 sniff[i] |= notDeclared
7d7d64c1
ILT
362 case "not-type":
363 sniff[i] |= notType
364 case "not-const":
365 sniff[i] |= notConst
366 }
367 }
368
369 if !completed {
f8d9fa9e 370 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
7d7d64c1
ILT
371 }
372
373 for i, n := range names {
374 switch sniff[i] {
f8d9fa9e 375 default:
7d7d64c1
ILT
376 error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go))
377 case notType:
378 n.Kind = "const"
379 case notConst:
380 n.Kind = "type"
381 case notConst | notType:
382 n.Kind = "not-type"
383 }
384 }
385 if nerrors > 0 {
f8d9fa9e
ILT
386 // Check if compiling the preamble by itself causes any errors,
387 // because the messages we've printed out so far aren't helpful
22b955cc 388 // to users debugging preamble mistakes. See issue 8442.
f8d9fa9e
ILT
389 preambleErrors := p.gccErrors([]byte(f.Preamble))
390 if len(preambleErrors) > 0 {
391 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
392 }
393
7d7d64c1
ILT
394 fatalf("unresolved names")
395 }
396
397 needType = append(needType, names...)
398 return needType
399}
400
401// loadDWARF parses the DWARF debug information generated
402// by gcc to learn the details of the constants, variables, and types
403// being referred to as C.xxx.
404func (p *Package) loadDWARF(f *File, names []*Name) {
405 // Extract the types from the DWARF section of an object
22b955cc 406 // from a well-formed C program. Gcc only generates DWARF info
7d7d64c1
ILT
407 // for symbols in the object file, so it is not enough to print the
408 // preamble and hope the symbols we care about will be there.
409 // Instead, emit
410 // __typeof__(names[i]) *__cgo__i;
411 // for each entry in names and then dereference the type we
412 // learn for __cgo__i.
413 var b bytes.Buffer
414 b.WriteString(f.Preamble)
415 b.WriteString(builtinProlog)
416 for i, n := range names {
417 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
418 if n.Kind == "const" {
419 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
420 }
421 }
422
423 // Apple's LLVM-based gcc does not include the enumeration
22b955cc 424 // names and values in its DWARF debug output. In case we're
7d7d64c1
ILT
425 // using such a gcc, create a data block initialized with the values.
426 // We can read them out of the object file.
427 fmt.Fprintf(&b, "long long __cgodebug_data[] = {\n")
428 for _, n := range names {
429 if n.Kind == "const" {
430 fmt.Fprintf(&b, "\t%s,\n", n.C)
431 } else {
432 fmt.Fprintf(&b, "\t0,\n")
433 }
434 }
22b955cc 435 // for the last entry, we cannot use 0, otherwise
7d7d64c1
ILT
436 // in case all __cgodebug_data is zero initialized,
437 // LLVM-based gcc will place the it in the __DATA.__common
438 // zero-filled section (our debug/macho doesn't support
439 // this)
440 fmt.Fprintf(&b, "\t1\n")
441 fmt.Fprintf(&b, "};\n")
442
443 d, bo, debugData := p.gccDebug(b.Bytes())
444 enumVal := make([]int64, len(debugData)/8)
445 for i := range enumVal {
446 enumVal[i] = int64(bo.Uint64(debugData[i*8:]))
447 }
448
449 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
450 types := make([]dwarf.Type, len(names))
451 enums := make([]dwarf.Offset, len(names))
452 nameToIndex := make(map[*Name]int)
453 for i, n := range names {
454 nameToIndex[n] = i
455 }
456 nameToRef := make(map[*Name]*Ref)
457 for _, ref := range f.Ref {
458 nameToRef[ref.Name] = ref
459 }
460 r := d.Reader()
461 for {
462 e, err := r.Next()
463 if err != nil {
464 fatalf("reading DWARF entry: %s", err)
465 }
466 if e == nil {
467 break
468 }
469 switch e.Tag {
470 case dwarf.TagEnumerationType:
471 offset := e.Offset
472 for {
473 e, err := r.Next()
474 if err != nil {
475 fatalf("reading DWARF entry: %s", err)
476 }
477 if e.Tag == 0 {
478 break
479 }
480 if e.Tag == dwarf.TagEnumerator {
481 entryName := e.Val(dwarf.AttrName).(string)
482 if strings.HasPrefix(entryName, "__cgo_enum__") {
483 n, _ := strconv.Atoi(entryName[len("__cgo_enum__"):])
484 if 0 <= n && n < len(names) {
485 enums[n] = offset
486 }
487 }
488 }
489 }
490 case dwarf.TagVariable:
491 name, _ := e.Val(dwarf.AttrName).(string)
492 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
493 if name == "" || typOff == 0 {
4944c779
ILT
494 if e.Val(dwarf.AttrSpecification) != nil {
495 // Since we are reading all the DWARF,
496 // assume we will see the variable elsewhere.
497 break
498 }
7d7d64c1
ILT
499 fatalf("malformed DWARF TagVariable entry")
500 }
501 if !strings.HasPrefix(name, "__cgo__") {
502 break
503 }
504 typ, err := d.Type(typOff)
505 if err != nil {
506 fatalf("loading DWARF type: %s", err)
507 }
508 t, ok := typ.(*dwarf.PtrType)
509 if !ok || t == nil {
510 fatalf("internal error: %s has non-pointer type", name)
511 }
512 i, err := strconv.Atoi(name[7:])
513 if err != nil {
514 fatalf("malformed __cgo__ name: %s", name)
515 }
516 if enums[i] != 0 {
517 t, err := d.Type(enums[i])
518 if err != nil {
519 fatalf("loading DWARF type: %s", err)
520 }
521 types[i] = t
522 } else {
523 types[i] = t.Type
524 }
525 }
526 if e.Tag != dwarf.TagCompileUnit {
527 r.SkipChildren()
528 }
529 }
530
531 // Record types and typedef information.
532 var conv typeConv
533 conv.Init(p.PtrSize, p.IntSize)
534 for i, n := range names {
535 if types[i] == nil {
536 continue
537 }
538 pos := token.NoPos
539 if ref, ok := nameToRef[n]; ok {
540 pos = ref.Pos()
541 }
542 f, fok := types[i].(*dwarf.FuncType)
543 if n.Kind != "type" && fok {
544 n.Kind = "func"
545 n.FuncType = conv.FuncType(f, pos)
546 } else {
547 n.Type = conv.Type(types[i], pos)
548 if enums[i] != 0 && n.Type.EnumValues != nil {
549 k := fmt.Sprintf("__cgo_enum__%d", i)
550 n.Kind = "const"
551 n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k])
552 // Remove injected enum to ensure the value will deep-compare
553 // equally in future loads of the same constant.
554 delete(n.Type.EnumValues, k)
555 }
556 // Prefer debug data over DWARF debug output, if we have it.
557 if n.Kind == "const" && i < len(enumVal) {
558 n.Const = fmt.Sprintf("%#x", enumVal[i])
559 }
560 }
561 conv.FinishType(pos)
562 }
563}
564
565// mangleName does name mangling to translate names
566// from the original Go source files to the names
567// used in the final Go files generated by cgo.
568func (p *Package) mangleName(n *Name) {
569 // When using gccgo variables have to be
570 // exported so that they become global symbols
571 // that the C code can refer to.
572 prefix := "_C"
573 if *gccgo && n.IsVar() {
574 prefix = "C"
575 }
576 n.Mangle = prefix + n.Kind + "_" + n.Go
577}
578
f98dd1a3
ILT
579// rewriteCalls rewrites all calls that pass pointers to check that
580// they follow the rules for passing pointers between Go and C.
581func (p *Package) rewriteCalls(f *File) {
582 for _, call := range f.Calls {
583 // This is a call to C.xxx; set goname to "xxx".
22b955cc 584 goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name
f98dd1a3
ILT
585 if goname == "malloc" {
586 continue
587 }
588 name := f.Name[goname]
589 if name.Kind != "func" {
590 // Probably a type conversion.
591 continue
592 }
593 p.rewriteCall(f, call, name)
594 }
595}
596
22b955cc 597// rewriteCall rewrites one call to add pointer checks. We replace
f98dd1a3 598// each pointer argument x with _cgoCheckPointer(x).(T).
22b955cc
ILT
599func (p *Package) rewriteCall(f *File, call *Call, name *Name) {
600 // Avoid a crash if the number of arguments is
601 // less than the number of parameters.
602 // This will be caught when the generated file is compiled.
603 if len(call.Call.Args) < len(name.FuncType.Params) {
604 return
605 }
606
607 any := false
f98dd1a3 608 for i, param := range name.FuncType.Params {
22b955cc
ILT
609 if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) {
610 any = true
611 break
612 }
613 }
614 if !any {
615 return
616 }
617
618 // We need to rewrite this call.
619 //
620 // We are going to rewrite C.f(p) to C.f(_cgoCheckPointer(p)).
621 // If the call to C.f is deferred, that will check p at the
622 // point of the defer statement, not when the function is called, so
623 // rewrite to func(_cgo0 ptype) { C.f(_cgoCheckPointer(_cgo0)) }(p)
624
625 var dargs []ast.Expr
626 if call.Deferred {
627 dargs = make([]ast.Expr, len(name.FuncType.Params))
628 }
629 for i, param := range name.FuncType.Params {
630 origArg := call.Call.Args[i]
631 darg := origArg
632
633 if call.Deferred {
634 dargs[i] = darg
635 darg = ast.NewIdent(fmt.Sprintf("_cgo%d", i))
636 call.Call.Args[i] = darg
f98dd1a3
ILT
637 }
638
22b955cc 639 if !p.needsPointerCheck(f, param.Go, origArg) {
f98dd1a3
ILT
640 continue
641 }
642
643 c := &ast.CallExpr{
644 Fun: ast.NewIdent("_cgoCheckPointer"),
645 Args: []ast.Expr{
22b955cc 646 darg,
f98dd1a3
ILT
647 },
648 }
649
650 // Add optional additional arguments for an address
651 // expression.
22b955cc 652 c.Args = p.checkAddrArgs(f, c.Args, origArg)
f98dd1a3
ILT
653
654 // _cgoCheckPointer returns interface{}.
655 // We need to type assert that to the type we want.
656 // If the Go version of this C type uses
657 // unsafe.Pointer, we can't use a type assertion,
658 // because the Go file might not import unsafe.
659 // Instead we use a local variant of _cgoCheckPointer.
660
661 var arg ast.Expr
22b955cc 662 if n := p.unsafeCheckPointerName(param.Go, call.Deferred); n != "" {
f98dd1a3
ILT
663 c.Fun = ast.NewIdent(n)
664 arg = c
665 } else {
666 // In order for the type assertion to succeed,
667 // we need it to match the actual type of the
22b955cc
ILT
668 // argument. The only type we have is the
669 // type of the function parameter. We know
f98dd1a3
ILT
670 // that the argument type must be assignable
671 // to the function parameter type, or the code
672 // would not compile, but there is nothing
673 // requiring that the types be exactly the
22b955cc 674 // same. Add a type conversion to the
f98dd1a3
ILT
675 // argument so that the type assertion will
676 // succeed.
677 c.Args[0] = &ast.CallExpr{
678 Fun: param.Go,
679 Args: []ast.Expr{
680 c.Args[0],
681 },
682 }
683
684 arg = &ast.TypeAssertExpr{
685 X: c,
686 Type: param.Go,
687 }
688 }
689
22b955cc
ILT
690 call.Call.Args[i] = arg
691 }
692
693 if call.Deferred {
694 params := make([]*ast.Field, len(name.FuncType.Params))
695 for i, param := range name.FuncType.Params {
696 ptype := param.Go
697 if p.hasUnsafePointer(ptype) {
698 // Avoid generating unsafe.Pointer by using
699 // interface{}. This works because we are
700 // going to call a _cgoCheckPointer function
701 // anyhow.
702 ptype = &ast.InterfaceType{
703 Methods: &ast.FieldList{},
704 }
705 }
706 params[i] = &ast.Field{
707 Names: []*ast.Ident{
708 ast.NewIdent(fmt.Sprintf("_cgo%d", i)),
709 },
710 Type: ptype,
711 }
712 }
713
714 dbody := &ast.CallExpr{
715 Fun: call.Call.Fun,
716 Args: call.Call.Args,
717 }
718 call.Call.Fun = &ast.FuncLit{
719 Type: &ast.FuncType{
720 Params: &ast.FieldList{
721 List: params,
722 },
723 },
724 Body: &ast.BlockStmt{
725 List: []ast.Stmt{
726 &ast.ExprStmt{
727 X: dbody,
728 },
729 },
730 },
731 }
732 call.Call.Args = dargs
733 call.Call.Lparen = token.NoPos
734 call.Call.Rparen = token.NoPos
735
736 // There is a Ref pointing to the old call.Call.Fun.
737 for _, ref := range f.Ref {
738 if ref.Expr == &call.Call.Fun {
739 ref.Expr = &dbody.Fun
740 }
741 }
f98dd1a3
ILT
742 }
743}
744
745// needsPointerCheck returns whether the type t needs a pointer check.
746// This is true if t is a pointer and if the value to which it points
747// might contain a pointer.
22b955cc
ILT
748func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
749 // An untyped nil does not need a pointer check, and when
750 // _cgoCheckPointer returns the untyped nil the type assertion we
751 // are going to insert will fail. Easier to just skip nil arguments.
752 // TODO: Note that this fails if nil is shadowed.
753 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
754 return false
755 }
756
f98dd1a3
ILT
757 return p.hasPointer(f, t, true)
758}
759
22b955cc 760// hasPointer is used by needsPointerCheck. If top is true it returns
f98dd1a3
ILT
761// whether t is or contains a pointer that might point to a pointer.
762// If top is false it returns whether t is or contains a pointer.
763// f may be nil.
764func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
765 switch t := t.(type) {
766 case *ast.ArrayType:
767 if t.Len == nil {
768 if !top {
769 return true
770 }
771 return p.hasPointer(f, t.Elt, false)
772 }
773 return p.hasPointer(f, t.Elt, top)
774 case *ast.StructType:
775 for _, field := range t.Fields.List {
776 if p.hasPointer(f, field.Type, top) {
777 return true
778 }
779 }
780 return false
781 case *ast.StarExpr: // Pointer type.
782 if !top {
783 return true
784 }
785 return p.hasPointer(f, t.X, false)
786 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
787 return true
788 case *ast.Ident:
789 // TODO: Handle types defined within function.
790 for _, d := range p.Decl {
791 gd, ok := d.(*ast.GenDecl)
792 if !ok || gd.Tok != token.TYPE {
793 continue
794 }
795 for _, spec := range gd.Specs {
796 ts, ok := spec.(*ast.TypeSpec)
797 if !ok {
798 continue
799 }
800 if ts.Name.Name == t.Name {
801 return p.hasPointer(f, ts.Type, top)
802 }
803 }
804 }
805 if def := typedef[t.Name]; def != nil {
806 return p.hasPointer(f, def.Go, top)
807 }
808 if t.Name == "string" {
809 return !top
810 }
811 if t.Name == "error" {
812 return true
813 }
814 if goTypes[t.Name] != nil {
815 return false
816 }
22b955cc 817 // We can't figure out the type. Conservative
f98dd1a3
ILT
818 // approach is to assume it has a pointer.
819 return true
820 case *ast.SelectorExpr:
821 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
822 // Type defined in a different package.
823 // Conservative approach is to assume it has a
824 // pointer.
825 return true
826 }
827 if f == nil {
828 // Conservative approach: assume pointer.
829 return true
830 }
831 name := f.Name[t.Sel.Name]
832 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
833 return p.hasPointer(f, name.Type.Go, top)
834 }
22b955cc 835 // We can't figure out the type. Conservative
f98dd1a3
ILT
836 // approach is to assume it has a pointer.
837 return true
838 default:
839 error_(t.Pos(), "could not understand type %s", gofmt(t))
840 return true
841 }
842}
843
844// checkAddrArgs tries to add arguments to the call of
22b955cc 845// _cgoCheckPointer when the argument is an address expression. We
f98dd1a3
ILT
846// pass true to mean that the argument is an address operation of
847// something other than a slice index, which means that it's only
848// necessary to check the specific element pointed to, not the entire
22b955cc 849// object. This is for &s.f, where f is a field in a struct. We can
f98dd1a3
ILT
850// pass a slice or array, meaning that we should check the entire
851// slice or array but need not check any other part of the object.
22b955cc 852// This is for &s.a[i], where we need to check all of a. However, we
f98dd1a3
ILT
853// only pass the slice or array if we can refer to it without side
854// effects.
855func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr {
856 // Strip type conversions.
857 for {
858 c, ok := x.(*ast.CallExpr)
859 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
860 break
861 }
862 x = c.Args[0]
863 }
864 u, ok := x.(*ast.UnaryExpr)
865 if !ok || u.Op != token.AND {
866 return args
867 }
868 index, ok := u.X.(*ast.IndexExpr)
869 if !ok {
870 // This is the address of something that is not an
22b955cc 871 // index expression. We only need to examine the
f98dd1a3
ILT
872 // single value to which it points.
873 // TODO: what if true is shadowed?
874 return append(args, ast.NewIdent("true"))
875 }
876 if !p.hasSideEffects(f, index.X) {
877 // Examine the entire slice.
878 return append(args, index.X)
879 }
880 // Treat the pointer as unknown.
881 return args
882}
883
884// hasSideEffects returns whether the expression x has any side
885// effects. x is an expression, not a statement, so the only side
886// effect is a function call.
887func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
888 found := false
889 f.walk(x, "expr",
890 func(f *File, x interface{}, context string) {
891 switch x.(type) {
892 case *ast.CallExpr:
893 found = true
894 }
895 })
896 return found
897}
898
899// isType returns whether the expression is definitely a type.
900// This is conservative--it returns false for an unknown identifier.
901func (p *Package) isType(t ast.Expr) bool {
902 switch t := t.(type) {
903 case *ast.SelectorExpr:
f98dd1a3
ILT
904 id, ok := t.X.(*ast.Ident)
905 if !ok {
906 return false
907 }
22b955cc
ILT
908 if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
909 return true
910 }
911 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
912 return true
913 }
914 return false
f98dd1a3
ILT
915 case *ast.Ident:
916 // TODO: This ignores shadowing.
917 switch t.Name {
918 case "unsafe.Pointer", "bool", "byte",
919 "complex64", "complex128",
920 "error",
921 "float32", "float64",
922 "int", "int8", "int16", "int32", "int64",
923 "rune", "string",
924 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
925
926 return true
927 }
928 case *ast.StarExpr:
929 return p.isType(t.X)
930 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
931 *ast.MapType, *ast.ChanType:
932
933 return true
934 }
935 return false
936}
937
22b955cc 938// unsafeCheckPointerName is given the Go version of a C type. If the
f98dd1a3 939// type uses unsafe.Pointer, we arrange to build a version of
22b955cc
ILT
940// _cgoCheckPointer that returns that type. This avoids using a type
941// assertion to unsafe.Pointer in our copy of user code. We return
f98dd1a3
ILT
942// the name of the _cgoCheckPointer function we are going to build, or
943// the empty string if the type does not use unsafe.Pointer.
22b955cc
ILT
944//
945// The deferred parameter is true if this check is for the argument of
946// a deferred function. In that case we need to use an empty interface
947// as the argument type, because the deferred function we introduce in
948// rewriteCall will use an empty interface type, and we can't add a
949// type assertion. This is handled by keeping a separate list, and
950// writing out the lists separately in writeDefs.
951func (p *Package) unsafeCheckPointerName(t ast.Expr, deferred bool) string {
f98dd1a3
ILT
952 if !p.hasUnsafePointer(t) {
953 return ""
954 }
955 var buf bytes.Buffer
956 conf.Fprint(&buf, fset, t)
957 s := buf.String()
22b955cc
ILT
958 checks := &p.CgoChecks
959 if deferred {
960 checks = &p.DeferredCgoChecks
961 }
962 for i, t := range *checks {
f98dd1a3 963 if s == t {
22b955cc 964 return p.unsafeCheckPointerNameIndex(i, deferred)
f98dd1a3
ILT
965 }
966 }
22b955cc
ILT
967 *checks = append(*checks, s)
968 return p.unsafeCheckPointerNameIndex(len(*checks)-1, deferred)
f98dd1a3
ILT
969}
970
971// hasUnsafePointer returns whether the Go type t uses unsafe.Pointer.
972// t is the Go version of a C type, so we don't need to handle every case.
973// We only care about direct references, not references via typedefs.
974func (p *Package) hasUnsafePointer(t ast.Expr) bool {
975 switch t := t.(type) {
976 case *ast.Ident:
977 // We don't see a SelectorExpr for unsafe.Pointer;
978 // this is created by code in this file.
979 return t.Name == "unsafe.Pointer"
980 case *ast.ArrayType:
981 return p.hasUnsafePointer(t.Elt)
982 case *ast.StructType:
983 for _, f := range t.Fields.List {
984 if p.hasUnsafePointer(f.Type) {
985 return true
986 }
987 }
988 case *ast.StarExpr: // Pointer type.
989 return p.hasUnsafePointer(t.X)
990 }
991 return false
992}
993
994// unsafeCheckPointerNameIndex returns the name to use for a
995// _cgoCheckPointer variant based on the index in the CgoChecks slice.
22b955cc
ILT
996func (p *Package) unsafeCheckPointerNameIndex(i int, deferred bool) string {
997 if deferred {
998 return fmt.Sprintf("_cgoCheckPointerInDefer%d", i)
999 }
f98dd1a3
ILT
1000 return fmt.Sprintf("_cgoCheckPointer%d", i)
1001}
1002
7d7d64c1
ILT
1003// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1004// Go equivalents, now that we have figured out the meaning of all
22b955cc 1005// the xxx. In *godefs mode, rewriteRef replaces the names
7d7d64c1
ILT
1006// with full definitions instead of mangled names.
1007func (p *Package) rewriteRef(f *File) {
1008 // Keep a list of all the functions, to remove the ones
1009 // only used as expressions and avoid generating bridge
1010 // code for them.
1011 functions := make(map[string]bool)
1012
1013 // Assign mangled names.
1014 for _, n := range f.Name {
1015 if n.Kind == "not-type" {
1016 n.Kind = "var"
1017 }
1018 if n.Mangle == "" {
1019 p.mangleName(n)
1020 }
1021 if n.Kind == "func" {
1022 functions[n.Go] = false
1023 }
1024 }
1025
1026 // Now that we have all the name types filled in,
1027 // scan through the Refs to identify the ones that
22b955cc 1028 // are trying to do a ,err call. Also check that
7d7d64c1
ILT
1029 // functions are only used in calls.
1030 for _, r := range f.Ref {
1031 if r.Name.Kind == "const" && r.Name.Const == "" {
1032 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1033 }
1034 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
1035 switch r.Context {
1036 case "call", "call2":
1037 if r.Name.Kind != "func" {
1038 if r.Name.Kind == "type" {
1039 r.Context = "type"
f98dd1a3
ILT
1040 if r.Name.Type == nil {
1041 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1042 break
1043 }
7d7d64c1
ILT
1044 expr = r.Name.Type.Go
1045 break
1046 }
1047 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1048 break
1049 }
1050 functions[r.Name.Go] = true
1051 if r.Context == "call2" {
1052 if r.Name.Go == "_CMalloc" {
1053 error_(r.Pos(), "no two-result form for C.malloc")
1054 break
1055 }
1056 // Invent new Name for the two-result function.
1057 n := f.Name["2"+r.Name.Go]
1058 if n == nil {
1059 n = new(Name)
1060 *n = *r.Name
1061 n.AddError = true
1062 n.Mangle = "_C2func_" + n.Go
1063 f.Name["2"+r.Name.Go] = n
1064 }
1065 expr = ast.NewIdent(n.Mangle)
1066 r.Name = n
1067 break
1068 }
1069 case "expr":
1070 if r.Name.Kind == "func" {
1071 // Function is being used in an expression, to e.g. pass around a C function pointer.
1072 // Create a new Name for this Ref which causes the variable to be declared in Go land.
1073 fpName := "fp_" + r.Name.Go
1074 name := f.Name[fpName]
1075 if name == nil {
1076 name = &Name{
1077 Go: fpName,
1078 C: r.Name.C,
1079 Kind: "fpvar",
1080 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1081 }
1082 p.mangleName(name)
1083 f.Name[fpName] = name
1084 }
1085 r.Name = name
22b955cc 1086 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
f8d9fa9e
ILT
1087 // function is defined in out.go and simply returns its argument. See
1088 // issue 7757.
1089 expr = &ast.CallExpr{
1090 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1091 Args: []ast.Expr{ast.NewIdent(name.Mangle)},
1092 }
7d7d64c1
ILT
1093 } else if r.Name.Kind == "type" {
1094 // Okay - might be new(T)
f98dd1a3
ILT
1095 if r.Name.Type == nil {
1096 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1097 break
1098 }
7d7d64c1
ILT
1099 expr = r.Name.Type.Go
1100 } else if r.Name.Kind == "var" {
1101 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1102 }
1103
af146490
ILT
1104 case "selector":
1105 if r.Name.Kind == "var" {
1106 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1107 } else {
22b955cc 1108 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
af146490
ILT
1109 }
1110
7d7d64c1
ILT
1111 case "type":
1112 if r.Name.Kind != "type" {
1113 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1114 } else if r.Name.Type == nil {
1115 // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1116 // GCC won't raise an error when using pointers to such unknown types.
1117 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1118 } else {
1119 expr = r.Name.Type.Go
1120 }
1121 default:
1122 if r.Name.Kind == "func" {
1123 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1124 }
1125 }
af146490 1126 if *godefs {
7d7d64c1
ILT
1127 // Substitute definition for mangled type name.
1128 if id, ok := expr.(*ast.Ident); ok {
1129 if t := typedef[id.Name]; t != nil {
1130 expr = t.Go
1131 }
1132 if id.Name == r.Name.Mangle && r.Name.Const != "" {
1133 expr = ast.NewIdent(r.Name.Const)
1134 }
1135 }
1136 }
1137
1138 // Copy position information from old expr into new expr,
1139 // in case expression being replaced is first on line.
1140 // See golang.org/issue/6563.
1141 pos := (*r.Expr).Pos()
1142 switch x := expr.(type) {
1143 case *ast.Ident:
1144 expr = &ast.Ident{NamePos: pos, Name: x.Name}
1145 }
1146
1147 *r.Expr = expr
1148 }
1149
1150 // Remove functions only used as expressions, so their respective
1151 // bridge functions are not generated.
1152 for name, used := range functions {
1153 if !used {
1154 delete(f.Name, name)
1155 }
1156 }
1157}
1158
1159// gccBaseCmd returns the start of the compiler command line.
1160// It uses $CC if set, or else $GCC, or else the compiler recorded
1161// during the initial build as defaultCC.
1162// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1163func (p *Package) gccBaseCmd() []string {
1164 // Use $CC if set, since that's what the build uses.
1165 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
1166 return ret
1167 }
1168 // Try $GCC if set, since that's what we used to use.
1169 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
1170 return ret
1171 }
1172 return strings.Fields(defaultCC)
1173}
1174
1175// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1176func (p *Package) gccMachine() []string {
1177 switch goarch {
1178 case "amd64":
1179 return []string{"-m64"}
1180 case "386":
1181 return []string{"-m32"}
1182 case "arm":
1183 return []string{"-marm"} // not thumb
af146490
ILT
1184 case "s390":
1185 return []string{"-m31"}
1186 case "s390x":
1187 return []string{"-m64"}
22b955cc
ILT
1188 case "mips64", "mips64le":
1189 return []string{"-mabi=64"}
7d7d64c1
ILT
1190 }
1191 return nil
1192}
1193
1194func gccTmp() string {
1195 return *objDir + "_cgo_.o"
1196}
1197
1198// gccCmd returns the gcc command line to use for compiling
1199// the input.
1200func (p *Package) gccCmd() []string {
1201 c := append(p.gccBaseCmd(),
1202 "-w", // no warnings
1203 "-Wno-error", // warnings are not errors
1204 "-o"+gccTmp(), // write object to tmp
1205 "-gdwarf-2", // generate DWARF v2 debugging symbols
1206 "-c", // do not link
1207 "-xc", // input language is C
1208 )
af146490 1209 if p.GccIsClang {
7d7d64c1
ILT
1210 c = append(c,
1211 "-ferror-limit=0",
1212 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1213 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1214 // flag to disable the warning. Yes, really good diagnostics, clang.
1215 "-Wno-unknown-warning-option",
1216 "-Wno-unneeded-internal-declaration",
1217 "-Wno-unused-function",
1218 "-Qunused-arguments",
1219 // Clang embeds prototypes for some builtin functions,
1220 // like malloc and calloc, but all size_t parameters are
1221 // incorrectly typed unsigned long. We work around that
1222 // by disabling the builtin functions (this is safe as
1223 // it won't affect the actual compilation of the C code).
af146490 1224 // See: https://golang.org/issue/6506.
7d7d64c1
ILT
1225 "-fno-builtin",
1226 )
1227 }
1228
1229 c = append(c, p.GccOptions...)
1230 c = append(c, p.gccMachine()...)
1231 c = append(c, "-") //read input from standard input
1232 return c
1233}
1234
1235// gccDebug runs gcc -gdwarf-2 over the C program stdin and
1236// returns the corresponding DWARF data and, if present, debug data block.
1237func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) {
1238 runGcc(stdin, p.gccCmd())
1239
1240 isDebugData := func(s string) bool {
1241 // Some systems use leading _ to denote non-assembly symbols.
1242 return s == "__cgodebug_data" || s == "___cgodebug_data"
1243 }
1244
1245 if f, err := macho.Open(gccTmp()); err == nil {
1246 defer f.Close()
1247 d, err := f.DWARF()
1248 if err != nil {
1249 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1250 }
1251 var data []byte
1252 if f.Symtab != nil {
1253 for i := range f.Symtab.Syms {
1254 s := &f.Symtab.Syms[i]
1255 if isDebugData(s.Name) {
22b955cc 1256 // Found it. Now find data section.
7d7d64c1
ILT
1257 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1258 sect := f.Sections[i]
1259 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1260 if sdat, err := sect.Data(); err == nil {
1261 data = sdat[s.Value-sect.Addr:]
1262 }
1263 }
1264 }
1265 }
1266 }
1267 }
1268 return d, f.ByteOrder, data
1269 }
1270
1271 if f, err := elf.Open(gccTmp()); err == nil {
1272 defer f.Close()
1273 d, err := f.DWARF()
1274 if err != nil {
1275 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1276 }
1277 var data []byte
1278 symtab, err := f.Symbols()
1279 if err == nil {
1280 for i := range symtab {
1281 s := &symtab[i]
1282 if isDebugData(s.Name) {
22b955cc 1283 // Found it. Now find data section.
7d7d64c1
ILT
1284 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1285 sect := f.Sections[i]
1286 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1287 if sdat, err := sect.Data(); err == nil {
1288 data = sdat[s.Value-sect.Addr:]
1289 }
1290 }
1291 }
1292 }
1293 }
1294 }
1295 return d, f.ByteOrder, data
1296 }
1297
1298 if f, err := pe.Open(gccTmp()); err == nil {
1299 defer f.Close()
1300 d, err := f.DWARF()
1301 if err != nil {
1302 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1303 }
1304 var data []byte
1305 for _, s := range f.Symbols {
1306 if isDebugData(s.Name) {
1307 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1308 sect := f.Sections[i]
1309 if s.Value < sect.Size {
1310 if sdat, err := sect.Data(); err == nil {
1311 data = sdat[s.Value:]
1312 }
1313 }
1314 }
1315 }
1316 }
1317 return d, binary.LittleEndian, data
1318 }
1319
1320 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
1321 panic("not reached")
1322}
1323
1324// gccDefines runs gcc -E -dM -xc - over the C program stdin
1325// and returns the corresponding standard output, which is the
1326// #defines that gcc encountered while processing the input
1327// and its included files.
1328func (p *Package) gccDefines(stdin []byte) string {
1329 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
1330 base = append(base, p.gccMachine()...)
1331 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
1332 return stdout
1333}
1334
1335// gccErrors runs gcc over the C program stdin and returns
22b955cc 1336// the errors that gcc prints. That is, this function expects
7d7d64c1
ILT
1337// gcc to fail.
1338func (p *Package) gccErrors(stdin []byte) string {
1339 // TODO(rsc): require failure
1340 args := p.gccCmd()
1341
22b955cc
ILT
1342 // Optimization options can confuse the error messages; remove them.
1343 nargs := make([]string, 0, len(args))
1344 for _, arg := range args {
1345 if !strings.HasPrefix(arg, "-O") {
1346 nargs = append(nargs, arg)
1347 }
1348 }
1349
7d7d64c1 1350 if *debugGcc {
22b955cc 1351 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
7d7d64c1
ILT
1352 os.Stderr.Write(stdin)
1353 fmt.Fprint(os.Stderr, "EOF\n")
1354 }
22b955cc 1355 stdout, stderr, _ := run(stdin, nargs)
7d7d64c1
ILT
1356 if *debugGcc {
1357 os.Stderr.Write(stdout)
1358 os.Stderr.Write(stderr)
1359 }
1360 return string(stderr)
1361}
1362
1363// runGcc runs the gcc command line args with stdin on standard input.
1364// If the command exits with a non-zero exit status, runGcc prints
1365// details about what was run and exits.
1366// Otherwise runGcc returns the data written to standard output and standard error.
1367// Note that for some of the uses we expect useful data back
1368// on standard error, but for those uses gcc must still exit 0.
1369func runGcc(stdin []byte, args []string) (string, string) {
1370 if *debugGcc {
1371 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
1372 os.Stderr.Write(stdin)
1373 fmt.Fprint(os.Stderr, "EOF\n")
1374 }
1375 stdout, stderr, ok := run(stdin, args)
1376 if *debugGcc {
1377 os.Stderr.Write(stdout)
1378 os.Stderr.Write(stderr)
1379 }
1380 if !ok {
1381 os.Stderr.Write(stderr)
1382 os.Exit(2)
1383 }
1384 return string(stdout), string(stderr)
1385}
1386
1387// A typeConv is a translator from dwarf types to Go types
1388// with equivalent memory layout.
1389type typeConv struct {
1390 // Cache of already-translated or in-progress types.
22b955cc 1391 m map[dwarf.Type]*Type
7d7d64c1
ILT
1392
1393 // Map from types to incomplete pointers to those types.
1394 ptrs map[dwarf.Type][]*Type
f8d9fa9e
ILT
1395 // Keys of ptrs in insertion order (deterministic worklist)
1396 ptrKeys []dwarf.Type
7d7d64c1
ILT
1397
1398 // Predeclared types.
1399 bool ast.Expr
1400 byte ast.Expr // denotes padding
1401 int8, int16, int32, int64 ast.Expr
1402 uint8, uint16, uint32, uint64, uintptr ast.Expr
1403 float32, float64 ast.Expr
1404 complex64, complex128 ast.Expr
1405 void ast.Expr
7d7d64c1
ILT
1406 string ast.Expr
1407 goVoid ast.Expr // _Ctype_void, denotes C's void
f8d9fa9e 1408 goVoidPtr ast.Expr // unsafe.Pointer or *byte
7d7d64c1
ILT
1409
1410 ptrSize int64
1411 intSize int64
1412}
1413
1414var tagGen int
1415var typedef = make(map[string]*Type)
1416var goIdent = make(map[string]*ast.Ident)
1417
1418func (c *typeConv) Init(ptrSize, intSize int64) {
1419 c.ptrSize = ptrSize
1420 c.intSize = intSize
1421 c.m = make(map[dwarf.Type]*Type)
1422 c.ptrs = make(map[dwarf.Type][]*Type)
1423 c.bool = c.Ident("bool")
1424 c.byte = c.Ident("byte")
1425 c.int8 = c.Ident("int8")
1426 c.int16 = c.Ident("int16")
1427 c.int32 = c.Ident("int32")
1428 c.int64 = c.Ident("int64")
1429 c.uint8 = c.Ident("uint8")
1430 c.uint16 = c.Ident("uint16")
1431 c.uint32 = c.Ident("uint32")
1432 c.uint64 = c.Ident("uint64")
1433 c.uintptr = c.Ident("uintptr")
1434 c.float32 = c.Ident("float32")
1435 c.float64 = c.Ident("float64")
1436 c.complex64 = c.Ident("complex64")
1437 c.complex128 = c.Ident("complex128")
7d7d64c1
ILT
1438 c.void = c.Ident("void")
1439 c.string = c.Ident("string")
1440 c.goVoid = c.Ident("_Ctype_void")
f8d9fa9e
ILT
1441
1442 // Normally cgo translates void* to unsafe.Pointer,
af146490
ILT
1443 // but for historical reasons -godefs uses *byte instead.
1444 if *godefs {
f8d9fa9e
ILT
1445 c.goVoidPtr = &ast.StarExpr{X: c.byte}
1446 } else {
1447 c.goVoidPtr = c.Ident("unsafe.Pointer")
1448 }
7d7d64c1
ILT
1449}
1450
1451// base strips away qualifiers and typedefs to get the underlying type
1452func base(dt dwarf.Type) dwarf.Type {
1453 for {
1454 if d, ok := dt.(*dwarf.QualType); ok {
1455 dt = d.Type
1456 continue
1457 }
1458 if d, ok := dt.(*dwarf.TypedefType); ok {
1459 dt = d.Type
1460 continue
1461 }
1462 break
1463 }
1464 return dt
1465}
1466
1467// Map from dwarf text names to aliases we use in package "C".
1468var dwarfToName = map[string]string{
1469 "long int": "long",
1470 "long unsigned int": "ulong",
1471 "unsigned int": "uint",
1472 "short unsigned int": "ushort",
f98dd1a3 1473 "unsigned short": "ushort", // Used by Clang; issue 13129.
7d7d64c1
ILT
1474 "short int": "short",
1475 "long long int": "longlong",
1476 "long long unsigned int": "ulonglong",
1477 "signed char": "schar",
f98dd1a3 1478 "unsigned char": "uchar",
7d7d64c1
ILT
1479}
1480
1481const signedDelta = 64
1482
22b955cc 1483// String returns the current type representation. Format arguments
7d7d64c1
ILT
1484// are assembled within this method so that any changes in mutable
1485// values are taken into account.
1486func (tr *TypeRepr) String() string {
1487 if len(tr.Repr) == 0 {
1488 return ""
1489 }
1490 if len(tr.FormatArgs) == 0 {
1491 return tr.Repr
1492 }
1493 return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
1494}
1495
af146490 1496// Empty reports whether the result of String would be "".
7d7d64c1
ILT
1497func (tr *TypeRepr) Empty() bool {
1498 return len(tr.Repr) == 0
1499}
1500
1501// Set modifies the type representation.
1502// If fargs are provided, repr is used as a format for fmt.Sprintf.
1503// Otherwise, repr is used unprocessed as the type representation.
1504func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
1505 tr.Repr = repr
1506 tr.FormatArgs = fargs
1507}
1508
1509// FinishType completes any outstanding type mapping work.
f8d9fa9e 1510// In particular, it resolves incomplete pointer types.
7d7d64c1
ILT
1511func (c *typeConv) FinishType(pos token.Pos) {
1512 // Completing one pointer type might produce more to complete.
1513 // Keep looping until they're all done.
f8d9fa9e
ILT
1514 for len(c.ptrKeys) > 0 {
1515 dtype := c.ptrKeys[0]
1516 c.ptrKeys = c.ptrKeys[1:]
7d7d64c1 1517
f8d9fa9e
ILT
1518 // Note Type might invalidate c.ptrs[dtype].
1519 t := c.Type(dtype, pos)
1520 for _, ptr := range c.ptrs[dtype] {
1521 ptr.Go.(*ast.StarExpr).X = t.Go
1522 ptr.C.Set("%s*", t.C)
1523 }
1524 c.ptrs[dtype] = nil // retain the map key
7d7d64c1 1525 }
7d7d64c1
ILT
1526}
1527
1528// Type returns a *Type with the same memory layout as
1529// dtype when used as the type of a variable or a struct field.
1530func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1531 if t, ok := c.m[dtype]; ok {
1532 if t.Go == nil {
1533 fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
1534 }
1535 return t
1536 }
1537
7d7d64c1
ILT
1538 t := new(Type)
1539 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
1540 t.Align = -1
1541 t.C = &TypeRepr{Repr: dtype.Common().Name}
1542 c.m[dtype] = t
1543
1544 switch dt := dtype.(type) {
1545 default:
1546 fatalf("%s: unexpected type: %s", lineno(pos), dtype)
1547
1548 case *dwarf.AddrType:
1549 if t.Size != c.ptrSize {
1550 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
1551 }
1552 t.Go = c.uintptr
1553 t.Align = t.Size
1554
1555 case *dwarf.ArrayType:
1556 if dt.StrideBitSize > 0 {
1557 // Cannot represent bit-sized elements in Go.
1558 t.Go = c.Opaque(t.Size)
1559 break
1560 }
f8d9fa9e
ILT
1561 count := dt.Count
1562 if count == -1 {
1563 // Indicates flexible array member, which Go doesn't support.
1564 // Translate to zero-length array instead.
1565 count = 0
1566 }
7d7d64c1
ILT
1567 sub := c.Type(dt.Type, pos)
1568 t.Align = sub.Align
1569 t.Go = &ast.ArrayType{
f8d9fa9e 1570 Len: c.intExpr(count),
7d7d64c1
ILT
1571 Elt: sub.Go,
1572 }
f8d9fa9e
ILT
1573 // Recalculate t.Size now that we know sub.Size.
1574 t.Size = count * sub.Size
7d7d64c1
ILT
1575 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
1576
1577 case *dwarf.BoolType:
1578 t.Go = c.bool
1579 t.Align = 1
1580
1581 case *dwarf.CharType:
1582 if t.Size != 1 {
1583 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
1584 }
1585 t.Go = c.int8
1586 t.Align = 1
1587
1588 case *dwarf.EnumType:
1589 if t.Align = t.Size; t.Align >= c.ptrSize {
1590 t.Align = c.ptrSize
1591 }
1592 t.C.Set("enum " + dt.EnumName)
1593 signed := 0
1594 t.EnumValues = make(map[string]int64)
1595 for _, ev := range dt.Val {
1596 t.EnumValues[ev.Name] = ev.Val
1597 if ev.Val < 0 {
1598 signed = signedDelta
1599 }
1600 }
1601 switch t.Size + int64(signed) {
1602 default:
1603 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
1604 case 1:
1605 t.Go = c.uint8
1606 case 2:
1607 t.Go = c.uint16
1608 case 4:
1609 t.Go = c.uint32
1610 case 8:
1611 t.Go = c.uint64
1612 case 1 + signedDelta:
1613 t.Go = c.int8
1614 case 2 + signedDelta:
1615 t.Go = c.int16
1616 case 4 + signedDelta:
1617 t.Go = c.int32
1618 case 8 + signedDelta:
1619 t.Go = c.int64
1620 }
1621
1622 case *dwarf.FloatType:
1623 switch t.Size {
1624 default:
1625 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
1626 case 4:
1627 t.Go = c.float32
1628 case 8:
1629 t.Go = c.float64
1630 }
1631 if t.Align = t.Size; t.Align >= c.ptrSize {
1632 t.Align = c.ptrSize
1633 }
1634
1635 case *dwarf.ComplexType:
1636 switch t.Size {
1637 default:
1638 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
1639 case 8:
1640 t.Go = c.complex64
1641 case 16:
1642 t.Go = c.complex128
1643 }
1644 if t.Align = t.Size; t.Align >= c.ptrSize {
1645 t.Align = c.ptrSize
1646 }
1647
1648 case *dwarf.FuncType:
1649 // No attempt at translation: would enable calls
1650 // directly between worlds, but we need to moderate those.
1651 t.Go = c.uintptr
1652 t.Align = c.ptrSize
1653
1654 case *dwarf.IntType:
1655 if dt.BitSize > 0 {
1656 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
1657 }
1658 switch t.Size {
1659 default:
1660 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
1661 case 1:
1662 t.Go = c.int8
1663 case 2:
1664 t.Go = c.int16
1665 case 4:
1666 t.Go = c.int32
1667 case 8:
1668 t.Go = c.int64
f98dd1a3
ILT
1669 case 16:
1670 t.Go = &ast.ArrayType{
1671 Len: c.intExpr(t.Size),
1672 Elt: c.uint8,
1673 }
7d7d64c1
ILT
1674 }
1675 if t.Align = t.Size; t.Align >= c.ptrSize {
1676 t.Align = c.ptrSize
1677 }
1678
1679 case *dwarf.PtrType:
f8d9fa9e
ILT
1680 // Clang doesn't emit DW_AT_byte_size for pointer types.
1681 if t.Size != c.ptrSize && t.Size != -1 {
1682 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
1683 }
1684 t.Size = c.ptrSize
7d7d64c1
ILT
1685 t.Align = c.ptrSize
1686
7d7d64c1 1687 if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
f8d9fa9e 1688 t.Go = c.goVoidPtr
7d7d64c1
ILT
1689 t.C.Set("void*")
1690 break
1691 }
1692
1693 // Placeholder initialization; completed in FinishType.
1694 t.Go = &ast.StarExpr{}
1695 t.C.Set("<incomplete>*")
f8d9fa9e
ILT
1696 if _, ok := c.ptrs[dt.Type]; !ok {
1697 c.ptrKeys = append(c.ptrKeys, dt.Type)
1698 }
7d7d64c1
ILT
1699 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
1700
1701 case *dwarf.QualType:
1702 // Ignore qualifier.
1703 t = c.Type(dt.Type, pos)
1704 c.m[dtype] = t
1705 return t
1706
1707 case *dwarf.StructType:
1708 // Convert to Go struct, being careful about alignment.
1709 // Have to give it a name to simulate C "struct foo" references.
1710 tag := dt.StructName
1711 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
1712 break
1713 }
1714 if tag == "" {
1715 tag = "__" + strconv.Itoa(tagGen)
1716 tagGen++
1717 } else if t.C.Empty() {
1718 t.C.Set(dt.Kind + " " + tag)
1719 }
1720 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
1721 t.Go = name // publish before recursive calls
1722 goIdent[name.Name] = name
1723 if dt.ByteSize < 0 {
1724 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
1725 // so execute the basic things that the struct case would do
1726 // other than try to determine a Go representation.
1727 tt := *t
1728 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
1729 tt.Go = c.Ident("struct{}")
1730 typedef[name.Name] = &tt
1731 break
1732 }
1733 switch dt.Kind {
1734 case "class", "union":
1735 t.Go = c.Opaque(t.Size)
1736 if t.C.Empty() {
1737 t.C.Set("__typeof__(unsigned char[%d])", t.Size)
1738 }
1739 t.Align = 1 // TODO: should probably base this on field alignment.
1740 typedef[name.Name] = t
1741 case "struct":
1742 g, csyntax, align := c.Struct(dt, pos)
1743 if t.C.Empty() {
1744 t.C.Set(csyntax)
1745 }
1746 t.Align = align
1747 tt := *t
1748 if tag != "" {
1749 tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
1750 }
1751 tt.Go = g
1752 typedef[name.Name] = &tt
1753 }
1754
1755 case *dwarf.TypedefType:
1756 // Record typedef for printing.
1757 if dt.Name == "_GoString_" {
1758 // Special C name for Go string type.
1759 // Knows string layout used by compilers: pointer plus length,
1760 // which rounds up to 2 pointers after alignment.
1761 t.Go = c.string
1762 t.Size = c.ptrSize * 2
1763 t.Align = c.ptrSize
1764 break
1765 }
1766 if dt.Name == "_GoBytes_" {
1767 // Special C name for Go []byte type.
1768 // Knows slice layout used by compilers: pointer, length, cap.
1769 t.Go = c.Ident("[]byte")
1770 t.Size = c.ptrSize + 4 + 4
1771 t.Align = c.ptrSize
1772 break
1773 }
1774 name := c.Ident("_Ctype_" + dt.Name)
1775 goIdent[name.Name] = name
1776 sub := c.Type(dt.Type, pos)
1777 t.Go = name
1778 t.Size = sub.Size
1779 t.Align = sub.Align
1780 oldType := typedef[name.Name]
1781 if oldType == nil {
1782 tt := *t
1783 tt.Go = sub.Go
1784 typedef[name.Name] = &tt
1785 }
1786
1787 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
1788 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
1789 // with the base type.
af146490
ILT
1790 // In -godefs mode, do this for all typedefs.
1791 if isStructUnionClass(sub.Go) || *godefs {
7d7d64c1
ILT
1792 t.Go = sub.Go
1793
1794 if isStructUnionClass(sub.Go) {
1795 // Use the typedef name for C code.
1796 typedef[sub.Go.(*ast.Ident).Name].C = t.C
1797 }
1798
1799 // If we've seen this typedef before, and it
1800 // was an anonymous struct/union/class before
1801 // too, use the old definition.
1802 // TODO: it would be safer to only do this if
1803 // we verify that the types are the same.
1804 if oldType != nil && isStructUnionClass(oldType.Go) {
1805 t.Go = oldType.Go
1806 }
1807 }
1808
1809 case *dwarf.UcharType:
1810 if t.Size != 1 {
1811 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
1812 }
1813 t.Go = c.uint8
1814 t.Align = 1
1815
1816 case *dwarf.UintType:
1817 if dt.BitSize > 0 {
1818 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
1819 }
1820 switch t.Size {
1821 default:
1822 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
1823 case 1:
1824 t.Go = c.uint8
1825 case 2:
1826 t.Go = c.uint16
1827 case 4:
1828 t.Go = c.uint32
1829 case 8:
1830 t.Go = c.uint64
f98dd1a3
ILT
1831 case 16:
1832 t.Go = &ast.ArrayType{
1833 Len: c.intExpr(t.Size),
1834 Elt: c.uint8,
1835 }
7d7d64c1
ILT
1836 }
1837 if t.Align = t.Size; t.Align >= c.ptrSize {
1838 t.Align = c.ptrSize
1839 }
1840
1841 case *dwarf.VoidType:
1842 t.Go = c.goVoid
1843 t.C.Set("void")
1844 t.Align = 1
1845 }
1846
1847 switch dtype.(type) {
f98dd1a3 1848 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
7d7d64c1
ILT
1849 s := dtype.Common().Name
1850 if s != "" {
1851 if ss, ok := dwarfToName[s]; ok {
1852 s = ss
1853 }
1854 s = strings.Join(strings.Split(s, " "), "") // strip spaces
1855 name := c.Ident("_Ctype_" + s)
1856 tt := *t
1857 typedef[name.Name] = &tt
af146490 1858 if !*godefs {
7d7d64c1
ILT
1859 t.Go = name
1860 }
1861 }
1862 }
1863
f8d9fa9e
ILT
1864 if t.Size < 0 {
1865 // Unsized types are [0]byte, unless they're typedefs of other types
1866 // or structs with tags.
1867 // if so, use the name we've already defined.
1868 t.Size = 0
1869 switch dt := dtype.(type) {
1870 case *dwarf.TypedefType:
1871 // ok
1872 case *dwarf.StructType:
1873 if dt.StructName != "" {
1874 break
7d7d64c1 1875 }
f8d9fa9e
ILT
1876 t.Go = c.Opaque(0)
1877 default:
1878 t.Go = c.Opaque(0)
1879 }
1880 if t.C.Empty() {
1881 t.C.Set("void")
7d7d64c1
ILT
1882 }
1883 }
1884
1885 if t.C.Empty() {
1886 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
1887 }
1888
1889 return t
1890}
1891
1892// isStructUnionClass reports whether the type described by the Go syntax x
1893// is a struct, union, or class with a tag.
1894func isStructUnionClass(x ast.Expr) bool {
1895 id, ok := x.(*ast.Ident)
1896 if !ok {
1897 return false
1898 }
1899 name := id.Name
1900 return strings.HasPrefix(name, "_Ctype_struct_") ||
1901 strings.HasPrefix(name, "_Ctype_union_") ||
1902 strings.HasPrefix(name, "_Ctype_class_")
1903}
1904
1905// FuncArg returns a Go type with the same memory layout as
1906// dtype when used as the type of a C function argument.
1907func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
1908 t := c.Type(dtype, pos)
1909 switch dt := dtype.(type) {
1910 case *dwarf.ArrayType:
1911 // Arrays are passed implicitly as pointers in C.
1912 // In Go, we must be explicit.
1913 tr := &TypeRepr{}
1914 tr.Set("%s*", t.C)
1915 return &Type{
1916 Size: c.ptrSize,
1917 Align: c.ptrSize,
1918 Go: &ast.StarExpr{X: t.Go},
1919 C: tr,
1920 }
1921 case *dwarf.TypedefType:
1922 // C has much more relaxed rules than Go for
22b955cc 1923 // implicit type conversions. When the parameter
7d7d64c1
ILT
1924 // is type T defined as *X, simulate a little of the
1925 // laxness of C by making the argument *X instead of T.
1926 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
1927 // Unless the typedef happens to point to void* since
1928 // Go has special rules around using unsafe.Pointer.
1929 if _, void := base(ptr.Type).(*dwarf.VoidType); void {
1930 break
1931 }
1932
1933 t = c.Type(ptr, pos)
1934 if t == nil {
1935 return nil
1936 }
1937
1938 // Remember the C spelling, in case the struct
22b955cc 1939 // has __attribute__((unavailable)) on it. See issue 2888.
7d7d64c1
ILT
1940 t.Typedef = dt.Name
1941 }
1942 }
1943 return t
1944}
1945
1946// FuncType returns the Go type analogous to dtype.
1947// There is no guarantee about matching memory layout.
1948func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
1949 p := make([]*Type, len(dtype.ParamType))
1950 gp := make([]*ast.Field, len(dtype.ParamType))
1951 for i, f := range dtype.ParamType {
1952 // gcc's DWARF generator outputs a single DotDotDotType parameter for
1953 // function pointers that specify no parameters (e.g. void
22b955cc 1954 // (*__cgo_0)()). Treat this special case as void. This case is
7d7d64c1
ILT
1955 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
1956 // legal).
1957 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
1958 p, gp = nil, nil
1959 break
1960 }
1961 p[i] = c.FuncArg(f, pos)
1962 gp[i] = &ast.Field{Type: p[i].Go}
1963 }
1964 var r *Type
1965 var gr []*ast.Field
1966 if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok {
1967 gr = []*ast.Field{{Type: c.goVoid}}
1968 } else if dtype.ReturnType != nil {
1969 r = c.Type(dtype.ReturnType, pos)
1970 gr = []*ast.Field{{Type: r.Go}}
1971 }
1972 return &FuncType{
1973 Params: p,
1974 Result: r,
1975 Go: &ast.FuncType{
1976 Params: &ast.FieldList{List: gp},
1977 Results: &ast.FieldList{List: gr},
1978 },
1979 }
1980}
1981
1982// Identifier
1983func (c *typeConv) Ident(s string) *ast.Ident {
1984 return ast.NewIdent(s)
1985}
1986
1987// Opaque type of n bytes.
1988func (c *typeConv) Opaque(n int64) ast.Expr {
1989 return &ast.ArrayType{
1990 Len: c.intExpr(n),
1991 Elt: c.byte,
1992 }
1993}
1994
1995// Expr for integer n.
1996func (c *typeConv) intExpr(n int64) ast.Expr {
1997 return &ast.BasicLit{
1998 Kind: token.INT,
1999 Value: strconv.FormatInt(n, 10),
2000 }
2001}
2002
2003// Add padding of given size to fld.
af146490 2004func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
7d7d64c1
ILT
2005 n := len(fld)
2006 fld = fld[0 : n+1]
2007 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
af146490
ILT
2008 sizes = sizes[0 : n+1]
2009 sizes[n] = size
2010 return fld, sizes
7d7d64c1
ILT
2011}
2012
af146490 2013// Struct conversion: return Go and (gc) C syntax for type.
7d7d64c1 2014func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
f8d9fa9e
ILT
2015 // Minimum alignment for a struct is 1 byte.
2016 align = 1
2017
7d7d64c1
ILT
2018 var buf bytes.Buffer
2019 buf.WriteString("struct {")
2020 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
af146490 2021 sizes := make([]int64, 0, 2*len(dt.Field)+1)
7d7d64c1
ILT
2022 off := int64(0)
2023
2024 // Rename struct fields that happen to be named Go keywords into
22b955cc
ILT
2025 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will
2026 // be mangled. Any existing identifier that already has the same name on
7d7d64c1
ILT
2027 // the C-side will cause the Go-mangled version to be prefixed with _.
2028 // (e.g. in a struct with fields '_type' and 'type', the latter would be
2029 // rendered as '__type' in Go).
2030 ident := make(map[string]string)
2031 used := make(map[string]bool)
2032 for _, f := range dt.Field {
2033 ident[f.Name] = f.Name
2034 used[f.Name] = true
2035 }
2036
af146490 2037 if !*godefs {
7d7d64c1
ILT
2038 for cid, goid := range ident {
2039 if token.Lookup(goid).IsKeyword() {
2040 // Avoid keyword
2041 goid = "_" + goid
2042
2043 // Also avoid existing fields
2044 for _, exist := used[goid]; exist; _, exist = used[goid] {
2045 goid = "_" + goid
2046 }
2047
2048 used[goid] = true
2049 ident[cid] = goid
2050 }
2051 }
2052 }
2053
2054 anon := 0
2055 for _, f := range dt.Field {
2056 if f.ByteOffset > off {
af146490 2057 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
7d7d64c1
ILT
2058 off = f.ByteOffset
2059 }
f8d9fa9e
ILT
2060
2061 name := f.Name
2062 ft := f.Type
2063
af146490 2064 // In godefs mode, if this field is a C11
f8d9fa9e 2065 // anonymous union then treat the first field in the
22b955cc 2066 // union as the field in the struct. This handles
f8d9fa9e
ILT
2067 // cases like the glibc <sys/resource.h> file; see
2068 // issue 6677.
af146490 2069 if *godefs {
f8d9fa9e
ILT
2070 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
2071 name = st.Field[0].Name
2072 ident[name] = name
2073 ft = st.Field[0].Type
2074 }
2075 }
2076
2077 // TODO: Handle fields that are anonymous structs by
2078 // promoting the fields of the inner struct.
2079
2080 t := c.Type(ft, pos)
7d7d64c1
ILT
2081 tgo := t.Go
2082 size := t.Size
2083 talign := t.Align
2084 if f.BitSize > 0 {
2085 if f.BitSize%8 != 0 {
2086 continue
2087 }
2088 size = f.BitSize / 8
2089 name := tgo.(*ast.Ident).String()
2090 if strings.HasPrefix(name, "int") {
2091 name = "int"
2092 } else {
2093 name = "uint"
2094 }
2095 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
2096 talign = size
2097 }
2098
af146490 2099 if talign > 0 && f.ByteOffset%talign != 0 {
7d7d64c1
ILT
2100 // Drop misaligned fields, the same way we drop integer bit fields.
2101 // The goal is to make available what can be made available.
2102 // Otherwise one bad and unneeded field in an otherwise okay struct
2103 // makes the whole program not compile. Much of the time these
2104 // structs are in system headers that cannot be corrected.
2105 continue
2106 }
2107 n := len(fld)
2108 fld = fld[0 : n+1]
7d7d64c1
ILT
2109 if name == "" {
2110 name = fmt.Sprintf("anon%d", anon)
2111 anon++
2112 ident[name] = name
2113 }
2114 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
af146490
ILT
2115 sizes = sizes[0 : n+1]
2116 sizes[n] = size
7d7d64c1
ILT
2117 off += size
2118 buf.WriteString(t.C.String())
2119 buf.WriteString(" ")
2120 buf.WriteString(name)
2121 buf.WriteString("; ")
2122 if talign > align {
2123 align = talign
2124 }
2125 }
2126 if off < dt.ByteSize {
af146490 2127 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
7d7d64c1
ILT
2128 off = dt.ByteSize
2129 }
af146490
ILT
2130
2131 // If the last field in a non-zero-sized struct is zero-sized
2132 // the compiler is going to pad it by one (see issue 9401).
2133 // We can't permit that, because then the size of the Go
2134 // struct will not be the same as the size of the C struct.
2135 // Our only option in such a case is to remove the field,
22b955cc 2136 // which means that it cannot be referenced from Go.
af146490
ILT
2137 for off > 0 && sizes[len(sizes)-1] == 0 {
2138 n := len(sizes)
2139 fld = fld[0 : n-1]
2140 sizes = sizes[0 : n-1]
2141 }
2142
7d7d64c1
ILT
2143 if off != dt.ByteSize {
2144 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
2145 }
2146 buf.WriteString("}")
2147 csyntax = buf.String()
2148
af146490 2149 if *godefs {
f8d9fa9e 2150 godefsFields(fld)
7d7d64c1
ILT
2151 }
2152 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
2153 return
2154}
2155
2156func upper(s string) string {
2157 if s == "" {
2158 return ""
2159 }
2160 r, size := utf8.DecodeRuneInString(s)
2161 if r == '_' {
2162 return "X" + s
2163 }
2164 return string(unicode.ToUpper(r)) + s[size:]
2165}
2166
2167// godefsFields rewrites field names for use in Go or C definitions.
2168// It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2169// converts names to upper case, and rewrites _ into Pad_godefs_n,
2170// so that all fields are exported.
2171func godefsFields(fld []*ast.Field) {
2172 prefix := fieldPrefix(fld)
2173 npad := 0
2174 for _, f := range fld {
2175 for _, n := range f.Names {
2176 if n.Name != prefix {
2177 n.Name = strings.TrimPrefix(n.Name, prefix)
2178 }
2179 if n.Name == "_" {
2180 // Use exported name instead.
2181 n.Name = "Pad_cgo_" + strconv.Itoa(npad)
2182 npad++
2183 }
af146490 2184 n.Name = upper(n.Name)
7d7d64c1 2185 }
7d7d64c1
ILT
2186 }
2187}
2188
2189// fieldPrefix returns the prefix that should be removed from all the
22b955cc 2190// field names when generating the C or Go code. For generated
7d7d64c1
ILT
2191// C, we leave the names as is (tv_sec, tv_usec), since that's what
2192// people are used to seeing in C. For generated Go code, such as
2193// package syscall's data structures, we drop a common prefix
2194// (so sec, usec, which will get turned into Sec, Usec for exporting).
2195func fieldPrefix(fld []*ast.Field) string {
7d7d64c1
ILT
2196 prefix := ""
2197 for _, f := range fld {
2198 for _, n := range f.Names {
2199 // Ignore field names that don't have the prefix we're
22b955cc 2200 // looking for. It is common in C headers to have fields
7d7d64c1
ILT
2201 // named, say, _pad in an otherwise prefixed header.
2202 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
2203 // still want to remove the tv_ prefix.
2204 // The check for "orig_" here handles orig_eax in the
2205 // x86 ptrace register sets, which otherwise have all fields
2206 // with reg_ prefixes.
2207 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
2208 continue
2209 }
2210 i := strings.Index(n.Name, "_")
2211 if i < 0 {
2212 continue
2213 }
2214 if prefix == "" {
2215 prefix = n.Name[:i+1]
2216 } else if prefix != n.Name[:i+1] {
2217 return ""
2218 }
2219 }
2220 }
2221 return prefix
2222}