Source file src/cmd/cgo/gcc.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Annotate Ref in Prog with C types by parsing gcc debug output.
     6  // Conversion of debug output to Go types.
     7  
     8  package main
     9  
    10  import (
    11  	"bytes"
    12  	"debug/dwarf"
    13  	"debug/elf"
    14  	"debug/macho"
    15  	"debug/pe"
    16  	"encoding/binary"
    17  	"errors"
    18  	"flag"
    19  	"fmt"
    20  	"go/ast"
    21  	"go/parser"
    22  	"go/token"
    23  	"internal/xcoff"
    24  	"math"
    25  	"os"
    26  	"os/exec"
    27  	"strconv"
    28  	"strings"
    29  	"unicode"
    30  	"unicode/utf8"
    31  
    32  	"cmd/internal/quoted"
    33  )
    34  
    35  var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
    36  var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
    37  
    38  var nameToC = map[string]string{
    39  	"schar":         "signed char",
    40  	"uchar":         "unsigned char",
    41  	"ushort":        "unsigned short",
    42  	"uint":          "unsigned int",
    43  	"ulong":         "unsigned long",
    44  	"longlong":      "long long",
    45  	"ulonglong":     "unsigned long long",
    46  	"complexfloat":  "float _Complex",
    47  	"complexdouble": "double _Complex",
    48  }
    49  
    50  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 r.Name.Go == "_CMalloc" {
  1605  				error_(r.Pos(), "no two-result form for C.malloc")
  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  		switch t.Size {
  2583  		default:
  2584  			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
  2585  		case 1:
  2586  			t.Go = c.int8
  2587  		case 2:
  2588  			t.Go = c.int16
  2589  		case 4:
  2590  			t.Go = c.int32
  2591  		case 8:
  2592  			t.Go = c.int64
  2593  		case 16:
  2594  			t.Go = &ast.ArrayType{
  2595  				Len: c.intExpr(t.Size),
  2596  				Elt: c.uint8,
  2597  			}
  2598  		}
  2599  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2600  			t.Align = c.ptrSize
  2601  		}
  2602  
  2603  	case *dwarf.PtrType:
  2604  		// Clang doesn't emit DW_AT_byte_size for pointer types.
  2605  		if t.Size != c.ptrSize && t.Size != -1 {
  2606  			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
  2607  		}
  2608  		t.Size = c.ptrSize
  2609  		t.Align = c.ptrSize
  2610  
  2611  		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
  2612  			t.Go = c.goVoidPtr
  2613  			t.C.Set("void*")
  2614  			dq := dt.Type
  2615  			for {
  2616  				if d, ok := dq.(*dwarf.QualType); ok {
  2617  					t.C.Set(d.Qual + " " + t.C.String())
  2618  					dq = d.Type
  2619  				} else {
  2620  					break
  2621  				}
  2622  			}
  2623  			break
  2624  		}
  2625  
  2626  		// Placeholder initialization; completed in FinishType.
  2627  		t.Go = &ast.StarExpr{}
  2628  		t.C.Set("<incomplete>*")
  2629  		key := dt.Type.String()
  2630  		if _, ok := c.ptrs[key]; !ok {
  2631  			c.ptrKeys = append(c.ptrKeys, dt.Type)
  2632  		}
  2633  		c.ptrs[key] = append(c.ptrs[key], t)
  2634  
  2635  	case *dwarf.QualType:
  2636  		t1 := c.Type(dt.Type, pos)
  2637  		t.Size = t1.Size
  2638  		t.Align = t1.Align
  2639  		t.Go = t1.Go
  2640  		if unionWithPointer[t1.Go] {
  2641  			unionWithPointer[t.Go] = true
  2642  		}
  2643  		t.EnumValues = nil
  2644  		t.Typedef = ""
  2645  		t.C.Set("%s "+dt.Qual, t1.C)
  2646  		return t
  2647  
  2648  	case *dwarf.StructType:
  2649  		// Convert to Go struct, being careful about alignment.
  2650  		// Have to give it a name to simulate C "struct foo" references.
  2651  		tag := dt.StructName
  2652  		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
  2653  			break
  2654  		}
  2655  		if tag == "" {
  2656  			tag = anonymousStructTag[dt]
  2657  			if tag == "" {
  2658  				tag = "__" + strconv.Itoa(tagGen)
  2659  				tagGen++
  2660  				anonymousStructTag[dt] = tag
  2661  			}
  2662  		} else if t.C.Empty() {
  2663  			t.C.Set(dt.Kind + " " + tag)
  2664  		}
  2665  		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
  2666  		t.Go = name // publish before recursive calls
  2667  		goIdent[name.Name] = name
  2668  		if dt.ByteSize < 0 {
  2669  			// Don't override old type
  2670  			if _, ok := typedef[name.Name]; ok {
  2671  				break
  2672  			}
  2673  
  2674  			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
  2675  			// so execute the basic things that the struct case would do
  2676  			// other than try to determine a Go representation.
  2677  			tt := *t
  2678  			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
  2679  			// We don't know what the representation of this struct is, so don't let
  2680  			// anyone allocate one on the Go side. As a side effect of this annotation,
  2681  			// pointers to this type will not be considered pointers in Go. They won't
  2682  			// get writebarrier-ed or adjusted during a stack copy. This should handle
  2683  			// all the cases badPointerTypedef used to handle, but hopefully will
  2684  			// continue to work going forward without any more need for cgo changes.
  2685  			tt.Go = c.Ident(incomplete)
  2686  			typedef[name.Name] = &tt
  2687  			break
  2688  		}
  2689  		switch dt.Kind {
  2690  		case "class", "union":
  2691  			t.Go = c.Opaque(t.Size)
  2692  			if c.dwarfHasPointer(dt, pos) {
  2693  				unionWithPointer[t.Go] = true
  2694  			}
  2695  			if t.C.Empty() {
  2696  				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
  2697  			}
  2698  			t.Align = 1 // TODO: should probably base this on field alignment.
  2699  			typedef[name.Name] = t
  2700  		case "struct":
  2701  			g, csyntax, align := c.Struct(dt, pos)
  2702  			if t.C.Empty() {
  2703  				t.C.Set(csyntax)
  2704  			}
  2705  			t.Align = align
  2706  			tt := *t
  2707  			if tag != "" {
  2708  				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
  2709  			}
  2710  			tt.Go = g
  2711  			if c.incompleteStructs[tag] {
  2712  				tt.Go = c.Ident(incomplete)
  2713  			}
  2714  			typedef[name.Name] = &tt
  2715  		}
  2716  
  2717  	case *dwarf.TypedefType:
  2718  		// Record typedef for printing.
  2719  		if dt.Name == "_GoString_" {
  2720  			// Special C name for Go string type.
  2721  			// Knows string layout used by compilers: pointer plus length,
  2722  			// which rounds up to 2 pointers after alignment.
  2723  			t.Go = c.string
  2724  			t.Size = c.ptrSize * 2
  2725  			t.Align = c.ptrSize
  2726  			break
  2727  		}
  2728  		if dt.Name == "_GoBytes_" {
  2729  			// Special C name for Go []byte type.
  2730  			// Knows slice layout used by compilers: pointer, length, cap.
  2731  			t.Go = c.Ident("[]byte")
  2732  			t.Size = c.ptrSize + 4 + 4
  2733  			t.Align = c.ptrSize
  2734  			break
  2735  		}
  2736  		name := c.Ident("_Ctype_" + dt.Name)
  2737  		goIdent[name.Name] = name
  2738  		akey := ""
  2739  		if c.anonymousStructTypedef(dt) {
  2740  			// only load type recursively for typedefs of anonymous
  2741  			// structs, see issues 37479 and 37621.
  2742  			akey = key
  2743  		}
  2744  		sub := c.loadType(dt.Type, pos, akey)
  2745  		if c.badPointerTypedef(dt) {
  2746  			// Treat this typedef as a uintptr.
  2747  			s := *sub
  2748  			s.Go = c.uintptr
  2749  			s.BadPointer = true
  2750  			sub = &s
  2751  			// Make sure we update any previously computed type.
  2752  			if oldType := typedef[name.Name]; oldType != nil {
  2753  				oldType.Go = sub.Go
  2754  				oldType.BadPointer = true
  2755  			}
  2756  		}
  2757  		if c.badVoidPointerTypedef(dt) {
  2758  			// Treat this typedef as a pointer to a _cgopackage.Incomplete.
  2759  			s := *sub
  2760  			s.Go = c.Ident("*" + incomplete)
  2761  			sub = &s
  2762  			// Make sure we update any previously computed type.
  2763  			if oldType := typedef[name.Name]; oldType != nil {
  2764  				oldType.Go = sub.Go
  2765  			}
  2766  		}
  2767  		// Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
  2768  		// typedefs that should be marked Incomplete.
  2769  		if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  2770  			if strct, ok := ptr.Type.(*dwarf.StructType); ok {
  2771  				if c.badStructPointerTypedef(dt.Name, strct) {
  2772  					c.incompleteStructs[strct.StructName] = true
  2773  					// Make sure we update any previously computed type.
  2774  					name := "_Ctype_struct_" + strct.StructName
  2775  					if oldType := typedef[name]; oldType != nil {
  2776  						oldType.Go = c.Ident(incomplete)
  2777  					}
  2778  				}
  2779  			}
  2780  		}
  2781  		t.Go = name
  2782  		t.BadPointer = sub.BadPointer
  2783  		if unionWithPointer[sub.Go] {
  2784  			unionWithPointer[t.Go] = true
  2785  		}
  2786  		t.Size = sub.Size
  2787  		t.Align = sub.Align
  2788  		oldType := typedef[name.Name]
  2789  		if oldType == nil {
  2790  			tt := *t
  2791  			tt.Go = sub.Go
  2792  			tt.BadPointer = sub.BadPointer
  2793  			typedef[name.Name] = &tt
  2794  		}
  2795  
  2796  		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
  2797  		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
  2798  		// with the base type.
  2799  		// In -godefs mode, do this for all typedefs.
  2800  		if isStructUnionClass(sub.Go) || *godefs {
  2801  			t.Go = sub.Go
  2802  
  2803  			if isStructUnionClass(sub.Go) {
  2804  				// Use the typedef name for C code.
  2805  				typedef[sub.Go.(*ast.Ident).Name].C = t.C
  2806  			}
  2807  
  2808  			// If we've seen this typedef before, and it
  2809  			// was an anonymous struct/union/class before
  2810  			// too, use the old definition.
  2811  			// TODO: it would be safer to only do this if
  2812  			// we verify that the types are the same.
  2813  			if oldType != nil && isStructUnionClass(oldType.Go) {
  2814  				t.Go = oldType.Go
  2815  			}
  2816  		}
  2817  
  2818  	case *dwarf.UcharType:
  2819  		if t.Size != 1 {
  2820  			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
  2821  		}
  2822  		t.Go = c.uint8
  2823  		t.Align = 1
  2824  
  2825  	case *dwarf.UintType:
  2826  		if dt.BitSize > 0 {
  2827  			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
  2828  		}
  2829  		switch t.Size {
  2830  		default:
  2831  			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
  2832  		case 1:
  2833  			t.Go = c.uint8
  2834  		case 2:
  2835  			t.Go = c.uint16
  2836  		case 4:
  2837  			t.Go = c.uint32
  2838  		case 8:
  2839  			t.Go = c.uint64
  2840  		case 16:
  2841  			t.Go = &ast.ArrayType{
  2842  				Len: c.intExpr(t.Size),
  2843  				Elt: c.uint8,
  2844  			}
  2845  		}
  2846  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2847  			t.Align = c.ptrSize
  2848  		}
  2849  
  2850  	case *dwarf.VoidType:
  2851  		t.Go = c.goVoid
  2852  		t.C.Set("void")
  2853  		t.Align = 1
  2854  	}
  2855  
  2856  	switch dtype.(type) {
  2857  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
  2858  		s := dtype.Common().Name
  2859  		if s != "" {
  2860  			if ss, ok := dwarfToName[s]; ok {
  2861  				s = ss
  2862  			}
  2863  			s = strings.Replace(s, " ", "", -1)
  2864  			name := c.Ident("_Ctype_" + s)
  2865  			tt := *t
  2866  			typedef[name.Name] = &tt
  2867  			if !*godefs {
  2868  				t.Go = name
  2869  			}
  2870  		}
  2871  	}
  2872  
  2873  	if t.Size < 0 {
  2874  		// Unsized types are [0]byte, unless they're typedefs of other types
  2875  		// or structs with tags.
  2876  		// if so, use the name we've already defined.
  2877  		t.Size = 0
  2878  		switch dt := dtype.(type) {
  2879  		case *dwarf.TypedefType:
  2880  			// ok
  2881  		case *dwarf.StructType:
  2882  			if dt.StructName != "" {
  2883  				break
  2884  			}
  2885  			t.Go = c.Opaque(0)
  2886  		default:
  2887  			t.Go = c.Opaque(0)
  2888  		}
  2889  		if t.C.Empty() {
  2890  			t.C.Set("void")
  2891  		}
  2892  	}
  2893  
  2894  	if t.C.Empty() {
  2895  		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
  2896  	}
  2897  
  2898  	return t
  2899  }
  2900  
  2901  // isStructUnionClass reports whether the type described by the Go syntax x
  2902  // is a struct, union, or class with a tag.
  2903  func isStructUnionClass(x ast.Expr) bool {
  2904  	id, ok := x.(*ast.Ident)
  2905  	if !ok {
  2906  		return false
  2907  	}
  2908  	name := id.Name
  2909  	return strings.HasPrefix(name, "_Ctype_struct_") ||
  2910  		strings.HasPrefix(name, "_Ctype_union_") ||
  2911  		strings.HasPrefix(name, "_Ctype_class_")
  2912  }
  2913  
  2914  // FuncArg returns a Go type with the same memory layout as
  2915  // dtype when used as the type of a C function argument.
  2916  func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
  2917  	t := c.Type(unqual(dtype), pos)
  2918  	switch dt := dtype.(type) {
  2919  	case *dwarf.ArrayType:
  2920  		// Arrays are passed implicitly as pointers in C.
  2921  		// In Go, we must be explicit.
  2922  		tr := &TypeRepr{}
  2923  		tr.Set("%s*", t.C)
  2924  		return &Type{
  2925  			Size:  c.ptrSize,
  2926  			Align: c.ptrSize,
  2927  			Go:    &ast.StarExpr{X: t.Go},
  2928  			C:     tr,
  2929  		}
  2930  	case *dwarf.TypedefType:
  2931  		// C has much more relaxed rules than Go for
  2932  		// implicit type conversions. When the parameter
  2933  		// is type T defined as *X, simulate a little of the
  2934  		// laxness of C by making the argument *X instead of T.
  2935  		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
  2936  			// Unless the typedef happens to point to void* since
  2937  			// Go has special rules around using unsafe.Pointer.
  2938  			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
  2939  				break
  2940  			}
  2941  			// ...or the typedef is one in which we expect bad pointers.
  2942  			// It will be a uintptr instead of *X.
  2943  			if c.baseBadPointerTypedef(dt) {
  2944  				break
  2945  			}
  2946  
  2947  			t = c.Type(ptr, pos)
  2948  			if t == nil {
  2949  				return nil
  2950  			}
  2951  
  2952  			// For a struct/union/class, remember the C spelling,
  2953  			// in case it has __attribute__((unavailable)).
  2954  			// See issue 2888.
  2955  			if isStructUnionClass(t.Go) {
  2956  				t.Typedef = dt.Name
  2957  			}
  2958  		}
  2959  	}
  2960  	return t
  2961  }
  2962  
  2963  // FuncType returns the Go type analogous to dtype.
  2964  // There is no guarantee about matching memory layout.
  2965  func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
  2966  	p := make([]*Type, len(dtype.ParamType))
  2967  	gp := make([]*ast.Field, len(dtype.ParamType))
  2968  	for i, f := range dtype.ParamType {
  2969  		// gcc's DWARF generator outputs a single DotDotDotType parameter for
  2970  		// function pointers that specify no parameters (e.g. void
  2971  		// (*__cgo_0)()).  Treat this special case as void. This case is
  2972  		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
  2973  		// legal).
  2974  		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
  2975  			p, gp = nil, nil
  2976  			break
  2977  		}
  2978  		p[i] = c.FuncArg(f, pos)
  2979  		gp[i] = &ast.Field{Type: p[i].Go}
  2980  	}
  2981  	var r *Type
  2982  	var gr []*ast.Field
  2983  	if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
  2984  		gr = []*ast.Field{{Type: c.goVoid}}
  2985  	} else if dtype.ReturnType != nil {
  2986  		r = c.Type(unqual(dtype.ReturnType), pos)
  2987  		gr = []*ast.Field{{Type: r.Go}}
  2988  	}
  2989  	return &FuncType{
  2990  		Params: p,
  2991  		Result: r,
  2992  		Go: &ast.FuncType{
  2993  			Params:  &ast.FieldList{List: gp},
  2994  			Results: &ast.FieldList{List: gr},
  2995  		},
  2996  	}
  2997  }
  2998  
  2999  // Identifier
  3000  func (c *typeConv) Ident(s string) *ast.Ident {
  3001  	return ast.NewIdent(s)
  3002  }
  3003  
  3004  // Opaque type of n bytes.
  3005  func (c *typeConv) Opaque(n int64) ast.Expr {
  3006  	return &ast.ArrayType{
  3007  		Len: c.intExpr(n),
  3008  		Elt: c.byte,
  3009  	}
  3010  }
  3011  
  3012  // Expr for integer n.
  3013  func (c *typeConv) intExpr(n int64) ast.Expr {
  3014  	return &ast.BasicLit{
  3015  		Kind:  token.INT,
  3016  		Value: strconv.FormatInt(n, 10),
  3017  	}
  3018  }
  3019  
  3020  // Add padding of given size to fld.
  3021  func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
  3022  	n := len(fld)
  3023  	fld = fld[0 : n+1]
  3024  	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
  3025  	sizes = sizes[0 : n+1]
  3026  	sizes[n] = size
  3027  	return fld, sizes
  3028  }
  3029  
  3030  // Struct conversion: return Go and (gc) C syntax for type.
  3031  func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
  3032  	// Minimum alignment for a struct is 1 byte.
  3033  	align = 1
  3034  
  3035  	var buf strings.Builder
  3036  	buf.WriteString("struct {")
  3037  	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
  3038  	sizes := make([]int64, 0, 2*len(dt.Field)+1)
  3039  	off := int64(0)
  3040  
  3041  	// Rename struct fields that happen to be named Go keywords into
  3042  	// _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
  3043  	// be mangled. Any existing identifier that already has the same name on
  3044  	// the C-side will cause the Go-mangled version to be prefixed with _.
  3045  	// (e.g. in a struct with fields '_type' and 'type', the latter would be
  3046  	// rendered as '__type' in Go).
  3047  	ident := make(map[string]string)
  3048  	used := make(map[string]bool)
  3049  	for _, f := range dt.Field {
  3050  		ident[f.Name] = f.Name
  3051  		used[f.Name] = true
  3052  	}
  3053  
  3054  	if !*godefs {
  3055  		for cid, goid := range ident {
  3056  			if token.Lookup(goid).IsKeyword() {
  3057  				// Avoid keyword
  3058  				goid = "_" + goid
  3059  
  3060  				// Also avoid existing fields
  3061  				for _, exist := used[goid]; exist; _, exist = used[goid] {
  3062  					goid = "_" + goid
  3063  				}
  3064  
  3065  				used[goid] = true
  3066  				ident[cid] = goid
  3067  			}
  3068  		}
  3069  	}
  3070  
  3071  	anon := 0
  3072  	for _, f := range dt.Field {
  3073  		name := f.Name
  3074  		ft := f.Type
  3075  
  3076  		// In godefs mode, if this field is a C11
  3077  		// anonymous union then treat the first field in the
  3078  		// union as the field in the struct. This handles
  3079  		// cases like the glibc <sys/resource.h> file; see
  3080  		// issue 6677.
  3081  		if *godefs {
  3082  			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
  3083  				name = st.Field[0].Name
  3084  				ident[name] = name
  3085  				ft = st.Field[0].Type
  3086  			}
  3087  		}
  3088  
  3089  		// TODO: Handle fields that are anonymous structs by
  3090  		// promoting the fields of the inner struct.
  3091  
  3092  		t := c.Type(ft, pos)
  3093  		tgo := t.Go
  3094  		size := t.Size
  3095  		talign := t.Align
  3096  		if f.BitOffset > 0 || f.BitSize > 0 {
  3097  			// The layout of bitfields is implementation defined,
  3098  			// so we don't know how they correspond to Go fields
  3099  			// even if they are aligned at byte boundaries.
  3100  			continue
  3101  		}
  3102  
  3103  		if talign > 0 && f.ByteOffset%talign != 0 {
  3104  			// Drop misaligned fields, the same way we drop integer bit fields.
  3105  			// The goal is to make available what can be made available.
  3106  			// Otherwise one bad and unneeded field in an otherwise okay struct
  3107  			// makes the whole program not compile. Much of the time these
  3108  			// structs are in system headers that cannot be corrected.
  3109  			continue
  3110  		}
  3111  
  3112  		// Round off up to talign, assumed to be a power of 2.
  3113  		off = (off + talign - 1) &^ (talign - 1)
  3114  
  3115  		if f.ByteOffset > off {
  3116  			fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
  3117  			off = f.ByteOffset
  3118  		}
  3119  		if f.ByteOffset < off {
  3120  			// Drop a packed field that we can't represent.
  3121  			continue
  3122  		}
  3123  
  3124  		n := len(fld)
  3125  		fld = fld[0 : n+1]
  3126  		if name == "" {
  3127  			name = fmt.Sprintf("anon%d", anon)
  3128  			anon++
  3129  			ident[name] = name
  3130  		}
  3131  		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
  3132  		sizes = sizes[0 : n+1]
  3133  		sizes[n] = size
  3134  		off += size
  3135  		buf.WriteString(t.C.String())
  3136  		buf.WriteString(" ")
  3137  		buf.WriteString(name)
  3138  		buf.WriteString("; ")
  3139  		if talign > align {
  3140  			align = talign
  3141  		}
  3142  	}
  3143  	if off < dt.ByteSize {
  3144  		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
  3145  		off = dt.ByteSize
  3146  	}
  3147  
  3148  	// If the last field in a non-zero-sized struct is zero-sized
  3149  	// the compiler is going to pad it by one (see issue 9401).
  3150  	// We can't permit that, because then the size of the Go
  3151  	// struct will not be the same as the size of the C struct.
  3152  	// Our only option in such a case is to remove the field,
  3153  	// which means that it cannot be referenced from Go.
  3154  	for off > 0 && sizes[len(sizes)-1] == 0 {
  3155  		n := len(sizes)
  3156  		fld = fld[0 : n-1]
  3157  		sizes = sizes[0 : n-1]
  3158  	}
  3159  
  3160  	if off != dt.ByteSize {
  3161  		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
  3162  	}
  3163  	buf.WriteString("}")
  3164  	csyntax = buf.String()
  3165  
  3166  	if *godefs {
  3167  		godefsFields(fld)
  3168  	}
  3169  	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
  3170  	return
  3171  }
  3172  
  3173  // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
  3174  func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
  3175  	switch dt := dt.(type) {
  3176  	default:
  3177  		fatalf("%s: unexpected type: %s", lineno(pos), dt)
  3178  		return false
  3179  
  3180  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
  3181  		*dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
  3182  		*dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
  3183  
  3184  		return false
  3185  
  3186  	case *dwarf.ArrayType:
  3187  		return c.dwarfHasPointer(dt.Type, pos)
  3188  
  3189  	case *dwarf.PtrType:
  3190  		return true
  3191  
  3192  	case *dwarf.QualType:
  3193  		return c.dwarfHasPointer(dt.Type, pos)
  3194  
  3195  	case *dwarf.StructType:
  3196  		for _, f := range dt.Field {
  3197  			if c.dwarfHasPointer(f.Type, pos) {
  3198  				return true
  3199  			}
  3200  		}
  3201  		return false
  3202  
  3203  	case *dwarf.TypedefType:
  3204  		if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
  3205  			return true
  3206  		}
  3207  		return c.dwarfHasPointer(dt.Type, pos)
  3208  	}
  3209  }
  3210  
  3211  func upper(s string) string {
  3212  	if s == "" {
  3213  		return ""
  3214  	}
  3215  	r, size := utf8.DecodeRuneInString(s)
  3216  	if r == '_' {
  3217  		return "X" + s
  3218  	}
  3219  	return string(unicode.ToUpper(r)) + s[size:]
  3220  }
  3221  
  3222  // godefsFields rewrites field names for use in Go or C definitions.
  3223  // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
  3224  // converts names to upper case, and rewrites _ into Pad_godefs_n,
  3225  // so that all fields are exported.
  3226  func godefsFields(fld []*ast.Field) {
  3227  	prefix := fieldPrefix(fld)
  3228  
  3229  	// Issue 48396: check for duplicate field names.
  3230  	if prefix != "" {
  3231  		names := make(map[string]bool)
  3232  	fldLoop:
  3233  		for _, f := range fld {
  3234  			for _, n := range f.Names {
  3235  				name := n.Name
  3236  				if name == "_" {
  3237  					continue
  3238  				}
  3239  				if name != prefix {
  3240  					name = strings.TrimPrefix(n.Name, prefix)
  3241  				}
  3242  				name = upper(name)
  3243  				if names[name] {
  3244  					// Field name conflict: don't remove prefix.
  3245  					prefix = ""
  3246  					break fldLoop
  3247  				}
  3248  				names[name] = true
  3249  			}
  3250  		}
  3251  	}
  3252  
  3253  	npad := 0
  3254  	for _, f := range fld {
  3255  		for _, n := range f.Names {
  3256  			if n.Name != prefix {
  3257  				n.Name = strings.TrimPrefix(n.Name, prefix)
  3258  			}
  3259  			if n.Name == "_" {
  3260  				// Use exported name instead.
  3261  				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
  3262  				npad++
  3263  			}
  3264  			n.Name = upper(n.Name)
  3265  		}
  3266  	}
  3267  }
  3268  
  3269  // fieldPrefix returns the prefix that should be removed from all the
  3270  // field names when generating the C or Go code. For generated
  3271  // C, we leave the names as is (tv_sec, tv_usec), since that's what
  3272  // people are used to seeing in C.  For generated Go code, such as
  3273  // package syscall's data structures, we drop a common prefix
  3274  // (so sec, usec, which will get turned into Sec, Usec for exporting).
  3275  func fieldPrefix(fld []*ast.Field) string {
  3276  	prefix := ""
  3277  	for _, f := range fld {
  3278  		for _, n := range f.Names {
  3279  			// Ignore field names that don't have the prefix we're
  3280  			// looking for. It is common in C headers to have fields
  3281  			// named, say, _pad in an otherwise prefixed header.
  3282  			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
  3283  			// still want to remove the tv_ prefix.
  3284  			// The check for "orig_" here handles orig_eax in the
  3285  			// x86 ptrace register sets, which otherwise have all fields
  3286  			// with reg_ prefixes.
  3287  			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
  3288  				continue
  3289  			}
  3290  			i := strings.Index(n.Name, "_")
  3291  			if i < 0 {
  3292  				continue
  3293  			}
  3294  			if prefix == "" {
  3295  				prefix = n.Name[:i+1]
  3296  			} else if prefix != n.Name[:i+1] {
  3297  				return ""
  3298  			}
  3299  		}
  3300  	}
  3301  	return prefix
  3302  }
  3303  
  3304  // anonymousStructTypedef reports whether dt is a C typedef for an anonymous
  3305  // struct.
  3306  func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
  3307  	st, ok := dt.Type.(*dwarf.StructType)
  3308  	return ok && st.StructName == ""
  3309  }
  3310  
  3311  // badPointerTypedef reports whether dt is a C typedef that should not be
  3312  // considered a pointer in Go. A typedef is bad if C code sometimes stores
  3313  // non-pointers in this type.
  3314  // TODO: Currently our best solution is to find these manually and list them as
  3315  // they come up. A better solution is desired.
  3316  // Note: DEPRECATED. There is now a better solution. Search for incomplete in this file.
  3317  func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
  3318  	if c.badCFType(dt) {
  3319  		return true
  3320  	}
  3321  	if c.badJNI(dt) {
  3322  		return true
  3323  	}
  3324  	if c.badEGLType(dt) {
  3325  		return true
  3326  	}
  3327  	return false
  3328  }
  3329  
  3330  // badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
  3331  func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
  3332  	// Match the Windows HANDLE type (#42018).
  3333  	if goos != "windows" || dt.Name != "HANDLE" {
  3334  		return false
  3335  	}
  3336  	// Check that the typedef is "typedef void *<name>".
  3337  	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  3338  		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
  3339  			return true
  3340  		}
  3341  	}
  3342  	return false
  3343  }
  3344  
  3345  // badStructPointerTypedef is like badVoidPointerTypedef but for structs.
  3346  func (c *typeConv) badStructPointerTypedef(name string, dt *dwarf.StructType) bool {
  3347  	// Windows handle types can all potentially contain non-pointers.
  3348  	// badVoidPointerTypedef handles the "void *" HANDLE type, but other
  3349  	// handles are defined as
  3350  	//
  3351  	// struct <name>__{int unused;}; typedef struct <name>__ *name;
  3352  	//
  3353  	// by the DECLARE_HANDLE macro in STRICT mode. The macro is declared in
  3354  	// the Windows ntdef.h header,
  3355  	//
  3356  	// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntdef.h#L779
  3357  	if goos != "windows" {
  3358  		return false
  3359  	}
  3360  	if len(dt.Field) != 1 {
  3361  		return false
  3362  	}
  3363  	if dt.StructName != name+"__" {
  3364  		return false
  3365  	}
  3366  	if f := dt.Field[0]; f.Name != "unused" || f.Type.Common().Name != "int" {
  3367  		return false
  3368  	}
  3369  	return true
  3370  }
  3371  
  3372  // baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
  3373  // as badPointerTypedef reports.
  3374  func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
  3375  	for {
  3376  		if t, ok := dt.Type.(*dwarf.TypedefType); ok {
  3377  			dt = t
  3378  			continue
  3379  		}
  3380  		break
  3381  	}
  3382  	return c.badPointerTypedef(dt)
  3383  }
  3384  
  3385  func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
  3386  	// The real bad types are CFNumberRef and CFDateRef.
  3387  	// Sometimes non-pointers are stored in these types.
  3388  	// CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
  3389  	// We return true for the other *Ref types just so casting between them is easier.
  3390  	// We identify the correct set of types as those ending in Ref and for which
  3391  	// there exists a corresponding GetTypeID function.
  3392  	// See comment below for details about the bad pointers.
  3393  	if goos != "darwin" && goos != "ios" {
  3394  		return false
  3395  	}
  3396  	s := dt.Name
  3397  	if !strings.HasSuffix(s, "Ref") {
  3398  		return false
  3399  	}
  3400  	s = s[:len(s)-3]
  3401  	if s == "CFType" {
  3402  		return true
  3403  	}
  3404  	if c.getTypeIDs[s] {
  3405  		return true
  3406  	}
  3407  	if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
  3408  		// Mutable and immutable variants share a type ID.
  3409  		return true
  3410  	}
  3411  	return false
  3412  }
  3413  
  3414  // Comment from Darwin's CFInternal.h
  3415  /*
  3416  // Tagged pointer support
  3417  // Low-bit set means tagged object, next 3 bits (currently)
  3418  // define the tagged object class, next 4 bits are for type
  3419  // information for the specific tagged object class.  Thus,
  3420  // the low byte is for type info, and the rest of a pointer
  3421  // (32 or 64-bit) is for payload, whatever the tagged class.
  3422  //
  3423  // Note that the specific integers used to identify the
  3424  // specific tagged classes can and will change from release
  3425  // to release (that's why this stuff is in CF*Internal*.h),
  3426  // as can the definition of type info vs payload above.
  3427  //
  3428  #if __LP64__
  3429  #define CF_IS_TAGGED_OBJ(PTR)	((uintptr_t)(PTR) & 0x1)
  3430  #define CF_TAGGED_OBJ_TYPE(PTR)	((uintptr_t)(PTR) & 0xF)
  3431  #else
  3432  #define CF_IS_TAGGED_OBJ(PTR)	0
  3433  #define CF_TAGGED_OBJ_TYPE(PTR)	0
  3434  #endif
  3435  
  3436  enum {
  3437      kCFTaggedObjectID_Invalid = 0,
  3438      kCFTaggedObjectID_Atom = (0 << 1) + 1,
  3439      kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
  3440      kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
  3441      kCFTaggedObjectID_Integer = (3 << 1) + 1,
  3442      kCFTaggedObjectID_DateTS = (4 << 1) + 1,
  3443      kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
  3444      kCFTaggedObjectID_Date = (6 << 1) + 1,
  3445      kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
  3446  };
  3447  */
  3448  
  3449  func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
  3450  	// In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
  3451  	// property that it is sometimes (always?) a small integer instead of a real pointer.
  3452  	// Note: although only the android JVMs are bad in this respect, we declare the JNI types
  3453  	// bad regardless of platform, so the same Go code compiles on both android and non-android.
  3454  	if parent, ok := jniTypes[dt.Name]; ok {
  3455  		// Try to make sure we're talking about a JNI type, not just some random user's
  3456  		// type that happens to use the same name.
  3457  		// C doesn't have the notion of a package, so it's hard to be certain.
  3458  
  3459  		// Walk up to jobject, checking each typedef on the way.
  3460  		w := dt
  3461  		for parent != "" {
  3462  			t, ok := w.Type.(*dwarf.TypedefType)
  3463  			if !ok || t.Name != parent {
  3464  				return false
  3465  			}
  3466  			w = t
  3467  			parent, ok = jniTypes[w.Name]
  3468  			if !ok {
  3469  				return false
  3470  			}
  3471  		}
  3472  
  3473  		// Check that the typedef is either:
  3474  		// 1:
  3475  		//     	struct _jobject;
  3476  		//     	typedef struct _jobject *jobject;
  3477  		// 2: (in NDK16 in C++)
  3478  		//     	class _jobject {};
  3479  		//     	typedef _jobject* jobject;
  3480  		// 3: (in NDK16 in C)
  3481  		//     	typedef void* jobject;
  3482  		if ptr, ok := w.Type.(*dwarf.PtrType); ok {
  3483  			switch v := ptr.Type.(type) {
  3484  			case *dwarf.VoidType:
  3485  				return true
  3486  			case *dwarf.StructType:
  3487  				if v.StructName == "_jobject" && len(v.Field) == 0 {
  3488  					switch v.Kind {
  3489  					case "struct":
  3490  						if v.Incomplete {
  3491  							return true
  3492  						}
  3493  					case "class":
  3494  						if !v.Incomplete {
  3495  							return true
  3496  						}
  3497  					}
  3498  				}
  3499  			}
  3500  		}
  3501  	}
  3502  	return false
  3503  }
  3504  
  3505  func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool {
  3506  	if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" {
  3507  		return false
  3508  	}
  3509  	// Check that the typedef is "typedef void *<name>".
  3510  	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  3511  		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
  3512  			return true
  3513  		}
  3514  	}
  3515  	return false
  3516  }
  3517  
  3518  // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
  3519  // they are mapped. The base "jobject" maps to the empty string.
  3520  var jniTypes = map[string]string{
  3521  	"jobject":       "",
  3522  	"jclass":        "jobject",
  3523  	"jthrowable":    "jobject",
  3524  	"jstring":       "jobject",
  3525  	"jarray":        "jobject",
  3526  	"jbooleanArray": "jarray",
  3527  	"jbyteArray":    "jarray",
  3528  	"jcharArray":    "jarray",
  3529  	"jshortArray":   "jarray",
  3530  	"jintArray":     "jarray",
  3531  	"jlongArray":    "jarray",
  3532  	"jfloatArray":   "jarray",
  3533  	"jdoubleArray":  "jarray",
  3534  	"jobjectArray":  "jarray",
  3535  	"jweak":         "jobject",
  3536  }
  3537  

View as plain text