github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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  	"os"
    24  	"strconv"
    25  	"strings"
    26  	"unicode"
    27  	"unicode/utf8"
    28  )
    29  
    30  var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
    31  var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
    32  
    33  var nameToC = map[string]string{
    34  	"schar":         "signed char",
    35  	"uchar":         "unsigned char",
    36  	"ushort":        "unsigned short",
    37  	"uint":          "unsigned int",
    38  	"ulong":         "unsigned long",
    39  	"longlong":      "long long",
    40  	"ulonglong":     "unsigned long long",
    41  	"complexfloat":  "float complex",
    42  	"complexdouble": "double complex",
    43  }
    44  
    45  // cname returns the C name to use for C.s.
    46  // The expansions are listed in nameToC and also
    47  // struct_foo becomes "struct foo", and similarly for
    48  // union and enum.
    49  func cname(s string) string {
    50  	if t, ok := nameToC[s]; ok {
    51  		return t
    52  	}
    53  
    54  	if strings.HasPrefix(s, "struct_") {
    55  		return "struct " + s[len("struct_"):]
    56  	}
    57  	if strings.HasPrefix(s, "union_") {
    58  		return "union " + s[len("union_"):]
    59  	}
    60  	if strings.HasPrefix(s, "enum_") {
    61  		return "enum " + s[len("enum_"):]
    62  	}
    63  	if strings.HasPrefix(s, "sizeof_") {
    64  		return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
    65  	}
    66  	return s
    67  }
    68  
    69  // DiscardCgoDirectives processes the import C preamble, and discards
    70  // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
    71  // way into _cgo_export.h.
    72  func (f *File) DiscardCgoDirectives() {
    73  	linesIn := strings.Split(f.Preamble, "\n")
    74  	linesOut := make([]string, 0, len(linesIn))
    75  	for _, line := range linesIn {
    76  		l := strings.TrimSpace(line)
    77  		if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
    78  			linesOut = append(linesOut, line)
    79  		} else {
    80  			linesOut = append(linesOut, "")
    81  		}
    82  	}
    83  	f.Preamble = strings.Join(linesOut, "\n")
    84  }
    85  
    86  // addToFlag appends args to flag.  All flags are later written out onto the
    87  // _cgo_flags file for the build system to use.
    88  func (p *Package) addToFlag(flag string, args []string) {
    89  	p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
    90  	if flag == "CFLAGS" {
    91  		// We'll also need these when preprocessing for dwarf information.
    92  		p.GccOptions = append(p.GccOptions, args...)
    93  	}
    94  }
    95  
    96  // splitQuoted splits the string s around each instance of one or more consecutive
    97  // white space characters while taking into account quotes and escaping, and
    98  // returns an array of substrings of s or an empty list if s contains only white space.
    99  // Single quotes and double quotes are recognized to prevent splitting within the
   100  // quoted region, and are removed from the resulting substrings. If a quote in s
   101  // isn't closed err will be set and r will have the unclosed argument as the
   102  // last element.  The backslash is used for escaping.
   103  //
   104  // For example, the following string:
   105  //
   106  //     `a b:"c d" 'e''f'  "g\""`
   107  //
   108  // Would be parsed as:
   109  //
   110  //     []string{"a", "b:c d", "ef", `g"`}
   111  //
   112  func splitQuoted(s string) (r []string, err error) {
   113  	var args []string
   114  	arg := make([]rune, len(s))
   115  	escaped := false
   116  	quoted := false
   117  	quote := '\x00'
   118  	i := 0
   119  	for _, r := range s {
   120  		switch {
   121  		case escaped:
   122  			escaped = false
   123  		case r == '\\':
   124  			escaped = true
   125  			continue
   126  		case quote != 0:
   127  			if r == quote {
   128  				quote = 0
   129  				continue
   130  			}
   131  		case r == '"' || r == '\'':
   132  			quoted = true
   133  			quote = r
   134  			continue
   135  		case unicode.IsSpace(r):
   136  			if quoted || i > 0 {
   137  				quoted = false
   138  				args = append(args, string(arg[:i]))
   139  				i = 0
   140  			}
   141  			continue
   142  		}
   143  		arg[i] = r
   144  		i++
   145  	}
   146  	if quoted || i > 0 {
   147  		args = append(args, string(arg[:i]))
   148  	}
   149  	if quote != 0 {
   150  		err = errors.New("unclosed quote")
   151  	} else if escaped {
   152  		err = errors.New("unfinished escaping")
   153  	}
   154  	return args, err
   155  }
   156  
   157  var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`)
   158  
   159  func safeName(s string) bool {
   160  	if s == "" {
   161  		return false
   162  	}
   163  	for i := 0; i < len(s); i++ {
   164  		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
   165  			return false
   166  		}
   167  	}
   168  	return true
   169  }
   170  
   171  // Translate rewrites f.AST, the original Go input, to remove
   172  // references to the imported package C, replacing them with
   173  // references to the equivalent Go types, functions, and variables.
   174  func (p *Package) Translate(f *File) {
   175  	for _, cref := range f.Ref {
   176  		// Convert C.ulong to C.unsigned long, etc.
   177  		cref.Name.C = cname(cref.Name.Go)
   178  	}
   179  	p.loadDefines(f)
   180  	needType := p.guessKinds(f)
   181  	if len(needType) > 0 {
   182  		p.loadDWARF(f, needType)
   183  	}
   184  	p.rewriteRef(f)
   185  }
   186  
   187  // loadDefines coerces gcc into spitting out the #defines in use
   188  // in the file f and saves relevant renamings in f.Name[name].Define.
   189  func (p *Package) loadDefines(f *File) {
   190  	var b bytes.Buffer
   191  	b.WriteString(builtinProlog)
   192  	b.WriteString(f.Preamble)
   193  	stdout := p.gccDefines(b.Bytes())
   194  
   195  	for _, line := range strings.Split(stdout, "\n") {
   196  		if len(line) < 9 || line[0:7] != "#define" {
   197  			continue
   198  		}
   199  
   200  		line = strings.TrimSpace(line[8:])
   201  
   202  		var key, val string
   203  		spaceIndex := strings.Index(line, " ")
   204  		tabIndex := strings.Index(line, "\t")
   205  
   206  		if spaceIndex == -1 && tabIndex == -1 {
   207  			continue
   208  		} else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
   209  			key = line[0:spaceIndex]
   210  			val = strings.TrimSpace(line[spaceIndex:])
   211  		} else {
   212  			key = line[0:tabIndex]
   213  			val = strings.TrimSpace(line[tabIndex:])
   214  		}
   215  
   216  		if n := f.Name[key]; n != nil {
   217  			if *debugDefine {
   218  				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
   219  			}
   220  			n.Define = val
   221  		}
   222  	}
   223  }
   224  
   225  // guessKinds tricks gcc into revealing the kind of each
   226  // name xxx for the references C.xxx in the Go input.
   227  // The kind is either a constant, type, or variable.
   228  func (p *Package) guessKinds(f *File) []*Name {
   229  	// Coerce gcc into telling us whether each name is
   230  	// a type, a value, or undeclared.  We compile a function
   231  	// containing the line:
   232  	//	name;
   233  	// If name is a type, gcc will print:
   234  	//	cgo-test:2: warning: useless type name in empty declaration
   235  	// If name is a value, gcc will print
   236  	//	cgo-test:2: warning: statement with no effect
   237  	// If name is undeclared, gcc will print
   238  	//	cgo-test:2: error: 'name' undeclared (first use in this function)
   239  	// A line number directive causes the line number to
   240  	// correspond to the index in the names array.
   241  	//
   242  	// The line also has an enum declaration:
   243  	//	name; enum { _cgo_enum_1 = name };
   244  	// If name is not a constant, gcc will print:
   245  	//	cgo-test:4: error: enumerator value for '_cgo_enum_4' is not an integer constant
   246  	// we assume lines without that error are constants.
   247  
   248  	// Make list of names that need sniffing, type lookup.
   249  	toSniff := make([]*Name, 0, len(f.Name))
   250  	needType := make([]*Name, 0, len(f.Name))
   251  
   252  	for _, n := range f.Name {
   253  		// If we've already found this name as a #define
   254  		// and we can translate it as a constant value, do so.
   255  		if n.Define != "" {
   256  			ok := false
   257  			if _, err := strconv.Atoi(n.Define); err == nil {
   258  				ok = true
   259  			} else if n.Define[0] == '"' || n.Define[0] == '\'' {
   260  				if _, err := parser.ParseExpr(n.Define); err == nil {
   261  					ok = true
   262  				}
   263  			}
   264  			if ok {
   265  				n.Kind = "const"
   266  				// Turn decimal into hex, just for consistency
   267  				// with enum-derived constants.  Otherwise
   268  				// in the cgo -godefs output half the constants
   269  				// are in hex and half are in whatever the #define used.
   270  				i, err := strconv.ParseInt(n.Define, 0, 64)
   271  				if err == nil {
   272  					n.Const = fmt.Sprintf("%#x", i)
   273  				} else {
   274  					n.Const = n.Define
   275  				}
   276  				continue
   277  			}
   278  
   279  			if isName(n.Define) {
   280  				n.C = n.Define
   281  			}
   282  		}
   283  
   284  		// If this is a struct, union, or enum type name,
   285  		// record the kind but also that we need type information.
   286  		if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
   287  			n.Kind = "type"
   288  			i := len(needType)
   289  			needType = needType[0 : i+1]
   290  			needType[i] = n
   291  			continue
   292  		}
   293  
   294  		i := len(toSniff)
   295  		toSniff = toSniff[0 : i+1]
   296  		toSniff[i] = n
   297  	}
   298  
   299  	if len(toSniff) == 0 {
   300  		return needType
   301  	}
   302  
   303  	var b bytes.Buffer
   304  	b.WriteString(builtinProlog)
   305  	b.WriteString(f.Preamble)
   306  	b.WriteString("void __cgo__f__(void) {\n")
   307  	b.WriteString("#line 1 \"cgo-test\"\n")
   308  	for i, n := range toSniff {
   309  		fmt.Fprintf(&b, "%s; /* #%d */\nenum { _cgo_enum_%d = %s }; /* #%d */\n", n.C, i, i, n.C, i)
   310  	}
   311  	b.WriteString("}\n")
   312  	stderr := p.gccErrors(b.Bytes())
   313  	if stderr == "" {
   314  		fatalf("gcc produced no output\non input:\n%s", b.Bytes())
   315  	}
   316  
   317  	names := make([]*Name, len(toSniff))
   318  	copy(names, toSniff)
   319  
   320  	isConst := make([]bool, len(toSniff))
   321  	for i := range isConst {
   322  		isConst[i] = true // until proven otherwise
   323  	}
   324  
   325  	for _, line := range strings.Split(stderr, "\n") {
   326  		if len(line) < 9 || line[0:9] != "cgo-test:" {
   327  			// the user will see any compiler errors when the code is compiled later.
   328  			continue
   329  		}
   330  		line = line[9:]
   331  		colon := strings.Index(line, ":")
   332  		if colon < 0 {
   333  			continue
   334  		}
   335  		i, err := strconv.Atoi(line[0:colon])
   336  		if err != nil {
   337  			continue
   338  		}
   339  		i = (i - 1) / 2
   340  		what := ""
   341  		switch {
   342  		default:
   343  			continue
   344  		case strings.Contains(line, ": useless type name in empty declaration"),
   345  			strings.Contains(line, ": declaration does not declare anything"),
   346  			strings.Contains(line, ": unexpected type name"):
   347  			what = "type"
   348  			isConst[i] = false
   349  		case strings.Contains(line, ": statement with no effect"),
   350  			strings.Contains(line, ": expression result unused"):
   351  			what = "not-type" // const or func or var
   352  		case strings.Contains(line, "undeclared"):
   353  			error_(token.NoPos, "%s", strings.TrimSpace(line[colon+1:]))
   354  		case strings.Contains(line, "is not an integer constant"):
   355  			isConst[i] = false
   356  			continue
   357  		}
   358  		n := toSniff[i]
   359  		if n == nil {
   360  			continue
   361  		}
   362  		toSniff[i] = nil
   363  		n.Kind = what
   364  
   365  		j := len(needType)
   366  		needType = needType[0 : j+1]
   367  		needType[j] = n
   368  	}
   369  	for i, b := range isConst {
   370  		if b {
   371  			names[i].Kind = "const"
   372  			if toSniff[i] != nil && names[i].Const == "" {
   373  				j := len(needType)
   374  				needType = needType[0 : j+1]
   375  				needType[j] = names[i]
   376  			}
   377  		}
   378  	}
   379  	for _, n := range toSniff {
   380  		if n == nil {
   381  			continue
   382  		}
   383  		if n.Kind != "" {
   384  			continue
   385  		}
   386  		error_(token.NoPos, "could not determine kind of name for C.%s", n.Go)
   387  	}
   388  	if nerrors > 0 {
   389  		fatalf("unresolved names")
   390  	}
   391  	return needType
   392  }
   393  
   394  // loadDWARF parses the DWARF debug information generated
   395  // by gcc to learn the details of the constants, variables, and types
   396  // being referred to as C.xxx.
   397  func (p *Package) loadDWARF(f *File, names []*Name) {
   398  	// Extract the types from the DWARF section of an object
   399  	// from a well-formed C program.  Gcc only generates DWARF info
   400  	// for symbols in the object file, so it is not enough to print the
   401  	// preamble and hope the symbols we care about will be there.
   402  	// Instead, emit
   403  	//	typeof(names[i]) *__cgo__i;
   404  	// for each entry in names and then dereference the type we
   405  	// learn for __cgo__i.
   406  	var b bytes.Buffer
   407  	b.WriteString(builtinProlog)
   408  	b.WriteString(f.Preamble)
   409  	for i, n := range names {
   410  		fmt.Fprintf(&b, "typeof(%s) *__cgo__%d;\n", n.C, i)
   411  		if n.Kind == "const" {
   412  			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
   413  		}
   414  	}
   415  
   416  	// Apple's LLVM-based gcc does not include the enumeration
   417  	// names and values in its DWARF debug output.  In case we're
   418  	// using such a gcc, create a data block initialized with the values.
   419  	// We can read them out of the object file.
   420  	fmt.Fprintf(&b, "long long __cgodebug_data[] = {\n")
   421  	for _, n := range names {
   422  		if n.Kind == "const" {
   423  			fmt.Fprintf(&b, "\t%s,\n", n.C)
   424  		} else {
   425  			fmt.Fprintf(&b, "\t0,\n")
   426  		}
   427  	}
   428  	// for the last entry, we can not use 0, otherwise
   429  	// in case all __cgodebug_data is zero initialized,
   430  	// LLVM-based gcc will place the it in the __DATA.__common
   431  	// zero-filled section (our debug/macho doesn't support
   432  	// this)
   433  	fmt.Fprintf(&b, "\t1\n")
   434  	fmt.Fprintf(&b, "};\n")
   435  
   436  	d, bo, debugData := p.gccDebug(b.Bytes())
   437  	enumVal := make([]int64, len(debugData)/8)
   438  	for i := range enumVal {
   439  		enumVal[i] = int64(bo.Uint64(debugData[i*8:]))
   440  	}
   441  
   442  	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
   443  	types := make([]dwarf.Type, len(names))
   444  	enums := make([]dwarf.Offset, len(names))
   445  	nameToIndex := make(map[*Name]int)
   446  	for i, n := range names {
   447  		nameToIndex[n] = i
   448  	}
   449  	nameToRef := make(map[*Name]*Ref)
   450  	for _, ref := range f.Ref {
   451  		nameToRef[ref.Name] = ref
   452  	}
   453  	r := d.Reader()
   454  	for {
   455  		e, err := r.Next()
   456  		if err != nil {
   457  			fatalf("reading DWARF entry: %s", err)
   458  		}
   459  		if e == nil {
   460  			break
   461  		}
   462  		switch e.Tag {
   463  		case dwarf.TagEnumerationType:
   464  			offset := e.Offset
   465  			for {
   466  				e, err := r.Next()
   467  				if err != nil {
   468  					fatalf("reading DWARF entry: %s", err)
   469  				}
   470  				if e.Tag == 0 {
   471  					break
   472  				}
   473  				if e.Tag == dwarf.TagEnumerator {
   474  					entryName := e.Val(dwarf.AttrName).(string)
   475  					if strings.HasPrefix(entryName, "__cgo_enum__") {
   476  						n, _ := strconv.Atoi(entryName[len("__cgo_enum__"):])
   477  						if 0 <= n && n < len(names) {
   478  							enums[n] = offset
   479  						}
   480  					}
   481  				}
   482  			}
   483  		case dwarf.TagVariable:
   484  			name, _ := e.Val(dwarf.AttrName).(string)
   485  			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
   486  			if name == "" || typOff == 0 {
   487  				fatalf("malformed DWARF TagVariable entry")
   488  			}
   489  			if !strings.HasPrefix(name, "__cgo__") {
   490  				break
   491  			}
   492  			typ, err := d.Type(typOff)
   493  			if err != nil {
   494  				fatalf("loading DWARF type: %s", err)
   495  			}
   496  			t, ok := typ.(*dwarf.PtrType)
   497  			if !ok || t == nil {
   498  				fatalf("internal error: %s has non-pointer type", name)
   499  			}
   500  			i, err := strconv.Atoi(name[7:])
   501  			if err != nil {
   502  				fatalf("malformed __cgo__ name: %s", name)
   503  			}
   504  			if enums[i] != 0 {
   505  				t, err := d.Type(enums[i])
   506  				if err != nil {
   507  					fatalf("loading DWARF type: %s", err)
   508  				}
   509  				types[i] = t
   510  			} else {
   511  				types[i] = t.Type
   512  			}
   513  		}
   514  		if e.Tag != dwarf.TagCompileUnit {
   515  			r.SkipChildren()
   516  		}
   517  	}
   518  
   519  	// Record types and typedef information.
   520  	var conv typeConv
   521  	conv.Init(p.PtrSize, p.IntSize)
   522  	for i, n := range names {
   523  		if types[i] == nil {
   524  			continue
   525  		}
   526  		pos := token.NoPos
   527  		if ref, ok := nameToRef[n]; ok {
   528  			pos = ref.Pos()
   529  		}
   530  		f, fok := types[i].(*dwarf.FuncType)
   531  		if n.Kind != "type" && fok {
   532  			n.Kind = "func"
   533  			n.FuncType = conv.FuncType(f, pos)
   534  		} else {
   535  			n.Type = conv.Type(types[i], pos)
   536  			if enums[i] != 0 && n.Type.EnumValues != nil {
   537  				k := fmt.Sprintf("__cgo_enum__%d", i)
   538  				n.Kind = "const"
   539  				n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k])
   540  				// Remove injected enum to ensure the value will deep-compare
   541  				// equally in future loads of the same constant.
   542  				delete(n.Type.EnumValues, k)
   543  			}
   544  			// Prefer debug data over DWARF debug output, if we have it.
   545  			if n.Kind == "const" && i < len(enumVal) {
   546  				n.Const = fmt.Sprintf("%#x", enumVal[i])
   547  			}
   548  		}
   549  	}
   550  
   551  }
   552  
   553  // mangleName does name mangling to translate names
   554  // from the original Go source files to the names
   555  // used in the final Go files generated by cgo.
   556  func (p *Package) mangleName(n *Name) {
   557  	// When using gccgo variables have to be
   558  	// exported so that they become global symbols
   559  	// that the C code can refer to.
   560  	prefix := "_C"
   561  	if *gccgo && n.IsVar() {
   562  		prefix = "C"
   563  	}
   564  	n.Mangle = prefix + n.Kind + "_" + n.Go
   565  }
   566  
   567  // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
   568  // Go equivalents, now that we have figured out the meaning of all
   569  // the xxx.  In *godefs or *cdefs mode, rewriteRef replaces the names
   570  // with full definitions instead of mangled names.
   571  func (p *Package) rewriteRef(f *File) {
   572  	// Keep a list of all the functions, to remove the ones
   573  	// only used as expressions and avoid generating bridge
   574  	// code for them.
   575  	functions := make(map[string]bool)
   576  
   577  	// Assign mangled names.
   578  	for _, n := range f.Name {
   579  		if n.Kind == "not-type" {
   580  			n.Kind = "var"
   581  		}
   582  		if n.Mangle == "" {
   583  			p.mangleName(n)
   584  		}
   585  		if n.Kind == "func" {
   586  			functions[n.Go] = false
   587  		}
   588  	}
   589  
   590  	// Now that we have all the name types filled in,
   591  	// scan through the Refs to identify the ones that
   592  	// are trying to do a ,err call.  Also check that
   593  	// functions are only used in calls.
   594  	for _, r := range f.Ref {
   595  		if r.Name.Kind == "const" && r.Name.Const == "" {
   596  			error_(r.Pos(), "unable to find value of constant C.%s", r.Name.Go)
   597  		}
   598  		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
   599  		switch r.Context {
   600  		case "call", "call2":
   601  			if r.Name.Kind != "func" {
   602  				if r.Name.Kind == "type" {
   603  					r.Context = "type"
   604  					expr = r.Name.Type.Go
   605  					break
   606  				}
   607  				error_(r.Pos(), "call of non-function C.%s", r.Name.Go)
   608  				break
   609  			}
   610  			functions[r.Name.Go] = true
   611  			if r.Context == "call2" {
   612  				// Invent new Name for the two-result function.
   613  				n := f.Name["2"+r.Name.Go]
   614  				if n == nil {
   615  					n = new(Name)
   616  					*n = *r.Name
   617  					n.AddError = true
   618  					n.Mangle = "_C2func_" + n.Go
   619  					f.Name["2"+r.Name.Go] = n
   620  				}
   621  				expr = ast.NewIdent(n.Mangle)
   622  				r.Name = n
   623  				break
   624  			}
   625  		case "expr":
   626  			if r.Name.Kind == "func" {
   627  				// Function is being used in an expression, to e.g. pass around a C function pointer.
   628  				// Create a new Name for this Ref which causes the variable to be declared in Go land.
   629  				fpName := "fp_" + r.Name.Go
   630  				name := f.Name[fpName]
   631  				if name == nil {
   632  					name = &Name{
   633  						Go:   fpName,
   634  						C:    r.Name.C,
   635  						Kind: "fpvar",
   636  						Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
   637  					}
   638  					p.mangleName(name)
   639  					f.Name[fpName] = name
   640  				}
   641  				r.Name = name
   642  				expr = ast.NewIdent(name.Mangle)
   643  			} else if r.Name.Kind == "type" {
   644  				// Okay - might be new(T)
   645  				expr = r.Name.Type.Go
   646  			} else if r.Name.Kind == "var" {
   647  				expr = &ast.StarExpr{X: expr}
   648  			}
   649  
   650  		case "type":
   651  			if r.Name.Kind != "type" {
   652  				error_(r.Pos(), "expression C.%s used as type", r.Name.Go)
   653  			} else if r.Name.Type == nil {
   654  				// Use of C.enum_x, C.struct_x or C.union_x without C definition.
   655  				// GCC won't raise an error when using pointers to such unknown types.
   656  				error_(r.Pos(), "type C.%s: undefined C type '%s'", r.Name.Go, r.Name.C)
   657  			} else {
   658  				expr = r.Name.Type.Go
   659  			}
   660  		default:
   661  			if r.Name.Kind == "func" {
   662  				error_(r.Pos(), "must call C.%s", r.Name.Go)
   663  			}
   664  		}
   665  		if *godefs || *cdefs {
   666  			// Substitute definition for mangled type name.
   667  			if id, ok := expr.(*ast.Ident); ok {
   668  				if t := typedef[id.Name]; t != nil {
   669  					expr = t.Go
   670  				}
   671  				if id.Name == r.Name.Mangle && r.Name.Const != "" {
   672  					expr = ast.NewIdent(r.Name.Const)
   673  				}
   674  			}
   675  		}
   676  		*r.Expr = expr
   677  	}
   678  
   679  	// Remove functions only used as expressions, so their respective
   680  	// bridge functions are not generated.
   681  	for name, used := range functions {
   682  		if !used {
   683  			delete(f.Name, name)
   684  		}
   685  	}
   686  }
   687  
   688  // gccBaseCmd returns the start of the compiler command line.
   689  // It uses $CC if set, or else $GCC, or else the compiler recorded
   690  // during the initial build as defaultCC.
   691  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
   692  func (p *Package) gccBaseCmd() []string {
   693  	// Use $CC if set, since that's what the build uses.
   694  	if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
   695  		return ret
   696  	}
   697  	// Try $GCC if set, since that's what we used to use.
   698  	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
   699  		return ret
   700  	}
   701  	return strings.Fields(defaultCC)
   702  }
   703  
   704  // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
   705  func (p *Package) gccMachine() []string {
   706  	switch goarch {
   707  	case "amd64":
   708  		return []string{"-m64"}
   709  	case "386":
   710  		return []string{"-m32"}
   711  	case "arm":
   712  		return []string{"-marm"} // not thumb
   713  	}
   714  	return nil
   715  }
   716  
   717  func gccTmp() string {
   718  	return *objDir + "_cgo_.o"
   719  }
   720  
   721  // gccCmd returns the gcc command line to use for compiling
   722  // the input.
   723  func (p *Package) gccCmd() []string {
   724  	c := append(p.gccBaseCmd(),
   725  		"-Wall",                             // many warnings
   726  		"-Werror",                           // warnings are errors
   727  		"-o"+gccTmp(),                       // write object to tmp
   728  		"-gdwarf-2",                         // generate DWARF v2 debugging symbols
   729  		"-fno-eliminate-unused-debug-types", // gets rid of e.g. untyped enum otherwise
   730  		"-c",  // do not link
   731  		"-xc", // input language is C
   732  	)
   733  	if strings.Contains(c[0], "clang") {
   734  		c = append(c,
   735  			"-ferror-limit=0",
   736  			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
   737  			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
   738  			// flag to disable the warning. Yes, really good diagnostics, clang.
   739  			"-Wno-unknown-warning-option",
   740  			"-Wno-unneeded-internal-declaration",
   741  			"-Wno-unused-function",
   742  			"-Qunused-arguments",
   743  		)
   744  	}
   745  
   746  	c = append(c, p.GccOptions...)
   747  	c = append(c, p.gccMachine()...)
   748  	c = append(c, "-") //read input from standard input
   749  	return c
   750  }
   751  
   752  // gccDebug runs gcc -gdwarf-2 over the C program stdin and
   753  // returns the corresponding DWARF data and, if present, debug data block.
   754  func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) {
   755  	runGcc(stdin, p.gccCmd())
   756  
   757  	if f, err := macho.Open(gccTmp()); err == nil {
   758  		defer f.Close()
   759  		d, err := f.DWARF()
   760  		if err != nil {
   761  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   762  		}
   763  		var data []byte
   764  		if f.Symtab != nil {
   765  			for i := range f.Symtab.Syms {
   766  				s := &f.Symtab.Syms[i]
   767  				// Mach-O still uses a leading _ to denote non-assembly symbols.
   768  				if s.Name == "_"+"__cgodebug_data" {
   769  					// Found it.  Now find data section.
   770  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
   771  						sect := f.Sections[i]
   772  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
   773  							if sdat, err := sect.Data(); err == nil {
   774  								data = sdat[s.Value-sect.Addr:]
   775  							}
   776  						}
   777  					}
   778  				}
   779  			}
   780  		}
   781  		return d, f.ByteOrder, data
   782  	}
   783  
   784  	if f, err := elf.Open(gccTmp()); err == nil {
   785  		defer f.Close()
   786  		d, err := f.DWARF()
   787  		if err != nil {
   788  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   789  		}
   790  		var data []byte
   791  		symtab, err := f.Symbols()
   792  		if err == nil {
   793  			for i := range symtab {
   794  				s := &symtab[i]
   795  				if s.Name == "__cgodebug_data" {
   796  					// Found it.  Now find data section.
   797  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
   798  						sect := f.Sections[i]
   799  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
   800  							if sdat, err := sect.Data(); err == nil {
   801  								data = sdat[s.Value-sect.Addr:]
   802  							}
   803  						}
   804  					}
   805  				}
   806  			}
   807  		}
   808  		return d, f.ByteOrder, data
   809  	}
   810  
   811  	if f, err := pe.Open(gccTmp()); err == nil {
   812  		defer f.Close()
   813  		d, err := f.DWARF()
   814  		if err != nil {
   815  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   816  		}
   817  		var data []byte
   818  		for _, s := range f.Symbols {
   819  			if s.Name == "_"+"__cgodebug_data" {
   820  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
   821  					sect := f.Sections[i]
   822  					if s.Value < sect.Size {
   823  						if sdat, err := sect.Data(); err == nil {
   824  							data = sdat[s.Value:]
   825  						}
   826  					}
   827  				}
   828  			}
   829  		}
   830  		return d, binary.LittleEndian, data
   831  	}
   832  
   833  	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
   834  	panic("not reached")
   835  }
   836  
   837  // gccDefines runs gcc -E -dM -xc - over the C program stdin
   838  // and returns the corresponding standard output, which is the
   839  // #defines that gcc encountered while processing the input
   840  // and its included files.
   841  func (p *Package) gccDefines(stdin []byte) string {
   842  	base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
   843  	base = append(base, p.gccMachine()...)
   844  	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
   845  	return stdout
   846  }
   847  
   848  // gccErrors runs gcc over the C program stdin and returns
   849  // the errors that gcc prints.  That is, this function expects
   850  // gcc to fail.
   851  func (p *Package) gccErrors(stdin []byte) string {
   852  	// TODO(rsc): require failure
   853  	args := p.gccCmd()
   854  
   855  	// GCC 4.8.0 has a bug: it sometimes does not apply
   856  	// -Wunused-value to values that are macros defined in system
   857  	// headers.  See issue 5118.  Adding -Wsystem-headers avoids
   858  	// that problem.  This will produce additional errors, but it
   859  	// doesn't matter because we will ignore all errors that are
   860  	// not marked for the cgo-test file.
   861  	args = append(args, "-Wsystem-headers")
   862  
   863  	if *debugGcc {
   864  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
   865  		os.Stderr.Write(stdin)
   866  		fmt.Fprint(os.Stderr, "EOF\n")
   867  	}
   868  	stdout, stderr, _ := run(stdin, args)
   869  	if *debugGcc {
   870  		os.Stderr.Write(stdout)
   871  		os.Stderr.Write(stderr)
   872  	}
   873  	return string(stderr)
   874  }
   875  
   876  // runGcc runs the gcc command line args with stdin on standard input.
   877  // If the command exits with a non-zero exit status, runGcc prints
   878  // details about what was run and exits.
   879  // Otherwise runGcc returns the data written to standard output and standard error.
   880  // Note that for some of the uses we expect useful data back
   881  // on standard error, but for those uses gcc must still exit 0.
   882  func runGcc(stdin []byte, args []string) (string, string) {
   883  	if *debugGcc {
   884  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
   885  		os.Stderr.Write(stdin)
   886  		fmt.Fprint(os.Stderr, "EOF\n")
   887  	}
   888  	stdout, stderr, ok := run(stdin, args)
   889  	if *debugGcc {
   890  		os.Stderr.Write(stdout)
   891  		os.Stderr.Write(stderr)
   892  	}
   893  	if !ok {
   894  		os.Stderr.Write(stderr)
   895  		os.Exit(2)
   896  	}
   897  	return string(stdout), string(stderr)
   898  }
   899  
   900  // A typeConv is a translator from dwarf types to Go types
   901  // with equivalent memory layout.
   902  type typeConv struct {
   903  	// Cache of already-translated or in-progress types.
   904  	m       map[dwarf.Type]*Type
   905  	typedef map[string]ast.Expr
   906  
   907  	// Predeclared types.
   908  	bool                                   ast.Expr
   909  	byte                                   ast.Expr // denotes padding
   910  	int8, int16, int32, int64              ast.Expr
   911  	uint8, uint16, uint32, uint64, uintptr ast.Expr
   912  	float32, float64                       ast.Expr
   913  	complex64, complex128                  ast.Expr
   914  	void                                   ast.Expr
   915  	unsafePointer                          ast.Expr
   916  	string                                 ast.Expr
   917  	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
   918  
   919  	ptrSize int64
   920  	intSize int64
   921  }
   922  
   923  var tagGen int
   924  var typedef = make(map[string]*Type)
   925  var goIdent = make(map[string]*ast.Ident)
   926  
   927  func (c *typeConv) Init(ptrSize, intSize int64) {
   928  	c.ptrSize = ptrSize
   929  	c.intSize = intSize
   930  	c.m = make(map[dwarf.Type]*Type)
   931  	c.bool = c.Ident("bool")
   932  	c.byte = c.Ident("byte")
   933  	c.int8 = c.Ident("int8")
   934  	c.int16 = c.Ident("int16")
   935  	c.int32 = c.Ident("int32")
   936  	c.int64 = c.Ident("int64")
   937  	c.uint8 = c.Ident("uint8")
   938  	c.uint16 = c.Ident("uint16")
   939  	c.uint32 = c.Ident("uint32")
   940  	c.uint64 = c.Ident("uint64")
   941  	c.uintptr = c.Ident("uintptr")
   942  	c.float32 = c.Ident("float32")
   943  	c.float64 = c.Ident("float64")
   944  	c.complex64 = c.Ident("complex64")
   945  	c.complex128 = c.Ident("complex128")
   946  	c.unsafePointer = c.Ident("unsafe.Pointer")
   947  	c.void = c.Ident("void")
   948  	c.string = c.Ident("string")
   949  	c.goVoid = c.Ident("_Ctype_void")
   950  }
   951  
   952  // base strips away qualifiers and typedefs to get the underlying type
   953  func base(dt dwarf.Type) dwarf.Type {
   954  	for {
   955  		if d, ok := dt.(*dwarf.QualType); ok {
   956  			dt = d.Type
   957  			continue
   958  		}
   959  		if d, ok := dt.(*dwarf.TypedefType); ok {
   960  			dt = d.Type
   961  			continue
   962  		}
   963  		break
   964  	}
   965  	return dt
   966  }
   967  
   968  // Map from dwarf text names to aliases we use in package "C".
   969  var dwarfToName = map[string]string{
   970  	"long int":               "long",
   971  	"long unsigned int":      "ulong",
   972  	"unsigned int":           "uint",
   973  	"short unsigned int":     "ushort",
   974  	"short int":              "short",
   975  	"long long int":          "longlong",
   976  	"long long unsigned int": "ulonglong",
   977  	"signed char":            "schar",
   978  	"float complex":          "complexfloat",
   979  	"double complex":         "complexdouble",
   980  }
   981  
   982  const signedDelta = 64
   983  
   984  // String returns the current type representation.  Format arguments
   985  // are assembled within this method so that any changes in mutable
   986  // values are taken into account.
   987  func (tr *TypeRepr) String() string {
   988  	if len(tr.Repr) == 0 {
   989  		return ""
   990  	}
   991  	if len(tr.FormatArgs) == 0 {
   992  		return tr.Repr
   993  	}
   994  	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
   995  }
   996  
   997  // Empty returns true if the result of String would be "".
   998  func (tr *TypeRepr) Empty() bool {
   999  	return len(tr.Repr) == 0
  1000  }
  1001  
  1002  // Set modifies the type representation.
  1003  // If fargs are provided, repr is used as a format for fmt.Sprintf.
  1004  // Otherwise, repr is used unprocessed as the type representation.
  1005  func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
  1006  	tr.Repr = repr
  1007  	tr.FormatArgs = fargs
  1008  }
  1009  
  1010  // Type returns a *Type with the same memory layout as
  1011  // dtype when used as the type of a variable or a struct field.
  1012  func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
  1013  	if t, ok := c.m[dtype]; ok {
  1014  		if t.Go == nil {
  1015  			fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
  1016  		}
  1017  		return t
  1018  	}
  1019  
  1020  	// clang won't generate DW_AT_byte_size for pointer types,
  1021  	// so we have to fix it here.
  1022  	if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
  1023  		dt.ByteSize = c.ptrSize
  1024  	}
  1025  
  1026  	t := new(Type)
  1027  	t.Size = dtype.Size()
  1028  	t.Align = -1
  1029  	t.C = &TypeRepr{Repr: dtype.Common().Name}
  1030  	c.m[dtype] = t
  1031  
  1032  	if t.Size < 0 {
  1033  		// Unsized types are [0]byte
  1034  		t.Size = 0
  1035  		t.Go = c.Opaque(0)
  1036  		if t.C.Empty() {
  1037  			t.C.Set("void")
  1038  		}
  1039  		return t
  1040  	}
  1041  
  1042  	switch dt := dtype.(type) {
  1043  	default:
  1044  		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
  1045  
  1046  	case *dwarf.AddrType:
  1047  		if t.Size != c.ptrSize {
  1048  			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
  1049  		}
  1050  		t.Go = c.uintptr
  1051  		t.Align = t.Size
  1052  
  1053  	case *dwarf.ArrayType:
  1054  		if dt.StrideBitSize > 0 {
  1055  			// Cannot represent bit-sized elements in Go.
  1056  			t.Go = c.Opaque(t.Size)
  1057  			break
  1058  		}
  1059  		gt := &ast.ArrayType{
  1060  			Len: c.intExpr(dt.Count),
  1061  		}
  1062  		t.Go = gt // publish before recursive call
  1063  		sub := c.Type(dt.Type, pos)
  1064  		t.Align = sub.Align
  1065  		gt.Elt = sub.Go
  1066  		t.C.Set("typeof(%s[%d])", sub.C, dt.Count)
  1067  
  1068  	case *dwarf.BoolType:
  1069  		t.Go = c.bool
  1070  		t.Align = 1
  1071  
  1072  	case *dwarf.CharType:
  1073  		if t.Size != 1 {
  1074  			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
  1075  		}
  1076  		t.Go = c.int8
  1077  		t.Align = 1
  1078  
  1079  	case *dwarf.EnumType:
  1080  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1081  			t.Align = c.ptrSize
  1082  		}
  1083  		t.C.Set("enum " + dt.EnumName)
  1084  		signed := 0
  1085  		t.EnumValues = make(map[string]int64)
  1086  		for _, ev := range dt.Val {
  1087  			t.EnumValues[ev.Name] = ev.Val
  1088  			if ev.Val < 0 {
  1089  				signed = signedDelta
  1090  			}
  1091  		}
  1092  		switch t.Size + int64(signed) {
  1093  		default:
  1094  			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
  1095  		case 1:
  1096  			t.Go = c.uint8
  1097  		case 2:
  1098  			t.Go = c.uint16
  1099  		case 4:
  1100  			t.Go = c.uint32
  1101  		case 8:
  1102  			t.Go = c.uint64
  1103  		case 1 + signedDelta:
  1104  			t.Go = c.int8
  1105  		case 2 + signedDelta:
  1106  			t.Go = c.int16
  1107  		case 4 + signedDelta:
  1108  			t.Go = c.int32
  1109  		case 8 + signedDelta:
  1110  			t.Go = c.int64
  1111  		}
  1112  
  1113  	case *dwarf.FloatType:
  1114  		switch t.Size {
  1115  		default:
  1116  			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
  1117  		case 4:
  1118  			t.Go = c.float32
  1119  		case 8:
  1120  			t.Go = c.float64
  1121  		}
  1122  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1123  			t.Align = c.ptrSize
  1124  		}
  1125  
  1126  	case *dwarf.ComplexType:
  1127  		switch t.Size {
  1128  		default:
  1129  			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
  1130  		case 8:
  1131  			t.Go = c.complex64
  1132  		case 16:
  1133  			t.Go = c.complex128
  1134  		}
  1135  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1136  			t.Align = c.ptrSize
  1137  		}
  1138  
  1139  	case *dwarf.FuncType:
  1140  		// No attempt at translation: would enable calls
  1141  		// directly between worlds, but we need to moderate those.
  1142  		t.Go = c.uintptr
  1143  		t.Align = c.ptrSize
  1144  
  1145  	case *dwarf.IntType:
  1146  		if dt.BitSize > 0 {
  1147  			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
  1148  		}
  1149  		switch t.Size {
  1150  		default:
  1151  			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
  1152  		case 1:
  1153  			t.Go = c.int8
  1154  		case 2:
  1155  			t.Go = c.int16
  1156  		case 4:
  1157  			t.Go = c.int32
  1158  		case 8:
  1159  			t.Go = c.int64
  1160  		}
  1161  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1162  			t.Align = c.ptrSize
  1163  		}
  1164  
  1165  	case *dwarf.PtrType:
  1166  		t.Align = c.ptrSize
  1167  
  1168  		// Translate void* as unsafe.Pointer
  1169  		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
  1170  			t.Go = c.unsafePointer
  1171  			t.C.Set("void*")
  1172  			break
  1173  		}
  1174  
  1175  		gt := &ast.StarExpr{}
  1176  		t.Go = gt // publish before recursive call
  1177  		sub := c.Type(dt.Type, pos)
  1178  		gt.X = sub.Go
  1179  		t.C.Set("%s*", sub.C)
  1180  
  1181  	case *dwarf.QualType:
  1182  		// Ignore qualifier.
  1183  		t = c.Type(dt.Type, pos)
  1184  		c.m[dtype] = t
  1185  		return t
  1186  
  1187  	case *dwarf.StructType:
  1188  		// Convert to Go struct, being careful about alignment.
  1189  		// Have to give it a name to simulate C "struct foo" references.
  1190  		tag := dt.StructName
  1191  		if tag == "" {
  1192  			tag = "__" + strconv.Itoa(tagGen)
  1193  			tagGen++
  1194  		} else if t.C.Empty() {
  1195  			t.C.Set(dt.Kind + " " + tag)
  1196  		}
  1197  		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
  1198  		t.Go = name // publish before recursive calls
  1199  		goIdent[name.Name] = name
  1200  		switch dt.Kind {
  1201  		case "class", "union":
  1202  			t.Go = c.Opaque(t.Size)
  1203  			if t.C.Empty() {
  1204  				t.C.Set("typeof(unsigned char[%d])", t.Size)
  1205  			}
  1206  			t.Align = 1 // TODO: should probably base this on field alignment.
  1207  			typedef[name.Name] = t
  1208  		case "struct":
  1209  			g, csyntax, align := c.Struct(dt, pos)
  1210  			if t.C.Empty() {
  1211  				t.C.Set(csyntax)
  1212  			}
  1213  			t.Align = align
  1214  			tt := *t
  1215  			if tag != "" {
  1216  				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
  1217  			}
  1218  			tt.Go = g
  1219  			typedef[name.Name] = &tt
  1220  		}
  1221  
  1222  	case *dwarf.TypedefType:
  1223  		// Record typedef for printing.
  1224  		if dt.Name == "_GoString_" {
  1225  			// Special C name for Go string type.
  1226  			// Knows string layout used by compilers: pointer plus length,
  1227  			// which rounds up to 2 pointers after alignment.
  1228  			t.Go = c.string
  1229  			t.Size = c.ptrSize * 2
  1230  			t.Align = c.ptrSize
  1231  			break
  1232  		}
  1233  		if dt.Name == "_GoBytes_" {
  1234  			// Special C name for Go []byte type.
  1235  			// Knows slice layout used by compilers: pointer, length, cap.
  1236  			t.Go = c.Ident("[]byte")
  1237  			t.Size = c.ptrSize + 4 + 4
  1238  			t.Align = c.ptrSize
  1239  			break
  1240  		}
  1241  		name := c.Ident("_Ctype_" + dt.Name)
  1242  		goIdent[name.Name] = name
  1243  		t.Go = name // publish before recursive call
  1244  		sub := c.Type(dt.Type, pos)
  1245  		t.Size = sub.Size
  1246  		t.Align = sub.Align
  1247  		if _, ok := typedef[name.Name]; !ok {
  1248  			tt := *t
  1249  			tt.Go = sub.Go
  1250  			typedef[name.Name] = &tt
  1251  		}
  1252  		if *godefs || *cdefs {
  1253  			t.Go = sub.Go
  1254  		}
  1255  
  1256  	case *dwarf.UcharType:
  1257  		if t.Size != 1 {
  1258  			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
  1259  		}
  1260  		t.Go = c.uint8
  1261  		t.Align = 1
  1262  
  1263  	case *dwarf.UintType:
  1264  		if dt.BitSize > 0 {
  1265  			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
  1266  		}
  1267  		switch t.Size {
  1268  		default:
  1269  			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
  1270  		case 1:
  1271  			t.Go = c.uint8
  1272  		case 2:
  1273  			t.Go = c.uint16
  1274  		case 4:
  1275  			t.Go = c.uint32
  1276  		case 8:
  1277  			t.Go = c.uint64
  1278  		}
  1279  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1280  			t.Align = c.ptrSize
  1281  		}
  1282  
  1283  	case *dwarf.VoidType:
  1284  		t.Go = c.goVoid
  1285  		t.C.Set("void")
  1286  		t.Align = 1
  1287  	}
  1288  
  1289  	switch dtype.(type) {
  1290  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
  1291  		s := dtype.Common().Name
  1292  		if s != "" {
  1293  			if ss, ok := dwarfToName[s]; ok {
  1294  				s = ss
  1295  			}
  1296  			s = strings.Join(strings.Split(s, " "), "") // strip spaces
  1297  			name := c.Ident("_Ctype_" + s)
  1298  			tt := *t
  1299  			typedef[name.Name] = &tt
  1300  			if !*godefs && !*cdefs {
  1301  				t.Go = name
  1302  			}
  1303  		}
  1304  	}
  1305  
  1306  	if t.C.Empty() {
  1307  		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
  1308  	}
  1309  
  1310  	return t
  1311  }
  1312  
  1313  // FuncArg returns a Go type with the same memory layout as
  1314  // dtype when used as the type of a C function argument.
  1315  func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
  1316  	t := c.Type(dtype, pos)
  1317  	switch dt := dtype.(type) {
  1318  	case *dwarf.ArrayType:
  1319  		// Arrays are passed implicitly as pointers in C.
  1320  		// In Go, we must be explicit.
  1321  		tr := &TypeRepr{}
  1322  		tr.Set("%s*", t.C)
  1323  		return &Type{
  1324  			Size:  c.ptrSize,
  1325  			Align: c.ptrSize,
  1326  			Go:    &ast.StarExpr{X: t.Go},
  1327  			C:     tr,
  1328  		}
  1329  	case *dwarf.TypedefType:
  1330  		// C has much more relaxed rules than Go for
  1331  		// implicit type conversions.  When the parameter
  1332  		// is type T defined as *X, simulate a little of the
  1333  		// laxness of C by making the argument *X instead of T.
  1334  		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
  1335  			// Unless the typedef happens to point to void* since
  1336  			// Go has special rules around using unsafe.Pointer.
  1337  			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
  1338  				break
  1339  			}
  1340  
  1341  			t = c.Type(ptr, pos)
  1342  			if t == nil {
  1343  				return nil
  1344  			}
  1345  
  1346  			// Remember the C spelling, in case the struct
  1347  			// has __attribute__((unavailable)) on it.  See issue 2888.
  1348  			t.Typedef = dt.Name
  1349  		}
  1350  	}
  1351  	return t
  1352  }
  1353  
  1354  // FuncType returns the Go type analogous to dtype.
  1355  // There is no guarantee about matching memory layout.
  1356  func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
  1357  	p := make([]*Type, len(dtype.ParamType))
  1358  	gp := make([]*ast.Field, len(dtype.ParamType))
  1359  	for i, f := range dtype.ParamType {
  1360  		// gcc's DWARF generator outputs a single DotDotDotType parameter for
  1361  		// function pointers that specify no parameters (e.g. void
  1362  		// (*__cgo_0)()).  Treat this special case as void.  This case is
  1363  		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
  1364  		// legal).
  1365  		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
  1366  			p, gp = nil, nil
  1367  			break
  1368  		}
  1369  		p[i] = c.FuncArg(f, pos)
  1370  		gp[i] = &ast.Field{Type: p[i].Go}
  1371  	}
  1372  	var r *Type
  1373  	var gr []*ast.Field
  1374  	if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok {
  1375  		gr = []*ast.Field{{Type: c.goVoid}}
  1376  	} else if dtype.ReturnType != nil {
  1377  		r = c.Type(dtype.ReturnType, pos)
  1378  		gr = []*ast.Field{{Type: r.Go}}
  1379  	}
  1380  	return &FuncType{
  1381  		Params: p,
  1382  		Result: r,
  1383  		Go: &ast.FuncType{
  1384  			Params:  &ast.FieldList{List: gp},
  1385  			Results: &ast.FieldList{List: gr},
  1386  		},
  1387  	}
  1388  }
  1389  
  1390  // Identifier
  1391  func (c *typeConv) Ident(s string) *ast.Ident {
  1392  	return ast.NewIdent(s)
  1393  }
  1394  
  1395  // Opaque type of n bytes.
  1396  func (c *typeConv) Opaque(n int64) ast.Expr {
  1397  	return &ast.ArrayType{
  1398  		Len: c.intExpr(n),
  1399  		Elt: c.byte,
  1400  	}
  1401  }
  1402  
  1403  // Expr for integer n.
  1404  func (c *typeConv) intExpr(n int64) ast.Expr {
  1405  	return &ast.BasicLit{
  1406  		Kind:  token.INT,
  1407  		Value: strconv.FormatInt(n, 10),
  1408  	}
  1409  }
  1410  
  1411  // Add padding of given size to fld.
  1412  func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
  1413  	n := len(fld)
  1414  	fld = fld[0 : n+1]
  1415  	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
  1416  	return fld
  1417  }
  1418  
  1419  // Struct conversion: return Go and (6g) C syntax for type.
  1420  func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
  1421  	var buf bytes.Buffer
  1422  	buf.WriteString("struct {")
  1423  	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
  1424  	off := int64(0)
  1425  
  1426  	// Rename struct fields that happen to be named Go keywords into
  1427  	// _{keyword}.  Create a map from C ident -> Go ident.  The Go ident will
  1428  	// be mangled.  Any existing identifier that already has the same name on
  1429  	// the C-side will cause the Go-mangled version to be prefixed with _.
  1430  	// (e.g. in a struct with fields '_type' and 'type', the latter would be
  1431  	// rendered as '__type' in Go).
  1432  	ident := make(map[string]string)
  1433  	used := make(map[string]bool)
  1434  	for _, f := range dt.Field {
  1435  		ident[f.Name] = f.Name
  1436  		used[f.Name] = true
  1437  	}
  1438  
  1439  	if !*godefs && !*cdefs {
  1440  		for cid, goid := range ident {
  1441  			if token.Lookup(goid).IsKeyword() {
  1442  				// Avoid keyword
  1443  				goid = "_" + goid
  1444  
  1445  				// Also avoid existing fields
  1446  				for _, exist := used[goid]; exist; _, exist = used[goid] {
  1447  					goid = "_" + goid
  1448  				}
  1449  
  1450  				used[goid] = true
  1451  				ident[cid] = goid
  1452  			}
  1453  		}
  1454  	}
  1455  
  1456  	anon := 0
  1457  	for _, f := range dt.Field {
  1458  		if f.ByteOffset > off {
  1459  			fld = c.pad(fld, f.ByteOffset-off)
  1460  			off = f.ByteOffset
  1461  		}
  1462  		t := c.Type(f.Type, pos)
  1463  		tgo := t.Go
  1464  		size := t.Size
  1465  
  1466  		if f.BitSize > 0 {
  1467  			if f.BitSize%8 != 0 {
  1468  				continue
  1469  			}
  1470  			size = f.BitSize / 8
  1471  			name := tgo.(*ast.Ident).String()
  1472  			if strings.HasPrefix(name, "int") {
  1473  				name = "int"
  1474  			} else {
  1475  				name = "uint"
  1476  			}
  1477  			tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
  1478  		}
  1479  
  1480  		n := len(fld)
  1481  		fld = fld[0 : n+1]
  1482  		name := f.Name
  1483  		if name == "" {
  1484  			name = fmt.Sprintf("anon%d", anon)
  1485  			anon++
  1486  			ident[name] = name
  1487  		}
  1488  		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
  1489  		off += size
  1490  		buf.WriteString(t.C.String())
  1491  		buf.WriteString(" ")
  1492  		buf.WriteString(name)
  1493  		buf.WriteString("; ")
  1494  		if t.Align > align {
  1495  			align = t.Align
  1496  		}
  1497  	}
  1498  	if off < dt.ByteSize {
  1499  		fld = c.pad(fld, dt.ByteSize-off)
  1500  		off = dt.ByteSize
  1501  	}
  1502  	if off != dt.ByteSize {
  1503  		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
  1504  	}
  1505  	buf.WriteString("}")
  1506  	csyntax = buf.String()
  1507  
  1508  	if *godefs || *cdefs {
  1509  		godefsFields(fld)
  1510  	}
  1511  	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
  1512  	return
  1513  }
  1514  
  1515  func upper(s string) string {
  1516  	if s == "" {
  1517  		return ""
  1518  	}
  1519  	r, size := utf8.DecodeRuneInString(s)
  1520  	if r == '_' {
  1521  		return "X" + s
  1522  	}
  1523  	return string(unicode.ToUpper(r)) + s[size:]
  1524  }
  1525  
  1526  // godefsFields rewrites field names for use in Go or C definitions.
  1527  // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
  1528  // converts names to upper case, and rewrites _ into Pad_godefs_n,
  1529  // so that all fields are exported.
  1530  func godefsFields(fld []*ast.Field) {
  1531  	prefix := fieldPrefix(fld)
  1532  	npad := 0
  1533  	for _, f := range fld {
  1534  		for _, n := range f.Names {
  1535  			if n.Name != prefix {
  1536  				n.Name = strings.TrimPrefix(n.Name, prefix)
  1537  			}
  1538  			if n.Name == "_" {
  1539  				// Use exported name instead.
  1540  				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
  1541  				npad++
  1542  			}
  1543  			if !*cdefs {
  1544  				n.Name = upper(n.Name)
  1545  			}
  1546  		}
  1547  		p := &f.Type
  1548  		t := *p
  1549  		if star, ok := t.(*ast.StarExpr); ok {
  1550  			star = &ast.StarExpr{X: star.X}
  1551  			*p = star
  1552  			p = &star.X
  1553  			t = *p
  1554  		}
  1555  		if id, ok := t.(*ast.Ident); ok {
  1556  			if id.Name == "unsafe.Pointer" {
  1557  				*p = ast.NewIdent("*byte")
  1558  			}
  1559  		}
  1560  	}
  1561  }
  1562  
  1563  // fieldPrefix returns the prefix that should be removed from all the
  1564  // field names when generating the C or Go code.  For generated
  1565  // C, we leave the names as is (tv_sec, tv_usec), since that's what
  1566  // people are used to seeing in C.  For generated Go code, such as
  1567  // package syscall's data structures, we drop a common prefix
  1568  // (so sec, usec, which will get turned into Sec, Usec for exporting).
  1569  func fieldPrefix(fld []*ast.Field) string {
  1570  	if *cdefs {
  1571  		return ""
  1572  	}
  1573  	prefix := ""
  1574  	for _, f := range fld {
  1575  		for _, n := range f.Names {
  1576  			// Ignore field names that don't have the prefix we're
  1577  			// looking for.  It is common in C headers to have fields
  1578  			// named, say, _pad in an otherwise prefixed header.
  1579  			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
  1580  			// still want to remove the tv_ prefix.
  1581  			// The check for "orig_" here handles orig_eax in the
  1582  			// x86 ptrace register sets, which otherwise have all fields
  1583  			// with reg_ prefixes.
  1584  			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
  1585  				continue
  1586  			}
  1587  			i := strings.Index(n.Name, "_")
  1588  			if i < 0 {
  1589  				continue
  1590  			}
  1591  			if prefix == "" {
  1592  				prefix = n.Name[:i+1]
  1593  			} else if prefix != n.Name[:i+1] {
  1594  				return ""
  1595  			}
  1596  		}
  1597  	}
  1598  	return prefix
  1599  }