本文整理汇总了Golang中github.com/axw/llgo/types.Underlying函数的典型用法代码示例。如果您正苦于以下问题:Golang Underlying函数的具体用法?Golang Underlying怎么用?Golang Underlying使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Underlying函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: Convert
func (v ConstValue) Convert(dst_typ types.Type) Value {
// Get the underlying type, if any.
if name, isname := dst_typ.(*types.Name); isname {
dst_typ = types.Underlying(name)
}
if !types.Identical(v.typ, dst_typ) {
// Get the Basic type.
isBasic := false
if name, isname := types.Underlying(dst_typ).(*types.Name); isname {
_, isBasic = name.Underlying.(*types.Basic)
}
compiler := v.compiler
if isBasic {
return ConstValue{*v.Const.Convert(&dst_typ), compiler, dst_typ}
} else {
return compiler.NewLLVMValue(v.LLVMValue(), v.Type()).Convert(dst_typ)
//panic(fmt.Errorf("unhandled conversion from %v to %v", v.typ, dst_typ))
}
} else {
// TODO convert to dst type. ConstValue may need to change to allow
// storage of types other than Basic.
}
return v
}
开发者ID:prattmic,项目名称:llgo,代码行数:26,代码来源:value.go
示例2: UnaryOp
func (v *LLVMValue) UnaryOp(op token.Token) Value {
b := v.compiler.builder
switch op {
case token.SUB:
var value llvm.Value
isfp := types.Identical(types.Underlying(v.typ), types.Float32) ||
types.Identical(types.Underlying(v.typ), types.Float64)
if isfp {
zero := llvm.ConstNull(v.compiler.types.ToLLVM(v.Type()))
value = b.CreateFSub(zero, v.LLVMValue(), "")
} else {
value = b.CreateNeg(v.LLVMValue(), "")
}
return v.compiler.NewLLVMValue(value, v.typ)
case token.ADD:
return v // No-op
case token.AND:
return v.pointer
case token.NOT:
value := b.CreateNot(v.LLVMValue(), "")
return v.compiler.NewLLVMValue(value, v.typ)
case token.XOR:
lhs := v.LLVMValue()
rhs := llvm.ConstAllOnes(lhs.Type())
value := b.CreateXor(lhs, rhs, "")
return v.compiler.NewLLVMValue(value, v.typ)
default:
panic("Unhandled operator: ") // + expr.Op)
}
panic("unreachable")
}
开发者ID:spate,项目名称:llgo,代码行数:31,代码来源:value.go
示例3: VisitSliceExpr
func (c *compiler) VisitSliceExpr(expr *ast.SliceExpr) Value {
// expr.X, expr.Low, expr.High
value := c.VisitExpr(expr.X)
var low, high llvm.Value
if expr.Low != nil {
low = c.VisitExpr(expr.Low).Convert(types.Int32).LLVMValue()
} else {
low = llvm.ConstNull(llvm.Int32Type())
}
if expr.High != nil {
high = c.VisitExpr(expr.High).Convert(types.Int32).LLVMValue()
} else {
high = llvm.ConstAllOnes(llvm.Int32Type()) // -1
}
if _, ok := types.Underlying(value.Type()).(*types.Pointer); ok {
value = value.(*LLVMValue).makePointee()
}
switch typ := types.Underlying(value.Type()).(type) {
case *types.Array:
sliceslice := c.NamedFunction("runtime.sliceslice", "func f(t uintptr, s slice, low, high int32) slice")
i8slice := sliceslice.Type().ElementType().ReturnType()
sliceValue := llvm.Undef(i8slice) // temporary slice
arrayptr := value.(*LLVMValue).pointer.LLVMValue()
arrayptr = c.builder.CreateBitCast(arrayptr, i8slice.StructElementTypes()[0], "")
arraylen := llvm.ConstInt(llvm.Int32Type(), typ.Len, false)
sliceValue = c.builder.CreateInsertValue(sliceValue, arrayptr, 0, "")
sliceValue = c.builder.CreateInsertValue(sliceValue, arraylen, 1, "")
sliceValue = c.builder.CreateInsertValue(sliceValue, arraylen, 2, "")
sliceTyp := &types.Slice{Elt: typ.Elt}
runtimeTyp := c.types.ToRuntime(sliceTyp)
runtimeTyp = c.builder.CreatePtrToInt(runtimeTyp, c.target.IntPtrType(), "")
args := []llvm.Value{runtimeTyp, sliceValue, low, high}
result := c.builder.CreateCall(sliceslice, args, "")
llvmSliceTyp := c.types.ToLLVM(sliceTyp)
return c.NewLLVMValue(c.coerceSlice(result, llvmSliceTyp), sliceTyp)
case *types.Slice:
sliceslice := c.NamedFunction("runtime.sliceslice", "func f(t uintptr, s slice, low, high int32) slice")
i8slice := sliceslice.Type().ElementType().ReturnType()
sliceValue := value.LLVMValue()
sliceTyp := sliceValue.Type()
sliceValue = c.coerceSlice(sliceValue, i8slice)
runtimeTyp := c.types.ToRuntime(value.Type())
runtimeTyp = c.builder.CreatePtrToInt(runtimeTyp, c.target.IntPtrType(), "")
args := []llvm.Value{runtimeTyp, sliceValue, low, high}
result := c.builder.CreateCall(sliceslice, args, "")
return c.NewLLVMValue(c.coerceSlice(result, sliceTyp), value.Type())
case *types.Name: // String
stringslice := c.NamedFunction("runtime.stringslice", "func f(a string, low, high int32) string")
args := []llvm.Value{value.LLVMValue(), low, high}
result := c.builder.CreateCall(stringslice, args, "")
return c.NewLLVMValue(result, value.Type())
default:
panic("unimplemented")
}
panic("unreachable")
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:58,代码来源:slice.go
示例4: VisitLen
func (c *compiler) VisitLen(expr *ast.CallExpr) Value {
if len(expr.Args) > 1 {
panic("Expecting only one argument to len")
}
value := c.VisitExpr(expr.Args[0])
typ := value.Type()
if name, ok := types.Underlying(typ).(*types.Name); ok {
typ = name.Underlying
}
switch typ := types.Underlying(typ).(type) {
case *types.Pointer:
// XXX Converting to a string to be converted back to an int is
// silly. The values need an overhaul? Perhaps have types based
// on fundamental types, with the additional methods to make
// them llgo.Value's.
if a, isarray := typ.Base.(*types.Array); isarray {
return c.NewConstValue(token.INT,
strconv.FormatUint(a.Len, 10))
}
v := strconv.FormatUint(uint64(unsafe.Sizeof(uintptr(0))), 10)
return c.NewConstValue(token.INT, v)
case *types.Slice:
sliceval := value.LLVMValue()
lenval := c.builder.CreateExtractValue(sliceval, 1, "")
return c.NewLLVMValue(lenval, types.Int32).Convert(types.Int)
case *types.Map:
mapval := value.LLVMValue()
f := c.NamedFunction("runtime.maplen", "func f(m uintptr) int")
lenval := c.builder.CreateCall(f, []llvm.Value{mapval}, "")
return c.NewLLVMValue(lenval, types.Int)
case *types.Array:
v := strconv.FormatUint(typ.Len, 10)
return c.NewConstValue(token.INT, v)
case *types.Basic:
if typ == types.String.Underlying {
switch value := value.(type) {
case *LLVMValue:
ptr := value.pointer
len_field := c.builder.CreateStructGEP(ptr.LLVMValue(), 1, "")
len_value := c.builder.CreateLoad(len_field, "")
return c.NewLLVMValue(len_value, types.Int32).Convert(types.Int)
case ConstValue:
s := value.Val.(string)
n := uint64(len(s))
return c.NewConstValue(token.INT, strconv.FormatUint(n, 10))
}
}
}
panic(fmt.Sprint("Unhandled value type: ", value.Type()))
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:56,代码来源:len.go
示例5: VisitIndexExpr
func (c *compiler) VisitIndexExpr(expr *ast.IndexExpr) Value {
value := c.VisitExpr(expr.X)
index := c.VisitExpr(expr.Index)
typ := types.Underlying(value.Type())
if typ == types.String {
ptr := c.builder.CreateExtractValue(value.LLVMValue(), 0, "")
gepindices := []llvm.Value{index.LLVMValue()}
ptr = c.builder.CreateGEP(ptr, gepindices, "")
result := c.NewLLVMValue(ptr, &types.Pointer{Base: types.Byte})
return result.makePointee()
}
// We can index a pointer to an array.
if _, ok := typ.(*types.Pointer); ok {
value = value.(*LLVMValue).makePointee()
typ = value.Type()
}
switch typ := types.Underlying(typ).(type) {
case *types.Array:
index := index.LLVMValue()
var ptr llvm.Value
value := value.(*LLVMValue)
if value.pointer != nil {
ptr = value.pointer.LLVMValue()
} else {
init := value.LLVMValue()
ptr = c.builder.CreateAlloca(init.Type(), "")
c.builder.CreateStore(init, ptr)
}
zero := llvm.ConstNull(llvm.Int32Type())
element := c.builder.CreateGEP(ptr, []llvm.Value{zero, index}, "")
result := c.NewLLVMValue(element, &types.Pointer{Base: typ.Elt})
return result.makePointee()
case *types.Slice:
index := index.LLVMValue()
ptr := c.builder.CreateExtractValue(value.LLVMValue(), 0, "")
element := c.builder.CreateGEP(ptr, []llvm.Value{index}, "")
result := c.NewLLVMValue(element, &types.Pointer{Base: typ.Elt})
return result.makePointee()
case *types.Map:
value, _ = c.mapLookup(value.(*LLVMValue), index, false)
return value
}
panic(fmt.Sprintf("unreachable (%s)", typ))
}
开发者ID:kisielk,项目名称:llgo,代码行数:49,代码来源:expr.go
示例6: VisitMake
func (c *compiler) VisitMake(expr *ast.CallExpr) Value {
typ := c.types.expr[expr]
switch utyp := types.Underlying(typ).(type) {
case *types.Slice:
var length, capacity Value
switch len(expr.Args) {
case 3:
capacity = c.VisitExpr(expr.Args[2])
fallthrough
case 2:
length = c.VisitExpr(expr.Args[1])
}
slice := c.makeSlice(utyp.Elt, length, capacity)
return c.NewLLVMValue(slice, typ)
case *types.Chan:
f := c.NamedFunction("runtime.makechan", "func f(t uintptr, cap uint32) uintptr")
dyntyp := c.types.ToRuntime(typ)
dyntyp = c.builder.CreatePtrToInt(dyntyp, c.target.IntPtrType(), "")
var cap_ llvm.Value
if len(expr.Args) > 1 {
cap_ = c.VisitExpr(expr.Args[1]).LLVMValue()
}
args := []llvm.Value{dyntyp, cap_}
ptr := c.builder.CreateCall(f, args, "")
return c.NewLLVMValue(ptr, typ)
case *types.Map:
f := c.NamedFunction("runtime.makemap", "func f(t uintptr) uintptr")
dyntyp := c.types.ToRuntime(typ)
dyntyp = c.builder.CreatePtrToInt(dyntyp, c.target.IntPtrType(), "")
mapval := c.builder.CreateCall(f, []llvm.Value{dyntyp}, "")
return c.NewLLVMValue(mapval, typ)
}
panic(fmt.Sprintf("unhandled type: %s", typ))
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:34,代码来源:make.go
示例7: destructureExpr
// destructureExpr evaluates the right-hand side of a
// multiple assignment where the right-hand side is a single expression.
func (c *compiler) destructureExpr(x ast.Expr) []Value {
var values []Value
switch x := x.(type) {
case *ast.IndexExpr:
// value, ok := m[k]
m := c.VisitExpr(x.X).(*LLVMValue)
index := c.VisitExpr(x.Index)
value, notnull := c.mapLookup(m, index, false)
values = []Value{value, notnull}
case *ast.CallExpr:
value := c.VisitExpr(x)
aggregate := value.LLVMValue()
struct_type := value.Type().(*types.Struct)
values = make([]Value, len(struct_type.Fields))
for i, f := range struct_type.Fields {
t := f.Type.(types.Type)
value_ := c.builder.CreateExtractValue(aggregate, i, "")
values[i] = c.NewLLVMValue(value_, t)
}
case *ast.TypeAssertExpr:
lhs := c.VisitExpr(x.X).(*LLVMValue)
typ := c.types.expr[x]
switch typ := types.Underlying(typ).(type) {
case *types.Interface:
value, ok := lhs.convertI2I(typ)
values = []Value{value, ok}
default:
value, ok := lhs.convertI2V(typ)
values = []Value{value, ok}
}
}
return values
}
开发者ID:kisielk,项目名称:llgo,代码行数:35,代码来源:stmt.go
示例8: VisitIndexExpr
func (c *compiler) VisitIndexExpr(expr *ast.IndexExpr) Value {
value := c.VisitExpr(expr.X).(*LLVMValue)
index := c.VisitExpr(expr.Index)
typ := value.Type()
if typ == types.String {
ptr := c.builder.CreateExtractValue(value.LLVMValue(), 0, "")
gepindices := []llvm.Value{index.LLVMValue()}
ptr = c.builder.CreateGEP(ptr, gepindices, "")
result := c.NewLLVMValue(ptr, &types.Pointer{Base: types.Byte})
return result.makePointee()
}
// We can index a pointer to an array.
if _, ok := types.Underlying(typ).(*types.Pointer); ok {
value = value.makePointee()
typ = value.Type()
}
switch types.Underlying(typ).(type) {
case *types.Array, *types.Slice:
var gep_indices []llvm.Value
var ptr llvm.Value
var result_type types.Type
switch typ := types.Underlying(typ).(type) {
case *types.Array:
// FIXME what to do if value is not addressable?
// Do we have to load the array onto the stack?
result_type = typ.Elt
ptr = value.pointer.LLVMValue()
gep_indices = append(gep_indices, llvm.ConstNull(llvm.Int32Type()))
case *types.Slice:
result_type = typ.Elt
ptr = c.builder.CreateExtractValue(value.LLVMValue(), 0, "")
}
gep_indices = append(gep_indices, index.LLVMValue())
element := c.builder.CreateGEP(ptr, gep_indices, "")
result := c.NewLLVMValue(element, &types.Pointer{Base: result_type})
return result.makePointee()
case *types.Map:
value, _ = c.mapLookup(value, index, false)
return value
}
panic(fmt.Sprintf("unreachable (%s)", typ))
}
开发者ID:spate,项目名称:llgo,代码行数:47,代码来源:expr.go
示例9: 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))
}
开发者ID:spate,项目名称:llgo,代码行数:57,代码来源:value.go
示例10: chanRecv
func (v *LLVMValue) chanRecv() *LLVMValue {
c := v.compiler
elttyp := types.Underlying(v.typ).(*types.Chan).Elt
ptr := c.builder.CreateAlloca(c.types.ToLLVM(elttyp), "")
uintptr_ := c.builder.CreatePtrToInt(ptr, c.target.IntPtrType(), "")
f := c.NamedFunction("runtime.chanrecv", "func f(c, ptr uintptr)")
c.builder.CreateCall(f, []llvm.Value{v.LLVMValue(), uintptr_}, "")
value := c.builder.CreateLoad(ptr, "")
return c.NewLLVMValue(value, elttyp)
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:10,代码来源:channels.go
示例11: convertI2I
// convertI2I converts an interface to another interface.
func (v *LLVMValue) convertI2I(iface *types.Interface) (result Value, success Value) {
c := v.compiler
builder := v.compiler.builder
src_typ := types.Underlying(v.Type())
vptr := v.pointer.LLVMValue()
zero_iface_struct := llvm.ConstNull(c.types.ToLLVM(iface))
iface_struct := zero_iface_struct
dynamicType := builder.CreateLoad(builder.CreateStructGEP(vptr, 0, ""), "")
receiver := builder.CreateLoad(builder.CreateStructGEP(vptr, 1, ""), "")
// 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)
goto check_dynamic
} else {
method := builder.CreateStructGEP(vptr, mi+2, "")
fptr := builder.CreateLoad(method, "")
iface_struct = builder.CreateInsertValue(iface_struct, fptr, i+2, "")
}
}
iface_struct = builder.CreateInsertValue(iface_struct, dynamicType, 0, "")
iface_struct = builder.CreateInsertValue(iface_struct, receiver, 1, "")
result = c.NewLLVMValue(iface_struct, iface)
success = ConstValue{types.Const{true}, c, types.Bool}
return result, success
check_dynamic:
runtimeConvertI2I := c.NamedFunction("runtime.convertI2I", "func f(typ, from, to uintptr) bool")
llvmUintptr := runtimeConvertI2I.Type().ElementType().ParamTypes()[0]
runtimeType := c.builder.CreatePtrToInt(c.types.ToRuntime(iface), llvmUintptr, "")
from := c.builder.CreatePtrToInt(vptr, llvmUintptr, "")
to := c.builder.CreateAlloca(iface_struct.Type(), "")
c.builder.CreateStore(iface_struct, to)
toUintptr := c.builder.CreatePtrToInt(to, llvmUintptr, "")
args := []llvm.Value{runtimeType, from, toUintptr}
ok := c.builder.CreateCall(runtimeConvertI2I, args, "")
value := c.builder.CreateLoad(to, "")
value = c.builder.CreateSelect(ok, value, zero_iface_struct, "")
result = c.NewLLVMValue(value, iface)
success = c.NewLLVMValue(ok, types.Bool)
return result, success
}
开发者ID:kisielk,项目名称:llgo,代码行数:56,代码来源:interfaces.go
示例12: VisitTypeSpec
func (c *compiler) VisitTypeSpec(spec *ast.TypeSpec) {
obj := spec.Name.Obj
type_, istype := (obj.Type).(types.Type)
if !istype {
type_ = c.GetType(spec.Type)
if name, isname := type_.(*types.Name); isname {
type_ = types.Underlying(name)
}
obj.Type = &types.Name{Underlying: type_, Obj: obj}
}
}
开发者ID:c0der007,项目名称:llgo,代码行数:11,代码来源:decl.go
示例13: ToLLVM
func (tm *TypeMap) ToLLVM(t types.Type) llvm.Type {
t = types.Underlying(t)
lt, ok := tm.types[t]
if !ok {
lt = tm.makeLLVMType(t)
if lt.IsNil() {
panic(fmt.Sprint("Failed to create LLVM type for: ", t))
}
tm.types[t] = lt
}
return lt
}
开发者ID:c0der007,项目名称:llgo,代码行数:12,代码来源:llvmtypes.go
示例14: ToRuntime
func (tm *TypeMap) ToRuntime(t types.Type) llvm.Value {
t = types.Underlying(t)
r, ok := tm.runtime[t]
if !ok {
_, r = tm.makeRuntimeType(t)
if r.IsNil() {
panic(fmt.Sprint("Failed to create runtime type for: ", t))
}
tm.runtime[t] = r
}
return r
}
开发者ID:c0der007,项目名称:llgo,代码行数:12,代码来源:llvmtypes.go
示例15: Convert
func (v ConstValue) Convert(dstTyp types.Type) Value {
// Get the underlying type, if any.
origDstTyp := dstTyp
dstTyp = types.Underlying(dstTyp)
if !types.Identical(v.typ, dstTyp) {
isBasic := false
if name, isname := types.Underlying(dstTyp).(*types.Name); isname {
_, isBasic = name.Underlying.(*types.Basic)
}
compiler := v.compiler
if isBasic {
return ConstValue{v.Const.Convert(&dstTyp), compiler, origDstTyp}
} else {
return compiler.NewLLVMValue(v.LLVMValue(), v.Type()).Convert(origDstTyp)
//panic(fmt.Errorf("unhandled conversion from %v to %v", v.typ, dstTyp))
}
} else {
v.typ = origDstTyp
}
return v
}
开发者ID:spate,项目名称:llgo,代码行数:23,代码来源:value.go
示例16: chanSend
func (v *LLVMValue) chanSend(value Value) {
var ptr llvm.Value
if value, ok := value.(*LLVMValue); ok && value.pointer != nil {
ptr = value.pointer.LLVMValue()
}
elttyp := types.Underlying(v.typ).(*types.Chan).Elt
c := v.compiler
if ptr.IsNil() {
ptr = c.builder.CreateAlloca(c.types.ToLLVM(elttyp), "")
value := value.Convert(elttyp).LLVMValue()
c.builder.CreateStore(value, ptr)
}
uintptr_ := c.builder.CreatePtrToInt(ptr, c.target.IntPtrType(), "")
f := c.NamedFunction("runtime.chansend", "func f(c, ptr uintptr)")
c.builder.CreateCall(f, []llvm.Value{v.LLVMValue(), uintptr_}, "")
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:16,代码来源:channels.go
示例17: VisitMake
func (c *compiler) VisitMake(expr *ast.CallExpr) Value {
typ := c.GetType(expr.Args[0])
switch utyp := types.Underlying(typ).(type) {
case *types.Slice:
var length, capacity Value
switch len(expr.Args) {
case 3:
capacity = c.VisitExpr(expr.Args[2])
fallthrough
case 2:
length = c.VisitExpr(expr.Args[1])
}
slice := c.makeSlice(utyp.Elt, length, capacity)
return c.NewLLVMValue(slice, typ)
}
// TODO map, chan
return c.NewLLVMValue(llvm.ConstNull(c.types.ToLLVM(typ)), typ)
}
开发者ID:spate,项目名称:llgo,代码行数:18,代码来源:make.go
示例18: loadI2V
// loadI2V loads an interface value to a type, without checking
// that the interface type matches.
func (v *LLVMValue) loadI2V(typ types.Type) Value {
c := v.compiler
if c.Sizeof(typ) > c.target.PointerSize() {
ptr := c.builder.CreateExtractValue(v.LLVMValue(), 1, "")
typ = &types.Pointer{Base: typ}
ptr = c.builder.CreateBitCast(ptr, c.types.ToLLVM(typ), "")
return c.NewLLVMValue(ptr, typ).makePointee()
}
value := c.builder.CreateExtractValue(v.LLVMValue(), 1, "")
if _, ok := types.Underlying(typ).(*types.Pointer); ok {
value = c.builder.CreateBitCast(value, c.types.ToLLVM(typ), "")
return c.NewLLVMValue(value, typ)
}
bits := c.target.TypeSizeInBits(c.types.ToLLVM(typ))
value = c.builder.CreatePtrToInt(value, llvm.IntType(int(bits)), "")
value = c.coerce(value, c.types.ToLLVM(typ))
return c.NewLLVMValue(value, typ)
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:21,代码来源:interfaces.go
示例19: VisitCompositeLit
func (c *compiler) VisitCompositeLit(lit *ast.CompositeLit) Value {
typ := c.types.expr[lit]
var valuemap map[interface{}]Value
var valuelist []Value
_, isstruct := types.Underlying(typ).(*types.Struct)
if lit.Elts != nil {
for _, elt := range lit.Elts {
var value Value
if kv, iskv := elt.(*ast.KeyValueExpr); iskv {
value = c.VisitExpr(kv.Value)
if valuemap == nil {
valuemap = make(map[interface{}]Value)
}
var key interface{}
if isstruct {
key = kv.Key.(*ast.Ident).Name
} else {
key = c.VisitExpr(kv.Key)
}
valuemap[key] = value
} else {
value = c.VisitExpr(elt)
valuelist = append(valuelist, value)
}
}
}
// For array/slice types, convert key:value to contiguous
// values initialiser.
switch types.Underlying(typ).(type) {
case *types.Array, *types.Slice:
if len(valuemap) > 0 {
maxi := int64(-1)
for key, _ := range valuemap {
i := key.(ConstValue).Int64()
if i < 0 {
panic("array index must be non-negative integer constant")
} else if i > maxi {
maxi = i
}
}
valuelist = make([]Value, maxi+1)
for key, value := range valuemap {
i := key.(ConstValue).Int64()
valuelist[i] = value
}
}
}
origtyp := typ
switch typ := types.Underlying(typ).(type) {
case *types.Array:
elttype := typ.Elt
llvmelttype := c.types.ToLLVM(elttype)
llvmvalues := make([]llvm.Value, typ.Len)
for i := range llvmvalues {
var value Value
if i < len(valuelist) {
value = valuelist[i]
}
if value == nil {
llvmvalues[i] = llvm.ConstNull(llvmelttype)
} else if _, ok := value.(ConstValue); ok || value.LLVMValue().IsConstant() {
llvmvalues[i] = value.Convert(elttype).LLVMValue()
} else {
llvmvalues[i] = llvm.Undef(llvmelttype)
}
}
array := llvm.ConstArray(llvmelttype, llvmvalues)
for i, value := range valuelist {
if llvmvalues[i].IsUndef() {
value := value.Convert(elttype).LLVMValue()
array = c.builder.CreateInsertValue(array, value, i, "")
}
}
return c.NewLLVMValue(array, origtyp)
case *types.Slice:
ptr := c.createTypeMalloc(c.types.ToLLVM(typ))
eltType := c.types.ToLLVM(typ.Elt)
arrayType := llvm.ArrayType(eltType, len(valuelist))
valuesPtr := c.createMalloc(llvm.SizeOf(arrayType))
valuesPtr = c.builder.CreateIntToPtr(valuesPtr, llvm.PointerType(eltType, 0), "")
//valuesPtr = c.builder.CreateBitCast(valuesPtr, llvm.PointerType(valuesPtr.Type(), 0), "")
// TODO check result of mallocs
length := llvm.ConstInt(llvm.Int32Type(), uint64(len(valuelist)), false)
c.builder.CreateStore(valuesPtr, c.builder.CreateStructGEP(ptr, 0, "")) // data
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 1, "")) // len
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 2, "")) // cap
null := llvm.ConstNull(c.types.ToLLVM(typ.Elt))
for i, value := range valuelist {
index := llvm.ConstInt(llvm.Int32Type(), uint64(i), false)
valuePtr := c.builder.CreateGEP(valuesPtr, []llvm.Value{index}, "")
if value == nil {
c.builder.CreateStore(null, valuePtr)
} else {
c.builder.CreateStore(value.Convert(typ.Elt).LLVMValue(), valuePtr)
}
//.........这里部分代码省略.........
开发者ID:octabrain,项目名称:llgo,代码行数:101,代码来源:literals.go
示例20: VisitSelectorExpr
func (c *compiler) VisitSelectorExpr(expr *ast.SelectorExpr) Value {
lhs := c.VisitExpr(expr.X)
if lhs == nil {
// The only time we should get a nil result is if the object is
// a package.
obj := expr.Sel.Obj
if obj.Kind == ast.Typ {
return TypeValue{obj.Type.(types.Type)}
}
return c.Resolve(obj)
}
// Method expression. Returns an unbound function pointer.
// FIXME this is just the most basic case. It's also possible to
// create a pointer-receiver function from a method that has a
// value receiver (see Method Expressions in spec).
name := expr.Sel.Name
if _, ok := lhs.(TypeValue); ok {
methodobj := expr.Sel.Obj
value := c.Resolve(methodobj).(*LLVMValue)
ftyp := value.typ.(*types.Func)
methodParams := make(types.ObjList, len(ftyp.Params)+1)
methodParams[0] = ftyp.Recv
copy(methodParams[1:], ftyp.Params)
ftyp = &types.Func{
Recv: nil,
Params: methodParams,
Results: ftyp.Results,
IsVariadic: ftyp.IsVariadic,
}
return c.NewLLVMValue(value.value, ftyp)
}
// TODO(?) record path to field/method during typechecking, so we don't
// have to search again here.
if iface, ok := types.Underlying(lhs.Type()).(*types.Interface); ok {
i := sort.Search(len(iface.Methods), func(i int) bool {
return iface.Methods[i].Name >= name
})
structValue := lhs.LLVMValue()
receiver := c.builder.CreateExtractValue(structValue, 1, "")
f := c.builder.CreateExtractValue(structValue, i+2, "")
i8ptr := &types.Pointer{Base: types.Int8}
ftype := iface.Methods[i].Type.(*types.Func)
ftype.Recv = ast.NewObj(ast.Var, "")
ftype.Recv.Type = i8ptr
f = c.builder.CreateBitCast(f, c.types.ToLLVM(ftype), "")
ftype.Recv = nil
method := c.NewLLVMValue(f, ftype)
method.receiver = c.NewLLVMValue(receiver, i8ptr)
return method
}
// Search through embedded types for field/method.
var result selectorCandidate
curr := []selectorCandidate{{nil, lhs.Type()}}
for result.Type == nil && len(curr) > 0 {
var next []selectorCandidate
for _, candidate := range curr {
indices := candidate.Indices[0:]
t := candidate.Type
if p, ok := types.Underlying(t).(*types.Pointer); ok {
if _, ok := types.Underlying(p.Base).(*types.Struct); ok {
t = p.Base
}
}
if n, ok := t.(*types.Name); ok {
i := sort.Search(len(n.Methods), func(i int) bool {
return n.Methods[i].Name >= name
})
if i < len(n.Methods) && n.Methods[i].Name == name {
result.Indices = indices
result.Type = t
}
}
if t, ok := types.Underlying(t).(*types.Struct); ok {
if i, ok := t.FieldIndices[name]; ok {
result.Indices = append(indices, int(i))
result.Type = t
} else {
// Add embedded types to the next set of types
// to check.
for i, field := range t.Fields {
if field.Name == "" {
indices = append(indices[0:], i)
t := field.Type.(types.Type)
candidate := selectorCandidate{indices, t}
next = append(next, candidate)
}
}
}
}
}
curr = next
}
//.........这里部分代码省略.........
开发者ID:kisielk,项目名称:llgo,代码行数:101,代码来源:expr.go
注:本文中的github.com/axw/llgo/types.Underlying函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论