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