github.com/ActiveState/go@v0.0.0-20170614201249-0b81c023a722/src/cmd/cgo/gcc.go (about)

     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  	"math"
    24  	"os"
    25  	"strconv"
    26  	"strings"
    27  	"unicode"
    28  	"unicode/utf8"
    29  )
    30  
    31  var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
    32  var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
    33  
    34  var nameToC = map[string]string{
    35  	"schar":         "signed char",
    36  	"uchar":         "unsigned char",
    37  	"ushort":        "unsigned short",
    38  	"uint":          "unsigned int",
    39  	"ulong":         "unsigned long",
    40  	"longlong":      "long long",
    41  	"ulonglong":     "unsigned long long",
    42  	"complexfloat":  "float _Complex",
    43  	"complexdouble": "double _Complex",
    44  }
    45  
    46  // cname returns the C name to use for C.s.
    47  // The expansions are listed in nameToC and also
    48  // struct_foo becomes "struct foo", and similarly for
    49  // union and enum.
    50  func cname(s string) string {
    51  	if t, ok := nameToC[s]; ok {
    52  		return t
    53  	}
    54  
    55  	if strings.HasPrefix(s, "struct_") {
    56  		return "struct " + s[len("struct_"):]
    57  	}
    58  	if strings.HasPrefix(s, "union_") {
    59  		return "union " + s[len("union_"):]
    60  	}
    61  	if strings.HasPrefix(s, "enum_") {
    62  		return "enum " + s[len("enum_"):]
    63  	}
    64  	if strings.HasPrefix(s, "sizeof_") {
    65  		return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
    66  	}
    67  	return s
    68  }
    69  
    70  // DiscardCgoDirectives processes the import C preamble, and discards
    71  // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
    72  // way into _cgo_export.h.
    73  func (f *File) DiscardCgoDirectives() {
    74  	linesIn := strings.Split(f.Preamble, "\n")
    75  	linesOut := make([]string, 0, len(linesIn))
    76  	for _, line := range linesIn {
    77  		l := strings.TrimSpace(line)
    78  		if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
    79  			linesOut = append(linesOut, line)
    80  		} else {
    81  			linesOut = append(linesOut, "")
    82  		}
    83  	}
    84  	f.Preamble = strings.Join(linesOut, "\n")
    85  }
    86  
    87  // addToFlag appends args to flag. All flags are later written out onto the
    88  // _cgo_flags file for the build system to use.
    89  func (p *Package) addToFlag(flag string, args []string) {
    90  	p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
    91  	if flag == "CFLAGS" {
    92  		// We'll also need these when preprocessing for dwarf information.
    93  		p.GccOptions = append(p.GccOptions, args...)
    94  	}
    95  }
    96  
    97  // splitQuoted splits the string s around each instance of one or more consecutive
    98  // white space characters while taking into account quotes and escaping, and
    99  // returns an array of substrings of s or an empty list if s contains only white space.
   100  // Single quotes and double quotes are recognized to prevent splitting within the
   101  // quoted region, and are removed from the resulting substrings. If a quote in s
   102  // isn't closed err will be set and r will have the unclosed argument as the
   103  // last element. The backslash is used for escaping.
   104  //
   105  // For example, the following string:
   106  //
   107  //     `a b:"c d" 'e''f'  "g\""`
   108  //
   109  // Would be parsed as:
   110  //
   111  //     []string{"a", "b:c d", "ef", `g"`}
   112  //
   113  func splitQuoted(s string) (r []string, err error) {
   114  	var args []string
   115  	arg := make([]rune, len(s))
   116  	escaped := false
   117  	quoted := false
   118  	quote := '\x00'
   119  	i := 0
   120  	for _, r := range s {
   121  		switch {
   122  		case escaped:
   123  			escaped = false
   124  		case r == '\\':
   125  			escaped = true
   126  			continue
   127  		case quote != 0:
   128  			if r == quote {
   129  				quote = 0
   130  				continue
   131  			}
   132  		case r == '"' || r == '\'':
   133  			quoted = true
   134  			quote = r
   135  			continue
   136  		case unicode.IsSpace(r):
   137  			if quoted || i > 0 {
   138  				quoted = false
   139  				args = append(args, string(arg[:i]))
   140  				i = 0
   141  			}
   142  			continue
   143  		}
   144  		arg[i] = r
   145  		i++
   146  	}
   147  	if quoted || i > 0 {
   148  		args = append(args, string(arg[:i]))
   149  	}
   150  	if quote != 0 {
   151  		err = errors.New("unclosed quote")
   152  	} else if escaped {
   153  		err = errors.New("unfinished escaping")
   154  	}
   155  	return args, err
   156  }
   157  
   158  // Translate rewrites f.AST, the original Go input, to remove
   159  // references to the imported package C, replacing them with
   160  // references to the equivalent Go types, functions, and variables.
   161  func (p *Package) Translate(f *File) {
   162  	for _, cref := range f.Ref {
   163  		// Convert C.ulong to C.unsigned long, etc.
   164  		cref.Name.C = cname(cref.Name.Go)
   165  	}
   166  	p.loadDefines(f)
   167  	needType := p.guessKinds(f)
   168  	if len(needType) > 0 {
   169  		p.loadDWARF(f, needType)
   170  	}
   171  	if p.rewriteCalls(f) {
   172  		// Add `import _cgo_unsafe "unsafe"` as the first decl
   173  		// after the package statement.
   174  		imp := &ast.GenDecl{
   175  			Tok: token.IMPORT,
   176  			Specs: []ast.Spec{
   177  				&ast.ImportSpec{
   178  					Name: ast.NewIdent("_cgo_unsafe"),
   179  					Path: &ast.BasicLit{
   180  						Kind:  token.STRING,
   181  						Value: `"unsafe"`,
   182  					},
   183  				},
   184  			},
   185  		}
   186  		f.AST.Decls = append([]ast.Decl{imp}, f.AST.Decls...)
   187  	}
   188  	p.rewriteRef(f)
   189  }
   190  
   191  // loadDefines coerces gcc into spitting out the #defines in use
   192  // in the file f and saves relevant renamings in f.Name[name].Define.
   193  func (p *Package) loadDefines(f *File) {
   194  	var b bytes.Buffer
   195  	b.WriteString(f.Preamble)
   196  	b.WriteString(builtinProlog)
   197  	stdout := p.gccDefines(b.Bytes())
   198  
   199  	for _, line := range strings.Split(stdout, "\n") {
   200  		if len(line) < 9 || line[0:7] != "#define" {
   201  			continue
   202  		}
   203  
   204  		line = strings.TrimSpace(line[8:])
   205  
   206  		var key, val string
   207  		spaceIndex := strings.Index(line, " ")
   208  		tabIndex := strings.Index(line, "\t")
   209  
   210  		if spaceIndex == -1 && tabIndex == -1 {
   211  			continue
   212  		} else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
   213  			key = line[0:spaceIndex]
   214  			val = strings.TrimSpace(line[spaceIndex:])
   215  		} else {
   216  			key = line[0:tabIndex]
   217  			val = strings.TrimSpace(line[tabIndex:])
   218  		}
   219  
   220  		if key == "__clang__" {
   221  			p.GccIsClang = true
   222  		}
   223  
   224  		if n := f.Name[key]; n != nil {
   225  			if *debugDefine {
   226  				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
   227  			}
   228  			n.Define = val
   229  		}
   230  	}
   231  }
   232  
   233  // guessKinds tricks gcc into revealing the kind of each
   234  // name xxx for the references C.xxx in the Go input.
   235  // The kind is either a constant, type, or variable.
   236  func (p *Package) guessKinds(f *File) []*Name {
   237  	// Determine kinds for names we already know about,
   238  	// like #defines or 'struct foo', before bothering with gcc.
   239  	var names, needType []*Name
   240  	for _, key := range nameKeys(f.Name) {
   241  		n := f.Name[key]
   242  		// If we've already found this name as a #define
   243  		// and we can translate it as a constant value, do so.
   244  		if n.Define != "" {
   245  			if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
   246  				n.Kind = "iconst"
   247  				// Turn decimal into hex, just for consistency
   248  				// with enum-derived constants. Otherwise
   249  				// in the cgo -godefs output half the constants
   250  				// are in hex and half are in whatever the #define used.
   251  				n.Const = fmt.Sprintf("%#x", i)
   252  			} else if n.Define[0] == '\'' {
   253  				if _, err := parser.ParseExpr(n.Define); err == nil {
   254  					n.Kind = "iconst"
   255  					n.Const = n.Define
   256  				}
   257  			} else if n.Define[0] == '"' {
   258  				if _, err := parser.ParseExpr(n.Define); err == nil {
   259  					n.Kind = "sconst"
   260  					n.Const = n.Define
   261  				}
   262  			}
   263  
   264  			if n.IsConst() {
   265  				continue
   266  			}
   267  
   268  			if isName(n.Define) {
   269  				n.C = n.Define
   270  			}
   271  		}
   272  
   273  		// If this is a struct, union, or enum type name, no need to guess the kind.
   274  		if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
   275  			n.Kind = "type"
   276  			needType = append(needType, n)
   277  			continue
   278  		}
   279  
   280  		// Otherwise, we'll need to find out from gcc.
   281  		names = append(names, n)
   282  	}
   283  
   284  	// Bypass gcc if there's nothing left to find out.
   285  	if len(names) == 0 {
   286  		return needType
   287  	}
   288  
   289  	// Coerce gcc into telling us whether each name is a type, a value, or undeclared.
   290  	// For names, find out whether they are integer constants.
   291  	// We used to look at specific warning or error messages here, but that tied the
   292  	// behavior too closely to specific versions of the compilers.
   293  	// Instead, arrange that we can infer what we need from only the presence or absence
   294  	// of an error on a specific line.
   295  	//
   296  	// For each name, we generate these lines, where xxx is the index in toSniff plus one.
   297  	//
   298  	//	#line xxx "not-declared"
   299  	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
   300  	//	#line xxx "not-type"
   301  	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
   302  	//	#line xxx "not-int-const"
   303  	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
   304  	//	#line xxx "not-num-const"
   305  	//	void __cgo_f_xxx_4(void) { static const double x = (name); }
   306  	//	#line xxx "not-str-lit"
   307  	//	void __cgo_f_xxx_5(void) { static const char x[] = (name); }
   308  	//	#line xxx "not-signed-int-const"
   309  	//	#if 0 < -(name)
   310  	//	#line xxx "not-signed-int-const"
   311  	//	#error found unsigned int
   312  	//	#endif
   313  	//
   314  	// If we see an error at not-declared:xxx, the corresponding name is not declared.
   315  	// If we see an error at not-type:xxx, the corresponding name is a type.
   316  	// If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
   317  	// If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
   318  	// If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
   319  	// If we see an error at not-signed-int-const:xxx, the corresponding name is not a signed integer literal.
   320  	//
   321  	// The specific input forms are chosen so that they are valid C syntax regardless of
   322  	// whether name denotes a type or an expression.
   323  
   324  	var b bytes.Buffer
   325  	b.WriteString(f.Preamble)
   326  	b.WriteString(builtinProlog)
   327  
   328  	for i, n := range names {
   329  		fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
   330  			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
   331  			"#line %d \"not-type\"\n"+
   332  			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
   333  			"#line %d \"not-int-const\"\n"+
   334  			"void __cgo_f_%d_3(void) { enum { __cgo_undefined__ = (%s)*1 }; }\n"+
   335  			"#line %d \"not-num-const\"\n"+
   336  			"void __cgo_f_%d_4(void) { static const double x = (%s); }\n"+
   337  			"#line %d \"not-str-lit\"\n"+
   338  			"void __cgo_f_%d_5(void) { static const char s[] = (%s); }\n"+
   339  			"#line %d \"not-signed-int-const\"\n"+
   340  			"#if 0 < (%s)\n"+
   341  			"#line %d \"not-signed-int-const\"\n"+
   342  			"#error found unsigned int\n"+
   343  			"#endif\n",
   344  			i+1, i+1, n.C,
   345  			i+1, i+1, n.C,
   346  			i+1, i+1, n.C,
   347  			i+1, i+1, n.C,
   348  			i+1, i+1, n.C,
   349  			i+1, n.C, i+1,
   350  		)
   351  	}
   352  	fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
   353  		"int __cgo__1 = __cgo__2;\n")
   354  
   355  	stderr := p.gccErrors(b.Bytes())
   356  	if stderr == "" {
   357  		fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
   358  	}
   359  
   360  	completed := false
   361  	sniff := make([]int, len(names))
   362  	const (
   363  		notType = 1 << iota
   364  		notIntConst
   365  		notNumConst
   366  		notStrLiteral
   367  		notDeclared
   368  		notSignedIntConst
   369  	)
   370  	sawUnmatchedErrors := false
   371  	for _, line := range strings.Split(stderr, "\n") {
   372  		// Ignore warnings and random comments, with one
   373  		// exception: newer GCC versions will sometimes emit
   374  		// an error on a macro #define with a note referring
   375  		// to where the expansion occurs. We care about where
   376  		// the expansion occurs, so in that case treat the note
   377  		// as an error.
   378  		isError := strings.Contains(line, ": error:")
   379  		isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
   380  		if !isError && !isErrorNote {
   381  			continue
   382  		}
   383  
   384  		c1 := strings.Index(line, ":")
   385  		if c1 < 0 {
   386  			continue
   387  		}
   388  		c2 := strings.Index(line[c1+1:], ":")
   389  		if c2 < 0 {
   390  			continue
   391  		}
   392  		c2 += c1 + 1
   393  
   394  		filename := line[:c1]
   395  		i, _ := strconv.Atoi(line[c1+1 : c2])
   396  		i--
   397  		if i < 0 || i >= len(names) {
   398  			if isError {
   399  				sawUnmatchedErrors = true
   400  			}
   401  			continue
   402  		}
   403  
   404  		switch filename {
   405  		case "completed":
   406  			// Strictly speaking, there is no guarantee that seeing the error at completed:1
   407  			// (at the end of the file) means we've seen all the errors from earlier in the file,
   408  			// but usually it does. Certainly if we don't see the completed:1 error, we did
   409  			// not get all the errors we expected.
   410  			completed = true
   411  
   412  		case "not-declared":
   413  			sniff[i] |= notDeclared
   414  		case "not-type":
   415  			sniff[i] |= notType
   416  		case "not-int-const":
   417  			sniff[i] |= notIntConst
   418  		case "not-num-const":
   419  			sniff[i] |= notNumConst
   420  		case "not-str-lit":
   421  			sniff[i] |= notStrLiteral
   422  		case "not-signed-int-const":
   423  			sniff[i] |= notSignedIntConst
   424  		default:
   425  			if isError {
   426  				sawUnmatchedErrors = true
   427  			}
   428  			continue
   429  		}
   430  
   431  		sawUnmatchedErrors = false
   432  	}
   433  
   434  	if !completed {
   435  		fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
   436  	}
   437  
   438  	for i, n := range names {
   439  		switch sniff[i] &^ notSignedIntConst {
   440  		default:
   441  			var tpos token.Pos
   442  			for _, ref := range f.Ref {
   443  				if ref.Name == n {
   444  					tpos = ref.Pos()
   445  					break
   446  				}
   447  			}
   448  			error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go))
   449  		case notStrLiteral | notType:
   450  			if sniff[i]&notSignedIntConst != 0 {
   451  				n.Kind = "uconst"
   452  			} else {
   453  				n.Kind = "iconst"
   454  			}
   455  		case notIntConst | notStrLiteral | notType:
   456  			n.Kind = "fconst"
   457  		case notIntConst | notNumConst | notType:
   458  			n.Kind = "sconst"
   459  		case notIntConst | notNumConst | notStrLiteral:
   460  			n.Kind = "type"
   461  		case notIntConst | notNumConst | notStrLiteral | notType:
   462  			n.Kind = "not-type"
   463  		}
   464  	}
   465  	if nerrors > 0 {
   466  		// Check if compiling the preamble by itself causes any errors,
   467  		// because the messages we've printed out so far aren't helpful
   468  		// to users debugging preamble mistakes. See issue 8442.
   469  		preambleErrors := p.gccErrors([]byte(f.Preamble))
   470  		if len(preambleErrors) > 0 {
   471  			error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
   472  		}
   473  
   474  		fatalf("unresolved names")
   475  	}
   476  
   477  	needType = append(needType, names...)
   478  	return needType
   479  }
   480  
   481  // loadDWARF parses the DWARF debug information generated
   482  // by gcc to learn the details of the constants, variables, and types
   483  // being referred to as C.xxx.
   484  func (p *Package) loadDWARF(f *File, names []*Name) {
   485  	// Extract the types from the DWARF section of an object
   486  	// from a well-formed C program. Gcc only generates DWARF info
   487  	// for symbols in the object file, so it is not enough to print the
   488  	// preamble and hope the symbols we care about will be there.
   489  	// Instead, emit
   490  	//	__typeof__(names[i]) *__cgo__i;
   491  	// for each entry in names and then dereference the type we
   492  	// learn for __cgo__i.
   493  	var b bytes.Buffer
   494  	b.WriteString(f.Preamble)
   495  	b.WriteString(builtinProlog)
   496  	b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
   497  	for i, n := range names {
   498  		fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
   499  		if n.Kind == "iconst" || n.Kind == "uconst" {
   500  			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
   501  		}
   502  	}
   503  
   504  	// We create a data block initialized with the values,
   505  	// so we can read them out of the object file.
   506  	fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
   507  	for _, n := range names {
   508  		if n.Kind == "iconst" || n.Kind == "uconst" {
   509  			fmt.Fprintf(&b, "\t%s,\n", n.C)
   510  		} else {
   511  			fmt.Fprintf(&b, "\t0,\n")
   512  		}
   513  	}
   514  	// for the last entry, we cannot use 0, otherwise
   515  	// in case all __cgodebug_data is zero initialized,
   516  	// LLVM-based gcc will place the it in the __DATA.__common
   517  	// zero-filled section (our debug/macho doesn't support
   518  	// this)
   519  	fmt.Fprintf(&b, "\t1\n")
   520  	fmt.Fprintf(&b, "};\n")
   521  
   522  	// do the same work for floats.
   523  	fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n")
   524  	for _, n := range names {
   525  		if n.Kind == "fconst" {
   526  			fmt.Fprintf(&b, "\t%s,\n", n.C)
   527  		} else {
   528  			fmt.Fprintf(&b, "\t0,\n")
   529  		}
   530  	}
   531  	fmt.Fprintf(&b, "\t1\n")
   532  	fmt.Fprintf(&b, "};\n")
   533  
   534  	// do the same work for strings.
   535  	for i, n := range names {
   536  		if n.Kind == "sconst" {
   537  			fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C)
   538  			fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C)
   539  		}
   540  	}
   541  
   542  	d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
   543  
   544  	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
   545  	types := make([]dwarf.Type, len(names))
   546  	nameToIndex := make(map[*Name]int)
   547  	for i, n := range names {
   548  		nameToIndex[n] = i
   549  	}
   550  	nameToRef := make(map[*Name]*Ref)
   551  	for _, ref := range f.Ref {
   552  		nameToRef[ref.Name] = ref
   553  	}
   554  	r := d.Reader()
   555  	for {
   556  		e, err := r.Next()
   557  		if err != nil {
   558  			fatalf("reading DWARF entry: %s", err)
   559  		}
   560  		if e == nil {
   561  			break
   562  		}
   563  		switch e.Tag {
   564  		case dwarf.TagVariable:
   565  			name, _ := e.Val(dwarf.AttrName).(string)
   566  			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
   567  			if name == "" || typOff == 0 {
   568  				if e.Val(dwarf.AttrSpecification) != nil {
   569  					// Since we are reading all the DWARF,
   570  					// assume we will see the variable elsewhere.
   571  					break
   572  				}
   573  				fatalf("malformed DWARF TagVariable entry")
   574  			}
   575  			if !strings.HasPrefix(name, "__cgo__") {
   576  				break
   577  			}
   578  			typ, err := d.Type(typOff)
   579  			if err != nil {
   580  				fatalf("loading DWARF type: %s", err)
   581  			}
   582  			t, ok := typ.(*dwarf.PtrType)
   583  			if !ok || t == nil {
   584  				fatalf("internal error: %s has non-pointer type", name)
   585  			}
   586  			i, err := strconv.Atoi(name[7:])
   587  			if err != nil {
   588  				fatalf("malformed __cgo__ name: %s", name)
   589  			}
   590  			types[i] = t.Type
   591  		}
   592  		if e.Tag != dwarf.TagCompileUnit {
   593  			r.SkipChildren()
   594  		}
   595  	}
   596  
   597  	// Record types and typedef information.
   598  	var conv typeConv
   599  	conv.Init(p.PtrSize, p.IntSize)
   600  	for i, n := range names {
   601  		if types[i] == nil {
   602  			continue
   603  		}
   604  		pos := token.NoPos
   605  		if ref, ok := nameToRef[n]; ok {
   606  			pos = ref.Pos()
   607  		}
   608  		f, fok := types[i].(*dwarf.FuncType)
   609  		if n.Kind != "type" && fok {
   610  			n.Kind = "func"
   611  			n.FuncType = conv.FuncType(f, pos)
   612  		} else {
   613  			n.Type = conv.Type(types[i], pos)
   614  			switch n.Kind {
   615  			case "iconst":
   616  				if i < len(ints) {
   617  					n.Const = fmt.Sprintf("%#x", ints[i])
   618  				}
   619  			case "uconst":
   620  				if i < len(ints) {
   621  					n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
   622  				}
   623  			case "fconst":
   624  				if i < len(floats) {
   625  					n.Const = fmt.Sprintf("%f", floats[i])
   626  				}
   627  			case "sconst":
   628  				if i < len(strs) {
   629  					n.Const = fmt.Sprintf("%q", strs[i])
   630  				}
   631  			}
   632  		}
   633  		conv.FinishType(pos)
   634  	}
   635  }
   636  
   637  // mangleName does name mangling to translate names
   638  // from the original Go source files to the names
   639  // used in the final Go files generated by cgo.
   640  func (p *Package) mangleName(n *Name) {
   641  	// When using gccgo variables have to be
   642  	// exported so that they become global symbols
   643  	// that the C code can refer to.
   644  	prefix := "_C"
   645  	if *gccgo && n.IsVar() {
   646  		prefix = "C"
   647  	}
   648  	n.Mangle = prefix + n.Kind + "_" + n.Go
   649  }
   650  
   651  // rewriteCalls rewrites all calls that pass pointers to check that
   652  // they follow the rules for passing pointers between Go and C.
   653  // This returns whether the package needs to import unsafe as _cgo_unsafe.
   654  func (p *Package) rewriteCalls(f *File) bool {
   655  	needsUnsafe := false
   656  	for _, call := range f.Calls {
   657  		// This is a call to C.xxx; set goname to "xxx".
   658  		goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name
   659  		if goname == "malloc" {
   660  			continue
   661  		}
   662  		name := f.Name[goname]
   663  		if name.Kind != "func" {
   664  			// Probably a type conversion.
   665  			continue
   666  		}
   667  		if p.rewriteCall(f, call, name) {
   668  			needsUnsafe = true
   669  		}
   670  	}
   671  	return needsUnsafe
   672  }
   673  
   674  // rewriteCall rewrites one call to add pointer checks.
   675  // If any pointer checks are required, we rewrite the call into a
   676  // function literal that calls _cgoCheckPointer for each pointer
   677  // argument and then calls the original function.
   678  // This returns whether the package needs to import unsafe as _cgo_unsafe.
   679  func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
   680  	// Avoid a crash if the number of arguments is
   681  	// less than the number of parameters.
   682  	// This will be caught when the generated file is compiled.
   683  	if len(call.Call.Args) < len(name.FuncType.Params) {
   684  		return false
   685  	}
   686  
   687  	any := false
   688  	for i, param := range name.FuncType.Params {
   689  		if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) {
   690  			any = true
   691  			break
   692  		}
   693  	}
   694  	if !any {
   695  		return false
   696  	}
   697  
   698  	// We need to rewrite this call.
   699  	//
   700  	// We are going to rewrite C.f(p) to
   701  	//    func (_cgo0 ptype) {
   702  	//            _cgoCheckPointer(_cgo0)
   703  	//            C.f(_cgo0)
   704  	//    }(p)
   705  	// Using a function literal like this lets us do correct
   706  	// argument type checking, and works correctly if the call is
   707  	// deferred.
   708  	needsUnsafe := false
   709  	params := make([]*ast.Field, len(name.FuncType.Params))
   710  	nargs := make([]ast.Expr, len(name.FuncType.Params))
   711  	var stmts []ast.Stmt
   712  	for i, param := range name.FuncType.Params {
   713  		// params is going to become the parameters of the
   714  		// function literal.
   715  		// nargs is going to become the list of arguments made
   716  		// by the call within the function literal.
   717  		// nparam is the parameter of the function literal that
   718  		// corresponds to param.
   719  
   720  		origArg := call.Call.Args[i]
   721  		nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
   722  		nargs[i] = nparam
   723  
   724  		// The Go version of the C type might use unsafe.Pointer,
   725  		// but the file might not import unsafe.
   726  		// Rewrite the Go type if necessary to use _cgo_unsafe.
   727  		ptype := p.rewriteUnsafe(param.Go)
   728  		if ptype != param.Go {
   729  			needsUnsafe = true
   730  		}
   731  
   732  		params[i] = &ast.Field{
   733  			Names: []*ast.Ident{nparam},
   734  			Type:  ptype,
   735  		}
   736  
   737  		if !p.needsPointerCheck(f, param.Go, origArg) {
   738  			continue
   739  		}
   740  
   741  		// Run the cgo pointer checks on nparam.
   742  
   743  		// Change the function literal to call the real function
   744  		// with the parameter passed through _cgoCheckPointer.
   745  		c := &ast.CallExpr{
   746  			Fun: ast.NewIdent("_cgoCheckPointer"),
   747  			Args: []ast.Expr{
   748  				nparam,
   749  			},
   750  		}
   751  
   752  		// Add optional additional arguments for an address
   753  		// expression.
   754  		c.Args = p.checkAddrArgs(f, c.Args, origArg)
   755  
   756  		stmt := &ast.ExprStmt{
   757  			X: c,
   758  		}
   759  		stmts = append(stmts, stmt)
   760  	}
   761  
   762  	fcall := &ast.CallExpr{
   763  		Fun:  call.Call.Fun,
   764  		Args: nargs,
   765  	}
   766  	ftype := &ast.FuncType{
   767  		Params: &ast.FieldList{
   768  			List: params,
   769  		},
   770  	}
   771  	if name.FuncType.Result != nil {
   772  		rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
   773  		if rtype != name.FuncType.Result.Go {
   774  			needsUnsafe = true
   775  		}
   776  		ftype.Results = &ast.FieldList{
   777  			List: []*ast.Field{
   778  				&ast.Field{
   779  					Type: rtype,
   780  				},
   781  			},
   782  		}
   783  	}
   784  
   785  	// There is a Ref pointing to the old call.Call.Fun.
   786  	for _, ref := range f.Ref {
   787  		if ref.Expr == &call.Call.Fun {
   788  			ref.Expr = &fcall.Fun
   789  
   790  			// If this call expects two results, we have to
   791  			// adjust the results of the function we generated.
   792  			if ref.Context == "call2" {
   793  				if ftype.Results == nil {
   794  					// An explicit void argument
   795  					// looks odd but it seems to
   796  					// be how cgo has worked historically.
   797  					ftype.Results = &ast.FieldList{
   798  						List: []*ast.Field{
   799  							&ast.Field{
   800  								Type: ast.NewIdent("_Ctype_void"),
   801  							},
   802  						},
   803  					}
   804  				}
   805  				ftype.Results.List = append(ftype.Results.List,
   806  					&ast.Field{
   807  						Type: ast.NewIdent("error"),
   808  					})
   809  			}
   810  		}
   811  	}
   812  
   813  	var fbody ast.Stmt
   814  	if ftype.Results == nil {
   815  		fbody = &ast.ExprStmt{
   816  			X: fcall,
   817  		}
   818  	} else {
   819  		fbody = &ast.ReturnStmt{
   820  			Results: []ast.Expr{fcall},
   821  		}
   822  	}
   823  	call.Call.Fun = &ast.FuncLit{
   824  		Type: ftype,
   825  		Body: &ast.BlockStmt{
   826  			List: append(stmts, fbody),
   827  		},
   828  	}
   829  	call.Call.Lparen = token.NoPos
   830  	call.Call.Rparen = token.NoPos
   831  
   832  	return needsUnsafe
   833  }
   834  
   835  // needsPointerCheck returns whether the type t needs a pointer check.
   836  // This is true if t is a pointer and if the value to which it points
   837  // might contain a pointer.
   838  func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
   839  	// An untyped nil does not need a pointer check, and when
   840  	// _cgoCheckPointer returns the untyped nil the type assertion we
   841  	// are going to insert will fail.  Easier to just skip nil arguments.
   842  	// TODO: Note that this fails if nil is shadowed.
   843  	if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
   844  		return false
   845  	}
   846  
   847  	return p.hasPointer(f, t, true)
   848  }
   849  
   850  // hasPointer is used by needsPointerCheck. If top is true it returns
   851  // whether t is or contains a pointer that might point to a pointer.
   852  // If top is false it returns whether t is or contains a pointer.
   853  // f may be nil.
   854  func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
   855  	switch t := t.(type) {
   856  	case *ast.ArrayType:
   857  		if t.Len == nil {
   858  			if !top {
   859  				return true
   860  			}
   861  			return p.hasPointer(f, t.Elt, false)
   862  		}
   863  		return p.hasPointer(f, t.Elt, top)
   864  	case *ast.StructType:
   865  		for _, field := range t.Fields.List {
   866  			if p.hasPointer(f, field.Type, top) {
   867  				return true
   868  			}
   869  		}
   870  		return false
   871  	case *ast.StarExpr: // Pointer type.
   872  		if !top {
   873  			return true
   874  		}
   875  		// Check whether this is a pointer to a C union (or class)
   876  		// type that contains a pointer.
   877  		if unionWithPointer[t.X] {
   878  			return true
   879  		}
   880  		return p.hasPointer(f, t.X, false)
   881  	case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
   882  		return true
   883  	case *ast.Ident:
   884  		// TODO: Handle types defined within function.
   885  		for _, d := range p.Decl {
   886  			gd, ok := d.(*ast.GenDecl)
   887  			if !ok || gd.Tok != token.TYPE {
   888  				continue
   889  			}
   890  			for _, spec := range gd.Specs {
   891  				ts, ok := spec.(*ast.TypeSpec)
   892  				if !ok {
   893  					continue
   894  				}
   895  				if ts.Name.Name == t.Name {
   896  					return p.hasPointer(f, ts.Type, top)
   897  				}
   898  			}
   899  		}
   900  		if def := typedef[t.Name]; def != nil {
   901  			return p.hasPointer(f, def.Go, top)
   902  		}
   903  		if t.Name == "string" {
   904  			return !top
   905  		}
   906  		if t.Name == "error" {
   907  			return true
   908  		}
   909  		if goTypes[t.Name] != nil {
   910  			return false
   911  		}
   912  		// We can't figure out the type. Conservative
   913  		// approach is to assume it has a pointer.
   914  		return true
   915  	case *ast.SelectorExpr:
   916  		if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
   917  			// Type defined in a different package.
   918  			// Conservative approach is to assume it has a
   919  			// pointer.
   920  			return true
   921  		}
   922  		if f == nil {
   923  			// Conservative approach: assume pointer.
   924  			return true
   925  		}
   926  		name := f.Name[t.Sel.Name]
   927  		if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
   928  			return p.hasPointer(f, name.Type.Go, top)
   929  		}
   930  		// We can't figure out the type. Conservative
   931  		// approach is to assume it has a pointer.
   932  		return true
   933  	default:
   934  		error_(t.Pos(), "could not understand type %s", gofmt(t))
   935  		return true
   936  	}
   937  }
   938  
   939  // checkAddrArgs tries to add arguments to the call of
   940  // _cgoCheckPointer when the argument is an address expression. We
   941  // pass true to mean that the argument is an address operation of
   942  // something other than a slice index, which means that it's only
   943  // necessary to check the specific element pointed to, not the entire
   944  // object. This is for &s.f, where f is a field in a struct. We can
   945  // pass a slice or array, meaning that we should check the entire
   946  // slice or array but need not check any other part of the object.
   947  // This is for &s.a[i], where we need to check all of a. However, we
   948  // only pass the slice or array if we can refer to it without side
   949  // effects.
   950  func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr {
   951  	// Strip type conversions.
   952  	for {
   953  		c, ok := x.(*ast.CallExpr)
   954  		if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
   955  			break
   956  		}
   957  		x = c.Args[0]
   958  	}
   959  	u, ok := x.(*ast.UnaryExpr)
   960  	if !ok || u.Op != token.AND {
   961  		return args
   962  	}
   963  	index, ok := u.X.(*ast.IndexExpr)
   964  	if !ok {
   965  		// This is the address of something that is not an
   966  		// index expression. We only need to examine the
   967  		// single value to which it points.
   968  		// TODO: what if true is shadowed?
   969  		return append(args, ast.NewIdent("true"))
   970  	}
   971  	if !p.hasSideEffects(f, index.X) {
   972  		// Examine the entire slice.
   973  		return append(args, index.X)
   974  	}
   975  	// Treat the pointer as unknown.
   976  	return args
   977  }
   978  
   979  // hasSideEffects returns whether the expression x has any side
   980  // effects.  x is an expression, not a statement, so the only side
   981  // effect is a function call.
   982  func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
   983  	found := false
   984  	f.walk(x, "expr",
   985  		func(f *File, x interface{}, context string) {
   986  			switch x.(type) {
   987  			case *ast.CallExpr:
   988  				found = true
   989  			}
   990  		})
   991  	return found
   992  }
   993  
   994  // isType returns whether the expression is definitely a type.
   995  // This is conservative--it returns false for an unknown identifier.
   996  func (p *Package) isType(t ast.Expr) bool {
   997  	switch t := t.(type) {
   998  	case *ast.SelectorExpr:
   999  		id, ok := t.X.(*ast.Ident)
  1000  		if !ok {
  1001  			return false
  1002  		}
  1003  		if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
  1004  			return true
  1005  		}
  1006  		if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
  1007  			return true
  1008  		}
  1009  		return false
  1010  	case *ast.Ident:
  1011  		// TODO: This ignores shadowing.
  1012  		switch t.Name {
  1013  		case "unsafe.Pointer", "bool", "byte",
  1014  			"complex64", "complex128",
  1015  			"error",
  1016  			"float32", "float64",
  1017  			"int", "int8", "int16", "int32", "int64",
  1018  			"rune", "string",
  1019  			"uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
  1020  
  1021  			return true
  1022  		}
  1023  	case *ast.StarExpr:
  1024  		return p.isType(t.X)
  1025  	case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
  1026  		*ast.MapType, *ast.ChanType:
  1027  
  1028  		return true
  1029  	}
  1030  	return false
  1031  }
  1032  
  1033  // rewriteUnsafe returns a version of t with references to unsafe.Pointer
  1034  // rewritten to use _cgo_unsafe.Pointer instead.
  1035  func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
  1036  	switch t := t.(type) {
  1037  	case *ast.Ident:
  1038  		// We don't see a SelectorExpr for unsafe.Pointer;
  1039  		// this is created by code in this file.
  1040  		if t.Name == "unsafe.Pointer" {
  1041  			return ast.NewIdent("_cgo_unsafe.Pointer")
  1042  		}
  1043  	case *ast.ArrayType:
  1044  		t1 := p.rewriteUnsafe(t.Elt)
  1045  		if t1 != t.Elt {
  1046  			r := *t
  1047  			r.Elt = t1
  1048  			return &r
  1049  		}
  1050  	case *ast.StructType:
  1051  		changed := false
  1052  		fields := *t.Fields
  1053  		fields.List = nil
  1054  		for _, f := range t.Fields.List {
  1055  			ft := p.rewriteUnsafe(f.Type)
  1056  			if ft == f.Type {
  1057  				fields.List = append(fields.List, f)
  1058  			} else {
  1059  				fn := *f
  1060  				fn.Type = ft
  1061  				fields.List = append(fields.List, &fn)
  1062  				changed = true
  1063  			}
  1064  		}
  1065  		if changed {
  1066  			r := *t
  1067  			r.Fields = &fields
  1068  			return &r
  1069  		}
  1070  	case *ast.StarExpr: // Pointer type.
  1071  		x1 := p.rewriteUnsafe(t.X)
  1072  		if x1 != t.X {
  1073  			r := *t
  1074  			r.X = x1
  1075  			return &r
  1076  		}
  1077  	}
  1078  	return t
  1079  }
  1080  
  1081  // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
  1082  // Go equivalents, now that we have figured out the meaning of all
  1083  // the xxx. In *godefs mode, rewriteRef replaces the names
  1084  // with full definitions instead of mangled names.
  1085  func (p *Package) rewriteRef(f *File) {
  1086  	// Keep a list of all the functions, to remove the ones
  1087  	// only used as expressions and avoid generating bridge
  1088  	// code for them.
  1089  	functions := make(map[string]bool)
  1090  
  1091  	// Assign mangled names.
  1092  	for _, n := range f.Name {
  1093  		if n.Kind == "not-type" {
  1094  			n.Kind = "var"
  1095  		}
  1096  		if n.Mangle == "" {
  1097  			p.mangleName(n)
  1098  		}
  1099  		if n.Kind == "func" {
  1100  			functions[n.Go] = false
  1101  		}
  1102  	}
  1103  
  1104  	// Now that we have all the name types filled in,
  1105  	// scan through the Refs to identify the ones that
  1106  	// are trying to do a ,err call. Also check that
  1107  	// functions are only used in calls.
  1108  	for _, r := range f.Ref {
  1109  		if r.Name.IsConst() && r.Name.Const == "" {
  1110  			error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
  1111  		}
  1112  		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
  1113  		switch r.Context {
  1114  		case "call", "call2":
  1115  			if r.Name.Kind != "func" {
  1116  				if r.Name.Kind == "type" {
  1117  					r.Context = "type"
  1118  					if r.Name.Type == nil {
  1119  						error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1120  						break
  1121  					}
  1122  					expr = r.Name.Type.Go
  1123  					break
  1124  				}
  1125  				error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
  1126  				break
  1127  			}
  1128  			functions[r.Name.Go] = true
  1129  			if r.Context == "call2" {
  1130  				if r.Name.Go == "_CMalloc" {
  1131  					error_(r.Pos(), "no two-result form for C.malloc")
  1132  					break
  1133  				}
  1134  				// Invent new Name for the two-result function.
  1135  				n := f.Name["2"+r.Name.Go]
  1136  				if n == nil {
  1137  					n = new(Name)
  1138  					*n = *r.Name
  1139  					n.AddError = true
  1140  					n.Mangle = "_C2func_" + n.Go
  1141  					f.Name["2"+r.Name.Go] = n
  1142  				}
  1143  				expr = ast.NewIdent(n.Mangle)
  1144  				r.Name = n
  1145  				break
  1146  			}
  1147  		case "expr":
  1148  			if r.Name.Kind == "func" {
  1149  				if builtinDefs[r.Name.C] != "" {
  1150  					error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
  1151  				}
  1152  
  1153  				// Function is being used in an expression, to e.g. pass around a C function pointer.
  1154  				// Create a new Name for this Ref which causes the variable to be declared in Go land.
  1155  				fpName := "fp_" + r.Name.Go
  1156  				name := f.Name[fpName]
  1157  				if name == nil {
  1158  					name = &Name{
  1159  						Go:   fpName,
  1160  						C:    r.Name.C,
  1161  						Kind: "fpvar",
  1162  						Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
  1163  					}
  1164  					p.mangleName(name)
  1165  					f.Name[fpName] = name
  1166  				}
  1167  				r.Name = name
  1168  				// Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
  1169  				// function is defined in out.go and simply returns its argument. See
  1170  				// issue 7757.
  1171  				expr = &ast.CallExpr{
  1172  					Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
  1173  					Args: []ast.Expr{ast.NewIdent(name.Mangle)},
  1174  				}
  1175  			} else if r.Name.Kind == "type" {
  1176  				// Okay - might be new(T)
  1177  				if r.Name.Type == nil {
  1178  					error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1179  					break
  1180  				}
  1181  				expr = r.Name.Type.Go
  1182  			} else if r.Name.Kind == "var" {
  1183  				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
  1184  			}
  1185  
  1186  		case "selector":
  1187  			if r.Name.Kind == "var" {
  1188  				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
  1189  			} else {
  1190  				error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
  1191  			}
  1192  
  1193  		case "type":
  1194  			if r.Name.Kind != "type" {
  1195  				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
  1196  			} else if r.Name.Type == nil {
  1197  				// Use of C.enum_x, C.struct_x or C.union_x without C definition.
  1198  				// GCC won't raise an error when using pointers to such unknown types.
  1199  				error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1200  			} else {
  1201  				expr = r.Name.Type.Go
  1202  			}
  1203  		default:
  1204  			if r.Name.Kind == "func" {
  1205  				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
  1206  			}
  1207  		}
  1208  		if *godefs {
  1209  			// Substitute definition for mangled type name.
  1210  			if id, ok := expr.(*ast.Ident); ok {
  1211  				if t := typedef[id.Name]; t != nil {
  1212  					expr = t.Go
  1213  				}
  1214  				if id.Name == r.Name.Mangle && r.Name.Const != "" {
  1215  					expr = ast.NewIdent(r.Name.Const)
  1216  				}
  1217  			}
  1218  		}
  1219  
  1220  		// Copy position information from old expr into new expr,
  1221  		// in case expression being replaced is first on line.
  1222  		// See golang.org/issue/6563.
  1223  		pos := (*r.Expr).Pos()
  1224  		switch x := expr.(type) {
  1225  		case *ast.Ident:
  1226  			expr = &ast.Ident{NamePos: pos, Name: x.Name}
  1227  		}
  1228  
  1229  		*r.Expr = expr
  1230  	}
  1231  
  1232  	// Remove functions only used as expressions, so their respective
  1233  	// bridge functions are not generated.
  1234  	for name, used := range functions {
  1235  		if !used {
  1236  			delete(f.Name, name)
  1237  		}
  1238  	}
  1239  }
  1240  
  1241  // gccBaseCmd returns the start of the compiler command line.
  1242  // It uses $CC if set, or else $GCC, or else the compiler recorded
  1243  // during the initial build as defaultCC.
  1244  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  1245  func (p *Package) gccBaseCmd() []string {
  1246  	// Use $CC if set, since that's what the build uses.
  1247  	if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
  1248  		return ret
  1249  	}
  1250  	// Try $GCC if set, since that's what we used to use.
  1251  	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
  1252  		return ret
  1253  	}
  1254  	return strings.Fields(defaultCC)
  1255  }
  1256  
  1257  // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
  1258  func (p *Package) gccMachine() []string {
  1259  	switch goarch {
  1260  	case "amd64":
  1261  		return []string{"-m64"}
  1262  	case "386":
  1263  		return []string{"-m32"}
  1264  	case "arm":
  1265  		return []string{"-marm"} // not thumb
  1266  	case "s390":
  1267  		return []string{"-m31"}
  1268  	case "s390x":
  1269  		return []string{"-m64"}
  1270  	case "mips64", "mips64le":
  1271  		return []string{"-mabi=64"}
  1272  	case "mips", "mipsle":
  1273  		return []string{"-mabi=32"}
  1274  	}
  1275  	return nil
  1276  }
  1277  
  1278  func gccTmp() string {
  1279  	return *objDir + "_cgo_.o"
  1280  }
  1281  
  1282  // gccCmd returns the gcc command line to use for compiling
  1283  // the input.
  1284  func (p *Package) gccCmd() []string {
  1285  	c := append(p.gccBaseCmd(),
  1286  		"-w",          // no warnings
  1287  		"-Wno-error",  // warnings are not errors
  1288  		"-o"+gccTmp(), // write object to tmp
  1289  		"-gdwarf-2",   // generate DWARF v2 debugging symbols
  1290  		"-c",          // do not link
  1291  		"-xc",         // input language is C
  1292  	)
  1293  	if p.GccIsClang {
  1294  		c = append(c,
  1295  			"-ferror-limit=0",
  1296  			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
  1297  			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
  1298  			// flag to disable the warning. Yes, really good diagnostics, clang.
  1299  			"-Wno-unknown-warning-option",
  1300  			"-Wno-unneeded-internal-declaration",
  1301  			"-Wno-unused-function",
  1302  			"-Qunused-arguments",
  1303  			// Clang embeds prototypes for some builtin functions,
  1304  			// like malloc and calloc, but all size_t parameters are
  1305  			// incorrectly typed unsigned long. We work around that
  1306  			// by disabling the builtin functions (this is safe as
  1307  			// it won't affect the actual compilation of the C code).
  1308  			// See: https://golang.org/issue/6506.
  1309  			"-fno-builtin",
  1310  		)
  1311  	}
  1312  
  1313  	c = append(c, p.GccOptions...)
  1314  	c = append(c, p.gccMachine()...)
  1315  	c = append(c, "-") //read input from standard input
  1316  	return c
  1317  }
  1318  
  1319  // gccDebug runs gcc -gdwarf-2 over the C program stdin and
  1320  // returns the corresponding DWARF data and, if present, debug data block.
  1321  func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
  1322  	runGcc(stdin, p.gccCmd())
  1323  
  1324  	isDebugInts := func(s string) bool {
  1325  		// Some systems use leading _ to denote non-assembly symbols.
  1326  		return s == "__cgodebug_ints" || s == "___cgodebug_ints"
  1327  	}
  1328  	isDebugFloats := func(s string) bool {
  1329  		// Some systems use leading _ to denote non-assembly symbols.
  1330  		return s == "__cgodebug_floats" || s == "___cgodebug_floats"
  1331  	}
  1332  	indexOfDebugStr := func(s string) int {
  1333  		// Some systems use leading _ to denote non-assembly symbols.
  1334  		if strings.HasPrefix(s, "___") {
  1335  			s = s[1:]
  1336  		}
  1337  		if strings.HasPrefix(s, "__cgodebug_str__") {
  1338  			if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
  1339  				return n
  1340  			}
  1341  		}
  1342  		return -1
  1343  	}
  1344  	indexOfDebugStrlen := func(s string) int {
  1345  		// Some systems use leading _ to denote non-assembly symbols.
  1346  		if strings.HasPrefix(s, "___") {
  1347  			s = s[1:]
  1348  		}
  1349  		if strings.HasPrefix(s, "__cgodebug_strlen__") {
  1350  			if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
  1351  				return n
  1352  			}
  1353  		}
  1354  		return -1
  1355  	}
  1356  
  1357  	strs = make([]string, nnames)
  1358  
  1359  	strdata := make(map[int]string, nnames)
  1360  	strlens := make(map[int]int, nnames)
  1361  
  1362  	buildStrings := func() {
  1363  		for n, strlen := range strlens {
  1364  			data := strdata[n]
  1365  			if len(data) <= strlen {
  1366  				fatalf("invalid string literal")
  1367  			}
  1368  			strs[n] = string(data[:strlen])
  1369  		}
  1370  	}
  1371  
  1372  	if f, err := macho.Open(gccTmp()); err == nil {
  1373  		defer f.Close()
  1374  		d, err := f.DWARF()
  1375  		if err != nil {
  1376  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1377  		}
  1378  		bo := f.ByteOrder
  1379  		if f.Symtab != nil {
  1380  			for i := range f.Symtab.Syms {
  1381  				s := &f.Symtab.Syms[i]
  1382  				switch {
  1383  				case isDebugInts(s.Name):
  1384  					// Found it. Now find data section.
  1385  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1386  						sect := f.Sections[i]
  1387  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1388  							if sdat, err := sect.Data(); err == nil {
  1389  								data := sdat[s.Value-sect.Addr:]
  1390  								ints = make([]int64, len(data)/8)
  1391  								for i := range ints {
  1392  									ints[i] = int64(bo.Uint64(data[i*8:]))
  1393  								}
  1394  							}
  1395  						}
  1396  					}
  1397  				case isDebugFloats(s.Name):
  1398  					// Found it. Now find data section.
  1399  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1400  						sect := f.Sections[i]
  1401  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1402  							if sdat, err := sect.Data(); err == nil {
  1403  								data := sdat[s.Value-sect.Addr:]
  1404  								floats = make([]float64, len(data)/8)
  1405  								for i := range floats {
  1406  									floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  1407  								}
  1408  							}
  1409  						}
  1410  					}
  1411  				default:
  1412  					if n := indexOfDebugStr(s.Name); n != -1 {
  1413  						// Found it. Now find data section.
  1414  						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1415  							sect := f.Sections[i]
  1416  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1417  								if sdat, err := sect.Data(); err == nil {
  1418  									data := sdat[s.Value-sect.Addr:]
  1419  									strdata[n] = string(data)
  1420  								}
  1421  							}
  1422  						}
  1423  						break
  1424  					}
  1425  					if n := indexOfDebugStrlen(s.Name); n != -1 {
  1426  						// Found it. Now find data section.
  1427  						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1428  							sect := f.Sections[i]
  1429  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1430  								if sdat, err := sect.Data(); err == nil {
  1431  									data := sdat[s.Value-sect.Addr:]
  1432  									strlen := bo.Uint64(data[:8])
  1433  									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1434  										fatalf("string literal too big")
  1435  									}
  1436  									strlens[n] = int(strlen)
  1437  								}
  1438  							}
  1439  						}
  1440  						break
  1441  					}
  1442  				}
  1443  			}
  1444  
  1445  			buildStrings()
  1446  		}
  1447  		return d, ints, floats, strs
  1448  	}
  1449  
  1450  	if f, err := elf.Open(gccTmp()); err == nil {
  1451  		defer f.Close()
  1452  		d, err := f.DWARF()
  1453  		if err != nil {
  1454  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1455  		}
  1456  		bo := f.ByteOrder
  1457  		symtab, err := f.Symbols()
  1458  		if err == nil {
  1459  			for i := range symtab {
  1460  				s := &symtab[i]
  1461  				switch {
  1462  				case isDebugInts(s.Name):
  1463  					// Found it. Now find data section.
  1464  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1465  						sect := f.Sections[i]
  1466  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1467  							if sdat, err := sect.Data(); err == nil {
  1468  								data := sdat[s.Value-sect.Addr:]
  1469  								ints = make([]int64, len(data)/8)
  1470  								for i := range ints {
  1471  									ints[i] = int64(bo.Uint64(data[i*8:]))
  1472  								}
  1473  							}
  1474  						}
  1475  					}
  1476  				case isDebugFloats(s.Name):
  1477  					// Found it. Now find data section.
  1478  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1479  						sect := f.Sections[i]
  1480  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1481  							if sdat, err := sect.Data(); err == nil {
  1482  								data := sdat[s.Value-sect.Addr:]
  1483  								floats = make([]float64, len(data)/8)
  1484  								for i := range floats {
  1485  									floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  1486  								}
  1487  							}
  1488  						}
  1489  					}
  1490  				default:
  1491  					if n := indexOfDebugStr(s.Name); n != -1 {
  1492  						// Found it. Now find data section.
  1493  						if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1494  							sect := f.Sections[i]
  1495  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1496  								if sdat, err := sect.Data(); err == nil {
  1497  									data := sdat[s.Value-sect.Addr:]
  1498  									strdata[n] = string(data)
  1499  								}
  1500  							}
  1501  						}
  1502  						break
  1503  					}
  1504  					if n := indexOfDebugStrlen(s.Name); n != -1 {
  1505  						// Found it. Now find data section.
  1506  						if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1507  							sect := f.Sections[i]
  1508  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1509  								if sdat, err := sect.Data(); err == nil {
  1510  									data := sdat[s.Value-sect.Addr:]
  1511  									strlen := bo.Uint64(data[:8])
  1512  									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1513  										fatalf("string literal too big")
  1514  									}
  1515  									strlens[n] = int(strlen)
  1516  								}
  1517  							}
  1518  						}
  1519  						break
  1520  					}
  1521  				}
  1522  			}
  1523  
  1524  			buildStrings()
  1525  		}
  1526  		return d, ints, floats, strs
  1527  	}
  1528  
  1529  	if f, err := pe.Open(gccTmp()); err == nil {
  1530  		defer f.Close()
  1531  		d, err := f.DWARF()
  1532  		if err != nil {
  1533  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1534  		}
  1535  		bo := binary.LittleEndian
  1536  		for _, s := range f.Symbols {
  1537  			switch {
  1538  			case isDebugInts(s.Name):
  1539  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1540  					sect := f.Sections[i]
  1541  					if s.Value < sect.Size {
  1542  						if sdat, err := sect.Data(); err == nil {
  1543  							data := sdat[s.Value:]
  1544  							ints = make([]int64, len(data)/8)
  1545  							for i := range ints {
  1546  								ints[i] = int64(bo.Uint64(data[i*8:]))
  1547  							}
  1548  						}
  1549  					}
  1550  				}
  1551  			case isDebugFloats(s.Name):
  1552  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1553  					sect := f.Sections[i]
  1554  					if s.Value < sect.Size {
  1555  						if sdat, err := sect.Data(); err == nil {
  1556  							data := sdat[s.Value:]
  1557  							floats = make([]float64, len(data)/8)
  1558  							for i := range floats {
  1559  								floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  1560  							}
  1561  						}
  1562  					}
  1563  				}
  1564  			default:
  1565  				if n := indexOfDebugStr(s.Name); n != -1 {
  1566  					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1567  						sect := f.Sections[i]
  1568  						if s.Value < sect.Size {
  1569  							if sdat, err := sect.Data(); err == nil {
  1570  								data := sdat[s.Value:]
  1571  								strdata[n] = string(data)
  1572  							}
  1573  						}
  1574  					}
  1575  					break
  1576  				}
  1577  				if n := indexOfDebugStrlen(s.Name); n != -1 {
  1578  					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1579  						sect := f.Sections[i]
  1580  						if s.Value < sect.Size {
  1581  							if sdat, err := sect.Data(); err == nil {
  1582  								data := sdat[s.Value:]
  1583  								strlen := bo.Uint64(data[:8])
  1584  								if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1585  									fatalf("string literal too big")
  1586  								}
  1587  								strlens[n] = int(strlen)
  1588  							}
  1589  						}
  1590  					}
  1591  					break
  1592  				}
  1593  			}
  1594  		}
  1595  
  1596  		buildStrings()
  1597  
  1598  		return d, ints, floats, strs
  1599  	}
  1600  
  1601  	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
  1602  	panic("not reached")
  1603  }
  1604  
  1605  // gccDefines runs gcc -E -dM -xc - over the C program stdin
  1606  // and returns the corresponding standard output, which is the
  1607  // #defines that gcc encountered while processing the input
  1608  // and its included files.
  1609  func (p *Package) gccDefines(stdin []byte) string {
  1610  	base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
  1611  	base = append(base, p.gccMachine()...)
  1612  	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
  1613  	return stdout
  1614  }
  1615  
  1616  // gccErrors runs gcc over the C program stdin and returns
  1617  // the errors that gcc prints. That is, this function expects
  1618  // gcc to fail.
  1619  func (p *Package) gccErrors(stdin []byte) string {
  1620  	// TODO(rsc): require failure
  1621  	args := p.gccCmd()
  1622  
  1623  	// Optimization options can confuse the error messages; remove them.
  1624  	nargs := make([]string, 0, len(args))
  1625  	for _, arg := range args {
  1626  		if !strings.HasPrefix(arg, "-O") {
  1627  			nargs = append(nargs, arg)
  1628  		}
  1629  	}
  1630  
  1631  	if *debugGcc {
  1632  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
  1633  		os.Stderr.Write(stdin)
  1634  		fmt.Fprint(os.Stderr, "EOF\n")
  1635  	}
  1636  	stdout, stderr, _ := run(stdin, nargs)
  1637  	if *debugGcc {
  1638  		os.Stderr.Write(stdout)
  1639  		os.Stderr.Write(stderr)
  1640  	}
  1641  	return string(stderr)
  1642  }
  1643  
  1644  // runGcc runs the gcc command line args with stdin on standard input.
  1645  // If the command exits with a non-zero exit status, runGcc prints
  1646  // details about what was run and exits.
  1647  // Otherwise runGcc returns the data written to standard output and standard error.
  1648  // Note that for some of the uses we expect useful data back
  1649  // on standard error, but for those uses gcc must still exit 0.
  1650  func runGcc(stdin []byte, args []string) (string, string) {
  1651  	if *debugGcc {
  1652  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
  1653  		os.Stderr.Write(stdin)
  1654  		fmt.Fprint(os.Stderr, "EOF\n")
  1655  	}
  1656  	stdout, stderr, ok := run(stdin, args)
  1657  	if *debugGcc {
  1658  		os.Stderr.Write(stdout)
  1659  		os.Stderr.Write(stderr)
  1660  	}
  1661  	if !ok {
  1662  		os.Stderr.Write(stderr)
  1663  		os.Exit(2)
  1664  	}
  1665  	return string(stdout), string(stderr)
  1666  }
  1667  
  1668  // A typeConv is a translator from dwarf types to Go types
  1669  // with equivalent memory layout.
  1670  type typeConv struct {
  1671  	// Cache of already-translated or in-progress types.
  1672  	m map[dwarf.Type]*Type
  1673  
  1674  	// Map from types to incomplete pointers to those types.
  1675  	ptrs map[dwarf.Type][]*Type
  1676  	// Keys of ptrs in insertion order (deterministic worklist)
  1677  	ptrKeys []dwarf.Type
  1678  
  1679  	// Predeclared types.
  1680  	bool                                   ast.Expr
  1681  	byte                                   ast.Expr // denotes padding
  1682  	int8, int16, int32, int64              ast.Expr
  1683  	uint8, uint16, uint32, uint64, uintptr ast.Expr
  1684  	float32, float64                       ast.Expr
  1685  	complex64, complex128                  ast.Expr
  1686  	void                                   ast.Expr
  1687  	string                                 ast.Expr
  1688  	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
  1689  	goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
  1690  
  1691  	ptrSize int64
  1692  	intSize int64
  1693  }
  1694  
  1695  var tagGen int
  1696  var typedef = make(map[string]*Type)
  1697  var goIdent = make(map[string]*ast.Ident)
  1698  
  1699  // unionWithPointer is true for a Go type that represents a C union (or class)
  1700  // that may contain a pointer. This is used for cgo pointer checking.
  1701  var unionWithPointer = make(map[ast.Expr]bool)
  1702  
  1703  func (c *typeConv) Init(ptrSize, intSize int64) {
  1704  	c.ptrSize = ptrSize
  1705  	c.intSize = intSize
  1706  	c.m = make(map[dwarf.Type]*Type)
  1707  	c.ptrs = make(map[dwarf.Type][]*Type)
  1708  	c.bool = c.Ident("bool")
  1709  	c.byte = c.Ident("byte")
  1710  	c.int8 = c.Ident("int8")
  1711  	c.int16 = c.Ident("int16")
  1712  	c.int32 = c.Ident("int32")
  1713  	c.int64 = c.Ident("int64")
  1714  	c.uint8 = c.Ident("uint8")
  1715  	c.uint16 = c.Ident("uint16")
  1716  	c.uint32 = c.Ident("uint32")
  1717  	c.uint64 = c.Ident("uint64")
  1718  	c.uintptr = c.Ident("uintptr")
  1719  	c.float32 = c.Ident("float32")
  1720  	c.float64 = c.Ident("float64")
  1721  	c.complex64 = c.Ident("complex64")
  1722  	c.complex128 = c.Ident("complex128")
  1723  	c.void = c.Ident("void")
  1724  	c.string = c.Ident("string")
  1725  	c.goVoid = c.Ident("_Ctype_void")
  1726  
  1727  	// Normally cgo translates void* to unsafe.Pointer,
  1728  	// but for historical reasons -godefs uses *byte instead.
  1729  	if *godefs {
  1730  		c.goVoidPtr = &ast.StarExpr{X: c.byte}
  1731  	} else {
  1732  		c.goVoidPtr = c.Ident("unsafe.Pointer")
  1733  	}
  1734  }
  1735  
  1736  // base strips away qualifiers and typedefs to get the underlying type
  1737  func base(dt dwarf.Type) dwarf.Type {
  1738  	for {
  1739  		if d, ok := dt.(*dwarf.QualType); ok {
  1740  			dt = d.Type
  1741  			continue
  1742  		}
  1743  		if d, ok := dt.(*dwarf.TypedefType); ok {
  1744  			dt = d.Type
  1745  			continue
  1746  		}
  1747  		break
  1748  	}
  1749  	return dt
  1750  }
  1751  
  1752  // unqual strips away qualifiers from a DWARF type.
  1753  // In general we don't care about top-level qualifiers.
  1754  func unqual(dt dwarf.Type) dwarf.Type {
  1755  	for {
  1756  		if d, ok := dt.(*dwarf.QualType); ok {
  1757  			dt = d.Type
  1758  		} else {
  1759  			break
  1760  		}
  1761  	}
  1762  	return dt
  1763  }
  1764  
  1765  // Map from dwarf text names to aliases we use in package "C".
  1766  var dwarfToName = map[string]string{
  1767  	"long int":               "long",
  1768  	"long unsigned int":      "ulong",
  1769  	"unsigned int":           "uint",
  1770  	"short unsigned int":     "ushort",
  1771  	"unsigned short":         "ushort", // Used by Clang; issue 13129.
  1772  	"short int":              "short",
  1773  	"long long int":          "longlong",
  1774  	"long long unsigned int": "ulonglong",
  1775  	"signed char":            "schar",
  1776  	"unsigned char":          "uchar",
  1777  }
  1778  
  1779  const signedDelta = 64
  1780  
  1781  // String returns the current type representation. Format arguments
  1782  // are assembled within this method so that any changes in mutable
  1783  // values are taken into account.
  1784  func (tr *TypeRepr) String() string {
  1785  	if len(tr.Repr) == 0 {
  1786  		return ""
  1787  	}
  1788  	if len(tr.FormatArgs) == 0 {
  1789  		return tr.Repr
  1790  	}
  1791  	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
  1792  }
  1793  
  1794  // Empty reports whether the result of String would be "".
  1795  func (tr *TypeRepr) Empty() bool {
  1796  	return len(tr.Repr) == 0
  1797  }
  1798  
  1799  // Set modifies the type representation.
  1800  // If fargs are provided, repr is used as a format for fmt.Sprintf.
  1801  // Otherwise, repr is used unprocessed as the type representation.
  1802  func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
  1803  	tr.Repr = repr
  1804  	tr.FormatArgs = fargs
  1805  }
  1806  
  1807  // FinishType completes any outstanding type mapping work.
  1808  // In particular, it resolves incomplete pointer types.
  1809  func (c *typeConv) FinishType(pos token.Pos) {
  1810  	// Completing one pointer type might produce more to complete.
  1811  	// Keep looping until they're all done.
  1812  	for len(c.ptrKeys) > 0 {
  1813  		dtype := c.ptrKeys[0]
  1814  		c.ptrKeys = c.ptrKeys[1:]
  1815  
  1816  		// Note Type might invalidate c.ptrs[dtype].
  1817  		t := c.Type(dtype, pos)
  1818  		for _, ptr := range c.ptrs[dtype] {
  1819  			ptr.Go.(*ast.StarExpr).X = t.Go
  1820  			ptr.C.Set("%s*", t.C)
  1821  		}
  1822  		c.ptrs[dtype] = nil // retain the map key
  1823  	}
  1824  }
  1825  
  1826  // Type returns a *Type with the same memory layout as
  1827  // dtype when used as the type of a variable or a struct field.
  1828  func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
  1829  	if t, ok := c.m[dtype]; ok {
  1830  		if t.Go == nil {
  1831  			fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
  1832  		}
  1833  		return t
  1834  	}
  1835  
  1836  	t := new(Type)
  1837  	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
  1838  	t.Align = -1
  1839  	t.C = &TypeRepr{Repr: dtype.Common().Name}
  1840  	c.m[dtype] = t
  1841  
  1842  	switch dt := dtype.(type) {
  1843  	default:
  1844  		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
  1845  
  1846  	case *dwarf.AddrType:
  1847  		if t.Size != c.ptrSize {
  1848  			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
  1849  		}
  1850  		t.Go = c.uintptr
  1851  		t.Align = t.Size
  1852  
  1853  	case *dwarf.ArrayType:
  1854  		if dt.StrideBitSize > 0 {
  1855  			// Cannot represent bit-sized elements in Go.
  1856  			t.Go = c.Opaque(t.Size)
  1857  			break
  1858  		}
  1859  		count := dt.Count
  1860  		if count == -1 {
  1861  			// Indicates flexible array member, which Go doesn't support.
  1862  			// Translate to zero-length array instead.
  1863  			count = 0
  1864  		}
  1865  		sub := c.Type(dt.Type, pos)
  1866  		t.Align = sub.Align
  1867  		t.Go = &ast.ArrayType{
  1868  			Len: c.intExpr(count),
  1869  			Elt: sub.Go,
  1870  		}
  1871  		// Recalculate t.Size now that we know sub.Size.
  1872  		t.Size = count * sub.Size
  1873  		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
  1874  
  1875  	case *dwarf.BoolType:
  1876  		t.Go = c.bool
  1877  		t.Align = 1
  1878  
  1879  	case *dwarf.CharType:
  1880  		if t.Size != 1 {
  1881  			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
  1882  		}
  1883  		t.Go = c.int8
  1884  		t.Align = 1
  1885  
  1886  	case *dwarf.EnumType:
  1887  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1888  			t.Align = c.ptrSize
  1889  		}
  1890  		t.C.Set("enum " + dt.EnumName)
  1891  		signed := 0
  1892  		t.EnumValues = make(map[string]int64)
  1893  		for _, ev := range dt.Val {
  1894  			t.EnumValues[ev.Name] = ev.Val
  1895  			if ev.Val < 0 {
  1896  				signed = signedDelta
  1897  			}
  1898  		}
  1899  		switch t.Size + int64(signed) {
  1900  		default:
  1901  			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
  1902  		case 1:
  1903  			t.Go = c.uint8
  1904  		case 2:
  1905  			t.Go = c.uint16
  1906  		case 4:
  1907  			t.Go = c.uint32
  1908  		case 8:
  1909  			t.Go = c.uint64
  1910  		case 1 + signedDelta:
  1911  			t.Go = c.int8
  1912  		case 2 + signedDelta:
  1913  			t.Go = c.int16
  1914  		case 4 + signedDelta:
  1915  			t.Go = c.int32
  1916  		case 8 + signedDelta:
  1917  			t.Go = c.int64
  1918  		}
  1919  
  1920  	case *dwarf.FloatType:
  1921  		switch t.Size {
  1922  		default:
  1923  			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
  1924  		case 4:
  1925  			t.Go = c.float32
  1926  		case 8:
  1927  			t.Go = c.float64
  1928  		}
  1929  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1930  			t.Align = c.ptrSize
  1931  		}
  1932  
  1933  	case *dwarf.ComplexType:
  1934  		switch t.Size {
  1935  		default:
  1936  			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
  1937  		case 8:
  1938  			t.Go = c.complex64
  1939  		case 16:
  1940  			t.Go = c.complex128
  1941  		}
  1942  		if t.Align = t.Size / 2; t.Align >= c.ptrSize {
  1943  			t.Align = c.ptrSize
  1944  		}
  1945  
  1946  	case *dwarf.FuncType:
  1947  		// No attempt at translation: would enable calls
  1948  		// directly between worlds, but we need to moderate those.
  1949  		t.Go = c.uintptr
  1950  		t.Align = c.ptrSize
  1951  
  1952  	case *dwarf.IntType:
  1953  		if dt.BitSize > 0 {
  1954  			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
  1955  		}
  1956  		switch t.Size {
  1957  		default:
  1958  			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
  1959  		case 1:
  1960  			t.Go = c.int8
  1961  		case 2:
  1962  			t.Go = c.int16
  1963  		case 4:
  1964  			t.Go = c.int32
  1965  		case 8:
  1966  			t.Go = c.int64
  1967  		case 16:
  1968  			t.Go = &ast.ArrayType{
  1969  				Len: c.intExpr(t.Size),
  1970  				Elt: c.uint8,
  1971  			}
  1972  		}
  1973  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1974  			t.Align = c.ptrSize
  1975  		}
  1976  
  1977  	case *dwarf.PtrType:
  1978  		// Clang doesn't emit DW_AT_byte_size for pointer types.
  1979  		if t.Size != c.ptrSize && t.Size != -1 {
  1980  			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
  1981  		}
  1982  		t.Size = c.ptrSize
  1983  		t.Align = c.ptrSize
  1984  
  1985  		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
  1986  			t.Go = c.goVoidPtr
  1987  			t.C.Set("void*")
  1988  			dq := dt.Type
  1989  			for {
  1990  				if d, ok := dq.(*dwarf.QualType); ok {
  1991  					t.C.Set(d.Qual + " " + t.C.String())
  1992  					dq = d.Type
  1993  				} else {
  1994  					break
  1995  				}
  1996  			}
  1997  			break
  1998  		}
  1999  
  2000  		// Placeholder initialization; completed in FinishType.
  2001  		t.Go = &ast.StarExpr{}
  2002  		t.C.Set("<incomplete>*")
  2003  		if _, ok := c.ptrs[dt.Type]; !ok {
  2004  			c.ptrKeys = append(c.ptrKeys, dt.Type)
  2005  		}
  2006  		c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
  2007  
  2008  	case *dwarf.QualType:
  2009  		t1 := c.Type(dt.Type, pos)
  2010  		t.Size = t1.Size
  2011  		t.Align = t1.Align
  2012  		t.Go = t1.Go
  2013  		if unionWithPointer[t1.Go] {
  2014  			unionWithPointer[t.Go] = true
  2015  		}
  2016  		t.EnumValues = nil
  2017  		t.Typedef = ""
  2018  		t.C.Set("%s "+dt.Qual, t1.C)
  2019  		return t
  2020  
  2021  	case *dwarf.StructType:
  2022  		// Convert to Go struct, being careful about alignment.
  2023  		// Have to give it a name to simulate C "struct foo" references.
  2024  		tag := dt.StructName
  2025  		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
  2026  			break
  2027  		}
  2028  		if tag == "" {
  2029  			tag = "__" + strconv.Itoa(tagGen)
  2030  			tagGen++
  2031  		} else if t.C.Empty() {
  2032  			t.C.Set(dt.Kind + " " + tag)
  2033  		}
  2034  		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
  2035  		t.Go = name // publish before recursive calls
  2036  		goIdent[name.Name] = name
  2037  		if dt.ByteSize < 0 {
  2038  			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
  2039  			// so execute the basic things that the struct case would do
  2040  			// other than try to determine a Go representation.
  2041  			tt := *t
  2042  			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
  2043  			tt.Go = c.Ident("struct{}")
  2044  			typedef[name.Name] = &tt
  2045  			break
  2046  		}
  2047  		switch dt.Kind {
  2048  		case "class", "union":
  2049  			t.Go = c.Opaque(t.Size)
  2050  			if c.dwarfHasPointer(dt, pos) {
  2051  				unionWithPointer[t.Go] = true
  2052  			}
  2053  			if t.C.Empty() {
  2054  				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
  2055  			}
  2056  			t.Align = 1 // TODO: should probably base this on field alignment.
  2057  			typedef[name.Name] = t
  2058  		case "struct":
  2059  			g, csyntax, align := c.Struct(dt, pos)
  2060  			if t.C.Empty() {
  2061  				t.C.Set(csyntax)
  2062  			}
  2063  			t.Align = align
  2064  			tt := *t
  2065  			if tag != "" {
  2066  				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
  2067  			}
  2068  			tt.Go = g
  2069  			typedef[name.Name] = &tt
  2070  		}
  2071  
  2072  	case *dwarf.TypedefType:
  2073  		// Record typedef for printing.
  2074  		if dt.Name == "_GoString_" {
  2075  			// Special C name for Go string type.
  2076  			// Knows string layout used by compilers: pointer plus length,
  2077  			// which rounds up to 2 pointers after alignment.
  2078  			t.Go = c.string
  2079  			t.Size = c.ptrSize * 2
  2080  			t.Align = c.ptrSize
  2081  			break
  2082  		}
  2083  		if dt.Name == "_GoBytes_" {
  2084  			// Special C name for Go []byte type.
  2085  			// Knows slice layout used by compilers: pointer, length, cap.
  2086  			t.Go = c.Ident("[]byte")
  2087  			t.Size = c.ptrSize + 4 + 4
  2088  			t.Align = c.ptrSize
  2089  			break
  2090  		}
  2091  		name := c.Ident("_Ctype_" + dt.Name)
  2092  		goIdent[name.Name] = name
  2093  		sub := c.Type(dt.Type, pos)
  2094  		t.Go = name
  2095  		if unionWithPointer[sub.Go] {
  2096  			unionWithPointer[t.Go] = true
  2097  		}
  2098  		t.Size = sub.Size
  2099  		t.Align = sub.Align
  2100  		oldType := typedef[name.Name]
  2101  		if oldType == nil {
  2102  			tt := *t
  2103  			tt.Go = sub.Go
  2104  			typedef[name.Name] = &tt
  2105  		}
  2106  
  2107  		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
  2108  		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
  2109  		// with the base type.
  2110  		// In -godefs mode, do this for all typedefs.
  2111  		if isStructUnionClass(sub.Go) || *godefs {
  2112  			t.Go = sub.Go
  2113  
  2114  			if isStructUnionClass(sub.Go) {
  2115  				// Use the typedef name for C code.
  2116  				typedef[sub.Go.(*ast.Ident).Name].C = t.C
  2117  			}
  2118  
  2119  			// If we've seen this typedef before, and it
  2120  			// was an anonymous struct/union/class before
  2121  			// too, use the old definition.
  2122  			// TODO: it would be safer to only do this if
  2123  			// we verify that the types are the same.
  2124  			if oldType != nil && isStructUnionClass(oldType.Go) {
  2125  				t.Go = oldType.Go
  2126  			}
  2127  		}
  2128  
  2129  	case *dwarf.UcharType:
  2130  		if t.Size != 1 {
  2131  			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
  2132  		}
  2133  		t.Go = c.uint8
  2134  		t.Align = 1
  2135  
  2136  	case *dwarf.UintType:
  2137  		if dt.BitSize > 0 {
  2138  			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
  2139  		}
  2140  		switch t.Size {
  2141  		default:
  2142  			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
  2143  		case 1:
  2144  			t.Go = c.uint8
  2145  		case 2:
  2146  			t.Go = c.uint16
  2147  		case 4:
  2148  			t.Go = c.uint32
  2149  		case 8:
  2150  			t.Go = c.uint64
  2151  		case 16:
  2152  			t.Go = &ast.ArrayType{
  2153  				Len: c.intExpr(t.Size),
  2154  				Elt: c.uint8,
  2155  			}
  2156  		}
  2157  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2158  			t.Align = c.ptrSize
  2159  		}
  2160  
  2161  	case *dwarf.VoidType:
  2162  		t.Go = c.goVoid
  2163  		t.C.Set("void")
  2164  		t.Align = 1
  2165  	}
  2166  
  2167  	switch dtype.(type) {
  2168  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
  2169  		s := dtype.Common().Name
  2170  		if s != "" {
  2171  			if ss, ok := dwarfToName[s]; ok {
  2172  				s = ss
  2173  			}
  2174  			s = strings.Join(strings.Split(s, " "), "") // strip spaces
  2175  			name := c.Ident("_Ctype_" + s)
  2176  			tt := *t
  2177  			typedef[name.Name] = &tt
  2178  			if !*godefs {
  2179  				t.Go = name
  2180  			}
  2181  		}
  2182  	}
  2183  
  2184  	if t.Size < 0 {
  2185  		// Unsized types are [0]byte, unless they're typedefs of other types
  2186  		// or structs with tags.
  2187  		// if so, use the name we've already defined.
  2188  		t.Size = 0
  2189  		switch dt := dtype.(type) {
  2190  		case *dwarf.TypedefType:
  2191  			// ok
  2192  		case *dwarf.StructType:
  2193  			if dt.StructName != "" {
  2194  				break
  2195  			}
  2196  			t.Go = c.Opaque(0)
  2197  		default:
  2198  			t.Go = c.Opaque(0)
  2199  		}
  2200  		if t.C.Empty() {
  2201  			t.C.Set("void")
  2202  		}
  2203  	}
  2204  
  2205  	if t.C.Empty() {
  2206  		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
  2207  	}
  2208  
  2209  	return t
  2210  }
  2211  
  2212  // isStructUnionClass reports whether the type described by the Go syntax x
  2213  // is a struct, union, or class with a tag.
  2214  func isStructUnionClass(x ast.Expr) bool {
  2215  	id, ok := x.(*ast.Ident)
  2216  	if !ok {
  2217  		return false
  2218  	}
  2219  	name := id.Name
  2220  	return strings.HasPrefix(name, "_Ctype_struct_") ||
  2221  		strings.HasPrefix(name, "_Ctype_union_") ||
  2222  		strings.HasPrefix(name, "_Ctype_class_")
  2223  }
  2224  
  2225  // FuncArg returns a Go type with the same memory layout as
  2226  // dtype when used as the type of a C function argument.
  2227  func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
  2228  	t := c.Type(unqual(dtype), pos)
  2229  	switch dt := dtype.(type) {
  2230  	case *dwarf.ArrayType:
  2231  		// Arrays are passed implicitly as pointers in C.
  2232  		// In Go, we must be explicit.
  2233  		tr := &TypeRepr{}
  2234  		tr.Set("%s*", t.C)
  2235  		return &Type{
  2236  			Size:  c.ptrSize,
  2237  			Align: c.ptrSize,
  2238  			Go:    &ast.StarExpr{X: t.Go},
  2239  			C:     tr,
  2240  		}
  2241  	case *dwarf.TypedefType:
  2242  		// C has much more relaxed rules than Go for
  2243  		// implicit type conversions. When the parameter
  2244  		// is type T defined as *X, simulate a little of the
  2245  		// laxness of C by making the argument *X instead of T.
  2246  		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
  2247  			// Unless the typedef happens to point to void* since
  2248  			// Go has special rules around using unsafe.Pointer.
  2249  			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
  2250  				break
  2251  			}
  2252  
  2253  			t = c.Type(ptr, pos)
  2254  			if t == nil {
  2255  				return nil
  2256  			}
  2257  
  2258  			// For a struct/union/class, remember the C spelling,
  2259  			// in case it has __attribute__((unavailable)).
  2260  			// See issue 2888.
  2261  			if isStructUnionClass(t.Go) {
  2262  				t.Typedef = dt.Name
  2263  			}
  2264  		}
  2265  	}
  2266  	return t
  2267  }
  2268  
  2269  // FuncType returns the Go type analogous to dtype.
  2270  // There is no guarantee about matching memory layout.
  2271  func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
  2272  	p := make([]*Type, len(dtype.ParamType))
  2273  	gp := make([]*ast.Field, len(dtype.ParamType))
  2274  	for i, f := range dtype.ParamType {
  2275  		// gcc's DWARF generator outputs a single DotDotDotType parameter for
  2276  		// function pointers that specify no parameters (e.g. void
  2277  		// (*__cgo_0)()).  Treat this special case as void. This case is
  2278  		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
  2279  		// legal).
  2280  		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
  2281  			p, gp = nil, nil
  2282  			break
  2283  		}
  2284  		p[i] = c.FuncArg(f, pos)
  2285  		gp[i] = &ast.Field{Type: p[i].Go}
  2286  	}
  2287  	var r *Type
  2288  	var gr []*ast.Field
  2289  	if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok {
  2290  		gr = []*ast.Field{{Type: c.goVoid}}
  2291  	} else if dtype.ReturnType != nil {
  2292  		r = c.Type(unqual(dtype.ReturnType), pos)
  2293  		gr = []*ast.Field{{Type: r.Go}}
  2294  	}
  2295  	return &FuncType{
  2296  		Params: p,
  2297  		Result: r,
  2298  		Go: &ast.FuncType{
  2299  			Params:  &ast.FieldList{List: gp},
  2300  			Results: &ast.FieldList{List: gr},
  2301  		},
  2302  	}
  2303  }
  2304  
  2305  // Identifier
  2306  func (c *typeConv) Ident(s string) *ast.Ident {
  2307  	return ast.NewIdent(s)
  2308  }
  2309  
  2310  // Opaque type of n bytes.
  2311  func (c *typeConv) Opaque(n int64) ast.Expr {
  2312  	return &ast.ArrayType{
  2313  		Len: c.intExpr(n),
  2314  		Elt: c.byte,
  2315  	}
  2316  }
  2317  
  2318  // Expr for integer n.
  2319  func (c *typeConv) intExpr(n int64) ast.Expr {
  2320  	return &ast.BasicLit{
  2321  		Kind:  token.INT,
  2322  		Value: strconv.FormatInt(n, 10),
  2323  	}
  2324  }
  2325  
  2326  // Add padding of given size to fld.
  2327  func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
  2328  	n := len(fld)
  2329  	fld = fld[0 : n+1]
  2330  	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
  2331  	sizes = sizes[0 : n+1]
  2332  	sizes[n] = size
  2333  	return fld, sizes
  2334  }
  2335  
  2336  // Struct conversion: return Go and (gc) C syntax for type.
  2337  func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
  2338  	// Minimum alignment for a struct is 1 byte.
  2339  	align = 1
  2340  
  2341  	var buf bytes.Buffer
  2342  	buf.WriteString("struct {")
  2343  	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
  2344  	sizes := make([]int64, 0, 2*len(dt.Field)+1)
  2345  	off := int64(0)
  2346  
  2347  	// Rename struct fields that happen to be named Go keywords into
  2348  	// _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
  2349  	// be mangled. Any existing identifier that already has the same name on
  2350  	// the C-side will cause the Go-mangled version to be prefixed with _.
  2351  	// (e.g. in a struct with fields '_type' and 'type', the latter would be
  2352  	// rendered as '__type' in Go).
  2353  	ident := make(map[string]string)
  2354  	used := make(map[string]bool)
  2355  	for _, f := range dt.Field {
  2356  		ident[f.Name] = f.Name
  2357  		used[f.Name] = true
  2358  	}
  2359  
  2360  	if !*godefs {
  2361  		for cid, goid := range ident {
  2362  			if token.Lookup(goid).IsKeyword() {
  2363  				// Avoid keyword
  2364  				goid = "_" + goid
  2365  
  2366  				// Also avoid existing fields
  2367  				for _, exist := used[goid]; exist; _, exist = used[goid] {
  2368  					goid = "_" + goid
  2369  				}
  2370  
  2371  				used[goid] = true
  2372  				ident[cid] = goid
  2373  			}
  2374  		}
  2375  	}
  2376  
  2377  	anon := 0
  2378  	for _, f := range dt.Field {
  2379  		if f.ByteOffset > off {
  2380  			fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
  2381  			off = f.ByteOffset
  2382  		}
  2383  
  2384  		name := f.Name
  2385  		ft := f.Type
  2386  
  2387  		// In godefs mode, if this field is a C11
  2388  		// anonymous union then treat the first field in the
  2389  		// union as the field in the struct. This handles
  2390  		// cases like the glibc <sys/resource.h> file; see
  2391  		// issue 6677.
  2392  		if *godefs {
  2393  			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
  2394  				name = st.Field[0].Name
  2395  				ident[name] = name
  2396  				ft = st.Field[0].Type
  2397  			}
  2398  		}
  2399  
  2400  		// TODO: Handle fields that are anonymous structs by
  2401  		// promoting the fields of the inner struct.
  2402  
  2403  		t := c.Type(ft, pos)
  2404  		tgo := t.Go
  2405  		size := t.Size
  2406  		talign := t.Align
  2407  		if f.BitSize > 0 {
  2408  			if f.BitSize%8 != 0 {
  2409  				continue
  2410  			}
  2411  			size = f.BitSize / 8
  2412  			name := tgo.(*ast.Ident).String()
  2413  			if strings.HasPrefix(name, "int") {
  2414  				name = "int"
  2415  			} else {
  2416  				name = "uint"
  2417  			}
  2418  			tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
  2419  			talign = size
  2420  		}
  2421  
  2422  		if talign > 0 && f.ByteOffset%talign != 0 {
  2423  			// Drop misaligned fields, the same way we drop integer bit fields.
  2424  			// The goal is to make available what can be made available.
  2425  			// Otherwise one bad and unneeded field in an otherwise okay struct
  2426  			// makes the whole program not compile. Much of the time these
  2427  			// structs are in system headers that cannot be corrected.
  2428  			continue
  2429  		}
  2430  		n := len(fld)
  2431  		fld = fld[0 : n+1]
  2432  		if name == "" {
  2433  			name = fmt.Sprintf("anon%d", anon)
  2434  			anon++
  2435  			ident[name] = name
  2436  		}
  2437  		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
  2438  		sizes = sizes[0 : n+1]
  2439  		sizes[n] = size
  2440  		off += size
  2441  		buf.WriteString(t.C.String())
  2442  		buf.WriteString(" ")
  2443  		buf.WriteString(name)
  2444  		buf.WriteString("; ")
  2445  		if talign > align {
  2446  			align = talign
  2447  		}
  2448  	}
  2449  	if off < dt.ByteSize {
  2450  		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
  2451  		off = dt.ByteSize
  2452  	}
  2453  
  2454  	// If the last field in a non-zero-sized struct is zero-sized
  2455  	// the compiler is going to pad it by one (see issue 9401).
  2456  	// We can't permit that, because then the size of the Go
  2457  	// struct will not be the same as the size of the C struct.
  2458  	// Our only option in such a case is to remove the field,
  2459  	// which means that it cannot be referenced from Go.
  2460  	for off > 0 && sizes[len(sizes)-1] == 0 {
  2461  		n := len(sizes)
  2462  		fld = fld[0 : n-1]
  2463  		sizes = sizes[0 : n-1]
  2464  	}
  2465  
  2466  	if off != dt.ByteSize {
  2467  		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
  2468  	}
  2469  	buf.WriteString("}")
  2470  	csyntax = buf.String()
  2471  
  2472  	if *godefs {
  2473  		godefsFields(fld)
  2474  	}
  2475  	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
  2476  	return
  2477  }
  2478  
  2479  // dwarfHasPointer returns whether the DWARF type dt contains a pointer.
  2480  func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
  2481  	switch dt := dt.(type) {
  2482  	default:
  2483  		fatalf("%s: unexpected type: %s", lineno(pos), dt)
  2484  		return false
  2485  
  2486  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
  2487  		*dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
  2488  		*dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
  2489  
  2490  		return false
  2491  
  2492  	case *dwarf.ArrayType:
  2493  		return c.dwarfHasPointer(dt.Type, pos)
  2494  
  2495  	case *dwarf.PtrType:
  2496  		return true
  2497  
  2498  	case *dwarf.QualType:
  2499  		return c.dwarfHasPointer(dt.Type, pos)
  2500  
  2501  	case *dwarf.StructType:
  2502  		for _, f := range dt.Field {
  2503  			if c.dwarfHasPointer(f.Type, pos) {
  2504  				return true
  2505  			}
  2506  		}
  2507  		return false
  2508  
  2509  	case *dwarf.TypedefType:
  2510  		if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
  2511  			return true
  2512  		}
  2513  		return c.dwarfHasPointer(dt.Type, pos)
  2514  	}
  2515  }
  2516  
  2517  func upper(s string) string {
  2518  	if s == "" {
  2519  		return ""
  2520  	}
  2521  	r, size := utf8.DecodeRuneInString(s)
  2522  	if r == '_' {
  2523  		return "X" + s
  2524  	}
  2525  	return string(unicode.ToUpper(r)) + s[size:]
  2526  }
  2527  
  2528  // godefsFields rewrites field names for use in Go or C definitions.
  2529  // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
  2530  // converts names to upper case, and rewrites _ into Pad_godefs_n,
  2531  // so that all fields are exported.
  2532  func godefsFields(fld []*ast.Field) {
  2533  	prefix := fieldPrefix(fld)
  2534  	npad := 0
  2535  	for _, f := range fld {
  2536  		for _, n := range f.Names {
  2537  			if n.Name != prefix {
  2538  				n.Name = strings.TrimPrefix(n.Name, prefix)
  2539  			}
  2540  			if n.Name == "_" {
  2541  				// Use exported name instead.
  2542  				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
  2543  				npad++
  2544  			}
  2545  			n.Name = upper(n.Name)
  2546  		}
  2547  	}
  2548  }
  2549  
  2550  // fieldPrefix returns the prefix that should be removed from all the
  2551  // field names when generating the C or Go code. For generated
  2552  // C, we leave the names as is (tv_sec, tv_usec), since that's what
  2553  // people are used to seeing in C.  For generated Go code, such as
  2554  // package syscall's data structures, we drop a common prefix
  2555  // (so sec, usec, which will get turned into Sec, Usec for exporting).
  2556  func fieldPrefix(fld []*ast.Field) string {
  2557  	prefix := ""
  2558  	for _, f := range fld {
  2559  		for _, n := range f.Names {
  2560  			// Ignore field names that don't have the prefix we're
  2561  			// looking for. It is common in C headers to have fields
  2562  			// named, say, _pad in an otherwise prefixed header.
  2563  			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
  2564  			// still want to remove the tv_ prefix.
  2565  			// The check for "orig_" here handles orig_eax in the
  2566  			// x86 ptrace register sets, which otherwise have all fields
  2567  			// with reg_ prefixes.
  2568  			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
  2569  				continue
  2570  			}
  2571  			i := strings.Index(n.Name, "_")
  2572  			if i < 0 {
  2573  				continue
  2574  			}
  2575  			if prefix == "" {
  2576  				prefix = n.Name[:i+1]
  2577  			} else if prefix != n.Name[:i+1] {
  2578  				return ""
  2579  			}
  2580  		}
  2581  	}
  2582  	return prefix
  2583  }