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