github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/cmd/cgo/gcc.go (about)

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