...

Source file src/cmd/cgo/gcc.go

Documentation: cmd/cgo

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

View as plain text