本文整理匯總了Golang中github.com/axw/gollvm/llvm.ConstStruct函數的典型用法代碼示例。如果您正苦於以下問題:Golang ConstStruct函數的具體用法?Golang ConstStruct怎麽用?Golang ConstStruct使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了ConstStruct函數的13個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: makeAlgorithmTable
func (tm *TypeMap) makeAlgorithmTable(t types.Type) llvm.Value {
// TODO set these to actual functions.
hashAlg := llvm.ConstNull(llvm.PointerType(tm.hashAlgFunctionType, 0))
printAlg := llvm.ConstNull(llvm.PointerType(tm.printAlgFunctionType, 0))
copyAlg := llvm.ConstNull(llvm.PointerType(tm.copyAlgFunctionType, 0))
const eqalgsig = "func(uintptr, unsafe.Pointer, unsafe.Pointer) bool"
var equalAlg llvm.Value
switch t := t.(type) {
case *types.Basic:
switch t.Kind() {
case types.String:
equalAlg = tm.functions.NamedFunction("runtime.streqalg", eqalgsig)
case types.Float32:
equalAlg = tm.functions.NamedFunction("runtime.f32eqalg", eqalgsig)
case types.Float64:
equalAlg = tm.functions.NamedFunction("runtime.f64eqalg", eqalgsig)
case types.Complex64:
equalAlg = tm.functions.NamedFunction("runtime.c64eqalg", eqalgsig)
case types.Complex128:
equalAlg = tm.functions.NamedFunction("runtime.c128eqalg", eqalgsig)
}
}
if equalAlg.IsNil() {
equalAlg = tm.functions.NamedFunction("runtime.memequal", eqalgsig)
}
elems := []llvm.Value{hashAlg, equalAlg, printAlg, copyAlg}
return llvm.ConstStruct(elems, false)
}
示例2: LLVMValue
func (v ConstValue) LLVMValue() llvm.Value {
typ := types.Underlying(v.Type())
switch typ {
case types.Int, types.Uint:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), true)
// TODO 32/64bit (probably wait for gc)
//int_val := v.Val.(*big.Int)
//if int_val.Cmp(maxBigInt32) > 0 || int_val.Cmp(minBigInt32) < 0 {
// panic(fmt.Sprint("const ", int_val, " overflows int"))
//}
//return llvm.ConstInt(v.compiler.target.IntPtrType(), uint64(v.Int64()), true)
case types.Uint:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), false)
case types.Int8:
return llvm.ConstInt(llvm.Int8Type(), uint64(v.Int64()), true)
case types.Uint8, types.Byte:
return llvm.ConstInt(llvm.Int8Type(), uint64(v.Int64()), false)
case types.Int16:
return llvm.ConstInt(llvm.Int16Type(), uint64(v.Int64()), true)
case types.Uint16:
return llvm.ConstInt(llvm.Int16Type(), uint64(v.Int64()), false)
case types.Int32, types.Rune:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), true)
case types.Uint32:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), false)
case types.Int64:
return llvm.ConstInt(llvm.Int64Type(), uint64(v.Int64()), true)
case types.Uint64:
return llvm.ConstInt(llvm.Int64Type(), uint64(v.Int64()), true)
case types.Float32:
return llvm.ConstFloat(llvm.FloatType(), float64(v.Float64()))
case types.Float64:
return llvm.ConstFloat(llvm.DoubleType(), float64(v.Float64()))
case types.UnsafePointer, types.Uintptr:
inttype := v.compiler.target.IntPtrType()
return llvm.ConstInt(inttype, uint64(v.Int64()), false)
case types.String:
strval := (v.Val).(string)
ptr := v.compiler.builder.CreateGlobalStringPtr(strval, "")
len_ := llvm.ConstInt(llvm.Int32Type(), uint64(len(strval)), false)
return llvm.ConstStruct([]llvm.Value{ptr, len_}, false)
case types.Bool:
if v := v.Val.(bool); v {
return llvm.ConstAllOnes(llvm.Int1Type())
}
return llvm.ConstNull(llvm.Int1Type())
}
panic(fmt.Errorf("Unhandled type: %v", typ)) //v.typ.Kind))
}
示例3: makeAlgorithmTable
func (tm *TypeMap) makeAlgorithmTable(t types.Type) llvm.Value {
// TODO set these to actual functions.
hashAlg := llvm.ConstNull(llvm.PointerType(tm.hashAlgFunctionType, 0))
printAlg := llvm.ConstNull(llvm.PointerType(tm.printAlgFunctionType, 0))
copyAlg := llvm.ConstNull(llvm.PointerType(tm.copyAlgFunctionType, 0))
equalAlg := tm.functions.NamedFunction("runtime.memequal", "func f(uintptr, unsafe.Pointer, unsafe.Pointer) bool")
elems := []llvm.Value{hashAlg, equalAlg, printAlg, copyAlg}
return llvm.ConstStruct(elems, false)
}
示例4: makeAlgorithmTable
func (tm *TypeMap) makeAlgorithmTable(t types.Type) llvm.Value {
// TODO set these to actual functions.
hashAlg := llvm.ConstNull(llvm.PointerType(tm.hashAlgFunctionType, 0))
equalAlg := llvm.ConstNull(llvm.PointerType(tm.equalAlgFunctionType, 0))
printAlg := llvm.ConstNull(llvm.PointerType(tm.printAlgFunctionType, 0))
copyAlg := llvm.ConstNull(llvm.PointerType(tm.copyAlgFunctionType, 0))
elems := []llvm.Value{hashAlg, equalAlg, printAlg, copyAlg}
return llvm.ConstStruct(elems, false)
}
示例5: globalStringPtr
// globalStringPtr returns a *string with the specified value.
func (tm *TypeMap) globalStringPtr(value string) llvm.Value {
strval := llvm.ConstString(value, false)
strglobal := llvm.AddGlobal(tm.module, strval.Type(), "")
strglobal.SetInitializer(strval)
strglobal = llvm.ConstBitCast(strglobal, llvm.PointerType(llvm.Int8Type(), 0))
strlen := llvm.ConstInt(tm.inttype, uint64(len(value)), false)
str := llvm.ConstStruct([]llvm.Value{strglobal, strlen}, false)
g := llvm.AddGlobal(tm.module, str.Type(), "")
g.SetInitializer(str)
return g
}
示例6: makeAlgorithmTable
func (tm *TypeMap) makeAlgorithmTable(t types.Type) llvm.Value {
// TODO set these to actual functions.
hashAlg := llvm.ConstNull(llvm.PointerType(tm.alg.hashAlgFunctionType, 0))
printAlg := llvm.ConstNull(llvm.PointerType(tm.alg.printAlgFunctionType, 0))
copyAlg := llvm.ConstNull(llvm.PointerType(tm.alg.copyAlgFunctionType, 0))
equalAlg := tm.alg.eqalg(t)
elems := []llvm.Value{
AlgorithmHash: hashAlg,
AlgorithmEqual: equalAlg,
AlgorithmPrint: printAlg,
AlgorithmCopy: copyAlg,
}
return llvm.ConstStruct(elems, false)
}
示例7: makeAlgorithmTable
func (tm *TypeMap) makeAlgorithmTable(t types.Type) llvm.Value {
// TODO set these to actual functions.
hashAlg := llvm.ConstNull(llvm.PointerType(tm.hashAlgFunctionType, 0))
printAlg := llvm.ConstNull(llvm.PointerType(tm.printAlgFunctionType, 0))
copyAlg := llvm.ConstNull(llvm.PointerType(tm.copyAlgFunctionType, 0))
equalAlgName := "runtime.memequal"
equalAlg := tm.module.NamedFunction(equalAlgName)
if equalAlg.IsNil() {
equalAlg = llvm.AddFunction(
tm.module, equalAlgName, tm.equalAlgFunctionType)
}
elems := []llvm.Value{hashAlg, equalAlg, printAlg, copyAlg}
return llvm.ConstStruct(elems, false)
}
示例8: convertI2I
// convertI2I converts an interface to another interface.
func (v *LLVMValue) convertI2I(iface *types.Interface) Value {
builder := v.compiler.builder
src_typ := v.Type()
vptr := v.pointer.LLVMValue()
src_typ = src_typ.(*types.Name).Underlying
iface_struct_type := v.compiler.types.ToLLVM(iface)
element_types := iface_struct_type.StructElementTypes()
iface_elements := make([]llvm.Value, len(element_types))
for i, _ := range iface_elements {
iface_elements[i] = llvm.ConstNull(element_types[i])
}
iface_struct := llvm.ConstStruct(iface_elements, false)
receiver := builder.CreateLoad(builder.CreateStructGEP(vptr, 0, ""), "")
iface_struct = builder.CreateInsertValue(iface_struct, receiver, 0, "")
// TODO check whether the functions in the struct take
// value or pointer receivers.
// TODO handle dynamic interface conversion (non-subset).
methods := src_typ.(*types.Interface).Methods
for i, m := range iface.Methods {
// TODO make this loop linear by iterating through the
// interface methods and type methods together.
mi := sort.Search(len(methods), func(i int) bool {
return methods[i].Name >= m.Name
})
if mi >= len(methods) || methods[mi].Name != m.Name {
panic("Failed to locate method: " + m.Name)
}
method := builder.CreateStructGEP(vptr, mi+2, "")
iface_struct = builder.CreateInsertValue(
iface_struct, builder.CreateLoad(method, ""), i+2, "")
}
return v.compiler.NewLLVMValue(iface_struct, iface)
}
示例9: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.initfuncs = make([]Value, 0)
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a TargetMachine from the OS & Arch.
triple := fmt.Sprintf("%s-unknown-%s",
getTripleArchName(compiler.targetArch),
compiler.targetOs)
var machine llvm.TargetMachine
for target := llvm.FirstTarget(); target.C != nil && machine.C == nil; target = target.NextTarget() {
if target.Name() == compiler.targetArch {
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
compiler.types = NewTypeMap(compiler.module.Module, compiler.target, exprTypes)
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
compiler.defineRuntimeIntrinsics()
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
if len(compiler.initfuncs) > 0 {
elttypes := []llvm.Type{
llvm.Int32Type(),
llvm.PointerType(
llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
ctors := make([]llvm.Value, len(compiler.initfuncs))
for i, fn := range compiler.initfuncs {
struct_values := []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 1, false),
fn.LLVMValue()}
ctors[i] = llvm.ConstStruct(struct_values, false)
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(
compiler.module.Module, global_ctors_init.Type(),
"llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
compiler.createMetadata()
return compiler.module, nil
//.........這裏部分代碼省略.........
示例10: convertV2I
// convertV2I converts a value to an interface.
func (v *LLVMValue) convertV2I(iface *types.Interface) Value {
// TODO deref indirect value, then use 'pointer' as pointer value.
var srcname *types.Name
srctyp := v.Type()
if name, isname := srctyp.(*types.Name); isname {
srcname = name
srctyp = name.Underlying
}
isptr := false
if p, fromptr := srctyp.(*types.Pointer); fromptr {
isptr = true
srctyp = p.Base
if name, isname := srctyp.(*types.Name); isname {
srcname = name
srctyp = name.Underlying
}
}
iface_struct_type := v.compiler.types.ToLLVM(iface)
element_types := iface_struct_type.StructElementTypes()
iface_elements := make([]llvm.Value, len(element_types))
for i, _ := range iface_elements {
iface_elements[i] = llvm.ConstNull(element_types[i])
}
iface_struct := llvm.ConstStruct(iface_elements, false)
builder := v.compiler.builder
var ptr llvm.Value
if isptr {
ptr = v.LLVMValue()
} else {
// If the value fits exactly in a pointer, then we can just
// bitcast it. Otherwise we need to malloc, and create a shim
// function to load the receiver.
lv := v.LLVMValue()
c := v.compiler
ptrsize := c.target.PointerSize()
if c.target.TypeStoreSize(lv.Type()) <= uint64(ptrsize) {
bits := c.target.TypeSizeInBits(lv.Type())
if bits > 0 {
lv = builder.CreateBitCast(lv, llvm.IntType(int(bits)), "")
ptr = builder.CreateIntToPtr(lv, element_types[0], "")
} else {
ptr = llvm.ConstNull(element_types[0])
}
} else {
ptr = builder.CreateMalloc(v.compiler.types.ToLLVM(srctyp), "")
builder.CreateStore(lv, ptr)
// TODO signal that shim functions are required. Probably later
// we'll have the CallExpr handler pick out the type, and check
// if the receiver is a pointer or a value type, and load as
// necessary.
}
}
ptr = builder.CreateBitCast(ptr, element_types[0], "")
iface_struct = builder.CreateInsertValue(iface_struct, ptr, 0, "")
var runtimeType llvm.Value
if srcname != nil {
runtimeType = v.compiler.types.ToRuntime(srcname)
} else {
runtimeType = v.compiler.types.ToRuntime(srctyp)
}
runtimeType = builder.CreateBitCast(runtimeType, element_types[1], "")
iface_struct = builder.CreateInsertValue(iface_struct, runtimeType, 1, "")
// TODO assert either source is a named type (or pointer to), or the
// interface has an empty methodset.
if srcname != nil {
// TODO check whether the functions in the struct take
// value or pointer receivers.
// Look up the method by name.
methods := srcname.Methods
for i, m := range iface.Methods {
// TODO make this loop linear by iterating through the
// interface methods and type methods together.
mi := sort.Search(len(methods), func(i int) bool {
return methods[i].Name >= m.Name
})
if mi >= len(methods) || methods[mi].Name != m.Name {
panic("Failed to locate method: " + m.Name)
}
method_obj := methods[mi]
method := v.compiler.Resolve(method_obj).(*LLVMValue)
llvm_value := method.LLVMValue()
llvm_value = builder.CreateBitCast(
llvm_value, element_types[i+2], "")
iface_struct = builder.CreateInsertValue(
iface_struct, llvm_value, i+2, "")
}
}
return v.compiler.NewLLVMValue(iface_struct, iface)
}
示例11: LLVMValue
func (v ConstValue) LLVMValue() llvm.Value {
typ := types.Underlying(v.Type())
if name, ok := typ.(*types.Name); ok {
typ = name.Underlying
}
switch typ.(*types.Basic).Kind {
case types.IntKind, types.UintKind:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), true)
// TODO 32/64bit (probably wait for gc)
//int_val := v.Val.(*big.Int)
//if int_val.Cmp(maxBigInt32) > 0 || int_val.Cmp(minBigInt32) < 0 {
// panic(fmt.Sprint("const ", int_val, " overflows int"))
//}
//return llvm.ConstInt(v.compiler.target.IntPtrType(), uint64(v.Int64()), true)
case types.Int8Kind:
return llvm.ConstInt(llvm.Int8Type(), uint64(v.Int64()), true)
case types.Uint8Kind:
return llvm.ConstInt(llvm.Int8Type(), uint64(v.Int64()), false)
case types.Int16Kind:
return llvm.ConstInt(llvm.Int16Type(), uint64(v.Int64()), true)
case types.Uint16Kind:
return llvm.ConstInt(llvm.Int16Type(), uint64(v.Int64()), false)
case types.Int32Kind:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), true)
case types.Uint32Kind:
return llvm.ConstInt(llvm.Int32Type(), uint64(v.Int64()), false)
case types.Int64Kind:
return llvm.ConstInt(llvm.Int64Type(), uint64(v.Int64()), true)
case types.Uint64Kind:
return llvm.ConstInt(llvm.Int64Type(), uint64(v.Int64()), false)
case types.Float32Kind:
return llvm.ConstFloat(llvm.FloatType(), float64(v.Float64()))
case types.Float64Kind:
return llvm.ConstFloat(llvm.DoubleType(), float64(v.Float64()))
case types.Complex64Kind:
r_, i_ := v.Complex()
r := llvm.ConstFloat(llvm.FloatType(), r_)
i := llvm.ConstFloat(llvm.FloatType(), i_)
return llvm.ConstStruct([]llvm.Value{r, i}, false)
case types.Complex128Kind:
r_, i_ := v.Complex()
r := llvm.ConstFloat(llvm.DoubleType(), r_)
i := llvm.ConstFloat(llvm.DoubleType(), i_)
return llvm.ConstStruct([]llvm.Value{r, i}, false)
case types.UnsafePointerKind, types.UintptrKind:
inttype := v.compiler.target.IntPtrType()
return llvm.ConstInt(inttype, uint64(v.Int64()), false)
case types.StringKind:
strval := (v.Val).(string)
strlen := len(strval)
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
var ptr llvm.Value
if strlen > 0 {
ptr = v.compiler.builder.CreateGlobalStringPtr(strval, "")
ptr = llvm.ConstBitCast(ptr, i8ptr)
} else {
ptr = llvm.ConstNull(i8ptr)
}
len_ := llvm.ConstInt(llvm.Int32Type(), uint64(strlen), false)
return llvm.ConstStruct([]llvm.Value{ptr, len_}, false)
case types.BoolKind:
if v := v.Val.(bool); v {
return llvm.ConstAllOnes(llvm.Int1Type())
}
return llvm.ConstNull(llvm.Int1Type())
}
panic(fmt.Errorf("Unhandled type: %v", typ)) //v.typ.Kind))
}
示例12: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package, importpath string,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME I'd prefer if we didn't modify global state. Perhaps
// we should always take a copy of types.Universe?
defer func() {
types.Universe.Lookup("true").Data = types.Const{true}
types.Universe.Lookup("false").Data = types.Const{false}
}()
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.importpath = importpath
compiler.initfuncs = nil
compiler.varinitfuncs = nil
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(compiler.TargetTriple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(compiler.llvmtypes, compiler.module.Module, importpath, exprTypes, compiler.FunctionCache, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Create global constructors. The initfuncs/varinitfuncs
// slices are in the order of visitation, and that is how
// their priorities are assigned.
//
// The llgo linker (llgo-link) is responsible for reordering
// global constructors according to package dependency order.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
elttypes := []llvm.Type{llvm.Int32Type(), llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
var ctors []llvm.Value
var priority uint64 = 1
for _, initfuncs := range initfuncs {
for _, fn := range initfuncs {
priorityval := llvm.ConstInt(llvm.Int32Type(), uint64(priority), false)
struct_values := []llvm.Value{priorityval, fn.LLVMValue()}
ctors = append(ctors, llvm.ConstStruct(struct_values, false))
priority++
}
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(compiler.module.Module, global_ctors_init.Type(), "llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
//.........這裏部分代碼省略.........
示例13: Compile
//.........這裏部分代碼省略.........
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
llvmtypemap := NewLLVMTypeMap(compiler.module.Module, compiler.target)
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(llvmtypemap, importpath, exprTypes, compiler.FunctionCache, compiler.pkgmap, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
elttypes := []llvm.Type{llvm.Int32Type(), llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
var ctors []llvm.Value
var priority uint64
for _, initfuncs := range initfuncs {
for _, fn := range initfuncs {
priorityval := llvm.ConstInt(llvm.Int32Type(), uint64(priority), false)
struct_values := []llvm.Value{priorityval, fn.LLVMValue()}
ctors = append(ctors, llvm.ConstStruct(struct_values, false))
priority++
}
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(compiler.module.Module, global_ctors_init.Type(), "llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
//compiler.createMetadata()
return compiler.module, nil
}