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