本文整理汇总了Golang中github.com/axw/llgo/types.Underlying函数的典型用法代码示例。如果您正苦于以下问题:Golang Underlying函数的具体用法?Golang Underlying怎么用?Golang Underlying使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Underlying函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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
}
示例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")
}
示例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")
}
示例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()))
}
示例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))
}
示例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))
}
示例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
}
示例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))
}
示例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))
}
示例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)
}
示例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
}
示例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}
}
}
示例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
}
示例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
}
示例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
}