compiler: move createConst to compilerContext
Move it from *builder to *compilerContext, so that it can be called in more places. This is necessary to create a string value (for the file name) in createEmbedGlobal.
Этот коммит содержится в:
родитель
9dd249a431
коммит
fd20f63ee3
1 изменённых файлов: 33 добавлений и 34 удалений
|
@ -2470,42 +2470,41 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
|
||||||
}
|
}
|
||||||
|
|
||||||
// createConst creates a LLVM constant value from a Go constant.
|
// createConst creates a LLVM constant value from a Go constant.
|
||||||
func (b *builder) createConst(expr *ssa.Const) llvm.Value {
|
func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value {
|
||||||
switch typ := expr.Type().Underlying().(type) {
|
switch typ := expr.Type().Underlying().(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
llvmType := b.getLLVMType(typ)
|
llvmType := c.getLLVMType(typ)
|
||||||
if typ.Info()&types.IsBoolean != 0 {
|
if typ.Info()&types.IsBoolean != 0 {
|
||||||
b := constant.BoolVal(expr.Value)
|
|
||||||
n := uint64(0)
|
n := uint64(0)
|
||||||
if b {
|
if constant.BoolVal(expr.Value) {
|
||||||
n = 1
|
n = 1
|
||||||
}
|
}
|
||||||
return llvm.ConstInt(llvmType, n, false)
|
return llvm.ConstInt(llvmType, n, false)
|
||||||
} else if typ.Info()&types.IsString != 0 {
|
} else if typ.Info()&types.IsString != 0 {
|
||||||
str := constant.StringVal(expr.Value)
|
str := constant.StringVal(expr.Value)
|
||||||
strLen := llvm.ConstInt(b.uintptrType, uint64(len(str)), false)
|
strLen := llvm.ConstInt(c.uintptrType, uint64(len(str)), false)
|
||||||
var strPtr llvm.Value
|
var strPtr llvm.Value
|
||||||
if str != "" {
|
if str != "" {
|
||||||
objname := b.pkg.Path() + "$string"
|
objname := c.pkg.Path() + "$string"
|
||||||
global := llvm.AddGlobal(b.mod, llvm.ArrayType(b.ctx.Int8Type(), len(str)), objname)
|
global := llvm.AddGlobal(c.mod, llvm.ArrayType(c.ctx.Int8Type(), len(str)), objname)
|
||||||
global.SetInitializer(b.ctx.ConstString(str, false))
|
global.SetInitializer(c.ctx.ConstString(str, false))
|
||||||
global.SetLinkage(llvm.InternalLinkage)
|
global.SetLinkage(llvm.InternalLinkage)
|
||||||
global.SetGlobalConstant(true)
|
global.SetGlobalConstant(true)
|
||||||
global.SetUnnamedAddr(true)
|
global.SetUnnamedAddr(true)
|
||||||
global.SetAlignment(1)
|
global.SetAlignment(1)
|
||||||
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
|
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
|
||||||
strPtr = b.CreateInBoundsGEP(global, []llvm.Value{zero, zero}, "")
|
strPtr = llvm.ConstInBoundsGEP(global, []llvm.Value{zero, zero})
|
||||||
} else {
|
} else {
|
||||||
strPtr = llvm.ConstNull(b.i8ptrType)
|
strPtr = llvm.ConstNull(c.i8ptrType)
|
||||||
}
|
}
|
||||||
strObj := llvm.ConstNamedStruct(b.getLLVMRuntimeType("_string"), []llvm.Value{strPtr, strLen})
|
strObj := llvm.ConstNamedStruct(c.getLLVMRuntimeType("_string"), []llvm.Value{strPtr, strLen})
|
||||||
return strObj
|
return strObj
|
||||||
} else if typ.Kind() == types.UnsafePointer {
|
} else if typ.Kind() == types.UnsafePointer {
|
||||||
if !expr.IsNil() {
|
if !expr.IsNil() {
|
||||||
value, _ := constant.Uint64Val(constant.ToInt(expr.Value))
|
value, _ := constant.Uint64Val(constant.ToInt(expr.Value))
|
||||||
return llvm.ConstIntToPtr(llvm.ConstInt(b.uintptrType, value, false), b.i8ptrType)
|
return llvm.ConstIntToPtr(llvm.ConstInt(c.uintptrType, value, false), c.i8ptrType)
|
||||||
}
|
}
|
||||||
return llvm.ConstNull(b.i8ptrType)
|
return llvm.ConstNull(c.i8ptrType)
|
||||||
} else if typ.Info()&types.IsUnsigned != 0 {
|
} else if typ.Info()&types.IsUnsigned != 0 {
|
||||||
n, _ := constant.Uint64Val(constant.ToInt(expr.Value))
|
n, _ := constant.Uint64Val(constant.ToInt(expr.Value))
|
||||||
return llvm.ConstInt(llvmType, n, false)
|
return llvm.ConstInt(llvmType, n, false)
|
||||||
|
@ -2516,18 +2515,18 @@ func (b *builder) createConst(expr *ssa.Const) llvm.Value {
|
||||||
n, _ := constant.Float64Val(expr.Value)
|
n, _ := constant.Float64Val(expr.Value)
|
||||||
return llvm.ConstFloat(llvmType, n)
|
return llvm.ConstFloat(llvmType, n)
|
||||||
} else if typ.Kind() == types.Complex64 {
|
} else if typ.Kind() == types.Complex64 {
|
||||||
r := b.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32]))
|
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32]))
|
||||||
i := b.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32]))
|
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32]))
|
||||||
cplx := llvm.Undef(b.ctx.StructType([]llvm.Type{b.ctx.FloatType(), b.ctx.FloatType()}, false))
|
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false))
|
||||||
cplx = b.CreateInsertValue(cplx, r, 0, "")
|
cplx = llvm.ConstInsertValue(cplx, r, []uint32{0})
|
||||||
cplx = b.CreateInsertValue(cplx, i, 1, "")
|
cplx = llvm.ConstInsertValue(cplx, i, []uint32{1})
|
||||||
return cplx
|
return cplx
|
||||||
} else if typ.Kind() == types.Complex128 {
|
} else if typ.Kind() == types.Complex128 {
|
||||||
r := b.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64]))
|
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64]))
|
||||||
i := b.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64]))
|
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64]))
|
||||||
cplx := llvm.Undef(b.ctx.StructType([]llvm.Type{b.ctx.DoubleType(), b.ctx.DoubleType()}, false))
|
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false))
|
||||||
cplx = b.CreateInsertValue(cplx, r, 0, "")
|
cplx = llvm.ConstInsertValue(cplx, r, []uint32{0})
|
||||||
cplx = b.CreateInsertValue(cplx, i, 1, "")
|
cplx = llvm.ConstInsertValue(cplx, i, []uint32{1})
|
||||||
return cplx
|
return cplx
|
||||||
} else {
|
} else {
|
||||||
panic("unknown constant of basic type: " + expr.String())
|
panic("unknown constant of basic type: " + expr.String())
|
||||||
|
@ -2536,35 +2535,35 @@ func (b *builder) createConst(expr *ssa.Const) llvm.Value {
|
||||||
if expr.Value != nil {
|
if expr.Value != nil {
|
||||||
panic("expected nil chan constant")
|
panic("expected nil chan constant")
|
||||||
}
|
}
|
||||||
return llvm.ConstNull(b.getLLVMType(expr.Type()))
|
return llvm.ConstNull(c.getLLVMType(expr.Type()))
|
||||||
case *types.Signature:
|
case *types.Signature:
|
||||||
if expr.Value != nil {
|
if expr.Value != nil {
|
||||||
panic("expected nil signature constant")
|
panic("expected nil signature constant")
|
||||||
}
|
}
|
||||||
return llvm.ConstNull(b.getLLVMType(expr.Type()))
|
return llvm.ConstNull(c.getLLVMType(expr.Type()))
|
||||||
case *types.Interface:
|
case *types.Interface:
|
||||||
if expr.Value != nil {
|
if expr.Value != nil {
|
||||||
panic("expected nil interface constant")
|
panic("expected nil interface constant")
|
||||||
}
|
}
|
||||||
// Create a generic nil interface with no dynamic type (typecode=0).
|
// Create a generic nil interface with no dynamic type (typecode=0).
|
||||||
fields := []llvm.Value{
|
fields := []llvm.Value{
|
||||||
llvm.ConstInt(b.uintptrType, 0, false),
|
llvm.ConstInt(c.uintptrType, 0, false),
|
||||||
llvm.ConstPointerNull(b.i8ptrType),
|
llvm.ConstPointerNull(c.i8ptrType),
|
||||||
}
|
}
|
||||||
return llvm.ConstNamedStruct(b.getLLVMRuntimeType("_interface"), fields)
|
return llvm.ConstNamedStruct(c.getLLVMRuntimeType("_interface"), fields)
|
||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
if expr.Value != nil {
|
if expr.Value != nil {
|
||||||
panic("expected nil pointer constant")
|
panic("expected nil pointer constant")
|
||||||
}
|
}
|
||||||
return llvm.ConstPointerNull(b.getLLVMType(typ))
|
return llvm.ConstPointerNull(c.getLLVMType(typ))
|
||||||
case *types.Slice:
|
case *types.Slice:
|
||||||
if expr.Value != nil {
|
if expr.Value != nil {
|
||||||
panic("expected nil slice constant")
|
panic("expected nil slice constant")
|
||||||
}
|
}
|
||||||
elemType := b.getLLVMType(typ.Elem())
|
elemType := c.getLLVMType(typ.Elem())
|
||||||
llvmPtr := llvm.ConstPointerNull(llvm.PointerType(elemType, 0))
|
llvmPtr := llvm.ConstPointerNull(llvm.PointerType(elemType, 0))
|
||||||
llvmLen := llvm.ConstInt(b.uintptrType, 0, false)
|
llvmLen := llvm.ConstInt(c.uintptrType, 0, false)
|
||||||
slice := b.ctx.ConstStruct([]llvm.Value{
|
slice := c.ctx.ConstStruct([]llvm.Value{
|
||||||
llvmPtr, // backing array
|
llvmPtr, // backing array
|
||||||
llvmLen, // len
|
llvmLen, // len
|
||||||
llvmLen, // cap
|
llvmLen, // cap
|
||||||
|
@ -2575,7 +2574,7 @@ func (b *builder) createConst(expr *ssa.Const) llvm.Value {
|
||||||
// I believe this is not allowed by the Go spec.
|
// I believe this is not allowed by the Go spec.
|
||||||
panic("non-nil map constant")
|
panic("non-nil map constant")
|
||||||
}
|
}
|
||||||
llvmType := b.getLLVMType(typ)
|
llvmType := c.getLLVMType(typ)
|
||||||
return llvm.ConstNull(llvmType)
|
return llvm.ConstNull(llvmType)
|
||||||
default:
|
default:
|
||||||
panic("unknown constant: " + expr.String())
|
panic("unknown constant: " + expr.String())
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче