Source file src/cmd/cgo/gcc.go

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

View as plain text