Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/cgo/gcc.go

Documentation: cmd/cgo

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

View as plain text