github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/irgen/typemap.go (about)

     1  //===- typemap.go - type and type descriptor mapping ----------------------===//
     2  //
     3  //                     The LLVM Compiler Infrastructure
     4  //
     5  // This file is distributed under the University of Illinois Open Source
     6  // License. See LICENSE.TXT for details.
     7  //
     8  //===----------------------------------------------------------------------===//
     9  //
    10  // This file implements the mapping from go/types types to LLVM types and to
    11  // type descriptors.
    12  //
    13  //===----------------------------------------------------------------------===//
    14  
    15  package irgen
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"sort"
    21  	"strconv"
    22  	"strings"
    23  
    24  	"llvm.org/llgo/third_party/gotools/go/ssa"
    25  	"llvm.org/llgo/third_party/gotools/go/ssa/ssautil"
    26  	"llvm.org/llgo/third_party/gotools/go/types"
    27  	"llvm.org/llgo/third_party/gotools/go/types/typeutil"
    28  	"llvm.org/llvm/bindings/go/llvm"
    29  )
    30  
    31  type MethodResolver interface {
    32  	ResolveMethod(*types.Selection) *govalue
    33  }
    34  
    35  // llvmTypeMap is provides a means of mapping from a types.Map
    36  // to llgo's corresponding LLVM type representation.
    37  type llvmTypeMap struct {
    38  	sizes      *types.StdSizes
    39  	ctx        llvm.Context
    40  	target     llvm.TargetData
    41  	inttype    llvm.Type
    42  	stringType llvm.Type
    43  
    44  	types typeutil.Map
    45  }
    46  
    47  type typeDescInfo struct {
    48  	global        llvm.Value
    49  	commonTypePtr llvm.Value
    50  	mapDescPtr    llvm.Value
    51  	gc, gcPtr     llvm.Value
    52  
    53  	interfaceMethodTables typeutil.Map
    54  }
    55  
    56  type TypeMap struct {
    57  	*llvmTypeMap
    58  	mc manglerContext
    59  
    60  	module         llvm.Module
    61  	pkgpath        string
    62  	types, algs    typeutil.Map
    63  	runtime        *runtimeInterface
    64  	methodResolver MethodResolver
    65  	types.MethodSetCache
    66  
    67  	commonTypeType, uncommonTypeType, ptrTypeType, funcTypeType, arrayTypeType, sliceTypeType, mapTypeType, chanTypeType, interfaceTypeType, structTypeType llvm.Type
    68  	mapDescType                                                                                                                                             llvm.Type
    69  
    70  	methodType, imethodType, structFieldType llvm.Type
    71  
    72  	typeSliceType, methodSliceType, imethodSliceType, structFieldSliceType llvm.Type
    73  
    74  	funcValType             llvm.Type
    75  	hashFnType, equalFnType llvm.Type
    76  
    77  	algsEmptyInterface,
    78  	algsInterface,
    79  	algsFloat,
    80  	algsComplex,
    81  	algsString,
    82  	algsIdentity,
    83  	algsError algorithms
    84  }
    85  
    86  type algorithms struct {
    87  	hash, hashDescriptor, equal, equalDescriptor llvm.Value
    88  }
    89  
    90  func NewLLVMTypeMap(ctx llvm.Context, target llvm.TargetData) *llvmTypeMap {
    91  	// spec says int is either 32-bit or 64-bit.
    92  	// ABI currently requires sizeof(int) == sizeof(uint) == sizeof(uintptr).
    93  	inttype := ctx.IntType(8 * target.PointerSize())
    94  
    95  	i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
    96  	elements := []llvm.Type{i8ptr, inttype}
    97  	stringType := llvm.StructType(elements, false)
    98  
    99  	return &llvmTypeMap{
   100  		ctx: ctx,
   101  		sizes: &types.StdSizes{
   102  			WordSize: int64(target.PointerSize()),
   103  			MaxAlign: 8,
   104  		},
   105  		target:     target,
   106  		inttype:    inttype,
   107  		stringType: stringType,
   108  	}
   109  }
   110  
   111  func NewTypeMap(pkg *ssa.Package, llvmtm *llvmTypeMap, module llvm.Module, r *runtimeInterface, mr MethodResolver) *TypeMap {
   112  	tm := &TypeMap{
   113  		llvmTypeMap:    llvmtm,
   114  		module:         module,
   115  		pkgpath:        pkg.Object.Path(),
   116  		runtime:        r,
   117  		methodResolver: mr,
   118  	}
   119  
   120  	tm.mc.init(pkg.Prog, &tm.MethodSetCache)
   121  
   122  	uintptrType := tm.inttype
   123  	voidPtrType := llvm.PointerType(tm.ctx.Int8Type(), 0)
   124  	boolType := llvm.Int8Type()
   125  	stringPtrType := llvm.PointerType(tm.stringType, 0)
   126  
   127  	tm.funcValType = tm.ctx.StructCreateNamed("funcVal")
   128  	tm.funcValType.StructSetBody([]llvm.Type{
   129  		llvm.PointerType(llvm.FunctionType(llvm.VoidType(), []llvm.Type{}, false), 0),
   130  	}, false)
   131  
   132  	params := []llvm.Type{voidPtrType, uintptrType}
   133  	tm.hashFnType = llvm.FunctionType(uintptrType, params, false)
   134  	params = []llvm.Type{voidPtrType, voidPtrType, uintptrType}
   135  	tm.equalFnType = llvm.FunctionType(boolType, params, false)
   136  
   137  	typeAlgorithms := [...]struct {
   138  		Name string
   139  		*algorithms
   140  	}{
   141  		{"empty_interface", &tm.algsEmptyInterface},
   142  		{"interface", &tm.algsInterface},
   143  		{"float", &tm.algsFloat},
   144  		{"complex", &tm.algsComplex},
   145  		{"string", &tm.algsString},
   146  		{"identity", &tm.algsIdentity},
   147  		{"error", &tm.algsError},
   148  	}
   149  	for _, typeAlgs := range typeAlgorithms {
   150  		hashFnName := "__go_type_hash_" + typeAlgs.Name
   151  		hashDescriptorName := hashFnName + "_descriptor"
   152  		equalFnName := "__go_type_equal_" + typeAlgs.Name
   153  		equalDescriptorName := equalFnName + "_descriptor"
   154  		typeAlgs.hash = llvm.AddGlobal(tm.module, tm.hashFnType, hashFnName)
   155  		typeAlgs.hashDescriptor = llvm.AddGlobal(tm.module, tm.funcValType, hashDescriptorName)
   156  		typeAlgs.equal = llvm.AddGlobal(tm.module, tm.equalFnType, equalFnName)
   157  		typeAlgs.equalDescriptor = llvm.AddGlobal(tm.module, tm.funcValType, equalDescriptorName)
   158  	}
   159  
   160  	tm.commonTypeType = tm.ctx.StructCreateNamed("commonType")
   161  	commonTypeTypePtr := llvm.PointerType(tm.commonTypeType, 0)
   162  
   163  	tm.methodType = tm.ctx.StructCreateNamed("method")
   164  	tm.methodType.StructSetBody([]llvm.Type{
   165  		stringPtrType,     // name
   166  		stringPtrType,     // pkgPath
   167  		commonTypeTypePtr, // mtype (without receiver)
   168  		commonTypeTypePtr, // type (with receiver)
   169  		voidPtrType,       // function
   170  	}, false)
   171  
   172  	tm.methodSliceType = tm.makeNamedSliceType("methodSlice", tm.methodType)
   173  
   174  	tm.uncommonTypeType = tm.ctx.StructCreateNamed("uncommonType")
   175  	tm.uncommonTypeType.StructSetBody([]llvm.Type{
   176  		stringPtrType,      // name
   177  		stringPtrType,      // pkgPath
   178  		tm.methodSliceType, // methods
   179  	}, false)
   180  
   181  	tm.commonTypeType.StructSetBody([]llvm.Type{
   182  		tm.ctx.Int8Type(),                        // Kind
   183  		tm.ctx.Int8Type(),                        // align
   184  		tm.ctx.Int8Type(),                        // fieldAlign
   185  		uintptrType,                              // size
   186  		tm.ctx.Int32Type(),                       // hash
   187  		llvm.PointerType(tm.funcValType, 0),      // hashfn
   188  		llvm.PointerType(tm.funcValType, 0),      // equalfn
   189  		voidPtrType,                              // gc
   190  		stringPtrType,                            // string
   191  		llvm.PointerType(tm.uncommonTypeType, 0), // uncommonType
   192  		commonTypeTypePtr,                        // ptrToThis
   193  	}, false)
   194  
   195  	tm.typeSliceType = tm.makeNamedSliceType("typeSlice", commonTypeTypePtr)
   196  
   197  	tm.ptrTypeType = tm.ctx.StructCreateNamed("ptrType")
   198  	tm.ptrTypeType.StructSetBody([]llvm.Type{
   199  		tm.commonTypeType,
   200  		commonTypeTypePtr,
   201  	}, false)
   202  
   203  	tm.funcTypeType = tm.ctx.StructCreateNamed("funcType")
   204  	tm.funcTypeType.StructSetBody([]llvm.Type{
   205  		tm.commonTypeType,
   206  		tm.ctx.Int8Type(), // dotdotdot
   207  		tm.typeSliceType,  // in
   208  		tm.typeSliceType,  // out
   209  	}, false)
   210  
   211  	tm.arrayTypeType = tm.ctx.StructCreateNamed("arrayType")
   212  	tm.arrayTypeType.StructSetBody([]llvm.Type{
   213  		tm.commonTypeType,
   214  		commonTypeTypePtr, // elem
   215  		commonTypeTypePtr, // slice
   216  		tm.inttype,        // len
   217  	}, false)
   218  
   219  	tm.sliceTypeType = tm.ctx.StructCreateNamed("sliceType")
   220  	tm.sliceTypeType.StructSetBody([]llvm.Type{
   221  		tm.commonTypeType,
   222  		commonTypeTypePtr, // elem
   223  	}, false)
   224  
   225  	tm.mapTypeType = tm.ctx.StructCreateNamed("mapType")
   226  	tm.mapTypeType.StructSetBody([]llvm.Type{
   227  		tm.commonTypeType,
   228  		commonTypeTypePtr, // key
   229  		commonTypeTypePtr, // elem
   230  	}, false)
   231  
   232  	tm.chanTypeType = tm.ctx.StructCreateNamed("chanType")
   233  	tm.chanTypeType.StructSetBody([]llvm.Type{
   234  		tm.commonTypeType,
   235  		commonTypeTypePtr, // elem
   236  		tm.inttype,        // dir
   237  	}, false)
   238  
   239  	tm.imethodType = tm.ctx.StructCreateNamed("imethod")
   240  	tm.imethodType.StructSetBody([]llvm.Type{
   241  		stringPtrType,     // name
   242  		stringPtrType,     // pkgPath
   243  		commonTypeTypePtr, // typ
   244  	}, false)
   245  
   246  	tm.imethodSliceType = tm.makeNamedSliceType("imethodSlice", tm.imethodType)
   247  
   248  	tm.interfaceTypeType = tm.ctx.StructCreateNamed("interfaceType")
   249  	tm.interfaceTypeType.StructSetBody([]llvm.Type{
   250  		tm.commonTypeType,
   251  		tm.imethodSliceType,
   252  	}, false)
   253  
   254  	tm.structFieldType = tm.ctx.StructCreateNamed("structField")
   255  	tm.structFieldType.StructSetBody([]llvm.Type{
   256  		stringPtrType,     // name
   257  		stringPtrType,     // pkgPath
   258  		commonTypeTypePtr, // typ
   259  		stringPtrType,     // tag
   260  		tm.inttype,        // offset
   261  	}, false)
   262  
   263  	tm.structFieldSliceType = tm.makeNamedSliceType("structFieldSlice", tm.structFieldType)
   264  
   265  	tm.structTypeType = tm.ctx.StructCreateNamed("structType")
   266  	tm.structTypeType.StructSetBody([]llvm.Type{
   267  		tm.commonTypeType,
   268  		tm.structFieldSliceType, // fields
   269  	}, false)
   270  
   271  	tm.mapDescType = tm.ctx.StructCreateNamed("mapDesc")
   272  	tm.mapDescType.StructSetBody([]llvm.Type{
   273  		commonTypeTypePtr, // map_descriptor
   274  		tm.inttype,        // entry_size
   275  		tm.inttype,        // key_offset
   276  		tm.inttype,        // value_offset
   277  	}, false)
   278  
   279  	return tm
   280  }
   281  
   282  func (tm *llvmTypeMap) ToLLVM(t types.Type) llvm.Type {
   283  	return tm.toLLVM(t, "")
   284  }
   285  
   286  func (tm *llvmTypeMap) toLLVM(t types.Type, name string) llvm.Type {
   287  	lt, ok := tm.types.At(t).(llvm.Type)
   288  	if !ok {
   289  		lt = tm.makeLLVMType(t, name)
   290  		if lt.IsNil() {
   291  			panic(fmt.Sprint("Failed to create LLVM type for: ", t))
   292  		}
   293  		tm.types.Set(t, lt)
   294  	}
   295  	return lt
   296  }
   297  
   298  func (tm *llvmTypeMap) makeLLVMType(t types.Type, name string) llvm.Type {
   299  	return tm.getBackendType(t).ToLLVM(tm.ctx)
   300  }
   301  
   302  func (tm *llvmTypeMap) Offsetsof(fields []*types.Var) []int64 {
   303  	offsets := make([]int64, len(fields))
   304  	var o int64
   305  	for i, f := range fields {
   306  		a := tm.Alignof(f.Type())
   307  		o = align(o, a)
   308  		offsets[i] = o
   309  		o += tm.Sizeof(f.Type())
   310  	}
   311  	return offsets
   312  }
   313  
   314  var basicSizes = [...]byte{
   315  	types.Bool:       1,
   316  	types.Int8:       1,
   317  	types.Int16:      2,
   318  	types.Int32:      4,
   319  	types.Int64:      8,
   320  	types.Uint8:      1,
   321  	types.Uint16:     2,
   322  	types.Uint32:     4,
   323  	types.Uint64:     8,
   324  	types.Float32:    4,
   325  	types.Float64:    8,
   326  	types.Complex64:  8,
   327  	types.Complex128: 16,
   328  }
   329  
   330  func (tm *llvmTypeMap) Sizeof(T types.Type) int64 {
   331  	switch t := T.Underlying().(type) {
   332  	case *types.Basic:
   333  		k := t.Kind()
   334  		if int(k) < len(basicSizes) {
   335  			if s := basicSizes[k]; s > 0 {
   336  				return int64(s)
   337  			}
   338  		}
   339  		if k == types.String {
   340  			return tm.sizes.WordSize * 2
   341  		}
   342  	case *types.Array:
   343  		a := tm.Alignof(t.Elem())
   344  		z := tm.Sizeof(t.Elem())
   345  		return align(z, a) * t.Len() // may be 0
   346  	case *types.Slice:
   347  		return tm.sizes.WordSize * 3
   348  	case *types.Struct:
   349  		n := t.NumFields()
   350  		if n == 0 {
   351  			return 0
   352  		}
   353  		fields := make([]*types.Var, t.NumFields())
   354  		for i := 0; i != t.NumFields(); i++ {
   355  			fields[i] = t.Field(i)
   356  		}
   357  		offsets := tm.Offsetsof(fields)
   358  		return align(offsets[n-1]+tm.Sizeof(t.Field(n-1).Type()), tm.Alignof(t))
   359  	case *types.Interface:
   360  		return tm.sizes.WordSize * 2
   361  	}
   362  	return tm.sizes.WordSize // catch-all
   363  }
   364  
   365  func (tm *llvmTypeMap) Alignof(t types.Type) int64 {
   366  	return tm.sizes.Alignof(t)
   367  }
   368  
   369  ///////////////////////////////////////////////////////////////////////////////
   370  
   371  func (tm *TypeMap) ToRuntime(t types.Type) llvm.Value {
   372  	return llvm.ConstBitCast(tm.getTypeDescriptorPointer(t), llvm.PointerType(llvm.Int8Type(), 0))
   373  }
   374  
   375  type localNamedTypeInfo struct {
   376  	functionName string
   377  	scopeNum     int
   378  }
   379  
   380  type namedTypeInfo struct {
   381  	pkgname, pkgpath string
   382  	name             string
   383  	localNamedTypeInfo
   384  }
   385  
   386  type manglerContext struct {
   387  	ti  map[*types.Named]localNamedTypeInfo
   388  	msc *types.MethodSetCache
   389  }
   390  
   391  // Assembles the method set into the order that gccgo uses (unexported methods first).
   392  // TODO(pcc): cache this.
   393  func orderedMethodSet(ms *types.MethodSet) []*types.Selection {
   394  	oms := make([]*types.Selection, ms.Len())
   395  	omsi := 0
   396  	for i := 0; i != ms.Len(); i++ {
   397  		if sel := ms.At(i); !sel.Obj().Exported() {
   398  			oms[omsi] = sel
   399  			omsi++
   400  		}
   401  	}
   402  	for i := 0; i != ms.Len(); i++ {
   403  		if sel := ms.At(i); sel.Obj().Exported() {
   404  			oms[omsi] = sel
   405  			omsi++
   406  		}
   407  	}
   408  	return oms
   409  }
   410  
   411  func (ctx *manglerContext) init(prog *ssa.Program, msc *types.MethodSetCache) {
   412  	ctx.msc = msc
   413  	ctx.ti = make(map[*types.Named]localNamedTypeInfo)
   414  	for f, _ := range ssautil.AllFunctions(prog) {
   415  		scopeNum := 0
   416  		var addNamedTypesToMap func(*types.Scope)
   417  		addNamedTypesToMap = func(scope *types.Scope) {
   418  			hasNamedTypes := false
   419  			for _, n := range scope.Names() {
   420  				if tn, ok := scope.Lookup(n).(*types.TypeName); ok {
   421  					hasNamedTypes = true
   422  					ctx.ti[tn.Type().(*types.Named)] = localNamedTypeInfo{f.Name(), scopeNum}
   423  				}
   424  			}
   425  			if hasNamedTypes {
   426  				scopeNum++
   427  			}
   428  			for i := 0; i != scope.NumChildren(); i++ {
   429  				addNamedTypesToMap(scope.Child(i))
   430  			}
   431  		}
   432  		if fobj, ok := f.Object().(*types.Func); ok && fobj.Scope() != nil {
   433  			addNamedTypesToMap(fobj.Scope())
   434  		}
   435  	}
   436  }
   437  
   438  func (ctx *manglerContext) getNamedTypeInfo(t types.Type) (nti namedTypeInfo) {
   439  	switch t := t.(type) {
   440  	case *types.Basic:
   441  		switch t.Kind() {
   442  		case types.Byte:
   443  			nti.name = "uint8"
   444  		case types.Rune:
   445  			nti.name = "int32"
   446  		case types.UnsafePointer:
   447  			nti.pkgname = "unsafe"
   448  			nti.pkgpath = "unsafe"
   449  			nti.name = "Pointer"
   450  		default:
   451  			nti.name = t.Name()
   452  		}
   453  
   454  	case *types.Named:
   455  		obj := t.Obj()
   456  		if pkg := obj.Pkg(); pkg != nil {
   457  			nti.pkgname = obj.Pkg().Name()
   458  			nti.pkgpath = obj.Pkg().Path()
   459  		}
   460  		nti.name = obj.Name()
   461  		nti.localNamedTypeInfo = ctx.ti[t]
   462  
   463  	default:
   464  		panic("not a named type")
   465  	}
   466  
   467  	return
   468  }
   469  
   470  func (ctx *manglerContext) mangleSignature(s *types.Signature, recv *types.Var, b *bytes.Buffer) {
   471  	b.WriteRune('F')
   472  	if recv != nil {
   473  		b.WriteRune('m')
   474  		ctx.mangleType(recv.Type(), b)
   475  	}
   476  
   477  	if p := s.Params(); p.Len() != 0 {
   478  		b.WriteRune('p')
   479  		for i := 0; i != p.Len(); i++ {
   480  			ctx.mangleType(p.At(i).Type(), b)
   481  		}
   482  		if s.Variadic() {
   483  			b.WriteRune('V')
   484  		}
   485  		b.WriteRune('e')
   486  	}
   487  
   488  	if r := s.Results(); r.Len() != 0 {
   489  		b.WriteRune('r')
   490  		for i := 0; i != r.Len(); i++ {
   491  			ctx.mangleType(r.At(i).Type(), b)
   492  		}
   493  		b.WriteRune('e')
   494  	}
   495  
   496  	b.WriteRune('e')
   497  }
   498  
   499  func ManglePackagePath(pkgpath string) string {
   500  	pkgpath = strings.Replace(pkgpath, "/", "_", -1)
   501  	pkgpath = strings.Replace(pkgpath, ".", "_", -1)
   502  	return pkgpath
   503  }
   504  
   505  func (ctx *manglerContext) mangleType(t types.Type, b *bytes.Buffer) {
   506  	switch t := t.(type) {
   507  	case *types.Basic, *types.Named:
   508  		var nb bytes.Buffer
   509  		ti := ctx.getNamedTypeInfo(t)
   510  		if ti.pkgpath != "" {
   511  			nb.WriteString(ManglePackagePath(ti.pkgpath))
   512  			nb.WriteRune('.')
   513  		}
   514  		if ti.functionName != "" {
   515  			nb.WriteString(ti.functionName)
   516  			nb.WriteRune('$')
   517  			if ti.scopeNum != 0 {
   518  				nb.WriteString(strconv.Itoa(ti.scopeNum))
   519  				nb.WriteRune('$')
   520  			}
   521  		}
   522  		nb.WriteString(ti.name)
   523  
   524  		b.WriteRune('N')
   525  		b.WriteString(strconv.Itoa(nb.Len()))
   526  		b.WriteRune('_')
   527  		b.WriteString(nb.String())
   528  
   529  	case *types.Pointer:
   530  		b.WriteRune('p')
   531  		ctx.mangleType(t.Elem(), b)
   532  
   533  	case *types.Map:
   534  		b.WriteRune('M')
   535  		ctx.mangleType(t.Key(), b)
   536  		b.WriteString("__")
   537  		ctx.mangleType(t.Elem(), b)
   538  
   539  	case *types.Chan:
   540  		b.WriteRune('C')
   541  		ctx.mangleType(t.Elem(), b)
   542  		switch t.Dir() {
   543  		case types.SendOnly:
   544  			b.WriteRune('s')
   545  		case types.RecvOnly:
   546  			b.WriteRune('r')
   547  		case types.SendRecv:
   548  			b.WriteString("sr")
   549  		}
   550  		b.WriteRune('e')
   551  
   552  	case *types.Signature:
   553  		ctx.mangleSignature(t, t.Recv(), b)
   554  
   555  	case *types.Array:
   556  		b.WriteRune('A')
   557  		ctx.mangleType(t.Elem(), b)
   558  		b.WriteString(strconv.FormatInt(t.Len(), 10))
   559  		b.WriteRune('e')
   560  
   561  	case *types.Slice:
   562  		b.WriteRune('A')
   563  		ctx.mangleType(t.Elem(), b)
   564  		b.WriteRune('e')
   565  
   566  	case *types.Struct:
   567  		b.WriteRune('S')
   568  		for i := 0; i != t.NumFields(); i++ {
   569  			f := t.Field(i)
   570  			if f.Anonymous() {
   571  				b.WriteString("0_")
   572  			} else {
   573  				b.WriteString(strconv.Itoa(len(f.Name())))
   574  				b.WriteRune('_')
   575  				b.WriteString(f.Name())
   576  			}
   577  			ctx.mangleType(f.Type(), b)
   578  			// TODO: tags are mangled here
   579  		}
   580  		b.WriteRune('e')
   581  
   582  	case *types.Interface:
   583  		b.WriteRune('I')
   584  		methodset := ctx.msc.MethodSet(t)
   585  		for _, m := range orderedMethodSet(methodset) {
   586  			method := m.Obj()
   587  			var nb bytes.Buffer
   588  			if !method.Exported() {
   589  				nb.WriteRune('.')
   590  				nb.WriteString(method.Pkg().Path())
   591  				nb.WriteRune('.')
   592  			}
   593  			nb.WriteString(method.Name())
   594  
   595  			b.WriteString(strconv.Itoa(nb.Len()))
   596  			b.WriteRune('_')
   597  			b.WriteString(nb.String())
   598  
   599  			ctx.mangleSignature(method.Type().(*types.Signature), nil, b)
   600  		}
   601  		b.WriteRune('e')
   602  
   603  	default:
   604  		panic(fmt.Sprintf("unhandled type: %#v", t))
   605  	}
   606  }
   607  
   608  func (ctx *manglerContext) mangleTypeDescriptorName(t types.Type, b *bytes.Buffer) {
   609  	switch t := t.(type) {
   610  	case *types.Basic, *types.Named:
   611  		b.WriteString("__go_tdn_")
   612  		ti := ctx.getNamedTypeInfo(t)
   613  		if ti.pkgpath != "" {
   614  			b.WriteString(ManglePackagePath(ti.pkgpath))
   615  			b.WriteRune('.')
   616  		}
   617  		if ti.functionName != "" {
   618  			b.WriteString(ti.functionName)
   619  			b.WriteRune('.')
   620  			if ti.scopeNum != 0 {
   621  				b.WriteString(strconv.Itoa(ti.scopeNum))
   622  				b.WriteRune('.')
   623  			}
   624  		}
   625  		b.WriteString(ti.name)
   626  
   627  	default:
   628  		b.WriteString("__go_td_")
   629  		ctx.mangleType(t, b)
   630  	}
   631  }
   632  
   633  func (ctx *manglerContext) mangleMapDescriptorName(t types.Type, b *bytes.Buffer) {
   634  	b.WriteString("__go_map_")
   635  	ctx.mangleType(t, b)
   636  }
   637  
   638  func (ctx *manglerContext) mangleImtName(srctype types.Type, targettype *types.Interface, b *bytes.Buffer) {
   639  	b.WriteString("__go_imt_")
   640  	ctx.mangleType(targettype, b)
   641  	b.WriteString("__")
   642  	ctx.mangleType(srctype, b)
   643  }
   644  
   645  func (ctx *manglerContext) mangleHashFunctionName(t types.Type) string {
   646  	var b bytes.Buffer
   647  	b.WriteString("__go_type_hash_")
   648  	ctx.mangleType(t, &b)
   649  	return b.String()
   650  }
   651  
   652  func (ctx *manglerContext) mangleEqualFunctionName(t types.Type) string {
   653  	var b bytes.Buffer
   654  	b.WriteString("__go_type_equal_")
   655  	ctx.mangleType(t, &b)
   656  	return b.String()
   657  }
   658  
   659  func (ctx *manglerContext) mangleFunctionName(f *ssa.Function) string {
   660  	var b bytes.Buffer
   661  
   662  	if f.Parent() != nil {
   663  		// Anonymous functions are not guaranteed to
   664  		// have unique identifiers at the global scope.
   665  		b.WriteString(ctx.mangleFunctionName(f.Parent()))
   666  		b.WriteRune(':')
   667  		b.WriteString(f.String())
   668  		return b.String()
   669  	}
   670  
   671  	// Synthetic bound and thunk functions are special cases; they can only be
   672  	// distinguished using private data that is only exposed via String().
   673  	if strings.HasSuffix(f.Name(), "$bound") || strings.HasSuffix(f.Name(), "$thunk") {
   674  		b.WriteString(f.String())
   675  		return b.String()
   676  	}
   677  
   678  	var pkg *types.Package
   679  	if f.Pkg != nil {
   680  		pkg = f.Pkg.Object
   681  	} else if !f.Object().Exported() {
   682  		pkg = f.Object().Pkg()
   683  	}
   684  
   685  	if pkg != nil {
   686  		b.WriteString(ManglePackagePath(pkg.Path()))
   687  		b.WriteRune('.')
   688  	}
   689  
   690  	if f.Signature.Recv() == nil && f.Name() == "init" {
   691  		b.WriteString(".import")
   692  	} else {
   693  		b.WriteString(f.Name())
   694  	}
   695  	if f.Signature.Recv() != nil {
   696  		b.WriteRune('.')
   697  		ctx.mangleType(f.Signature.Recv().Type(), &b)
   698  	}
   699  
   700  	return b.String()
   701  }
   702  
   703  func (ctx *manglerContext) mangleGlobalName(g *ssa.Global) string {
   704  	var b bytes.Buffer
   705  
   706  	b.WriteString(ManglePackagePath(g.Pkg.Object.Path()))
   707  	b.WriteRune('.')
   708  	b.WriteString(g.Name())
   709  
   710  	return b.String()
   711  }
   712  
   713  const (
   714  	// From gofrontend/types.h
   715  	gccgoTypeClassERROR = iota
   716  	gccgoTypeClassVOID
   717  	gccgoTypeClassBOOLEAN
   718  	gccgoTypeClassINTEGER
   719  	gccgoTypeClassFLOAT
   720  	gccgoTypeClassCOMPLEX
   721  	gccgoTypeClassSTRING
   722  	gccgoTypeClassSINK
   723  	gccgoTypeClassFUNCTION
   724  	gccgoTypeClassPOINTER
   725  	gccgoTypeClassNIL
   726  	gccgoTypeClassCALL_MULTIPLE_RESULT
   727  	gccgoTypeClassSTRUCT
   728  	gccgoTypeClassARRAY
   729  	gccgoTypeClassMAP
   730  	gccgoTypeClassCHANNEL
   731  	gccgoTypeClassINTERFACE
   732  	gccgoTypeClassNAMED
   733  	gccgoTypeClassFORWARD
   734  )
   735  
   736  func getStringHash(s string, h uint32) uint32 {
   737  	for _, c := range []byte(s) {
   738  		h ^= uint32(c)
   739  		h += 16777619
   740  	}
   741  	return h
   742  }
   743  
   744  func (tm *TypeMap) getTypeHash(t types.Type) uint32 {
   745  	switch t := t.(type) {
   746  	case *types.Basic, *types.Named:
   747  		nti := tm.mc.getNamedTypeInfo(t)
   748  		h := getStringHash(nti.functionName+nti.name+nti.pkgpath, 0)
   749  		h ^= uint32(nti.scopeNum)
   750  		return gccgoTypeClassNAMED + h
   751  
   752  	case *types.Signature:
   753  		var h uint32
   754  
   755  		p := t.Params()
   756  		for i := 0; i != p.Len(); i++ {
   757  			h += tm.getTypeHash(p.At(i).Type()) << uint32(i+1)
   758  		}
   759  
   760  		r := t.Results()
   761  		for i := 0; i != r.Len(); i++ {
   762  			h += tm.getTypeHash(r.At(i).Type()) << uint32(i+2)
   763  		}
   764  
   765  		if t.Variadic() {
   766  			h += 1
   767  		}
   768  		h <<= 4
   769  		return gccgoTypeClassFUNCTION + h
   770  
   771  	case *types.Pointer:
   772  		return gccgoTypeClassPOINTER + (tm.getTypeHash(t.Elem()) << 4)
   773  
   774  	case *types.Struct:
   775  		var h uint32
   776  		for i := 0; i != t.NumFields(); i++ {
   777  			h = (h << 1) + tm.getTypeHash(t.Field(i).Type())
   778  		}
   779  		h <<= 2
   780  		return gccgoTypeClassSTRUCT + h
   781  
   782  	case *types.Array:
   783  		return gccgoTypeClassARRAY + tm.getTypeHash(t.Elem()) + 1
   784  
   785  	case *types.Slice:
   786  		return gccgoTypeClassARRAY + tm.getTypeHash(t.Elem()) + 1
   787  
   788  	case *types.Map:
   789  		return gccgoTypeClassMAP + tm.getTypeHash(t.Key()) + tm.getTypeHash(t.Elem()) + 2
   790  
   791  	case *types.Chan:
   792  		var h uint32
   793  
   794  		switch t.Dir() {
   795  		case types.SendOnly:
   796  			h = 1
   797  		case types.RecvOnly:
   798  			h = 2
   799  		case types.SendRecv:
   800  			h = 3
   801  		}
   802  
   803  		h += tm.getTypeHash(t.Elem()) << 2
   804  		h <<= 3
   805  		return gccgoTypeClassCHANNEL + h
   806  
   807  	case *types.Interface:
   808  		var h uint32
   809  		for _, m := range orderedMethodSet(tm.MethodSet(t)) {
   810  			h = getStringHash(m.Obj().Name(), h)
   811  			h <<= 1
   812  		}
   813  		return gccgoTypeClassINTERFACE + h
   814  
   815  	default:
   816  		panic(fmt.Sprintf("unhandled type: %#v", t))
   817  	}
   818  }
   819  
   820  func (tm *TypeMap) writeType(typ types.Type, b *bytes.Buffer) {
   821  	switch t := typ.(type) {
   822  	case *types.Basic, *types.Named:
   823  		ti := tm.mc.getNamedTypeInfo(t)
   824  		if ti.pkgpath != "" {
   825  			b.WriteByte('\t')
   826  			b.WriteString(ManglePackagePath(ti.pkgpath))
   827  			b.WriteByte('\t')
   828  			b.WriteString(ti.pkgname)
   829  			b.WriteByte('.')
   830  		}
   831  		if ti.functionName != "" {
   832  			b.WriteByte('\t')
   833  			b.WriteString(ti.functionName)
   834  			b.WriteByte('$')
   835  			if ti.scopeNum != 0 {
   836  				b.WriteString(strconv.Itoa(ti.scopeNum))
   837  				b.WriteByte('$')
   838  			}
   839  			b.WriteByte('\t')
   840  		}
   841  		b.WriteString(ti.name)
   842  
   843  	case *types.Array:
   844  		fmt.Fprintf(b, "[%d]", t.Len())
   845  		tm.writeType(t.Elem(), b)
   846  
   847  	case *types.Slice:
   848  		b.WriteString("[]")
   849  		tm.writeType(t.Elem(), b)
   850  
   851  	case *types.Struct:
   852  		if t.NumFields() == 0 {
   853  			b.WriteString("struct {}")
   854  			return
   855  		}
   856  		b.WriteString("struct { ")
   857  		for i := 0; i != t.NumFields(); i++ {
   858  			f := t.Field(i)
   859  			if i > 0 {
   860  				b.WriteString("; ")
   861  			}
   862  			if !f.Anonymous() {
   863  				b.WriteString(f.Name())
   864  				b.WriteByte(' ')
   865  			}
   866  			tm.writeType(f.Type(), b)
   867  			if tag := t.Tag(i); tag != "" {
   868  				fmt.Fprintf(b, " %q", tag)
   869  			}
   870  		}
   871  		b.WriteString(" }")
   872  
   873  	case *types.Pointer:
   874  		b.WriteByte('*')
   875  		tm.writeType(t.Elem(), b)
   876  
   877  	case *types.Signature:
   878  		b.WriteString("func")
   879  		tm.writeSignature(t, b)
   880  
   881  	case *types.Interface:
   882  		if t.NumMethods() == 0 && t.NumEmbeddeds() == 0 {
   883  			b.WriteString("interface {}")
   884  			return
   885  		}
   886  		// We write the source-level methods and embedded types rather
   887  		// than the actual method set since resolved method signatures
   888  		// may have non-printable cycles if parameters have anonymous
   889  		// interface types that (directly or indirectly) embed the
   890  		// current interface. For instance, consider the result type
   891  		// of m:
   892  		//
   893  		//     type T interface{
   894  		//         m() interface{ T }
   895  		//     }
   896  		//
   897  		b.WriteString("interface { ")
   898  		// print explicit interface methods and embedded types
   899  		for i := 0; i != t.NumMethods(); i++ {
   900  			m := t.Method(i)
   901  			if i > 0 {
   902  				b.WriteString("; ")
   903  			}
   904  			if !m.Exported() {
   905  				b.WriteString(m.Pkg().Path())
   906  				b.WriteByte('.')
   907  			}
   908  			b.WriteString(m.Name())
   909  			tm.writeSignature(m.Type().(*types.Signature), b)
   910  		}
   911  		for i := 0; i != t.NumEmbeddeds(); i++ {
   912  			typ := t.Embedded(i)
   913  			if i > 0 || t.NumMethods() > 0 {
   914  				b.WriteString("; ")
   915  			}
   916  			tm.writeType(typ, b)
   917  		}
   918  		b.WriteString(" }")
   919  
   920  	case *types.Map:
   921  		b.WriteString("map[")
   922  		tm.writeType(t.Key(), b)
   923  		b.WriteByte(']')
   924  		tm.writeType(t.Elem(), b)
   925  
   926  	case *types.Chan:
   927  		var s string
   928  		var parens bool
   929  		switch t.Dir() {
   930  		case types.SendRecv:
   931  			s = "chan "
   932  			// chan (<-chan T) requires parentheses
   933  			if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly {
   934  				parens = true
   935  			}
   936  		case types.SendOnly:
   937  			s = "chan<- "
   938  		case types.RecvOnly:
   939  			s = "<-chan "
   940  		default:
   941  			panic("unreachable")
   942  		}
   943  		b.WriteString(s)
   944  		if parens {
   945  			b.WriteByte('(')
   946  		}
   947  		tm.writeType(t.Elem(), b)
   948  		if parens {
   949  			b.WriteByte(')')
   950  		}
   951  
   952  	default:
   953  		panic(fmt.Sprintf("unhandled type: %#v", t))
   954  	}
   955  }
   956  
   957  func (tm *TypeMap) writeTuple(tup *types.Tuple, variadic bool, b *bytes.Buffer) {
   958  	b.WriteByte('(')
   959  	if tup != nil {
   960  		for i := 0; i != tup.Len(); i++ {
   961  			v := tup.At(i)
   962  			if i > 0 {
   963  				b.WriteString(", ")
   964  			}
   965  			typ := v.Type()
   966  			if variadic && i == tup.Len()-1 {
   967  				b.WriteString("...")
   968  				typ = typ.(*types.Slice).Elem()
   969  			}
   970  			tm.writeType(typ, b)
   971  		}
   972  	}
   973  	b.WriteByte(')')
   974  }
   975  
   976  func (tm *TypeMap) writeSignature(sig *types.Signature, b *bytes.Buffer) {
   977  	tm.writeTuple(sig.Params(), sig.Variadic(), b)
   978  
   979  	n := sig.Results().Len()
   980  	if n == 0 {
   981  		// no result
   982  		return
   983  	}
   984  
   985  	b.WriteByte(' ')
   986  	if n == 1 {
   987  		tm.writeType(sig.Results().At(0).Type(), b)
   988  		return
   989  	}
   990  
   991  	// multiple results
   992  	tm.writeTuple(sig.Results(), false, b)
   993  }
   994  
   995  func (tm *TypeMap) getTypeDescType(t types.Type) llvm.Type {
   996  	switch t.Underlying().(type) {
   997  	case *types.Basic:
   998  		return tm.commonTypeType
   999  	case *types.Pointer:
  1000  		return tm.ptrTypeType
  1001  	case *types.Signature:
  1002  		return tm.funcTypeType
  1003  	case *types.Array:
  1004  		return tm.arrayTypeType
  1005  	case *types.Slice:
  1006  		return tm.sliceTypeType
  1007  	case *types.Map:
  1008  		return tm.mapTypeType
  1009  	case *types.Chan:
  1010  		return tm.chanTypeType
  1011  	case *types.Struct:
  1012  		return tm.structTypeType
  1013  	case *types.Interface:
  1014  		return tm.interfaceTypeType
  1015  	default:
  1016  		panic(fmt.Sprintf("unhandled type: %#v", t))
  1017  	}
  1018  }
  1019  
  1020  func (tm *TypeMap) getNamedTypeLinkage(nt *types.Named) (linkage llvm.Linkage, emit bool) {
  1021  	if pkg := nt.Obj().Pkg(); pkg != nil {
  1022  		linkage = llvm.ExternalLinkage
  1023  		emit = pkg.Path() == tm.pkgpath
  1024  	} else {
  1025  		linkage = llvm.LinkOnceODRLinkage
  1026  		emit = true
  1027  	}
  1028  
  1029  	return
  1030  }
  1031  
  1032  func (tm *TypeMap) getTypeDescLinkage(t types.Type) (linkage llvm.Linkage, emit bool) {
  1033  	switch t := t.(type) {
  1034  	case *types.Named:
  1035  		linkage, emit = tm.getNamedTypeLinkage(t)
  1036  
  1037  	case *types.Pointer:
  1038  		elem := t.Elem()
  1039  		if nt, ok := elem.(*types.Named); ok {
  1040  			// Thanks to the ptrToThis member, pointers to named types appear
  1041  			// in exactly the same objects as the named types themselves, so
  1042  			// we can give them the same linkage.
  1043  			linkage, emit = tm.getNamedTypeLinkage(nt)
  1044  			return
  1045  		}
  1046  		linkage = llvm.LinkOnceODRLinkage
  1047  		emit = true
  1048  
  1049  	default:
  1050  		linkage = llvm.LinkOnceODRLinkage
  1051  		emit = true
  1052  	}
  1053  
  1054  	return
  1055  }
  1056  
  1057  type typeAndInfo struct {
  1058  	typ        types.Type
  1059  	typeString string
  1060  	tdi        *typeDescInfo
  1061  }
  1062  
  1063  type byTypeName []typeAndInfo
  1064  
  1065  func (ts byTypeName) Len() int { return len(ts) }
  1066  func (ts byTypeName) Swap(i, j int) {
  1067  	ts[i], ts[j] = ts[j], ts[i]
  1068  }
  1069  func (ts byTypeName) Less(i, j int) bool {
  1070  	return ts[i].typeString < ts[j].typeString
  1071  }
  1072  
  1073  func (tm *TypeMap) emitTypeDescInitializers() {
  1074  	var maxSize, maxAlign int64
  1075  	maxAlign = 1
  1076  
  1077  	for changed := true; changed; {
  1078  		changed = false
  1079  
  1080  		var ts []typeAndInfo
  1081  
  1082  		tm.types.Iterate(func(key types.Type, value interface{}) {
  1083  			tdi := value.(*typeDescInfo)
  1084  			if tdi.global.Initializer().C == nil {
  1085  				linkage, emit := tm.getTypeDescLinkage(key)
  1086  				tdi.global.SetLinkage(linkage)
  1087  				tdi.gc.SetLinkage(linkage)
  1088  				if emit {
  1089  					changed = true
  1090  					ts = append(ts, typeAndInfo{key, key.String(), tdi})
  1091  				}
  1092  			}
  1093  		})
  1094  
  1095  		if changed {
  1096  			sort.Sort(byTypeName(ts))
  1097  			for _, t := range ts {
  1098  				tm.emitTypeDescInitializer(t.typ, t.tdi)
  1099  				if size := tm.Sizeof(t.typ); size > maxSize {
  1100  					maxSize = size
  1101  				}
  1102  				if align := tm.Alignof(t.typ); align > maxAlign {
  1103  					maxAlign = align
  1104  				}
  1105  			}
  1106  		}
  1107  	}
  1108  }
  1109  
  1110  const (
  1111  	// From libgo/runtime/mgc0.h
  1112  	gcOpcodeEND = iota
  1113  	gcOpcodePTR
  1114  	gcOpcodeAPTR
  1115  	gcOpcodeARRAY_START
  1116  	gcOpcodeARRAY_NEXT
  1117  	gcOpcodeCALL
  1118  	gcOpcodeCHAN_PTR
  1119  	gcOpcodeSTRING
  1120  	gcOpcodeEFACE
  1121  	gcOpcodeIFACE
  1122  	gcOpcodeSLICE
  1123  	gcOpcodeREGION
  1124  
  1125  	gcStackCapacity = 8
  1126  )
  1127  
  1128  func (tm *TypeMap) makeGcInst(val int64) llvm.Value {
  1129  	c := llvm.ConstInt(tm.inttype, uint64(val), false)
  1130  	return llvm.ConstIntToPtr(c, llvm.PointerType(tm.ctx.Int8Type(), 0))
  1131  }
  1132  
  1133  func (tm *TypeMap) appendGcInsts(insts []llvm.Value, t types.Type, offset, stackSize int64) []llvm.Value {
  1134  	switch u := t.Underlying().(type) {
  1135  	case *types.Basic:
  1136  		switch u.Kind() {
  1137  		case types.String:
  1138  			insts = append(insts, tm.makeGcInst(gcOpcodeSTRING), tm.makeGcInst(offset))
  1139  		case types.UnsafePointer:
  1140  			insts = append(insts, tm.makeGcInst(gcOpcodeAPTR), tm.makeGcInst(offset))
  1141  		}
  1142  	case *types.Pointer:
  1143  		insts = append(insts, tm.makeGcInst(gcOpcodePTR), tm.makeGcInst(offset),
  1144  			tm.getGcPointer(u.Elem()))
  1145  	case *types.Signature, *types.Map:
  1146  		insts = append(insts, tm.makeGcInst(gcOpcodeAPTR), tm.makeGcInst(offset))
  1147  	case *types.Array:
  1148  		if u.Len() == 0 {
  1149  			return insts
  1150  		} else if stackSize >= gcStackCapacity {
  1151  			insts = append(insts, tm.makeGcInst(gcOpcodeREGION), tm.makeGcInst(offset),
  1152  				tm.makeGcInst(tm.Sizeof(t)), tm.getGcPointer(t))
  1153  		} else {
  1154  			insts = append(insts, tm.makeGcInst(gcOpcodeARRAY_START), tm.makeGcInst(offset),
  1155  				tm.makeGcInst(u.Len()), tm.makeGcInst(tm.Sizeof(u.Elem())))
  1156  			insts = tm.appendGcInsts(insts, u.Elem(), 0, stackSize+1)
  1157  			insts = append(insts, tm.makeGcInst(gcOpcodeARRAY_NEXT))
  1158  		}
  1159  	case *types.Slice:
  1160  		if tm.Sizeof(u.Elem()) == 0 {
  1161  			insts = append(insts, tm.makeGcInst(gcOpcodeAPTR), tm.makeGcInst(offset))
  1162  		} else {
  1163  			insts = append(insts, tm.makeGcInst(gcOpcodeSLICE), tm.makeGcInst(offset),
  1164  				tm.getGcPointer(u.Elem()))
  1165  		}
  1166  	case *types.Chan:
  1167  		insts = append(insts, tm.makeGcInst(gcOpcodeCHAN_PTR), tm.makeGcInst(offset),
  1168  			tm.ToRuntime(t))
  1169  	case *types.Struct:
  1170  		fields := make([]*types.Var, u.NumFields())
  1171  		for i := range fields {
  1172  			fields[i] = u.Field(i)
  1173  		}
  1174  		offsets := tm.Offsetsof(fields)
  1175  
  1176  		for i, field := range fields {
  1177  			insts = tm.appendGcInsts(insts, field.Type(), offset+offsets[i], stackSize)
  1178  		}
  1179  	case *types.Interface:
  1180  		if u.NumMethods() == 0 {
  1181  			insts = append(insts, tm.makeGcInst(gcOpcodeEFACE), tm.makeGcInst(offset))
  1182  		} else {
  1183  			insts = append(insts, tm.makeGcInst(gcOpcodeIFACE), tm.makeGcInst(offset))
  1184  		}
  1185  	default:
  1186  		panic(fmt.Sprintf("unhandled type: %#v", t))
  1187  	}
  1188  
  1189  	return insts
  1190  }
  1191  
  1192  func (tm *TypeMap) emitTypeDescInitializer(t types.Type, tdi *typeDescInfo) {
  1193  	// initialize type descriptor
  1194  	tdi.global.SetInitializer(tm.makeTypeDescInitializer(t))
  1195  
  1196  	// initialize GC program
  1197  	insts := []llvm.Value{tm.makeGcInst(tm.Sizeof(t))}
  1198  	insts = tm.appendGcInsts(insts, t, 0, 0)
  1199  	insts = append(insts, tm.makeGcInst(gcOpcodeEND))
  1200  
  1201  	i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
  1202  	instArray := llvm.ConstArray(i8ptr, insts)
  1203  
  1204  	newGc := llvm.AddGlobal(tm.module, instArray.Type(), "")
  1205  	newGc.SetGlobalConstant(true)
  1206  	newGc.SetInitializer(instArray)
  1207  	gcName := tdi.gc.Name()
  1208  	tdi.gc.SetName("")
  1209  	newGc.SetName(gcName)
  1210  	newGc.SetLinkage(tdi.gc.Linkage())
  1211  
  1212  	tdi.gc.ReplaceAllUsesWith(llvm.ConstBitCast(newGc, tdi.gc.Type()))
  1213  	tdi.gc.EraseFromParentAsGlobal()
  1214  	tdi.gc = llvm.Value{nil}
  1215  	tdi.gcPtr = llvm.ConstBitCast(newGc, i8ptr)
  1216  }
  1217  
  1218  func (tm *TypeMap) makeTypeDescInitializer(t types.Type) llvm.Value {
  1219  	switch u := t.Underlying().(type) {
  1220  	case *types.Basic:
  1221  		return tm.makeBasicType(t, u)
  1222  	case *types.Pointer:
  1223  		return tm.makePointerType(t, u)
  1224  	case *types.Signature:
  1225  		return tm.makeFuncType(t, u)
  1226  	case *types.Array:
  1227  		return tm.makeArrayType(t, u)
  1228  	case *types.Slice:
  1229  		return tm.makeSliceType(t, u)
  1230  	case *types.Map:
  1231  		return tm.makeMapType(t, u)
  1232  	case *types.Chan:
  1233  		return tm.makeChanType(t, u)
  1234  	case *types.Struct:
  1235  		return tm.makeStructType(t, u)
  1236  	case *types.Interface:
  1237  		return tm.makeInterfaceType(t, u)
  1238  	default:
  1239  		panic(fmt.Sprintf("unhandled type: %#v", t))
  1240  	}
  1241  }
  1242  
  1243  func (tm *TypeMap) getStructAlgorithms(st *types.Struct) algorithms {
  1244  	if algs, ok := tm.algs.At(st).(algorithms); ok {
  1245  		return algs
  1246  	}
  1247  
  1248  	hashes := make([]llvm.Value, st.NumFields())
  1249  	equals := make([]llvm.Value, st.NumFields())
  1250  
  1251  	for i := range hashes {
  1252  		algs := tm.getAlgorithms(st.Field(i).Type())
  1253  		if algs.hashDescriptor == tm.algsError.hashDescriptor {
  1254  			return algs
  1255  		}
  1256  		hashes[i], equals[i] = algs.hash, algs.equal
  1257  	}
  1258  
  1259  	i8ptr := llvm.PointerType(tm.ctx.Int8Type(), 0)
  1260  	llsptrty := llvm.PointerType(tm.ToLLVM(st), 0)
  1261  
  1262  	builder := tm.ctx.NewBuilder()
  1263  	defer builder.Dispose()
  1264  
  1265  	hashFunctionName := tm.mc.mangleHashFunctionName(st)
  1266  	hash := llvm.AddFunction(tm.module, hashFunctionName, tm.hashFnType)
  1267  	hash.SetLinkage(llvm.LinkOnceODRLinkage)
  1268  	hashDescriptor := tm.createAlgorithmDescriptor(hashFunctionName+"_descriptor", hash)
  1269  
  1270  	builder.SetInsertPointAtEnd(llvm.AddBasicBlock(hash, "entry"))
  1271  	sptr := builder.CreateBitCast(hash.Param(0), llsptrty, "")
  1272  
  1273  	hashval := llvm.ConstNull(tm.inttype)
  1274  	i33 := llvm.ConstInt(tm.inttype, 33, false)
  1275  
  1276  	for i, fhash := range hashes {
  1277  		fptr := builder.CreateStructGEP(sptr, i, "")
  1278  		fptr = builder.CreateBitCast(fptr, i8ptr, "")
  1279  		fsize := llvm.ConstInt(tm.inttype, uint64(tm.sizes.Sizeof(st.Field(i).Type())), false)
  1280  		hashcall := builder.CreateCall(fhash, []llvm.Value{fptr, fsize}, "")
  1281  		hashval = builder.CreateMul(hashval, i33, "")
  1282  		hashval = builder.CreateAdd(hashval, hashcall, "")
  1283  	}
  1284  
  1285  	builder.CreateRet(hashval)
  1286  
  1287  	equalFunctionName := tm.mc.mangleEqualFunctionName(st)
  1288  	equal := llvm.AddFunction(tm.module, equalFunctionName, tm.equalFnType)
  1289  	equal.SetLinkage(llvm.LinkOnceODRLinkage)
  1290  	equalDescriptor := tm.createAlgorithmDescriptor(equalFunctionName+"_descriptor", equal)
  1291  
  1292  	eqentrybb := llvm.AddBasicBlock(equal, "entry")
  1293  	eqretzerobb := llvm.AddBasicBlock(equal, "retzero")
  1294  	builder.SetInsertPointAtEnd(eqentrybb)
  1295  	s1ptr := builder.CreateBitCast(equal.Param(0), llsptrty, "")
  1296  	s2ptr := builder.CreateBitCast(equal.Param(1), llsptrty, "")
  1297  
  1298  	zerobool := llvm.ConstNull(tm.ctx.Int8Type())
  1299  	onebool := llvm.ConstInt(tm.ctx.Int8Type(), 1, false)
  1300  
  1301  	for i, fequal := range equals {
  1302  		f1ptr := builder.CreateStructGEP(s1ptr, i, "")
  1303  		f1ptr = builder.CreateBitCast(f1ptr, i8ptr, "")
  1304  		f2ptr := builder.CreateStructGEP(s2ptr, i, "")
  1305  		f2ptr = builder.CreateBitCast(f2ptr, i8ptr, "")
  1306  		fsize := llvm.ConstInt(tm.inttype, uint64(tm.sizes.Sizeof(st.Field(i).Type())), false)
  1307  		equalcall := builder.CreateCall(fequal, []llvm.Value{f1ptr, f2ptr, fsize}, "")
  1308  		equaleqzero := builder.CreateICmp(llvm.IntEQ, equalcall, zerobool, "")
  1309  		contbb := llvm.AddBasicBlock(equal, "cont")
  1310  		builder.CreateCondBr(equaleqzero, eqretzerobb, contbb)
  1311  		builder.SetInsertPointAtEnd(contbb)
  1312  	}
  1313  
  1314  	builder.CreateRet(onebool)
  1315  
  1316  	builder.SetInsertPointAtEnd(eqretzerobb)
  1317  	builder.CreateRet(zerobool)
  1318  
  1319  	algs := algorithms{
  1320  		hash:            hash,
  1321  		hashDescriptor:  hashDescriptor,
  1322  		equal:           equal,
  1323  		equalDescriptor: equalDescriptor,
  1324  	}
  1325  	tm.algs.Set(st, algs)
  1326  	return algs
  1327  }
  1328  
  1329  func (tm *TypeMap) getArrayAlgorithms(at *types.Array) algorithms {
  1330  	if algs, ok := tm.algs.At(at).(algorithms); ok {
  1331  		return algs
  1332  	}
  1333  
  1334  	elemAlgs := tm.getAlgorithms(at.Elem())
  1335  	if elemAlgs.hashDescriptor == tm.algsError.hashDescriptor {
  1336  		return elemAlgs
  1337  	}
  1338  
  1339  	i8ptr := llvm.PointerType(tm.ctx.Int8Type(), 0)
  1340  	llelemty := llvm.PointerType(tm.ToLLVM(at.Elem()), 0)
  1341  
  1342  	i1 := llvm.ConstInt(tm.inttype, 1, false)
  1343  	alen := llvm.ConstInt(tm.inttype, uint64(at.Len()), false)
  1344  	esize := llvm.ConstInt(tm.inttype, uint64(tm.sizes.Sizeof(at.Elem())), false)
  1345  
  1346  	builder := tm.ctx.NewBuilder()
  1347  	defer builder.Dispose()
  1348  
  1349  	hashFunctionName := tm.mc.mangleHashFunctionName(at)
  1350  	hash := llvm.AddFunction(tm.module, hashFunctionName, tm.hashFnType)
  1351  	hash.SetLinkage(llvm.LinkOnceODRLinkage)
  1352  	hashDescriptor := tm.createAlgorithmDescriptor(hashFunctionName+"_descriptor", hash)
  1353  	equalFunctionName := tm.mc.mangleHashFunctionName(at)
  1354  	equal := llvm.AddFunction(tm.module, equalFunctionName, tm.equalFnType)
  1355  	equal.SetLinkage(llvm.LinkOnceODRLinkage)
  1356  	equalDescriptor := tm.createAlgorithmDescriptor(equalFunctionName+"_descriptor", equal)
  1357  	algs := algorithms{
  1358  		hash:            hash,
  1359  		hashDescriptor:  hashDescriptor,
  1360  		equal:           equal,
  1361  		equalDescriptor: equalDescriptor,
  1362  	}
  1363  	tm.algs.Set(at, algs)
  1364  
  1365  	hashentrybb := llvm.AddBasicBlock(hash, "entry")
  1366  	builder.SetInsertPointAtEnd(hashentrybb)
  1367  	if at.Len() == 0 {
  1368  		builder.CreateRet(llvm.ConstNull(tm.inttype))
  1369  	} else {
  1370  		i33 := llvm.ConstInt(tm.inttype, 33, false)
  1371  
  1372  		aptr := builder.CreateBitCast(hash.Param(0), llelemty, "")
  1373  		loopbb := llvm.AddBasicBlock(hash, "loop")
  1374  		builder.CreateBr(loopbb)
  1375  
  1376  		exitbb := llvm.AddBasicBlock(hash, "exit")
  1377  
  1378  		builder.SetInsertPointAtEnd(loopbb)
  1379  		indexphi := builder.CreatePHI(tm.inttype, "")
  1380  		index := indexphi
  1381  		hashvalphi := builder.CreatePHI(tm.inttype, "")
  1382  		hashval := hashvalphi
  1383  
  1384  		eptr := builder.CreateGEP(aptr, []llvm.Value{index}, "")
  1385  		eptr = builder.CreateBitCast(eptr, i8ptr, "")
  1386  
  1387  		hashcall := builder.CreateCall(elemAlgs.hash, []llvm.Value{eptr, esize}, "")
  1388  		hashval = builder.CreateMul(hashval, i33, "")
  1389  		hashval = builder.CreateAdd(hashval, hashcall, "")
  1390  
  1391  		index = builder.CreateAdd(index, i1, "")
  1392  
  1393  		indexphi.AddIncoming(
  1394  			[]llvm.Value{llvm.ConstNull(tm.inttype), index},
  1395  			[]llvm.BasicBlock{hashentrybb, loopbb},
  1396  		)
  1397  		hashvalphi.AddIncoming(
  1398  			[]llvm.Value{llvm.ConstNull(tm.inttype), hashval},
  1399  			[]llvm.BasicBlock{hashentrybb, loopbb},
  1400  		)
  1401  
  1402  		exit := builder.CreateICmp(llvm.IntEQ, index, alen, "")
  1403  		builder.CreateCondBr(exit, exitbb, loopbb)
  1404  
  1405  		builder.SetInsertPointAtEnd(exitbb)
  1406  		builder.CreateRet(hashval)
  1407  	}
  1408  
  1409  	zerobool := llvm.ConstNull(tm.ctx.Int8Type())
  1410  	onebool := llvm.ConstInt(tm.ctx.Int8Type(), 1, false)
  1411  
  1412  	eqentrybb := llvm.AddBasicBlock(equal, "entry")
  1413  	builder.SetInsertPointAtEnd(eqentrybb)
  1414  	if at.Len() == 0 {
  1415  		builder.CreateRet(onebool)
  1416  	} else {
  1417  		a1ptr := builder.CreateBitCast(equal.Param(0), llelemty, "")
  1418  		a2ptr := builder.CreateBitCast(equal.Param(1), llelemty, "")
  1419  		loopbb := llvm.AddBasicBlock(equal, "loop")
  1420  		builder.CreateBr(loopbb)
  1421  
  1422  		exitbb := llvm.AddBasicBlock(equal, "exit")
  1423  		retzerobb := llvm.AddBasicBlock(equal, "retzero")
  1424  
  1425  		builder.SetInsertPointAtEnd(loopbb)
  1426  		indexphi := builder.CreatePHI(tm.inttype, "")
  1427  		index := indexphi
  1428  
  1429  		e1ptr := builder.CreateGEP(a1ptr, []llvm.Value{index}, "")
  1430  		e1ptr = builder.CreateBitCast(e1ptr, i8ptr, "")
  1431  		e2ptr := builder.CreateGEP(a2ptr, []llvm.Value{index}, "")
  1432  		e2ptr = builder.CreateBitCast(e2ptr, i8ptr, "")
  1433  
  1434  		equalcall := builder.CreateCall(elemAlgs.equal, []llvm.Value{e1ptr, e2ptr, esize}, "")
  1435  		equaleqzero := builder.CreateICmp(llvm.IntEQ, equalcall, zerobool, "")
  1436  
  1437  		contbb := llvm.AddBasicBlock(equal, "cont")
  1438  		builder.CreateCondBr(equaleqzero, retzerobb, contbb)
  1439  
  1440  		builder.SetInsertPointAtEnd(contbb)
  1441  
  1442  		index = builder.CreateAdd(index, i1, "")
  1443  
  1444  		indexphi.AddIncoming(
  1445  			[]llvm.Value{llvm.ConstNull(tm.inttype), index},
  1446  			[]llvm.BasicBlock{eqentrybb, contbb},
  1447  		)
  1448  
  1449  		exit := builder.CreateICmp(llvm.IntEQ, index, alen, "")
  1450  		builder.CreateCondBr(exit, exitbb, loopbb)
  1451  
  1452  		builder.SetInsertPointAtEnd(exitbb)
  1453  		builder.CreateRet(onebool)
  1454  
  1455  		builder.SetInsertPointAtEnd(retzerobb)
  1456  		builder.CreateRet(zerobool)
  1457  	}
  1458  
  1459  	return algs
  1460  }
  1461  
  1462  func (tm *TypeMap) createAlgorithmDescriptor(name string, fn llvm.Value) llvm.Value {
  1463  	d := llvm.AddGlobal(tm.module, tm.funcValType, name)
  1464  	d.SetLinkage(llvm.LinkOnceODRLinkage)
  1465  	d.SetGlobalConstant(true)
  1466  	fn = llvm.ConstBitCast(fn, tm.funcValType.StructElementTypes()[0])
  1467  	init := llvm.ConstNull(tm.funcValType)
  1468  	init = llvm.ConstInsertValue(init, fn, []uint32{0})
  1469  	d.SetInitializer(init)
  1470  	return d
  1471  }
  1472  
  1473  func (tm *TypeMap) getAlgorithms(t types.Type) algorithms {
  1474  	switch t := t.Underlying().(type) {
  1475  	case *types.Interface:
  1476  		if t.NumMethods() == 0 {
  1477  			return tm.algsEmptyInterface
  1478  		}
  1479  		return tm.algsInterface
  1480  	case *types.Basic:
  1481  		switch t.Kind() {
  1482  		case types.Float32, types.Float64:
  1483  			return tm.algsFloat
  1484  		case types.Complex64, types.Complex128:
  1485  			return tm.algsComplex
  1486  		case types.String:
  1487  			return tm.algsString
  1488  		}
  1489  		return tm.algsIdentity
  1490  	case *types.Signature, *types.Map, *types.Slice:
  1491  		return tm.algsError
  1492  	case *types.Struct:
  1493  		return tm.getStructAlgorithms(t)
  1494  	case *types.Array:
  1495  		return tm.getArrayAlgorithms(t)
  1496  	}
  1497  	return tm.algsIdentity
  1498  }
  1499  
  1500  func (tm *TypeMap) getTypeDescInfo(t types.Type) *typeDescInfo {
  1501  	if tdi, ok := tm.types.At(t).(*typeDescInfo); ok {
  1502  		return tdi
  1503  	}
  1504  
  1505  	var b bytes.Buffer
  1506  	tm.mc.mangleTypeDescriptorName(t, &b)
  1507  
  1508  	global := llvm.AddGlobal(tm.module, tm.getTypeDescType(t), b.String())
  1509  	global.SetGlobalConstant(true)
  1510  	ptr := llvm.ConstBitCast(global, llvm.PointerType(tm.commonTypeType, 0))
  1511  
  1512  	gc := llvm.AddGlobal(tm.module, llvm.PointerType(llvm.Int8Type(), 0), b.String()+"$gc")
  1513  	gc.SetGlobalConstant(true)
  1514  	gcPtr := llvm.ConstBitCast(gc, llvm.PointerType(tm.ctx.Int8Type(), 0))
  1515  
  1516  	var mapDescPtr llvm.Value
  1517  	if m, ok := t.Underlying().(*types.Map); ok {
  1518  		var mapb bytes.Buffer
  1519  		tm.mc.mangleMapDescriptorName(t, &mapb)
  1520  
  1521  		mapDescPtr = llvm.AddGlobal(tm.module, tm.mapDescType, mapb.String())
  1522  		mapDescPtr.SetGlobalConstant(true)
  1523  		mapDescPtr.SetLinkage(llvm.LinkOnceODRLinkage)
  1524  		mapDescPtr.SetInitializer(tm.makeMapDesc(ptr, m))
  1525  	}
  1526  
  1527  	tdi := &typeDescInfo{
  1528  		global:        global,
  1529  		commonTypePtr: ptr,
  1530  		mapDescPtr:    mapDescPtr,
  1531  		gc:            gc,
  1532  		gcPtr:         gcPtr,
  1533  	}
  1534  	tm.types.Set(t, tdi)
  1535  	return tdi
  1536  }
  1537  
  1538  func (tm *TypeMap) getTypeDescriptorPointer(t types.Type) llvm.Value {
  1539  	return tm.getTypeDescInfo(t).commonTypePtr
  1540  }
  1541  
  1542  func (tm *TypeMap) getMapDescriptorPointer(t types.Type) llvm.Value {
  1543  	return tm.getTypeDescInfo(t).mapDescPtr
  1544  }
  1545  
  1546  func (tm *TypeMap) getGcPointer(t types.Type) llvm.Value {
  1547  	return tm.getTypeDescInfo(t).gcPtr
  1548  }
  1549  
  1550  func (tm *TypeMap) getItabPointer(srctype types.Type, targettype *types.Interface) llvm.Value {
  1551  	if targettype.NumMethods() == 0 {
  1552  		return tm.ToRuntime(srctype)
  1553  	} else {
  1554  		return tm.getImtPointer(srctype, targettype)
  1555  	}
  1556  }
  1557  
  1558  func (tm *TypeMap) getImtPointer(srctype types.Type, targettype *types.Interface) llvm.Value {
  1559  	tdi := tm.getTypeDescInfo(srctype)
  1560  
  1561  	if ptr, ok := tdi.interfaceMethodTables.At(targettype).(llvm.Value); ok {
  1562  		return ptr
  1563  	}
  1564  
  1565  	srcms := tm.MethodSet(srctype)
  1566  	targetms := tm.MethodSet(targettype)
  1567  
  1568  	i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
  1569  
  1570  	elems := make([]llvm.Value, targetms.Len()+1)
  1571  	elems[0] = tm.ToRuntime(srctype)
  1572  	for i, targetm := range orderedMethodSet(targetms) {
  1573  		srcm := srcms.Lookup(targetm.Obj().Pkg(), targetm.Obj().Name())
  1574  
  1575  		elems[i+1] = tm.methodResolver.ResolveMethod(srcm).value
  1576  	}
  1577  	imtinit := llvm.ConstArray(i8ptr, elems)
  1578  
  1579  	var b bytes.Buffer
  1580  	tm.mc.mangleImtName(srctype, targettype, &b)
  1581  	imt := llvm.AddGlobal(tm.module, imtinit.Type(), b.String())
  1582  	imt.SetGlobalConstant(true)
  1583  	imt.SetInitializer(imtinit)
  1584  	imt.SetLinkage(llvm.LinkOnceODRLinkage)
  1585  
  1586  	imtptr := llvm.ConstBitCast(imt, i8ptr)
  1587  	tdi.interfaceMethodTables.Set(targettype, imtptr)
  1588  	return imtptr
  1589  }
  1590  
  1591  const (
  1592  	// From gofrontend/types.h
  1593  	gccgoRuntimeTypeKindBOOL           = 1
  1594  	gccgoRuntimeTypeKindINT            = 2
  1595  	gccgoRuntimeTypeKindINT8           = 3
  1596  	gccgoRuntimeTypeKindINT16          = 4
  1597  	gccgoRuntimeTypeKindINT32          = 5
  1598  	gccgoRuntimeTypeKindINT64          = 6
  1599  	gccgoRuntimeTypeKindUINT           = 7
  1600  	gccgoRuntimeTypeKindUINT8          = 8
  1601  	gccgoRuntimeTypeKindUINT16         = 9
  1602  	gccgoRuntimeTypeKindUINT32         = 10
  1603  	gccgoRuntimeTypeKindUINT64         = 11
  1604  	gccgoRuntimeTypeKindUINTPTR        = 12
  1605  	gccgoRuntimeTypeKindFLOAT32        = 13
  1606  	gccgoRuntimeTypeKindFLOAT64        = 14
  1607  	gccgoRuntimeTypeKindCOMPLEX64      = 15
  1608  	gccgoRuntimeTypeKindCOMPLEX128     = 16
  1609  	gccgoRuntimeTypeKindARRAY          = 17
  1610  	gccgoRuntimeTypeKindCHAN           = 18
  1611  	gccgoRuntimeTypeKindFUNC           = 19
  1612  	gccgoRuntimeTypeKindINTERFACE      = 20
  1613  	gccgoRuntimeTypeKindMAP            = 21
  1614  	gccgoRuntimeTypeKindPTR            = 22
  1615  	gccgoRuntimeTypeKindSLICE          = 23
  1616  	gccgoRuntimeTypeKindSTRING         = 24
  1617  	gccgoRuntimeTypeKindSTRUCT         = 25
  1618  	gccgoRuntimeTypeKindUNSAFE_POINTER = 26
  1619  	gccgoRuntimeTypeKindDIRECT_IFACE   = (1 << 5)
  1620  	gccgoRuntimeTypeKindNO_POINTERS    = (1 << 7)
  1621  )
  1622  
  1623  func hasPointers(t types.Type) bool {
  1624  	switch t := t.(type) {
  1625  	case *types.Basic:
  1626  		return t.Kind() == types.String || t.Kind() == types.UnsafePointer
  1627  
  1628  	case *types.Signature, *types.Pointer, *types.Slice, *types.Map, *types.Chan, *types.Interface:
  1629  		return true
  1630  
  1631  	case *types.Struct:
  1632  		for i := 0; i != t.NumFields(); i++ {
  1633  			if hasPointers(t.Field(i).Type()) {
  1634  				return true
  1635  			}
  1636  		}
  1637  		return false
  1638  
  1639  	case *types.Named:
  1640  		return hasPointers(t.Underlying())
  1641  
  1642  	case *types.Array:
  1643  		return hasPointers(t.Elem())
  1644  
  1645  	default:
  1646  		panic("unrecognized type")
  1647  	}
  1648  }
  1649  
  1650  func runtimeTypeKind(t types.Type) (k uint8) {
  1651  	switch t := t.(type) {
  1652  	case *types.Basic:
  1653  		switch t.Kind() {
  1654  		case types.Bool:
  1655  			k = gccgoRuntimeTypeKindBOOL
  1656  		case types.Int:
  1657  			k = gccgoRuntimeTypeKindINT
  1658  		case types.Int8:
  1659  			k = gccgoRuntimeTypeKindINT8
  1660  		case types.Int16:
  1661  			k = gccgoRuntimeTypeKindINT16
  1662  		case types.Int32:
  1663  			k = gccgoRuntimeTypeKindINT32
  1664  		case types.Int64:
  1665  			k = gccgoRuntimeTypeKindINT64
  1666  		case types.Uint:
  1667  			k = gccgoRuntimeTypeKindUINT
  1668  		case types.Uint8:
  1669  			k = gccgoRuntimeTypeKindUINT8
  1670  		case types.Uint16:
  1671  			k = gccgoRuntimeTypeKindUINT16
  1672  		case types.Uint32:
  1673  			k = gccgoRuntimeTypeKindUINT32
  1674  		case types.Uint64:
  1675  			k = gccgoRuntimeTypeKindUINT64
  1676  		case types.Uintptr:
  1677  			k = gccgoRuntimeTypeKindUINTPTR
  1678  		case types.Float32:
  1679  			k = gccgoRuntimeTypeKindFLOAT32
  1680  		case types.Float64:
  1681  			k = gccgoRuntimeTypeKindFLOAT64
  1682  		case types.Complex64:
  1683  			k = gccgoRuntimeTypeKindCOMPLEX64
  1684  		case types.Complex128:
  1685  			k = gccgoRuntimeTypeKindCOMPLEX128
  1686  		case types.String:
  1687  			k = gccgoRuntimeTypeKindSTRING
  1688  		case types.UnsafePointer:
  1689  			k = gccgoRuntimeTypeKindUNSAFE_POINTER | gccgoRuntimeTypeKindDIRECT_IFACE
  1690  		default:
  1691  			panic("unrecognized builtin type")
  1692  		}
  1693  	case *types.Array:
  1694  		k = gccgoRuntimeTypeKindARRAY
  1695  	case *types.Slice:
  1696  		k = gccgoRuntimeTypeKindSLICE
  1697  	case *types.Struct:
  1698  		k = gccgoRuntimeTypeKindSTRUCT
  1699  	case *types.Pointer:
  1700  		k = gccgoRuntimeTypeKindPTR | gccgoRuntimeTypeKindDIRECT_IFACE
  1701  	case *types.Signature:
  1702  		k = gccgoRuntimeTypeKindFUNC
  1703  	case *types.Interface:
  1704  		k = gccgoRuntimeTypeKindINTERFACE
  1705  	case *types.Map:
  1706  		k = gccgoRuntimeTypeKindMAP
  1707  	case *types.Chan:
  1708  		k = gccgoRuntimeTypeKindCHAN
  1709  	case *types.Named:
  1710  		return runtimeTypeKind(t.Underlying())
  1711  	default:
  1712  		panic("unrecognized type")
  1713  	}
  1714  
  1715  	if !hasPointers(t) {
  1716  		k |= gccgoRuntimeTypeKindNO_POINTERS
  1717  	}
  1718  
  1719  	return
  1720  }
  1721  
  1722  func (tm *TypeMap) makeCommonType(t types.Type) llvm.Value {
  1723  	var vals [11]llvm.Value
  1724  	vals[0] = llvm.ConstInt(tm.ctx.Int8Type(), uint64(runtimeTypeKind(t)), false)
  1725  	vals[1] = llvm.ConstInt(tm.ctx.Int8Type(), uint64(tm.Alignof(t)), false)
  1726  	vals[2] = vals[1]
  1727  	vals[3] = llvm.ConstInt(tm.inttype, uint64(tm.Sizeof(t)), false)
  1728  	vals[4] = llvm.ConstInt(tm.ctx.Int32Type(), uint64(tm.getTypeHash(t)), false)
  1729  	algs := tm.getAlgorithms(t)
  1730  	vals[5] = algs.hashDescriptor
  1731  	vals[6] = algs.equalDescriptor
  1732  	vals[7] = tm.getGcPointer(t)
  1733  	var b bytes.Buffer
  1734  	tm.writeType(t, &b)
  1735  	vals[8] = tm.globalStringPtr(b.String())
  1736  	vals[9] = tm.makeUncommonTypePtr(t)
  1737  	switch t.(type) {
  1738  	case *types.Named, *types.Struct:
  1739  		vals[10] = tm.getTypeDescriptorPointer(types.NewPointer(t))
  1740  	default:
  1741  		vals[10] = llvm.ConstPointerNull(llvm.PointerType(tm.commonTypeType, 0))
  1742  	}
  1743  	return llvm.ConstNamedStruct(tm.commonTypeType, vals[:])
  1744  }
  1745  
  1746  func (tm *TypeMap) makeBasicType(t types.Type, u *types.Basic) llvm.Value {
  1747  	return tm.makeCommonType(t)
  1748  }
  1749  
  1750  func (tm *TypeMap) makeArrayType(t types.Type, a *types.Array) llvm.Value {
  1751  	var vals [4]llvm.Value
  1752  	vals[0] = tm.makeCommonType(t)
  1753  	vals[1] = tm.getTypeDescriptorPointer(a.Elem())
  1754  	vals[2] = tm.getTypeDescriptorPointer(types.NewSlice(a.Elem()))
  1755  	vals[3] = llvm.ConstInt(tm.inttype, uint64(a.Len()), false)
  1756  
  1757  	return llvm.ConstNamedStruct(tm.arrayTypeType, vals[:])
  1758  }
  1759  
  1760  func (tm *TypeMap) makeSliceType(t types.Type, s *types.Slice) llvm.Value {
  1761  	var vals [2]llvm.Value
  1762  	vals[0] = tm.makeCommonType(t)
  1763  	vals[1] = tm.getTypeDescriptorPointer(s.Elem())
  1764  
  1765  	return llvm.ConstNamedStruct(tm.sliceTypeType, vals[:])
  1766  }
  1767  
  1768  func (tm *TypeMap) makeStructType(t types.Type, s *types.Struct) llvm.Value {
  1769  	var vals [2]llvm.Value
  1770  	vals[0] = tm.makeCommonType(t)
  1771  
  1772  	fieldVars := make([]*types.Var, s.NumFields())
  1773  	for i := range fieldVars {
  1774  		fieldVars[i] = s.Field(i)
  1775  	}
  1776  	offsets := tm.Offsetsof(fieldVars)
  1777  	structFields := make([]llvm.Value, len(fieldVars))
  1778  	for i, field := range fieldVars {
  1779  		var sfvals [5]llvm.Value
  1780  		if !field.Anonymous() {
  1781  			sfvals[0] = tm.globalStringPtr(field.Name())
  1782  		} else {
  1783  			sfvals[0] = llvm.ConstPointerNull(llvm.PointerType(tm.stringType, 0))
  1784  		}
  1785  		if !field.Exported() && field.Pkg() != nil {
  1786  			sfvals[1] = tm.globalStringPtr(field.Pkg().Path())
  1787  		} else {
  1788  			sfvals[1] = llvm.ConstPointerNull(llvm.PointerType(tm.stringType, 0))
  1789  		}
  1790  		sfvals[2] = tm.getTypeDescriptorPointer(field.Type())
  1791  		if tag := s.Tag(i); tag != "" {
  1792  			sfvals[3] = tm.globalStringPtr(tag)
  1793  		} else {
  1794  			sfvals[3] = llvm.ConstPointerNull(llvm.PointerType(tm.stringType, 0))
  1795  		}
  1796  		sfvals[4] = llvm.ConstInt(tm.inttype, uint64(offsets[i]), false)
  1797  
  1798  		structFields[i] = llvm.ConstNamedStruct(tm.structFieldType, sfvals[:])
  1799  	}
  1800  	vals[1] = tm.makeSlice(structFields, tm.structFieldSliceType)
  1801  
  1802  	return llvm.ConstNamedStruct(tm.structTypeType, vals[:])
  1803  }
  1804  
  1805  func (tm *TypeMap) makePointerType(t types.Type, p *types.Pointer) llvm.Value {
  1806  	var vals [2]llvm.Value
  1807  	vals[0] = tm.makeCommonType(t)
  1808  	vals[1] = tm.getTypeDescriptorPointer(p.Elem())
  1809  
  1810  	return llvm.ConstNamedStruct(tm.ptrTypeType, vals[:])
  1811  }
  1812  
  1813  func (tm *TypeMap) rtypeSlice(t *types.Tuple) llvm.Value {
  1814  	rtypes := make([]llvm.Value, t.Len())
  1815  	for i := range rtypes {
  1816  		rtypes[i] = tm.getTypeDescriptorPointer(t.At(i).Type())
  1817  	}
  1818  	return tm.makeSlice(rtypes, tm.typeSliceType)
  1819  }
  1820  
  1821  func (tm *TypeMap) makeFuncType(t types.Type, f *types.Signature) llvm.Value {
  1822  	var vals [4]llvm.Value
  1823  	vals[0] = tm.makeCommonType(t)
  1824  	// dotdotdot
  1825  	variadic := 0
  1826  	if f.Variadic() {
  1827  		variadic = 1
  1828  	}
  1829  	vals[1] = llvm.ConstInt(llvm.Int8Type(), uint64(variadic), false)
  1830  	// in
  1831  	vals[2] = tm.rtypeSlice(f.Params())
  1832  	// out
  1833  	vals[3] = tm.rtypeSlice(f.Results())
  1834  
  1835  	return llvm.ConstNamedStruct(tm.funcTypeType, vals[:])
  1836  }
  1837  
  1838  func (tm *TypeMap) makeInterfaceType(t types.Type, i *types.Interface) llvm.Value {
  1839  	var vals [2]llvm.Value
  1840  	vals[0] = tm.makeCommonType(t)
  1841  
  1842  	methodset := tm.MethodSet(i)
  1843  	imethods := make([]llvm.Value, methodset.Len())
  1844  	for index, ms := range orderedMethodSet(methodset) {
  1845  		method := ms.Obj()
  1846  		var imvals [3]llvm.Value
  1847  		imvals[0] = tm.globalStringPtr(method.Name())
  1848  		if !method.Exported() && method.Pkg() != nil {
  1849  			imvals[1] = tm.globalStringPtr(method.Pkg().Path())
  1850  		} else {
  1851  			imvals[1] = llvm.ConstPointerNull(llvm.PointerType(tm.stringType, 0))
  1852  		}
  1853  		mtyp := method.Type().(*types.Signature)
  1854  		mftyp := types.NewSignature(nil, nil, mtyp.Params(), mtyp.Results(), mtyp.Variadic())
  1855  		imvals[2] = tm.getTypeDescriptorPointer(mftyp)
  1856  
  1857  		imethods[index] = llvm.ConstNamedStruct(tm.imethodType, imvals[:])
  1858  	}
  1859  	vals[1] = tm.makeSlice(imethods, tm.imethodSliceType)
  1860  
  1861  	return llvm.ConstNamedStruct(tm.interfaceTypeType, vals[:])
  1862  }
  1863  
  1864  func (tm *TypeMap) makeMapType(t types.Type, m *types.Map) llvm.Value {
  1865  	var vals [3]llvm.Value
  1866  	vals[0] = tm.makeCommonType(t)
  1867  	vals[1] = tm.getTypeDescriptorPointer(m.Key())
  1868  	vals[2] = tm.getTypeDescriptorPointer(m.Elem())
  1869  
  1870  	return llvm.ConstNamedStruct(tm.mapTypeType, vals[:])
  1871  }
  1872  
  1873  func (tm *TypeMap) makeMapDesc(ptr llvm.Value, m *types.Map) llvm.Value {
  1874  	mapEntryType := structBType{[]backendType{
  1875  		tm.getBackendType(types.Typ[types.UnsafePointer]),
  1876  		tm.getBackendType(m.Key()),
  1877  		tm.getBackendType(m.Elem()),
  1878  	}}.ToLLVM(tm.ctx)
  1879  
  1880  	var vals [4]llvm.Value
  1881  	// map_descriptor
  1882  	vals[0] = ptr
  1883  	// entry_size
  1884  	vals[1] = llvm.ConstInt(tm.inttype, tm.target.TypeAllocSize(mapEntryType), false)
  1885  	// key_offset
  1886  	vals[2] = llvm.ConstInt(tm.inttype, tm.target.ElementOffset(mapEntryType, 1), false)
  1887  	// value_offset
  1888  	vals[3] = llvm.ConstInt(tm.inttype, tm.target.ElementOffset(mapEntryType, 2), false)
  1889  
  1890  	return llvm.ConstNamedStruct(tm.mapDescType, vals[:])
  1891  }
  1892  
  1893  func (tm *TypeMap) makeChanType(t types.Type, c *types.Chan) llvm.Value {
  1894  	var vals [3]llvm.Value
  1895  	vals[0] = tm.makeCommonType(t)
  1896  	vals[1] = tm.getTypeDescriptorPointer(c.Elem())
  1897  
  1898  	// From gofrontend/go/types.cc
  1899  	// These bits must match the ones in libgo/runtime/go-type.h.
  1900  	var dir int
  1901  	switch c.Dir() {
  1902  	case types.RecvOnly:
  1903  		dir = 1
  1904  	case types.SendOnly:
  1905  		dir = 2
  1906  	case types.SendRecv:
  1907  		dir = 3
  1908  	}
  1909  	vals[2] = llvm.ConstInt(tm.inttype, uint64(dir), false)
  1910  
  1911  	return llvm.ConstNamedStruct(tm.chanTypeType, vals[:])
  1912  }
  1913  
  1914  func (tm *TypeMap) makeUncommonTypePtr(t types.Type) llvm.Value {
  1915  	_, isbasic := t.(*types.Basic)
  1916  	_, isnamed := t.(*types.Named)
  1917  
  1918  	var mset types.MethodSet
  1919  	// We store interface methods on the interface type.
  1920  	if _, ok := t.Underlying().(*types.Interface); !ok {
  1921  		mset = *tm.MethodSet(t)
  1922  	}
  1923  
  1924  	if !isbasic && !isnamed && mset.Len() == 0 {
  1925  		return llvm.ConstPointerNull(llvm.PointerType(tm.uncommonTypeType, 0))
  1926  	}
  1927  
  1928  	var vals [3]llvm.Value
  1929  
  1930  	nullStringPtr := llvm.ConstPointerNull(llvm.PointerType(tm.stringType, 0))
  1931  	vals[0] = nullStringPtr
  1932  	vals[1] = nullStringPtr
  1933  
  1934  	if isbasic || isnamed {
  1935  		nti := tm.mc.getNamedTypeInfo(t)
  1936  		vals[0] = tm.globalStringPtr(nti.name)
  1937  		if nti.pkgpath != "" {
  1938  			path := nti.pkgpath
  1939  			if nti.functionName != "" {
  1940  				path += "." + nti.functionName
  1941  				if nti.scopeNum != 0 {
  1942  					path += "$" + strconv.Itoa(nti.scopeNum)
  1943  				}
  1944  			}
  1945  			vals[1] = tm.globalStringPtr(path)
  1946  		}
  1947  	}
  1948  
  1949  	// Store methods. All methods must be stored, not only exported ones;
  1950  	// this is to allow satisfying of interfaces with non-exported methods.
  1951  	methods := make([]llvm.Value, mset.Len())
  1952  	omset := orderedMethodSet(&mset)
  1953  	for i := range methods {
  1954  		var mvals [5]llvm.Value
  1955  
  1956  		sel := omset[i]
  1957  		mname := sel.Obj().Name()
  1958  		mfunc := tm.methodResolver.ResolveMethod(sel)
  1959  		ftyp := mfunc.Type().(*types.Signature)
  1960  
  1961  		// name
  1962  		mvals[0] = tm.globalStringPtr(mname)
  1963  
  1964  		// pkgPath
  1965  		mvals[1] = nullStringPtr
  1966  		if pkg := sel.Obj().Pkg(); pkg != nil && !sel.Obj().Exported() {
  1967  			mvals[1] = tm.globalStringPtr(pkg.Path())
  1968  		}
  1969  
  1970  		// mtyp (method type, no receiver)
  1971  		mftyp := types.NewSignature(nil, nil, ftyp.Params(), ftyp.Results(), ftyp.Variadic())
  1972  		mvals[2] = tm.getTypeDescriptorPointer(mftyp)
  1973  
  1974  		// typ (function type, with receiver)
  1975  		recvparam := types.NewParam(0, nil, "", t)
  1976  		params := ftyp.Params()
  1977  		rfparams := make([]*types.Var, params.Len()+1)
  1978  		rfparams[0] = recvparam
  1979  		for i := 0; i != ftyp.Params().Len(); i++ {
  1980  			rfparams[i+1] = params.At(i)
  1981  		}
  1982  		rftyp := types.NewSignature(nil, nil, types.NewTuple(rfparams...), ftyp.Results(), ftyp.Variadic())
  1983  		mvals[3] = tm.getTypeDescriptorPointer(rftyp)
  1984  
  1985  		// function
  1986  		mvals[4] = mfunc.value
  1987  
  1988  		methods[i] = llvm.ConstNamedStruct(tm.methodType, mvals[:])
  1989  	}
  1990  
  1991  	vals[2] = tm.makeSlice(methods, tm.methodSliceType)
  1992  
  1993  	uncommonType := llvm.ConstNamedStruct(tm.uncommonTypeType, vals[:])
  1994  
  1995  	uncommonTypePtr := llvm.AddGlobal(tm.module, tm.uncommonTypeType, "")
  1996  	uncommonTypePtr.SetGlobalConstant(true)
  1997  	uncommonTypePtr.SetInitializer(uncommonType)
  1998  	uncommonTypePtr.SetLinkage(llvm.InternalLinkage)
  1999  	return uncommonTypePtr
  2000  }
  2001  
  2002  // globalStringPtr returns a *string with the specified value.
  2003  func (tm *TypeMap) globalStringPtr(value string) llvm.Value {
  2004  	strval := llvm.ConstString(value, false)
  2005  	strglobal := llvm.AddGlobal(tm.module, strval.Type(), "")
  2006  	strglobal.SetGlobalConstant(true)
  2007  	strglobal.SetLinkage(llvm.InternalLinkage)
  2008  	strglobal.SetInitializer(strval)
  2009  	strglobal = llvm.ConstBitCast(strglobal, llvm.PointerType(llvm.Int8Type(), 0))
  2010  	strlen := llvm.ConstInt(tm.inttype, uint64(len(value)), false)
  2011  	str := llvm.ConstStruct([]llvm.Value{strglobal, strlen}, false)
  2012  	g := llvm.AddGlobal(tm.module, str.Type(), "")
  2013  	g.SetGlobalConstant(true)
  2014  	g.SetLinkage(llvm.InternalLinkage)
  2015  	g.SetInitializer(str)
  2016  	return g
  2017  }
  2018  
  2019  func (tm *TypeMap) makeNamedSliceType(tname string, elemtyp llvm.Type) llvm.Type {
  2020  	t := tm.ctx.StructCreateNamed(tname)
  2021  	t.StructSetBody([]llvm.Type{
  2022  		llvm.PointerType(elemtyp, 0),
  2023  		tm.inttype,
  2024  		tm.inttype,
  2025  	}, false)
  2026  	return t
  2027  }
  2028  
  2029  func (tm *TypeMap) makeSlice(values []llvm.Value, slicetyp llvm.Type) llvm.Value {
  2030  	ptrtyp := slicetyp.StructElementTypes()[0]
  2031  	var globalptr llvm.Value
  2032  	if len(values) > 0 {
  2033  		array := llvm.ConstArray(ptrtyp.ElementType(), values)
  2034  		globalptr = llvm.AddGlobal(tm.module, array.Type(), "")
  2035  		globalptr.SetGlobalConstant(true)
  2036  		globalptr.SetLinkage(llvm.InternalLinkage)
  2037  		globalptr.SetInitializer(array)
  2038  		globalptr = llvm.ConstBitCast(globalptr, ptrtyp)
  2039  	} else {
  2040  		globalptr = llvm.ConstNull(ptrtyp)
  2041  	}
  2042  	len_ := llvm.ConstInt(tm.inttype, uint64(len(values)), false)
  2043  	slice := llvm.ConstNull(slicetyp)
  2044  	slice = llvm.ConstInsertValue(slice, globalptr, []uint32{0})
  2045  	slice = llvm.ConstInsertValue(slice, len_, []uint32{1})
  2046  	slice = llvm.ConstInsertValue(slice, len_, []uint32{2})
  2047  	return slice
  2048  }
  2049  
  2050  func isGlobalObject(obj types.Object) bool {
  2051  	pkg := obj.Pkg()
  2052  	return pkg == nil || obj.Parent() == pkg.Scope()
  2053  }