Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/cgo/gcc.go

Documentation: cmd/cgo

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

View as plain text