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.
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	"debug/xcoff"
17	"encoding/binary"
18	"errors"
19	"flag"
20	"fmt"
21	"go/ast"
22	"go/parser"
23	"go/token"
24	"math"
25	"os"
26	"strconv"
27	"strings"
28	"unicode"
29	"unicode/utf8"
30)
31
32var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
33var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
34
35var nameToC = map[string]string{
36	"schar":         "signed char",
37	"uchar":         "unsigned char",
38	"ushort":        "unsigned short",
39	"uint":          "unsigned int",
40	"ulong":         "unsigned long",
41	"longlong":      "long long",
42	"ulonglong":     "unsigned long long",
43	"complexfloat":  "float _Complex",
44	"complexdouble": "double _Complex",
45}
46
47// cname returns the C name to use for C.s.
48// The expansions are listed in nameToC and also
49// struct_foo becomes "struct foo", and similarly for
50// union and enum.
51func cname(s string) string {
52	if t, ok := nameToC[s]; ok {
53		return t
54	}
55
56	if strings.HasPrefix(s, "struct_") {
57		return "struct " + s[len("struct_"):]
58	}
59	if strings.HasPrefix(s, "union_") {
60		return "union " + s[len("union_"):]
61	}
62	if strings.HasPrefix(s, "enum_") {
63		return "enum " + s[len("enum_"):]
64	}
65	if strings.HasPrefix(s, "sizeof_") {
66		return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
67	}
68	return s
69}
70
71// DiscardCgoDirectives processes the import C preamble, and discards
72// all #cgo CFLAGS and LDFLAGS directives, so they don't make their
73// way into _cgo_export.h.
74func (f *File) DiscardCgoDirectives() {
75	linesIn := strings.Split(f.Preamble, "\n")
76	linesOut := make([]string, 0, len(linesIn))
77	for _, line := range linesIn {
78		l := strings.TrimSpace(line)
79		if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
80			linesOut = append(linesOut, line)
81		} else {
82			linesOut = append(linesOut, "")
83		}
84	}
85	f.Preamble = strings.Join(linesOut, "\n")
86}
87
88// addToFlag appends args to flag. All flags are later written out onto the
89// _cgo_flags file for the build system to use.
90func (p *Package) addToFlag(flag string, args []string) {
91	if flag == "CFLAGS" {
92		// We'll need these when preprocessing for dwarf information.
93		p.GccOptions = append(p.GccOptions, args...)
94	}
95
96	skip := false
97	for i, arg := range args {
98		// The go tool will pass us a -I option pointing to objdir;
99		// we don't need to record that for later, as the objdir
100		// will disappear anyhow.
101		if skip {
102			// Discard argument in "-I objdir" case.
103			skip = false
104		} else if strings.HasPrefix(arg, "-I") && strings.HasPrefix(arg[2:], *objDir) {
105			// This is -Iobjdir. Don't save this argument.
106		} else if arg == "-I" && i+1 < len(args) && strings.HasPrefix(args[i+1], *objDir) {
107			// This is -I objdir. Don't save this argument
108			// or the next one.
109			skip = true
110		} else {
111			p.CgoFlags[flag] = append(p.CgoFlags[flag], arg)
112		}
113	}
114}
115
116// splitQuoted splits the string s around each instance of one or more consecutive
117// white space characters while taking into account quotes and escaping, and
118// returns an array of substrings of s or an empty list if s contains only white space.
119// Single quotes and double quotes are recognized to prevent splitting within the
120// quoted region, and are removed from the resulting substrings. If a quote in s
121// isn't closed err will be set and r will have the unclosed argument as the
122// last element. The backslash is used for escaping.
123//
124// For example, the following string:
125//
126//     `a b:"c d" 'e''f'  "g\""`
127//
128// Would be parsed as:
129//
130//     []string{"a", "b:c d", "ef", `g"`}
131//
132func splitQuoted(s string) (r []string, err error) {
133	var args []string
134	arg := make([]rune, len(s))
135	escaped := false
136	quoted := false
137	quote := '\x00'
138	i := 0
139	for _, r := range s {
140		switch {
141		case escaped:
142			escaped = false
143		case r == '\\':
144			escaped = true
145			continue
146		case quote != 0:
147			if r == quote {
148				quote = 0
149				continue
150			}
151		case r == '"' || r == '\'':
152			quoted = true
153			quote = r
154			continue
155		case unicode.IsSpace(r):
156			if quoted || i > 0 {
157				quoted = false
158				args = append(args, string(arg[:i]))
159				i = 0
160			}
161			continue
162		}
163		arg[i] = r
164		i++
165	}
166	if quoted || i > 0 {
167		args = append(args, string(arg[:i]))
168	}
169	if quote != 0 {
170		err = errors.New("unclosed quote")
171	} else if escaped {
172		err = errors.New("unfinished escaping")
173	}
174	return args, err
175}
176
177// Translate rewrites f.AST, the original Go input, to remove
178// references to the imported package C, replacing them with
179// references to the equivalent Go types, functions, and variables.
180func (p *Package) Translate(f *File) {
181	for _, cref := range f.Ref {
182		// Convert C.ulong to C.unsigned long, etc.
183		cref.Name.C = cname(cref.Name.Go)
184	}
185	p.loadDefines(f)
186	needType := p.guessKinds(f)
187	if len(needType) > 0 {
188		p.loadDWARF(f, needType)
189	}
190	if p.rewriteCalls(f) {
191		// Add `import _cgo_unsafe "unsafe"` after the package statement.
192		f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
193	}
194	p.rewriteRef(f)
195}
196
197// loadDefines coerces gcc into spitting out the #defines in use
198// in the file f and saves relevant renamings in f.Name[name].Define.
199func (p *Package) loadDefines(f *File) {
200	var b bytes.Buffer
201	b.WriteString(builtinProlog)
202	b.WriteString(f.Preamble)
203	stdout := p.gccDefines(b.Bytes())
204
205	for _, line := range strings.Split(stdout, "\n") {
206		if len(line) < 9 || line[0:7] != "#define" {
207			continue
208		}
209
210		line = strings.TrimSpace(line[8:])
211
212		var key, val string
213		spaceIndex := strings.Index(line, " ")
214		tabIndex := strings.Index(line, "\t")
215
216		if spaceIndex == -1 && tabIndex == -1 {
217			continue
218		} else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
219			key = line[0:spaceIndex]
220			val = strings.TrimSpace(line[spaceIndex:])
221		} else {
222			key = line[0:tabIndex]
223			val = strings.TrimSpace(line[tabIndex:])
224		}
225
226		if key == "__clang__" {
227			p.GccIsClang = true
228		}
229
230		if n := f.Name[key]; n != nil {
231			if *debugDefine {
232				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
233			}
234			n.Define = val
235		}
236	}
237}
238
239// guessKinds tricks gcc into revealing the kind of each
240// name xxx for the references C.xxx in the Go input.
241// The kind is either a constant, type, or variable.
242func (p *Package) guessKinds(f *File) []*Name {
243	// Determine kinds for names we already know about,
244	// like #defines or 'struct foo', before bothering with gcc.
245	var names, needType []*Name
246	optional := map[*Name]bool{}
247	for _, key := range nameKeys(f.Name) {
248		n := f.Name[key]
249		// If we've already found this name as a #define
250		// and we can translate it as a constant value, do so.
251		if n.Define != "" {
252			if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
253				n.Kind = "iconst"
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				n.Const = fmt.Sprintf("%#x", i)
259			} else if n.Define[0] == '\'' {
260				if _, err := parser.ParseExpr(n.Define); err == nil {
261					n.Kind = "iconst"
262					n.Const = n.Define
263				}
264			} else if n.Define[0] == '"' {
265				if _, err := parser.ParseExpr(n.Define); err == nil {
266					n.Kind = "sconst"
267					n.Const = n.Define
268				}
269			}
270
271			if n.IsConst() {
272				continue
273			}
274		}
275
276		// If this is a struct, union, or enum type name, no need to guess the kind.
277		if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
278			n.Kind = "type"
279			needType = append(needType, n)
280			continue
281		}
282
283		if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
284			// For FooRef, find out if FooGetTypeID exists.
285			s := n.C[:len(n.C)-3] + "GetTypeID"
286			n := &Name{Go: s, C: s}
287			names = append(names, n)
288			optional[n] = true
289		}
290
291		// Otherwise, we'll need to find out from gcc.
292		names = append(names, n)
293	}
294
295	// Bypass gcc if there's nothing left to find out.
296	if len(names) == 0 {
297		return needType
298	}
299
300	// Coerce gcc into telling us whether each name is a type, a value, or undeclared.
301	// For names, find out whether they are integer constants.
302	// We used to look at specific warning or error messages here, but that tied the
303	// behavior too closely to specific versions of the compilers.
304	// Instead, arrange that we can infer what we need from only the presence or absence
305	// of an error on a specific line.
306	//
307	// For each name, we generate these lines, where xxx is the index in toSniff plus one.
308	//
309	//	#line xxx "not-declared"
310	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
311	//	#line xxx "not-type"
312	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
313	//	#line xxx "not-int-const"
314	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
315	//	#line xxx "not-num-const"
316	//	void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
317	//	#line xxx "not-str-lit"
318	//	void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
319	//
320	// If we see an error at not-declared:xxx, the corresponding name is not declared.
321	// If we see an error at not-type:xxx, the corresponding name is a type.
322	// If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
323	// If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
324	// If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
325	//
326	// The specific input forms are chosen so that they are valid C syntax regardless of
327	// whether name denotes a type or an expression.
328
329	var b bytes.Buffer
330	b.WriteString(builtinProlog)
331	b.WriteString(f.Preamble)
332
333	for i, n := range names {
334		fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
335			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
336			"#line %d \"not-type\"\n"+
337			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
338			"#line %d \"not-int-const\"\n"+
339			"void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
340			"#line %d \"not-num-const\"\n"+
341			"void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
342			"#line %d \"not-str-lit\"\n"+
343			"void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
344			i+1, i+1, n.C,
345			i+1, i+1, n.C,
346			i+1, i+1, n.C,
347			i+1, i+1, n.C,
348			i+1, i+1, n.C,
349		)
350	}
351	fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
352		"int __cgo__1 = __cgo__2;\n")
353
354	stderr := p.gccErrors(b.Bytes())
355	if stderr == "" {
356		fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
357	}
358
359	completed := false
360	sniff := make([]int, len(names))
361	const (
362		notType = 1 << iota
363		notIntConst
364		notNumConst
365		notStrLiteral
366		notDeclared
367	)
368	sawUnmatchedErrors := false
369	for _, line := range strings.Split(stderr, "\n") {
370		// Ignore warnings and random comments, with one
371		// exception: newer GCC versions will sometimes emit
372		// an error on a macro #define with a note referring
373		// to where the expansion occurs. We care about where
374		// the expansion occurs, so in that case treat the note
375		// as an error.
376		isError := strings.Contains(line, ": error:")
377		isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
378		if !isError && !isErrorNote {
379			continue
380		}
381
382		c1 := strings.Index(line, ":")
383		if c1 < 0 {
384			continue
385		}
386		c2 := strings.Index(line[c1+1:], ":")
387		if c2 < 0 {
388			continue
389		}
390		c2 += c1 + 1
391
392		filename := line[:c1]
393		i, _ := strconv.Atoi(line[c1+1 : c2])
394		i--
395		if i < 0 || i >= len(names) {
396			if isError {
397				sawUnmatchedErrors = true
398			}
399			continue
400		}
401
402		switch filename {
403		case "completed":
404			// Strictly speaking, there is no guarantee that seeing the error at completed:1
405			// (at the end of the file) means we've seen all the errors from earlier in the file,
406			// but usually it does. Certainly if we don't see the completed:1 error, we did
407			// not get all the errors we expected.
408			completed = true
409
410		case "not-declared":
411			sniff[i] |= notDeclared
412		case "not-type":
413			sniff[i] |= notType
414		case "not-int-const":
415			sniff[i] |= notIntConst
416		case "not-num-const":
417			sniff[i] |= notNumConst
418		case "not-str-lit":
419			sniff[i] |= notStrLiteral
420		default:
421			if isError {
422				sawUnmatchedErrors = true
423			}
424			continue
425		}
426
427		sawUnmatchedErrors = false
428	}
429
430	if !completed {
431		fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
432	}
433
434	for i, n := range names {
435		switch sniff[i] {
436		default:
437			if sniff[i]&notDeclared != 0 && optional[n] {
438				// Ignore optional undeclared identifiers.
439				// Don't report an error, and skip adding n to the needType array.
440				continue
441			}
442			error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
443		case notStrLiteral | notType:
444			n.Kind = "iconst"
445		case notIntConst | notStrLiteral | notType:
446			n.Kind = "fconst"
447		case notIntConst | notNumConst | notType:
448			n.Kind = "sconst"
449		case notIntConst | notNumConst | notStrLiteral:
450			n.Kind = "type"
451		case notIntConst | notNumConst | notStrLiteral | notType:
452			n.Kind = "not-type"
453		}
454		needType = append(needType, n)
455	}
456	if nerrors > 0 {
457		// Check if compiling the preamble by itself causes any errors,
458		// because the messages we've printed out so far aren't helpful
459		// to users debugging preamble mistakes. See issue 8442.
460		preambleErrors := p.gccErrors([]byte(f.Preamble))
461		if len(preambleErrors) > 0 {
462			error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
463		}
464
465		fatalf("unresolved names")
466	}
467
468	return needType
469}
470
471// loadDWARF parses the DWARF debug information generated
472// by gcc to learn the details of the constants, variables, and types
473// being referred to as C.xxx.
474func (p *Package) loadDWARF(f *File, names []*Name) {
475	// Extract the types from the DWARF section of an object
476	// from a well-formed C program. Gcc only generates DWARF info
477	// for symbols in the object file, so it is not enough to print the
478	// preamble and hope the symbols we care about will be there.
479	// Instead, emit
480	//	__typeof__(names[i]) *__cgo__i;
481	// for each entry in names and then dereference the type we
482	// learn for __cgo__i.
483	var b bytes.Buffer
484	b.WriteString(builtinProlog)
485	b.WriteString(f.Preamble)
486	b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
487	for i, n := range names {
488		fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
489		if n.Kind == "iconst" {
490			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
491		}
492	}
493
494	// We create a data block initialized with the values,
495	// so we can read them out of the object file.
496	fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
497	for _, n := range names {
498		if n.Kind == "iconst" {
499			fmt.Fprintf(&b, "\t%s,\n", n.C)
500		} else {
501			fmt.Fprintf(&b, "\t0,\n")
502		}
503	}
504	// for the last entry, we cannot use 0, otherwise
505	// in case all __cgodebug_data is zero initialized,
506	// LLVM-based gcc will place the it in the __DATA.__common
507	// zero-filled section (our debug/macho doesn't support
508	// this)
509	fmt.Fprintf(&b, "\t1\n")
510	fmt.Fprintf(&b, "};\n")
511
512	// do the same work for floats.
513	fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n")
514	for _, n := range names {
515		if n.Kind == "fconst" {
516			fmt.Fprintf(&b, "\t%s,\n", n.C)
517		} else {
518			fmt.Fprintf(&b, "\t0,\n")
519		}
520	}
521	fmt.Fprintf(&b, "\t1\n")
522	fmt.Fprintf(&b, "};\n")
523
524	// do the same work for strings.
525	for i, n := range names {
526		if n.Kind == "sconst" {
527			fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C)
528			fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C)
529		}
530	}
531
532	d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
533
534	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
535	types := make([]dwarf.Type, len(names))
536	r := d.Reader()
537	for {
538		e, err := r.Next()
539		if err != nil {
540			fatalf("reading DWARF entry: %s", err)
541		}
542		if e == nil {
543			break
544		}
545		switch e.Tag {
546		case dwarf.TagVariable:
547			name, _ := e.Val(dwarf.AttrName).(string)
548			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
549			if name == "" || typOff == 0 {
550				if e.Val(dwarf.AttrSpecification) != nil {
551					// Since we are reading all the DWARF,
552					// assume we will see the variable elsewhere.
553					break
554				}
555				fatalf("malformed DWARF TagVariable entry")
556			}
557			if !strings.HasPrefix(name, "__cgo__") {
558				break
559			}
560			typ, err := d.Type(typOff)
561			if err != nil {
562				fatalf("loading DWARF type: %s", err)
563			}
564			t, ok := typ.(*dwarf.PtrType)
565			if !ok || t == nil {
566				fatalf("internal error: %s has non-pointer type", name)
567			}
568			i, err := strconv.Atoi(name[7:])
569			if err != nil {
570				fatalf("malformed __cgo__ name: %s", name)
571			}
572			types[i] = t.Type
573		}
574		if e.Tag != dwarf.TagCompileUnit {
575			r.SkipChildren()
576		}
577	}
578
579	// Record types and typedef information.
580	var conv typeConv
581	conv.Init(p.PtrSize, p.IntSize)
582	for i, n := range names {
583		if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
584			conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
585		}
586	}
587	for i, n := range names {
588		if types[i] == nil {
589			continue
590		}
591		pos := f.NamePos[n]
592		f, fok := types[i].(*dwarf.FuncType)
593		if n.Kind != "type" && fok {
594			n.Kind = "func"
595			n.FuncType = conv.FuncType(f, pos)
596		} else {
597			n.Type = conv.Type(types[i], pos)
598			switch n.Kind {
599			case "iconst":
600				if i < len(ints) {
601					if _, ok := types[i].(*dwarf.UintType); ok {
602						n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
603					} else {
604						n.Const = fmt.Sprintf("%#x", ints[i])
605					}
606				}
607			case "fconst":
608				if i < len(floats) {
609					n.Const = fmt.Sprintf("%f", floats[i])
610				}
611			case "sconst":
612				if i < len(strs) {
613					n.Const = fmt.Sprintf("%q", strs[i])
614				}
615			}
616		}
617		conv.FinishType(pos)
618	}
619}
620
621// mangleName does name mangling to translate names
622// from the original Go source files to the names
623// used in the final Go files generated by cgo.
624func (p *Package) mangleName(n *Name) {
625	// When using gccgo variables have to be
626	// exported so that they become global symbols
627	// that the C code can refer to.
628	prefix := "_C"
629	if *gccgo && n.IsVar() {
630		prefix = "C"
631	}
632	n.Mangle = prefix + n.Kind + "_" + n.Go
633}
634
635// rewriteCalls rewrites all calls that pass pointers to check that
636// they follow the rules for passing pointers between Go and C.
637// This returns whether the package needs to import unsafe as _cgo_unsafe.
638func (p *Package) rewriteCalls(f *File) bool {
639	needsUnsafe := false
640	for _, call := range f.Calls {
641		// This is a call to C.xxx; set goname to "xxx".
642		goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name
643		if goname == "malloc" {
644			continue
645		}
646		name := f.Name[goname]
647		if name.Kind != "func" {
648			// Probably a type conversion.
649			continue
650		}
651		if p.rewriteCall(f, call, name) {
652			needsUnsafe = true
653		}
654	}
655	return needsUnsafe
656}
657
658// rewriteCall rewrites one call to add pointer checks.
659// If any pointer checks are required, we rewrite the call into a
660// function literal that calls _cgoCheckPointer for each pointer
661// argument and then calls the original function.
662// This returns whether the package needs to import unsafe as _cgo_unsafe.
663func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
664	// Avoid a crash if the number of arguments is
665	// less than the number of parameters.
666	// This will be caught when the generated file is compiled.
667	if len(call.Call.Args) < len(name.FuncType.Params) {
668		return false
669	}
670
671	any := false
672	for i, param := range name.FuncType.Params {
673		if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) {
674			any = true
675			break
676		}
677	}
678	if !any {
679		return false
680	}
681
682	// We need to rewrite this call.
683	//
684	// We are going to rewrite C.f(p) to
685	//    func (_cgo0 ptype) {
686	//            _cgoCheckPointer(_cgo0)
687	//            C.f(_cgo0)
688	//    }(p)
689	// Using a function literal like this lets us do correct
690	// argument type checking, and works correctly if the call is
691	// deferred.
692	needsUnsafe := false
693	params := make([]*ast.Field, len(name.FuncType.Params))
694	nargs := make([]ast.Expr, len(name.FuncType.Params))
695	var stmts []ast.Stmt
696	for i, param := range name.FuncType.Params {
697		// params is going to become the parameters of the
698		// function literal.
699		// nargs is going to become the list of arguments made
700		// by the call within the function literal.
701		// nparam is the parameter of the function literal that
702		// corresponds to param.
703
704		origArg := call.Call.Args[i]
705		nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
706		nargs[i] = nparam
707
708		// The Go version of the C type might use unsafe.Pointer,
709		// but the file might not import unsafe.
710		// Rewrite the Go type if necessary to use _cgo_unsafe.
711		ptype := p.rewriteUnsafe(param.Go)
712		if ptype != param.Go {
713			needsUnsafe = true
714		}
715
716		params[i] = &ast.Field{
717			Names: []*ast.Ident{nparam},
718			Type:  ptype,
719		}
720
721		if !p.needsPointerCheck(f, param.Go, origArg) {
722			continue
723		}
724
725		// Run the cgo pointer checks on nparam.
726
727		// Change the function literal to call the real function
728		// with the parameter passed through _cgoCheckPointer.
729		c := &ast.CallExpr{
730			Fun: ast.NewIdent("_cgoCheckPointer"),
731			Args: []ast.Expr{
732				nparam,
733			},
734		}
735
736		// Add optional additional arguments for an address
737		// expression.
738		c.Args = p.checkAddrArgs(f, c.Args, origArg)
739
740		stmt := &ast.ExprStmt{
741			X: c,
742		}
743		stmts = append(stmts, stmt)
744	}
745
746	const cgoMarker = "__cgo__###__marker__"
747	fcall := &ast.CallExpr{
748		Fun:  ast.NewIdent(cgoMarker),
749		Args: nargs,
750	}
751	ftype := &ast.FuncType{
752		Params: &ast.FieldList{
753			List: params,
754		},
755	}
756	if name.FuncType.Result != nil {
757		rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
758		if rtype != name.FuncType.Result.Go {
759			needsUnsafe = true
760		}
761		ftype.Results = &ast.FieldList{
762			List: []*ast.Field{
763				&ast.Field{
764					Type: rtype,
765				},
766			},
767		}
768	}
769
770	// If this call expects two results, we have to
771	// adjust the results of the function we generated.
772	for _, ref := range f.Ref {
773		if ref.Expr == &call.Call.Fun && ref.Context == ctxCall2 {
774			if ftype.Results == nil {
775				// An explicit void argument
776				// looks odd but it seems to
777				// be how cgo has worked historically.
778				ftype.Results = &ast.FieldList{
779					List: []*ast.Field{
780						&ast.Field{
781							Type: ast.NewIdent("_Ctype_void"),
782						},
783					},
784				}
785			}
786			ftype.Results.List = append(ftype.Results.List,
787				&ast.Field{
788					Type: ast.NewIdent("error"),
789				})
790		}
791	}
792
793	var fbody ast.Stmt
794	if ftype.Results == nil {
795		fbody = &ast.ExprStmt{
796			X: fcall,
797		}
798	} else {
799		fbody = &ast.ReturnStmt{
800			Results: []ast.Expr{fcall},
801		}
802	}
803	lit := &ast.FuncLit{
804		Type: ftype,
805		Body: &ast.BlockStmt{
806			List: append(stmts, fbody),
807		},
808	}
809	text := strings.Replace(gofmt(lit), "\n", ";", -1)
810	repl := strings.Split(text, cgoMarker)
811	f.Edit.Insert(f.offset(call.Call.Fun.Pos()), repl[0])
812	f.Edit.Insert(f.offset(call.Call.Fun.End()), repl[1])
813
814	return needsUnsafe
815}
816
817// needsPointerCheck returns whether the type t needs a pointer check.
818// This is true if t is a pointer and if the value to which it points
819// might contain a pointer.
820func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
821	// An untyped nil does not need a pointer check, and when
822	// _cgoCheckPointer returns the untyped nil the type assertion we
823	// are going to insert will fail.  Easier to just skip nil arguments.
824	// TODO: Note that this fails if nil is shadowed.
825	if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
826		return false
827	}
828
829	return p.hasPointer(f, t, true)
830}
831
832// hasPointer is used by needsPointerCheck. If top is true it returns
833// whether t is or contains a pointer that might point to a pointer.
834// If top is false it returns whether t is or contains a pointer.
835// f may be nil.
836func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
837	switch t := t.(type) {
838	case *ast.ArrayType:
839		if t.Len == nil {
840			if !top {
841				return true
842			}
843			return p.hasPointer(f, t.Elt, false)
844		}
845		return p.hasPointer(f, t.Elt, top)
846	case *ast.StructType:
847		for _, field := range t.Fields.List {
848			if p.hasPointer(f, field.Type, top) {
849				return true
850			}
851		}
852		return false
853	case *ast.StarExpr: // Pointer type.
854		if !top {
855			return true
856		}
857		// Check whether this is a pointer to a C union (or class)
858		// type that contains a pointer.
859		if unionWithPointer[t.X] {
860			return true
861		}
862		return p.hasPointer(f, t.X, false)
863	case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
864		return true
865	case *ast.Ident:
866		// TODO: Handle types defined within function.
867		for _, d := range p.Decl {
868			gd, ok := d.(*ast.GenDecl)
869			if !ok || gd.Tok != token.TYPE {
870				continue
871			}
872			for _, spec := range gd.Specs {
873				ts, ok := spec.(*ast.TypeSpec)
874				if !ok {
875					continue
876				}
877				if ts.Name.Name == t.Name {
878					return p.hasPointer(f, ts.Type, top)
879				}
880			}
881		}
882		if def := typedef[t.Name]; def != nil {
883			return p.hasPointer(f, def.Go, top)
884		}
885		if t.Name == "string" {
886			return !top
887		}
888		if t.Name == "error" {
889			return true
890		}
891		if goTypes[t.Name] != nil {
892			return false
893		}
894		// We can't figure out the type. Conservative
895		// approach is to assume it has a pointer.
896		return true
897	case *ast.SelectorExpr:
898		if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
899			// Type defined in a different package.
900			// Conservative approach is to assume it has a
901			// pointer.
902			return true
903		}
904		if f == nil {
905			// Conservative approach: assume pointer.
906			return true
907		}
908		name := f.Name[t.Sel.Name]
909		if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
910			return p.hasPointer(f, name.Type.Go, top)
911		}
912		// We can't figure out the type. Conservative
913		// approach is to assume it has a pointer.
914		return true
915	default:
916		error_(t.Pos(), "could not understand type %s", gofmt(t))
917		return true
918	}
919}
920
921// checkAddrArgs tries to add arguments to the call of
922// _cgoCheckPointer when the argument is an address expression. We
923// pass true to mean that the argument is an address operation of
924// something other than a slice index, which means that it's only
925// necessary to check the specific element pointed to, not the entire
926// object. This is for &s.f, where f is a field in a struct. We can
927// pass a slice or array, meaning that we should check the entire
928// slice or array but need not check any other part of the object.
929// This is for &s.a[i], where we need to check all of a. However, we
930// only pass the slice or array if we can refer to it without side
931// effects.
932func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr {
933	// Strip type conversions.
934	for {
935		c, ok := x.(*ast.CallExpr)
936		if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
937			break
938		}
939		x = c.Args[0]
940	}
941	u, ok := x.(*ast.UnaryExpr)
942	if !ok || u.Op != token.AND {
943		return args
944	}
945	index, ok := u.X.(*ast.IndexExpr)
946	if !ok {
947		// This is the address of something that is not an
948		// index expression. We only need to examine the
949		// single value to which it points.
950		// TODO: what if true is shadowed?
951		return append(args, ast.NewIdent("true"))
952	}
953	if !p.hasSideEffects(f, index.X) {
954		// Examine the entire slice.
955		return append(args, index.X)
956	}
957	// Treat the pointer as unknown.
958	return args
959}
960
961// hasSideEffects returns whether the expression x has any side
962// effects.  x is an expression, not a statement, so the only side
963// effect is a function call.
964func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
965	found := false
966	f.walk(x, ctxExpr,
967		func(f *File, x interface{}, context astContext) {
968			switch x.(type) {
969			case *ast.CallExpr:
970				found = true
971			}
972		})
973	return found
974}
975
976// isType returns whether the expression is definitely a type.
977// This is conservative--it returns false for an unknown identifier.
978func (p *Package) isType(t ast.Expr) bool {
979	switch t := t.(type) {
980	case *ast.SelectorExpr:
981		id, ok := t.X.(*ast.Ident)
982		if !ok {
983			return false
984		}
985		if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
986			return true
987		}
988		if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
989			return true
990		}
991		return false
992	case *ast.Ident:
993		// TODO: This ignores shadowing.
994		switch t.Name {
995		case "unsafe.Pointer", "bool", "byte",
996			"complex64", "complex128",
997			"error",
998			"float32", "float64",
999			"int", "int8", "int16", "int32", "int64",
1000			"rune", "string",
1001			"uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1002
1003			return true
1004		}
1005	case *ast.StarExpr:
1006		return p.isType(t.X)
1007	case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
1008		*ast.MapType, *ast.ChanType:
1009
1010		return true
1011	}
1012	return false
1013}
1014
1015// rewriteUnsafe returns a version of t with references to unsafe.Pointer
1016// rewritten to use _cgo_unsafe.Pointer instead.
1017func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
1018	switch t := t.(type) {
1019	case *ast.Ident:
1020		// We don't see a SelectorExpr for unsafe.Pointer;
1021		// this is created by code in this file.
1022		if t.Name == "unsafe.Pointer" {
1023			return ast.NewIdent("_cgo_unsafe.Pointer")
1024		}
1025	case *ast.ArrayType:
1026		t1 := p.rewriteUnsafe(t.Elt)
1027		if t1 != t.Elt {
1028			r := *t
1029			r.Elt = t1
1030			return &r
1031		}
1032	case *ast.StructType:
1033		changed := false
1034		fields := *t.Fields
1035		fields.List = nil
1036		for _, f := range t.Fields.List {
1037			ft := p.rewriteUnsafe(f.Type)
1038			if ft == f.Type {
1039				fields.List = append(fields.List, f)
1040			} else {
1041				fn := *f
1042				fn.Type = ft
1043				fields.List = append(fields.List, &fn)
1044				changed = true
1045			}
1046		}
1047		if changed {
1048			r := *t
1049			r.Fields = &fields
1050			return &r
1051		}
1052	case *ast.StarExpr: // Pointer type.
1053		x1 := p.rewriteUnsafe(t.X)
1054		if x1 != t.X {
1055			r := *t
1056			r.X = x1
1057			return &r
1058		}
1059	}
1060	return t
1061}
1062
1063// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1064// Go equivalents, now that we have figured out the meaning of all
1065// the xxx. In *godefs mode, rewriteRef replaces the names
1066// with full definitions instead of mangled names.
1067func (p *Package) rewriteRef(f *File) {
1068	// Keep a list of all the functions, to remove the ones
1069	// only used as expressions and avoid generating bridge
1070	// code for them.
1071	functions := make(map[string]bool)
1072
1073	// Assign mangled names.
1074	for _, n := range f.Name {
1075		if n.Kind == "not-type" {
1076			if n.Define == "" {
1077				n.Kind = "var"
1078			} else {
1079				n.Kind = "macro"
1080				n.FuncType = &FuncType{
1081					Result: n.Type,
1082					Go: &ast.FuncType{
1083						Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
1084					},
1085				}
1086			}
1087		}
1088		if n.Mangle == "" {
1089			p.mangleName(n)
1090		}
1091		if n.Kind == "func" {
1092			functions[n.Go] = false
1093		}
1094	}
1095
1096	// Now that we have all the name types filled in,
1097	// scan through the Refs to identify the ones that
1098	// are trying to do a ,err call. Also check that
1099	// functions are only used in calls.
1100	for _, r := range f.Ref {
1101		if r.Name.IsConst() && r.Name.Const == "" {
1102			error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1103		}
1104		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
1105		switch r.Context {
1106		case ctxCall, ctxCall2:
1107			if r.Name.Kind != "func" {
1108				if r.Name.Kind == "type" {
1109					r.Context = ctxType
1110					if r.Name.Type == nil {
1111						error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1112						break
1113					}
1114					expr = r.Name.Type.Go
1115					break
1116				}
1117				error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1118				break
1119			}
1120			functions[r.Name.Go] = true
1121			if r.Context == ctxCall2 {
1122				if r.Name.Go == "_CMalloc" {
1123					error_(r.Pos(), "no two-result form for C.malloc")
1124					break
1125				}
1126				// Invent new Name for the two-result function.
1127				n := f.Name["2"+r.Name.Go]
1128				if n == nil {
1129					n = new(Name)
1130					*n = *r.Name
1131					n.AddError = true
1132					n.Mangle = "_C2func_" + n.Go
1133					f.Name["2"+r.Name.Go] = n
1134				}
1135				expr = ast.NewIdent(n.Mangle)
1136				r.Name = n
1137				break
1138			}
1139		case ctxExpr:
1140			switch r.Name.Kind {
1141			case "func":
1142				if builtinDefs[r.Name.C] != "" {
1143					error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
1144				}
1145
1146				// Function is being used in an expression, to e.g. pass around a C function pointer.
1147				// Create a new Name for this Ref which causes the variable to be declared in Go land.
1148				fpName := "fp_" + r.Name.Go
1149				name := f.Name[fpName]
1150				if name == nil {
1151					name = &Name{
1152						Go:   fpName,
1153						C:    r.Name.C,
1154						Kind: "fpvar",
1155						Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1156					}
1157					p.mangleName(name)
1158					f.Name[fpName] = name
1159				}
1160				r.Name = name
1161				// Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1162				// function is defined in out.go and simply returns its argument. See
1163				// issue 7757.
1164				expr = &ast.CallExpr{
1165					Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1166					Args: []ast.Expr{ast.NewIdent(name.Mangle)},
1167				}
1168			case "type":
1169				// Okay - might be new(T)
1170				if r.Name.Type == nil {
1171					error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1172					break
1173				}
1174				expr = r.Name.Type.Go
1175			case "var":
1176				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1177			case "macro":
1178				expr = &ast.CallExpr{Fun: expr}
1179			}
1180		case ctxSelector:
1181			if r.Name.Kind == "var" {
1182				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1183			} else {
1184				error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
1185			}
1186		case ctxType:
1187			if r.Name.Kind != "type" {
1188				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1189			} else if r.Name.Type == nil {
1190				// Use of C.enum_x, C.struct_x or C.union_x without C definition.
1191				// GCC won't raise an error when using pointers to such unknown types.
1192				error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1193			} else {
1194				expr = r.Name.Type.Go
1195			}
1196		default:
1197			if r.Name.Kind == "func" {
1198				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1199			}
1200		}
1201
1202		if *godefs {
1203			// Substitute definition for mangled type name.
1204			if id, ok := expr.(*ast.Ident); ok {
1205				if t := typedef[id.Name]; t != nil {
1206					expr = t.Go
1207				}
1208				if id.Name == r.Name.Mangle && r.Name.Const != "" {
1209					expr = ast.NewIdent(r.Name.Const)
1210				}
1211			}
1212		}
1213
1214		// Copy position information from old expr into new expr,
1215		// in case expression being replaced is first on line.
1216		// See golang.org/issue/6563.
1217		pos := (*r.Expr).Pos()
1218		switch x := expr.(type) {
1219		case *ast.Ident:
1220			expr = &ast.Ident{NamePos: pos, Name: x.Name}
1221		}
1222
1223		// Change AST, because some later processing depends on it,
1224		// and also because -godefs mode still prints the AST.
1225		old := *r.Expr
1226		*r.Expr = expr
1227
1228		// Record source-level edit for cgo output.
1229		repl := gofmt(expr)
1230		if r.Name.Kind != "type" {
1231			repl = "(" + repl + ")"
1232		}
1233		f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
1234	}
1235
1236	// Remove functions only used as expressions, so their respective
1237	// bridge functions are not generated.
1238	for name, used := range functions {
1239		if !used {
1240			delete(f.Name, name)
1241		}
1242	}
1243}
1244
1245// gccBaseCmd returns the start of the compiler command line.
1246// It uses $CC if set, or else $GCC, or else the compiler recorded
1247// during the initial build as defaultCC.
1248// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1249func (p *Package) gccBaseCmd() []string {
1250	// Use $CC if set, since that's what the build uses.
1251	if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
1252		return ret
1253	}
1254	// Try $GCC if set, since that's what we used to use.
1255	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
1256		return ret
1257	}
1258	return strings.Fields(defaultCC(goos, goarch))
1259}
1260
1261// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1262func (p *Package) gccMachine() []string {
1263	switch goarch {
1264	case "amd64":
1265		return []string{"-m64"}
1266	case "386":
1267		return []string{"-m32"}
1268	case "arm":
1269		return []string{"-marm"} // not thumb
1270	case "s390":
1271		return []string{"-m31"}
1272	case "s390x":
1273		return []string{"-m64"}
1274	case "mips64", "mips64le":
1275		return []string{"-mabi=64"}
1276	case "mips", "mipsle":
1277		return []string{"-mabi=32"}
1278	case "ppc64":
1279		if goos == "aix" {
1280			return []string{"-maix64"}
1281		}
1282	}
1283	return nil
1284}
1285
1286func gccTmp() string {
1287	return *objDir + "_cgo_.o"
1288}
1289
1290// gccCmd returns the gcc command line to use for compiling
1291// the input.
1292func (p *Package) gccCmd() []string {
1293	c := append(p.gccBaseCmd(),
1294		"-w",          // no warnings
1295		"-Wno-error",  // warnings are not errors
1296		"-o"+gccTmp(), // write object to tmp
1297		"-gdwarf-2",   // generate DWARF v2 debugging symbols
1298		"-c",          // do not link
1299		"-xc",         // input language is C
1300	)
1301	if p.GccIsClang {
1302		c = append(c,
1303			"-ferror-limit=0",
1304			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1305			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1306			// flag to disable the warning. Yes, really good diagnostics, clang.
1307			"-Wno-unknown-warning-option",
1308			"-Wno-unneeded-internal-declaration",
1309			"-Wno-unused-function",
1310			"-Qunused-arguments",
1311			// Clang embeds prototypes for some builtin functions,
1312			// like malloc and calloc, but all size_t parameters are
1313			// incorrectly typed unsigned long. We work around that
1314			// by disabling the builtin functions (this is safe as
1315			// it won't affect the actual compilation of the C code).
1316			// See: https://golang.org/issue/6506.
1317			"-fno-builtin",
1318		)
1319	}
1320
1321	c = append(c, p.GccOptions...)
1322	c = append(c, p.gccMachine()...)
1323	c = append(c, "-") //read input from standard input
1324	return c
1325}
1326
1327// gccDebug runs gcc -gdwarf-2 over the C program stdin and
1328// returns the corresponding DWARF data and, if present, debug data block.
1329func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1330	runGcc(stdin, p.gccCmd())
1331
1332	isDebugInts := func(s string) bool {
1333		// Some systems use leading _ to denote non-assembly symbols.
1334		return s == "__cgodebug_ints" || s == "___cgodebug_ints"
1335	}
1336	isDebugFloats := func(s string) bool {
1337		// Some systems use leading _ to denote non-assembly symbols.
1338		return s == "__cgodebug_floats" || s == "___cgodebug_floats"
1339	}
1340	indexOfDebugStr := func(s string) int {
1341		// Some systems use leading _ to denote non-assembly symbols.
1342		if strings.HasPrefix(s, "___") {
1343			s = s[1:]
1344		}
1345		if strings.HasPrefix(s, "__cgodebug_str__") {
1346			if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
1347				return n
1348			}
1349		}
1350		return -1
1351	}
1352	indexOfDebugStrlen := func(s string) int {
1353		// Some systems use leading _ to denote non-assembly symbols.
1354		if strings.HasPrefix(s, "___") {
1355			s = s[1:]
1356		}
1357		if strings.HasPrefix(s, "__cgodebug_strlen__") {
1358			if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
1359				return n
1360			}
1361		}
1362		return -1
1363	}
1364
1365	strs = make([]string, nnames)
1366
1367	strdata := make(map[int]string, nnames)
1368	strlens := make(map[int]int, nnames)
1369
1370	buildStrings := func() {
1371		for n, strlen := range strlens {
1372			data := strdata[n]
1373			if len(data) <= strlen {
1374				fatalf("invalid string literal")
1375			}
1376			strs[n] = string(data[:strlen])
1377		}
1378	}
1379
1380	if f, err := macho.Open(gccTmp()); err == nil {
1381		defer f.Close()
1382		d, err := f.DWARF()
1383		if err != nil {
1384			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1385		}
1386		bo := f.ByteOrder
1387		if f.Symtab != nil {
1388			for i := range f.Symtab.Syms {
1389				s := &f.Symtab.Syms[i]
1390				switch {
1391				case isDebugInts(s.Name):
1392					// Found it. Now find data section.
1393					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1394						sect := f.Sections[i]
1395						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1396							if sdat, err := sect.Data(); err == nil {
1397								data := sdat[s.Value-sect.Addr:]
1398								ints = make([]int64, len(data)/8)
1399								for i := range ints {
1400									ints[i] = int64(bo.Uint64(data[i*8:]))
1401								}
1402							}
1403						}
1404					}
1405				case isDebugFloats(s.Name):
1406					// Found it. Now find data section.
1407					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1408						sect := f.Sections[i]
1409						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1410							if sdat, err := sect.Data(); err == nil {
1411								data := sdat[s.Value-sect.Addr:]
1412								floats = make([]float64, len(data)/8)
1413								for i := range floats {
1414									floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1415								}
1416							}
1417						}
1418					}
1419				default:
1420					if n := indexOfDebugStr(s.Name); n != -1 {
1421						// Found it. Now find data section.
1422						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1423							sect := f.Sections[i]
1424							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1425								if sdat, err := sect.Data(); err == nil {
1426									data := sdat[s.Value-sect.Addr:]
1427									strdata[n] = string(data)
1428								}
1429							}
1430						}
1431						break
1432					}
1433					if n := indexOfDebugStrlen(s.Name); n != -1 {
1434						// Found it. Now find data section.
1435						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1436							sect := f.Sections[i]
1437							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1438								if sdat, err := sect.Data(); err == nil {
1439									data := sdat[s.Value-sect.Addr:]
1440									strlen := bo.Uint64(data[:8])
1441									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1442										fatalf("string literal too big")
1443									}
1444									strlens[n] = int(strlen)
1445								}
1446							}
1447						}
1448						break
1449					}
1450				}
1451			}
1452
1453			buildStrings()
1454		}
1455		return d, ints, floats, strs
1456	}
1457
1458	if f, err := elf.Open(gccTmp()); err == nil {
1459		defer f.Close()
1460		d, err := f.DWARF()
1461		if err != nil {
1462			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1463		}
1464		bo := f.ByteOrder
1465		symtab, err := f.Symbols()
1466		if err == nil {
1467			for i := range symtab {
1468				s := &symtab[i]
1469				switch {
1470				case isDebugInts(s.Name):
1471					// Found it. Now find data section.
1472					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1473						sect := f.Sections[i]
1474						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1475							if sdat, err := sect.Data(); err == nil {
1476								data := sdat[s.Value-sect.Addr:]
1477								ints = make([]int64, len(data)/8)
1478								for i := range ints {
1479									ints[i] = int64(bo.Uint64(data[i*8:]))
1480								}
1481							}
1482						}
1483					}
1484				case isDebugFloats(s.Name):
1485					// Found it. Now find data section.
1486					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1487						sect := f.Sections[i]
1488						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1489							if sdat, err := sect.Data(); err == nil {
1490								data := sdat[s.Value-sect.Addr:]
1491								floats = make([]float64, len(data)/8)
1492								for i := range floats {
1493									floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1494								}
1495							}
1496						}
1497					}
1498				default:
1499					if n := indexOfDebugStr(s.Name); n != -1 {
1500						// Found it. Now find data section.
1501						if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1502							sect := f.Sections[i]
1503							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1504								if sdat, err := sect.Data(); err == nil {
1505									data := sdat[s.Value-sect.Addr:]
1506									strdata[n] = string(data)
1507								}
1508							}
1509						}
1510						break
1511					}
1512					if n := indexOfDebugStrlen(s.Name); n != -1 {
1513						// Found it. Now find data section.
1514						if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1515							sect := f.Sections[i]
1516							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1517								if sdat, err := sect.Data(); err == nil {
1518									data := sdat[s.Value-sect.Addr:]
1519									strlen := bo.Uint64(data[:8])
1520									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1521										fatalf("string literal too big")
1522									}
1523									strlens[n] = int(strlen)
1524								}
1525							}
1526						}
1527						break
1528					}
1529				}
1530			}
1531
1532			buildStrings()
1533		}
1534		return d, ints, floats, strs
1535	}
1536
1537	if f, err := pe.Open(gccTmp()); err == nil {
1538		defer f.Close()
1539		d, err := f.DWARF()
1540		if err != nil {
1541			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1542		}
1543		bo := binary.LittleEndian
1544		for _, s := range f.Symbols {
1545			switch {
1546			case isDebugInts(s.Name):
1547				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1548					sect := f.Sections[i]
1549					if s.Value < sect.Size {
1550						if sdat, err := sect.Data(); err == nil {
1551							data := sdat[s.Value:]
1552							ints = make([]int64, len(data)/8)
1553							for i := range ints {
1554								ints[i] = int64(bo.Uint64(data[i*8:]))
1555							}
1556						}
1557					}
1558				}
1559			case isDebugFloats(s.Name):
1560				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1561					sect := f.Sections[i]
1562					if s.Value < sect.Size {
1563						if sdat, err := sect.Data(); err == nil {
1564							data := sdat[s.Value:]
1565							floats = make([]float64, len(data)/8)
1566							for i := range floats {
1567								floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1568							}
1569						}
1570					}
1571				}
1572			default:
1573				if n := indexOfDebugStr(s.Name); n != -1 {
1574					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1575						sect := f.Sections[i]
1576						if s.Value < sect.Size {
1577							if sdat, err := sect.Data(); err == nil {
1578								data := sdat[s.Value:]
1579								strdata[n] = string(data)
1580							}
1581						}
1582					}
1583					break
1584				}
1585				if n := indexOfDebugStrlen(s.Name); n != -1 {
1586					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1587						sect := f.Sections[i]
1588						if s.Value < sect.Size {
1589							if sdat, err := sect.Data(); err == nil {
1590								data := sdat[s.Value:]
1591								strlen := bo.Uint64(data[:8])
1592								if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1593									fatalf("string literal too big")
1594								}
1595								strlens[n] = int(strlen)
1596							}
1597						}
1598					}
1599					break
1600				}
1601			}
1602		}
1603
1604		buildStrings()
1605
1606		return d, ints, floats, strs
1607	}
1608
1609	if f, err := xcoff.Open(gccTmp()); err == nil {
1610		defer f.Close()
1611		d, err := f.DWARF()
1612		if err != nil {
1613			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1614		}
1615		bo := binary.BigEndian
1616		for _, s := range f.Symbols {
1617			switch {
1618			case isDebugInts(s.Name):
1619				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1620					sect := f.Sections[i]
1621					if s.Value < sect.Size {
1622						if sdat, err := sect.Data(); err == nil {
1623							data := sdat[s.Value:]
1624							ints = make([]int64, len(data)/8)
1625							for i := range ints {
1626								ints[i] = int64(bo.Uint64(data[i*8:]))
1627							}
1628						}
1629					}
1630				}
1631			case isDebugFloats(s.Name):
1632				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1633					sect := f.Sections[i]
1634					if s.Value < sect.Size {
1635						if sdat, err := sect.Data(); err == nil {
1636							data := sdat[s.Value:]
1637							floats = make([]float64, len(data)/8)
1638							for i := range floats {
1639								floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1640							}
1641						}
1642					}
1643				}
1644			default:
1645				if n := indexOfDebugStr(s.Name); n != -1 {
1646					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1647						sect := f.Sections[i]
1648						if s.Value < sect.Size {
1649							if sdat, err := sect.Data(); err == nil {
1650								data := sdat[s.Value:]
1651								strdata[n] = string(data)
1652							}
1653						}
1654					}
1655					break
1656				}
1657				if n := indexOfDebugStrlen(s.Name); n != -1 {
1658					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1659						sect := f.Sections[i]
1660						if s.Value < sect.Size {
1661							if sdat, err := sect.Data(); err == nil {
1662								data := sdat[s.Value:]
1663								strlen := bo.Uint64(data[:8])
1664								if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1665									fatalf("string literal too big")
1666								}
1667								strlens[n] = int(strlen)
1668							}
1669						}
1670					}
1671					break
1672				}
1673			}
1674		}
1675
1676		buildStrings()
1677
1678		return d, ints, floats, strs
1679	}
1680
1681	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
1682	panic("not reached")
1683}
1684
1685// gccDefines runs gcc -E -dM -xc - over the C program stdin
1686// and returns the corresponding standard output, which is the
1687// #defines that gcc encountered while processing the input
1688// and its included files.
1689func (p *Package) gccDefines(stdin []byte) string {
1690	base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
1691	base = append(base, p.gccMachine()...)
1692	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
1693	return stdout
1694}
1695
1696// gccErrors runs gcc over the C program stdin and returns
1697// the errors that gcc prints. That is, this function expects
1698// gcc to fail.
1699func (p *Package) gccErrors(stdin []byte) string {
1700	// TODO(rsc): require failure
1701	args := p.gccCmd()
1702
1703	// Optimization options can confuse the error messages; remove them.
1704	nargs := make([]string, 0, len(args))
1705	for _, arg := range args {
1706		if !strings.HasPrefix(arg, "-O") {
1707			nargs = append(nargs, arg)
1708		}
1709	}
1710
1711	if *debugGcc {
1712		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
1713		os.Stderr.Write(stdin)
1714		fmt.Fprint(os.Stderr, "EOF\n")
1715	}
1716	stdout, stderr, _ := run(stdin, nargs)
1717	if *debugGcc {
1718		os.Stderr.Write(stdout)
1719		os.Stderr.Write(stderr)
1720	}
1721	return string(stderr)
1722}
1723
1724// runGcc runs the gcc command line args with stdin on standard input.
1725// If the command exits with a non-zero exit status, runGcc prints
1726// details about what was run and exits.
1727// Otherwise runGcc returns the data written to standard output and standard error.
1728// Note that for some of the uses we expect useful data back
1729// on standard error, but for those uses gcc must still exit 0.
1730func runGcc(stdin []byte, args []string) (string, string) {
1731	if *debugGcc {
1732		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
1733		os.Stderr.Write(stdin)
1734		fmt.Fprint(os.Stderr, "EOF\n")
1735	}
1736	stdout, stderr, ok := run(stdin, args)
1737	if *debugGcc {
1738		os.Stderr.Write(stdout)
1739		os.Stderr.Write(stderr)
1740	}
1741	if !ok {
1742		os.Stderr.Write(stderr)
1743		os.Exit(2)
1744	}
1745	return string(stdout), string(stderr)
1746}
1747
1748// A typeConv is a translator from dwarf types to Go types
1749// with equivalent memory layout.
1750type typeConv struct {
1751	// Cache of already-translated or in-progress types.
1752	m map[dwarf.Type]*Type
1753
1754	// Map from types to incomplete pointers to those types.
1755	ptrs map[dwarf.Type][]*Type
1756	// Keys of ptrs in insertion order (deterministic worklist)
1757	ptrKeys []dwarf.Type
1758
1759	// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
1760	getTypeIDs map[string]bool
1761
1762	// Predeclared types.
1763	bool                                   ast.Expr
1764	byte                                   ast.Expr // denotes padding
1765	int8, int16, int32, int64              ast.Expr
1766	uint8, uint16, uint32, uint64, uintptr ast.Expr
1767	float32, float64                       ast.Expr
1768	complex64, complex128                  ast.Expr
1769	void                                   ast.Expr
1770	string                                 ast.Expr
1771	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
1772	goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
1773
1774	ptrSize int64
1775	intSize int64
1776}
1777
1778var tagGen int
1779var typedef = make(map[string]*Type)
1780var goIdent = make(map[string]*ast.Ident)
1781
1782// unionWithPointer is true for a Go type that represents a C union (or class)
1783// that may contain a pointer. This is used for cgo pointer checking.
1784var unionWithPointer = make(map[ast.Expr]bool)
1785
1786func (c *typeConv) Init(ptrSize, intSize int64) {
1787	c.ptrSize = ptrSize
1788	c.intSize = intSize
1789	c.m = make(map[dwarf.Type]*Type)
1790	c.ptrs = make(map[dwarf.Type][]*Type)
1791	c.getTypeIDs = make(map[string]bool)
1792	c.bool = c.Ident("bool")
1793	c.byte = c.Ident("byte")
1794	c.int8 = c.Ident("int8")
1795	c.int16 = c.Ident("int16")
1796	c.int32 = c.Ident("int32")
1797	c.int64 = c.Ident("int64")
1798	c.uint8 = c.Ident("uint8")
1799	c.uint16 = c.Ident("uint16")
1800	c.uint32 = c.Ident("uint32")
1801	c.uint64 = c.Ident("uint64")
1802	c.uintptr = c.Ident("uintptr")
1803	c.float32 = c.Ident("float32")
1804	c.float64 = c.Ident("float64")
1805	c.complex64 = c.Ident("complex64")
1806	c.complex128 = c.Ident("complex128")
1807	c.void = c.Ident("void")
1808	c.string = c.Ident("string")
1809	c.goVoid = c.Ident("_Ctype_void")
1810
1811	// Normally cgo translates void* to unsafe.Pointer,
1812	// but for historical reasons -godefs uses *byte instead.
1813	if *godefs {
1814		c.goVoidPtr = &ast.StarExpr{X: c.byte}
1815	} else {
1816		c.goVoidPtr = c.Ident("unsafe.Pointer")
1817	}
1818}
1819
1820// base strips away qualifiers and typedefs to get the underlying type
1821func base(dt dwarf.Type) dwarf.Type {
1822	for {
1823		if d, ok := dt.(*dwarf.QualType); ok {
1824			dt = d.Type
1825			continue
1826		}
1827		if d, ok := dt.(*dwarf.TypedefType); ok {
1828			dt = d.Type
1829			continue
1830		}
1831		break
1832	}
1833	return dt
1834}
1835
1836// unqual strips away qualifiers from a DWARF type.
1837// In general we don't care about top-level qualifiers.
1838func unqual(dt dwarf.Type) dwarf.Type {
1839	for {
1840		if d, ok := dt.(*dwarf.QualType); ok {
1841			dt = d.Type
1842		} else {
1843			break
1844		}
1845	}
1846	return dt
1847}
1848
1849// Map from dwarf text names to aliases we use in package "C".
1850var dwarfToName = map[string]string{
1851	"long int":               "long",
1852	"long unsigned int":      "ulong",
1853	"unsigned int":           "uint",
1854	"short unsigned int":     "ushort",
1855	"unsigned short":         "ushort", // Used by Clang; issue 13129.
1856	"short int":              "short",
1857	"long long int":          "longlong",
1858	"long long unsigned int": "ulonglong",
1859	"signed char":            "schar",
1860	"unsigned char":          "uchar",
1861}
1862
1863const signedDelta = 64
1864
1865// String returns the current type representation. Format arguments
1866// are assembled within this method so that any changes in mutable
1867// values are taken into account.
1868func (tr *TypeRepr) String() string {
1869	if len(tr.Repr) == 0 {
1870		return ""
1871	}
1872	if len(tr.FormatArgs) == 0 {
1873		return tr.Repr
1874	}
1875	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
1876}
1877
1878// Empty reports whether the result of String would be "".
1879func (tr *TypeRepr) Empty() bool {
1880	return len(tr.Repr) == 0
1881}
1882
1883// Set modifies the type representation.
1884// If fargs are provided, repr is used as a format for fmt.Sprintf.
1885// Otherwise, repr is used unprocessed as the type representation.
1886func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
1887	tr.Repr = repr
1888	tr.FormatArgs = fargs
1889}
1890
1891// FinishType completes any outstanding type mapping work.
1892// In particular, it resolves incomplete pointer types.
1893func (c *typeConv) FinishType(pos token.Pos) {
1894	// Completing one pointer type might produce more to complete.
1895	// Keep looping until they're all done.
1896	for len(c.ptrKeys) > 0 {
1897		dtype := c.ptrKeys[0]
1898		c.ptrKeys = c.ptrKeys[1:]
1899
1900		// Note Type might invalidate c.ptrs[dtype].
1901		t := c.Type(dtype, pos)
1902		for _, ptr := range c.ptrs[dtype] {
1903			ptr.Go.(*ast.StarExpr).X = t.Go
1904			ptr.C.Set("%s*", t.C)
1905		}
1906		c.ptrs[dtype] = nil // retain the map key
1907	}
1908}
1909
1910// Type returns a *Type with the same memory layout as
1911// dtype when used as the type of a variable or a struct field.
1912func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1913	if t, ok := c.m[dtype]; ok {
1914		if t.Go == nil {
1915			fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
1916		}
1917		return t
1918	}
1919
1920	t := new(Type)
1921	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
1922	t.Align = -1
1923	t.C = &TypeRepr{Repr: dtype.Common().Name}
1924	c.m[dtype] = t
1925
1926	switch dt := dtype.(type) {
1927	default:
1928		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
1929
1930	case *dwarf.AddrType:
1931		if t.Size != c.ptrSize {
1932			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
1933		}
1934		t.Go = c.uintptr
1935		t.Align = t.Size
1936
1937	case *dwarf.ArrayType:
1938		if dt.StrideBitSize > 0 {
1939			// Cannot represent bit-sized elements in Go.
1940			t.Go = c.Opaque(t.Size)
1941			break
1942		}
1943		count := dt.Count
1944		if count == -1 {
1945			// Indicates flexible array member, which Go doesn't support.
1946			// Translate to zero-length array instead.
1947			count = 0
1948		}
1949		sub := c.Type(dt.Type, pos)
1950		t.Align = sub.Align
1951		t.Go = &ast.ArrayType{
1952			Len: c.intExpr(count),
1953			Elt: sub.Go,
1954		}
1955		// Recalculate t.Size now that we know sub.Size.
1956		t.Size = count * sub.Size
1957		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
1958
1959	case *dwarf.BoolType:
1960		t.Go = c.bool
1961		t.Align = 1
1962
1963	case *dwarf.CharType:
1964		if t.Size != 1 {
1965			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
1966		}
1967		t.Go = c.int8
1968		t.Align = 1
1969
1970	case *dwarf.EnumType:
1971		if t.Align = t.Size; t.Align >= c.ptrSize {
1972			t.Align = c.ptrSize
1973		}
1974		t.C.Set("enum " + dt.EnumName)
1975		signed := 0
1976		t.EnumValues = make(map[string]int64)
1977		for _, ev := range dt.Val {
1978			t.EnumValues[ev.Name] = ev.Val
1979			if ev.Val < 0 {
1980				signed = signedDelta
1981			}
1982		}
1983		switch t.Size + int64(signed) {
1984		default:
1985			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
1986		case 1:
1987			t.Go = c.uint8
1988		case 2:
1989			t.Go = c.uint16
1990		case 4:
1991			t.Go = c.uint32
1992		case 8:
1993			t.Go = c.uint64
1994		case 1 + signedDelta:
1995			t.Go = c.int8
1996		case 2 + signedDelta:
1997			t.Go = c.int16
1998		case 4 + signedDelta:
1999			t.Go = c.int32
2000		case 8 + signedDelta:
2001			t.Go = c.int64
2002		}
2003
2004	case *dwarf.FloatType:
2005		switch t.Size {
2006		default:
2007			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
2008		case 4:
2009			t.Go = c.float32
2010		case 8:
2011			t.Go = c.float64
2012		}
2013		if t.Align = t.Size; t.Align >= c.ptrSize {
2014			t.Align = c.ptrSize
2015		}
2016
2017	case *dwarf.ComplexType:
2018		switch t.Size {
2019		default:
2020			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
2021		case 8:
2022			t.Go = c.complex64
2023		case 16:
2024			t.Go = c.complex128
2025		}
2026		if t.Align = t.Size / 2; t.Align >= c.ptrSize {
2027			t.Align = c.ptrSize
2028		}
2029
2030	case *dwarf.FuncType:
2031		// No attempt at translation: would enable calls
2032		// directly between worlds, but we need to moderate those.
2033		t.Go = c.uintptr
2034		t.Align = c.ptrSize
2035
2036	case *dwarf.IntType:
2037		if dt.BitSize > 0 {
2038			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
2039		}
2040		switch t.Size {
2041		default:
2042			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2043		case 1:
2044			t.Go = c.int8
2045		case 2:
2046			t.Go = c.int16
2047		case 4:
2048			t.Go = c.int32
2049		case 8:
2050			t.Go = c.int64
2051		case 16:
2052			t.Go = &ast.ArrayType{
2053				Len: c.intExpr(t.Size),
2054				Elt: c.uint8,
2055			}
2056		}
2057		if t.Align = t.Size; t.Align >= c.ptrSize {
2058			t.Align = c.ptrSize
2059		}
2060
2061	case *dwarf.PtrType:
2062		// Clang doesn't emit DW_AT_byte_size for pointer types.
2063		if t.Size != c.ptrSize && t.Size != -1 {
2064			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2065		}
2066		t.Size = c.ptrSize
2067		t.Align = c.ptrSize
2068
2069		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2070			t.Go = c.goVoidPtr
2071			t.C.Set("void*")
2072			dq := dt.Type
2073			for {
2074				if d, ok := dq.(*dwarf.QualType); ok {
2075					t.C.Set(d.Qual + " " + t.C.String())
2076					dq = d.Type
2077				} else {
2078					break
2079				}
2080			}
2081			break
2082		}
2083
2084		// Placeholder initialization; completed in FinishType.
2085		t.Go = &ast.StarExpr{}
2086		t.C.Set("<incomplete>*")
2087		if _, ok := c.ptrs[dt.Type]; !ok {
2088			c.ptrKeys = append(c.ptrKeys, dt.Type)
2089		}
2090		c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
2091
2092	case *dwarf.QualType:
2093		t1 := c.Type(dt.Type, pos)
2094		t.Size = t1.Size
2095		t.Align = t1.Align
2096		t.Go = t1.Go
2097		if unionWithPointer[t1.Go] {
2098			unionWithPointer[t.Go] = true
2099		}
2100		t.EnumValues = nil
2101		t.Typedef = ""
2102		t.C.Set("%s "+dt.Qual, t1.C)
2103		return t
2104
2105	case *dwarf.StructType:
2106		// Convert to Go struct, being careful about alignment.
2107		// Have to give it a name to simulate C "struct foo" references.
2108		tag := dt.StructName
2109		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2110			break
2111		}
2112		if tag == "" {
2113			tag = "__" + strconv.Itoa(tagGen)
2114			tagGen++
2115		} else if t.C.Empty() {
2116			t.C.Set(dt.Kind + " " + tag)
2117		}
2118		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2119		t.Go = name // publish before recursive calls
2120		goIdent[name.Name] = name
2121		if dt.ByteSize < 0 {
2122			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2123			// so execute the basic things that the struct case would do
2124			// other than try to determine a Go representation.
2125			tt := *t
2126			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2127			tt.Go = c.Ident("struct{}")
2128			typedef[name.Name] = &tt
2129			break
2130		}
2131		switch dt.Kind {
2132		case "class", "union":
2133			t.Go = c.Opaque(t.Size)
2134			if c.dwarfHasPointer(dt, pos) {
2135				unionWithPointer[t.Go] = true
2136			}
2137			if t.C.Empty() {
2138				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2139			}
2140			t.Align = 1 // TODO: should probably base this on field alignment.
2141			typedef[name.Name] = t
2142		case "struct":
2143			g, csyntax, align := c.Struct(dt, pos)
2144			if t.C.Empty() {
2145				t.C.Set(csyntax)
2146			}
2147			t.Align = align
2148			tt := *t
2149			if tag != "" {
2150				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2151			}
2152			tt.Go = g
2153			typedef[name.Name] = &tt
2154		}
2155
2156	case *dwarf.TypedefType:
2157		// Record typedef for printing.
2158		if dt.Name == "_GoString_" {
2159			// Special C name for Go string type.
2160			// Knows string layout used by compilers: pointer plus length,
2161			// which rounds up to 2 pointers after alignment.
2162			t.Go = c.string
2163			t.Size = c.ptrSize * 2
2164			t.Align = c.ptrSize
2165			break
2166		}
2167		if dt.Name == "_GoBytes_" {
2168			// Special C name for Go []byte type.
2169			// Knows slice layout used by compilers: pointer, length, cap.
2170			t.Go = c.Ident("[]byte")
2171			t.Size = c.ptrSize + 4 + 4
2172			t.Align = c.ptrSize
2173			break
2174		}
2175		name := c.Ident("_Ctype_" + dt.Name)
2176		goIdent[name.Name] = name
2177		sub := c.Type(dt.Type, pos)
2178		if c.badPointerTypedef(dt) {
2179			// Treat this typedef as a uintptr.
2180			s := *sub
2181			s.Go = c.uintptr
2182			sub = &s
2183		}
2184		t.Go = name
2185		if unionWithPointer[sub.Go] {
2186			unionWithPointer[t.Go] = true
2187		}
2188		t.Size = sub.Size
2189		t.Align = sub.Align
2190		oldType := typedef[name.Name]
2191		if oldType == nil {
2192			tt := *t
2193			tt.Go = sub.Go
2194			typedef[name.Name] = &tt
2195		}
2196
2197		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2198		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
2199		// with the base type.
2200		// In -godefs mode, do this for all typedefs.
2201		if isStructUnionClass(sub.Go) || *godefs {
2202			t.Go = sub.Go
2203
2204			if isStructUnionClass(sub.Go) {
2205				// Use the typedef name for C code.
2206				typedef[sub.Go.(*ast.Ident).Name].C = t.C
2207			}
2208
2209			// If we've seen this typedef before, and it
2210			// was an anonymous struct/union/class before
2211			// too, use the old definition.
2212			// TODO: it would be safer to only do this if
2213			// we verify that the types are the same.
2214			if oldType != nil && isStructUnionClass(oldType.Go) {
2215				t.Go = oldType.Go
2216			}
2217		}
2218
2219	case *dwarf.UcharType:
2220		if t.Size != 1 {
2221			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2222		}
2223		t.Go = c.uint8
2224		t.Align = 1
2225
2226	case *dwarf.UintType:
2227		if dt.BitSize > 0 {
2228			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2229		}
2230		switch t.Size {
2231		default:
2232			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2233		case 1:
2234			t.Go = c.uint8
2235		case 2:
2236			t.Go = c.uint16
2237		case 4:
2238			t.Go = c.uint32
2239		case 8:
2240			t.Go = c.uint64
2241		case 16:
2242			t.Go = &ast.ArrayType{
2243				Len: c.intExpr(t.Size),
2244				Elt: c.uint8,
2245			}
2246		}
2247		if t.Align = t.Size; t.Align >= c.ptrSize {
2248			t.Align = c.ptrSize
2249		}
2250
2251	case *dwarf.VoidType:
2252		t.Go = c.goVoid
2253		t.C.Set("void")
2254		t.Align = 1
2255	}
2256
2257	switch dtype.(type) {
2258	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2259		s := dtype.Common().Name
2260		if s != "" {
2261			if ss, ok := dwarfToName[s]; ok {
2262				s = ss
2263			}
2264			s = strings.Replace(s, " ", "", -1)
2265			name := c.Ident("_Ctype_" + s)
2266			tt := *t
2267			typedef[name.Name] = &tt
2268			if !*godefs {
2269				t.Go = name
2270			}
2271		}
2272	}
2273
2274	if t.Size < 0 {
2275		// Unsized types are [0]byte, unless they're typedefs of other types
2276		// or structs with tags.
2277		// if so, use the name we've already defined.
2278		t.Size = 0
2279		switch dt := dtype.(type) {
2280		case *dwarf.TypedefType:
2281			// ok
2282		case *dwarf.StructType:
2283			if dt.StructName != "" {
2284				break
2285			}
2286			t.Go = c.Opaque(0)
2287		default:
2288			t.Go = c.Opaque(0)
2289		}
2290		if t.C.Empty() {
2291			t.C.Set("void")
2292		}
2293	}
2294
2295	if t.C.Empty() {
2296		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2297	}
2298
2299	return t
2300}
2301
2302// isStructUnionClass reports whether the type described by the Go syntax x
2303// is a struct, union, or class with a tag.
2304func isStructUnionClass(x ast.Expr) bool {
2305	id, ok := x.(*ast.Ident)
2306	if !ok {
2307		return false
2308	}
2309	name := id.Name
2310	return strings.HasPrefix(name, "_Ctype_struct_") ||
2311		strings.HasPrefix(name, "_Ctype_union_") ||
2312		strings.HasPrefix(name, "_Ctype_class_")
2313}
2314
2315// FuncArg returns a Go type with the same memory layout as
2316// dtype when used as the type of a C function argument.
2317func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2318	t := c.Type(unqual(dtype), pos)
2319	switch dt := dtype.(type) {
2320	case *dwarf.ArrayType:
2321		// Arrays are passed implicitly as pointers in C.
2322		// In Go, we must be explicit.
2323		tr := &TypeRepr{}
2324		tr.Set("%s*", t.C)
2325		return &Type{
2326			Size:  c.ptrSize,
2327			Align: c.ptrSize,
2328			Go:    &ast.StarExpr{X: t.Go},
2329			C:     tr,
2330		}
2331	case *dwarf.TypedefType:
2332		// C has much more relaxed rules than Go for
2333		// implicit type conversions. When the parameter
2334		// is type T defined as *X, simulate a little of the
2335		// laxness of C by making the argument *X instead of T.
2336		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2337			// Unless the typedef happens to point to void* since
2338			// Go has special rules around using unsafe.Pointer.
2339			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2340				break
2341			}
2342			// ...or the typedef is one in which we expect bad pointers.
2343			// It will be a uintptr instead of *X.
2344			if c.badPointerTypedef(dt) {
2345				break
2346			}
2347
2348			t = c.Type(ptr, pos)
2349			if t == nil {
2350				return nil
2351			}
2352
2353			// For a struct/union/class, remember the C spelling,
2354			// in case it has __attribute__((unavailable)).
2355			// See issue 2888.
2356			if isStructUnionClass(t.Go) {
2357				t.Typedef = dt.Name
2358			}
2359		}
2360	}
2361	return t
2362}
2363
2364// FuncType returns the Go type analogous to dtype.
2365// There is no guarantee about matching memory layout.
2366func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2367	p := make([]*Type, len(dtype.ParamType))
2368	gp := make([]*ast.Field, len(dtype.ParamType))
2369	for i, f := range dtype.ParamType {
2370		// gcc's DWARF generator outputs a single DotDotDotType parameter for
2371		// function pointers that specify no parameters (e.g. void
2372		// (*__cgo_0)()).  Treat this special case as void. This case is
2373		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2374		// legal).
2375		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2376			p, gp = nil, nil
2377			break
2378		}
2379		p[i] = c.FuncArg(f, pos)
2380		gp[i] = &ast.Field{Type: p[i].Go}
2381	}
2382	var r *Type
2383	var gr []*ast.Field
2384	if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2385		gr = []*ast.Field{{Type: c.goVoid}}
2386	} else if dtype.ReturnType != nil {
2387		r = c.Type(unqual(dtype.ReturnType), pos)
2388		gr = []*ast.Field{{Type: r.Go}}
2389	}
2390	return &FuncType{
2391		Params: p,
2392		Result: r,
2393		Go: &ast.FuncType{
2394			Params:  &ast.FieldList{List: gp},
2395			Results: &ast.FieldList{List: gr},
2396		},
2397	}
2398}
2399
2400// Identifier
2401func (c *typeConv) Ident(s string) *ast.Ident {
2402	return ast.NewIdent(s)
2403}
2404
2405// Opaque type of n bytes.
2406func (c *typeConv) Opaque(n int64) ast.Expr {
2407	return &ast.ArrayType{
2408		Len: c.intExpr(n),
2409		Elt: c.byte,
2410	}
2411}
2412
2413// Expr for integer n.
2414func (c *typeConv) intExpr(n int64) ast.Expr {
2415	return &ast.BasicLit{
2416		Kind:  token.INT,
2417		Value: strconv.FormatInt(n, 10),
2418	}
2419}
2420
2421// Add padding of given size to fld.
2422func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
2423	n := len(fld)
2424	fld = fld[0 : n+1]
2425	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
2426	sizes = sizes[0 : n+1]
2427	sizes[n] = size
2428	return fld, sizes
2429}
2430
2431// Struct conversion: return Go and (gc) C syntax for type.
2432func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
2433	// Minimum alignment for a struct is 1 byte.
2434	align = 1
2435
2436	var buf bytes.Buffer
2437	buf.WriteString("struct {")
2438	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
2439	sizes := make([]int64, 0, 2*len(dt.Field)+1)
2440	off := int64(0)
2441
2442	// Rename struct fields that happen to be named Go keywords into
2443	// _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
2444	// be mangled. Any existing identifier that already has the same name on
2445	// the C-side will cause the Go-mangled version to be prefixed with _.
2446	// (e.g. in a struct with fields '_type' and 'type', the latter would be
2447	// rendered as '__type' in Go).
2448	ident := make(map[string]string)
2449	used := make(map[string]bool)
2450	for _, f := range dt.Field {
2451		ident[f.Name] = f.Name
2452		used[f.Name] = true
2453	}
2454
2455	if !*godefs {
2456		for cid, goid := range ident {
2457			if token.Lookup(goid).IsKeyword() {
2458				// Avoid keyword
2459				goid = "_" + goid
2460
2461				// Also avoid existing fields
2462				for _, exist := used[goid]; exist; _, exist = used[goid] {
2463					goid = "_" + goid
2464				}
2465
2466				used[goid] = true
2467				ident[cid] = goid
2468			}
2469		}
2470	}
2471
2472	anon := 0
2473	for _, f := range dt.Field {
2474		if f.ByteOffset > off {
2475			fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
2476			off = f.ByteOffset
2477		}
2478
2479		name := f.Name
2480		ft := f.Type
2481
2482		// In godefs mode, if this field is a C11
2483		// anonymous union then treat the first field in the
2484		// union as the field in the struct. This handles
2485		// cases like the glibc <sys/resource.h> file; see
2486		// issue 6677.
2487		if *godefs {
2488			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
2489				name = st.Field[0].Name
2490				ident[name] = name
2491				ft = st.Field[0].Type
2492			}
2493		}
2494
2495		// TODO: Handle fields that are anonymous structs by
2496		// promoting the fields of the inner struct.
2497
2498		t := c.Type(ft, pos)
2499		tgo := t.Go
2500		size := t.Size
2501		talign := t.Align
2502		if f.BitSize > 0 {
2503			switch f.BitSize {
2504			case 8, 16, 32, 64:
2505			default:
2506				continue
2507			}
2508			size = f.BitSize / 8
2509			name := tgo.(*ast.Ident).String()
2510			if strings.HasPrefix(name, "int") {
2511				name = "int"
2512			} else {
2513				name = "uint"
2514			}
2515			tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
2516			talign = size
2517		}
2518
2519		if talign > 0 && f.ByteOffset%talign != 0 {
2520			// Drop misaligned fields, the same way we drop integer bit fields.
2521			// The goal is to make available what can be made available.
2522			// Otherwise one bad and unneeded field in an otherwise okay struct
2523			// makes the whole program not compile. Much of the time these
2524			// structs are in system headers that cannot be corrected.
2525			continue
2526		}
2527		n := len(fld)
2528		fld = fld[0 : n+1]
2529		if name == "" {
2530			name = fmt.Sprintf("anon%d", anon)
2531			anon++
2532			ident[name] = name
2533		}
2534		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
2535		sizes = sizes[0 : n+1]
2536		sizes[n] = size
2537		off += size
2538		buf.WriteString(t.C.String())
2539		buf.WriteString(" ")
2540		buf.WriteString(name)
2541		buf.WriteString("; ")
2542		if talign > align {
2543			align = talign
2544		}
2545	}
2546	if off < dt.ByteSize {
2547		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
2548		off = dt.ByteSize
2549	}
2550
2551	// If the last field in a non-zero-sized struct is zero-sized
2552	// the compiler is going to pad it by one (see issue 9401).
2553	// We can't permit that, because then the size of the Go
2554	// struct will not be the same as the size of the C struct.
2555	// Our only option in such a case is to remove the field,
2556	// which means that it cannot be referenced from Go.
2557	for off > 0 && sizes[len(sizes)-1] == 0 {
2558		n := len(sizes)
2559		fld = fld[0 : n-1]
2560		sizes = sizes[0 : n-1]
2561	}
2562
2563	if off != dt.ByteSize {
2564		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
2565	}
2566	buf.WriteString("}")
2567	csyntax = buf.String()
2568
2569	if *godefs {
2570		godefsFields(fld)
2571	}
2572	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
2573	return
2574}
2575
2576// dwarfHasPointer returns whether the DWARF type dt contains a pointer.
2577func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
2578	switch dt := dt.(type) {
2579	default:
2580		fatalf("%s: unexpected type: %s", lineno(pos), dt)
2581		return false
2582
2583	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
2584		*dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
2585		*dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
2586
2587		return false
2588
2589	case *dwarf.ArrayType:
2590		return c.dwarfHasPointer(dt.Type, pos)
2591
2592	case *dwarf.PtrType:
2593		return true
2594
2595	case *dwarf.QualType:
2596		return c.dwarfHasPointer(dt.Type, pos)
2597
2598	case *dwarf.StructType:
2599		for _, f := range dt.Field {
2600			if c.dwarfHasPointer(f.Type, pos) {
2601				return true
2602			}
2603		}
2604		return false
2605
2606	case *dwarf.TypedefType:
2607		if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
2608			return true
2609		}
2610		return c.dwarfHasPointer(dt.Type, pos)
2611	}
2612}
2613
2614func upper(s string) string {
2615	if s == "" {
2616		return ""
2617	}
2618	r, size := utf8.DecodeRuneInString(s)
2619	if r == '_' {
2620		return "X" + s
2621	}
2622	return string(unicode.ToUpper(r)) + s[size:]
2623}
2624
2625// godefsFields rewrites field names for use in Go or C definitions.
2626// It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2627// converts names to upper case, and rewrites _ into Pad_godefs_n,
2628// so that all fields are exported.
2629func godefsFields(fld []*ast.Field) {
2630	prefix := fieldPrefix(fld)
2631	npad := 0
2632	for _, f := range fld {
2633		for _, n := range f.Names {
2634			if n.Name != prefix {
2635				n.Name = strings.TrimPrefix(n.Name, prefix)
2636			}
2637			if n.Name == "_" {
2638				// Use exported name instead.
2639				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
2640				npad++
2641			}
2642			n.Name = upper(n.Name)
2643		}
2644	}
2645}
2646
2647// fieldPrefix returns the prefix that should be removed from all the
2648// field names when generating the C or Go code. For generated
2649// C, we leave the names as is (tv_sec, tv_usec), since that's what
2650// people are used to seeing in C.  For generated Go code, such as
2651// package syscall's data structures, we drop a common prefix
2652// (so sec, usec, which will get turned into Sec, Usec for exporting).
2653func fieldPrefix(fld []*ast.Field) string {
2654	prefix := ""
2655	for _, f := range fld {
2656		for _, n := range f.Names {
2657			// Ignore field names that don't have the prefix we're
2658			// looking for. It is common in C headers to have fields
2659			// named, say, _pad in an otherwise prefixed header.
2660			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
2661			// still want to remove the tv_ prefix.
2662			// The check for "orig_" here handles orig_eax in the
2663			// x86 ptrace register sets, which otherwise have all fields
2664			// with reg_ prefixes.
2665			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
2666				continue
2667			}
2668			i := strings.Index(n.Name, "_")
2669			if i < 0 {
2670				continue
2671			}
2672			if prefix == "" {
2673				prefix = n.Name[:i+1]
2674			} else if prefix != n.Name[:i+1] {
2675				return ""
2676			}
2677		}
2678	}
2679	return prefix
2680}
2681
2682// badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
2683// A typedef is bad if C code sometimes stores non-pointers in this type.
2684// TODO: Currently our best solution is to find these manually and list them as
2685// they come up. A better solution is desired.
2686func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
2687	if c.badCFType(dt) {
2688		return true
2689	}
2690	if c.badJNI(dt) {
2691		return true
2692	}
2693	return false
2694}
2695
2696func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
2697	// The real bad types are CFNumberRef and CFDateRef.
2698	// Sometimes non-pointers are stored in these types.
2699	// CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
2700	// We return true for the other *Ref types just so casting between them is easier.
2701	// We identify the correct set of types as those ending in Ref and for which
2702	// there exists a corresponding GetTypeID function.
2703	// See comment below for details about the bad pointers.
2704	if goos != "darwin" {
2705		return false
2706	}
2707	s := dt.Name
2708	if !strings.HasSuffix(s, "Ref") {
2709		return false
2710	}
2711	s = s[:len(s)-3]
2712	if s == "CFType" {
2713		return true
2714	}
2715	if c.getTypeIDs[s] {
2716		return true
2717	}
2718	if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
2719		// Mutable and immutable variants share a type ID.
2720		return true
2721	}
2722	return false
2723}
2724
2725// Comment from Darwin's CFInternal.h
2726/*
2727// Tagged pointer support
2728// Low-bit set means tagged object, next 3 bits (currently)
2729// define the tagged object class, next 4 bits are for type
2730// information for the specific tagged object class.  Thus,
2731// the low byte is for type info, and the rest of a pointer
2732// (32 or 64-bit) is for payload, whatever the tagged class.
2733//
2734// Note that the specific integers used to identify the
2735// specific tagged classes can and will change from release
2736// to release (that's why this stuff is in CF*Internal*.h),
2737// as can the definition of type info vs payload above.
2738//
2739#if __LP64__
2740#define CF_IS_TAGGED_OBJ(PTR)	((uintptr_t)(PTR) & 0x1)
2741#define CF_TAGGED_OBJ_TYPE(PTR)	((uintptr_t)(PTR) & 0xF)
2742#else
2743#define CF_IS_TAGGED_OBJ(PTR)	0
2744#define CF_TAGGED_OBJ_TYPE(PTR)	0
2745#endif
2746
2747enum {
2748    kCFTaggedObjectID_Invalid = 0,
2749    kCFTaggedObjectID_Atom = (0 << 1) + 1,
2750    kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
2751    kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
2752    kCFTaggedObjectID_Integer = (3 << 1) + 1,
2753    kCFTaggedObjectID_DateTS = (4 << 1) + 1,
2754    kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
2755    kCFTaggedObjectID_Date = (6 << 1) + 1,
2756    kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
2757};
2758*/
2759
2760func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
2761	// In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
2762	// property that it is sometimes (always?) a small integer instead of a real pointer.
2763	// Note: although only the android JVMs are bad in this respect, we declare the JNI types
2764	// bad regardless of platform, so the same Go code compiles on both android and non-android.
2765	if parent, ok := jniTypes[dt.Name]; ok {
2766		// Try to make sure we're talking about a JNI type, not just some random user's
2767		// type that happens to use the same name.
2768		// C doesn't have the notion of a package, so it's hard to be certain.
2769
2770		// Walk up to jobject, checking each typedef on the way.
2771		w := dt
2772		for parent != "" {
2773			t, ok := w.Type.(*dwarf.TypedefType)
2774			if !ok || t.Name != parent {
2775				return false
2776			}
2777			w = t
2778			parent, ok = jniTypes[w.Name]
2779			if !ok {
2780				return false
2781			}
2782		}
2783
2784		// Check that the typedef is:
2785		//     struct _jobject;
2786		//     typedef struct _jobject *jobject;
2787		if ptr, ok := w.Type.(*dwarf.PtrType); ok {
2788			if str, ok := ptr.Type.(*dwarf.StructType); ok {
2789				if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
2790					return true
2791				}
2792			}
2793		}
2794	}
2795	return false
2796}
2797
2798// jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
2799// they are mapped.  The base "jobject" maps to the empty string.
2800var jniTypes = map[string]string{
2801	"jobject":       "",
2802	"jclass":        "jobject",
2803	"jthrowable":    "jobject",
2804	"jstring":       "jobject",
2805	"jarray":        "jobject",
2806	"jbooleanArray": "jarray",
2807	"jbyteArray":    "jarray",
2808	"jcharArray":    "jarray",
2809	"jshortArray":   "jarray",
2810	"jintArray":     "jarray",
2811	"jlongArray":    "jarray",
2812	"jfloatArray":   "jarray",
2813	"jdoubleArray":  "jarray",
2814	"jobjectArray":  "jarray",
2815	"jweak":         "jobject",
2816}
2817