Source file src/cmd/cgo/gcc.go

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

View as plain text