github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/cmd/cgo/gcc.go (about)

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