Merge pull request #193 from visualfc/type

ssa: type uint/byte/int32/uint32/int64/uint64
This commit is contained in:
xushiwei
2024-05-17 11:04:12 +08:00
committed by GitHub
3 changed files with 88 additions and 9 deletions

View File

@@ -1250,7 +1250,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
conv := func(v llvm.Value) llvm.Value { conv := func(v llvm.Value) llvm.Value {
switch kind { switch kind {
case types.Float32: case types.Float32:
v = castInt(b, v, b.Prog.Type(types.Typ[types.Int32], InC)) v = castInt(b, v, b.Prog.Int32())
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
case types.Float64: case types.Float64:
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
@@ -1404,7 +1404,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl
return return
case vkString: case vkString:
etSize := b.Prog.SizeOf(b.Prog.Type(types.Typ[types.Byte], InGo)) etSize := b.Prog.SizeOf(b.Prog.Byte())
ret.Type = src.Type ret.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl
@@ -1420,24 +1420,24 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" ")) b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" "))
} }
var fn string var fn string
var typ types.Type var typ Type
switch arg.kind { switch arg.kind {
case vkBool: case vkBool:
fn = "PrintBool" fn = "PrintBool"
case vkSigned: case vkSigned:
fn = "PrintInt" fn = "PrintInt"
typ = types.Typ[types.Int64] typ = b.Prog.Int64()
case vkUnsigned: case vkUnsigned:
fn = "PrintUint" fn = "PrintUint"
typ = types.Typ[types.Uint64] typ = b.Prog.Uint64()
case vkFloat: case vkFloat:
fn = "PrintFloat" fn = "PrintFloat"
typ = types.Typ[types.Float64] typ = b.Prog.Float64()
case vkSlice: case vkSlice:
fn = "PrintSlice" fn = "PrintSlice"
case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef: case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef:
fn = "PrintPointer" fn = "PrintPointer"
typ = types.Typ[types.UnsafePointer] typ = b.Prog.VoidPtr()
case vkString: case vkString:
fn = "PrintString" fn = "PrintString"
case vkInterface: case vkInterface:
@@ -1447,8 +1447,8 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
default: default:
panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType())) panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType()))
} }
if typ != nil && typ != arg.raw.Type { if typ != nil && typ != arg.Type {
arg = b.Convert(b.Prog.Type(typ, InGo), arg) arg = b.Convert(typ, arg)
} }
b.InlineCall(b.Func.Pkg.rtFunc(fn), arg) b.InlineCall(b.Func.Pkg.rtFunc(fn), arg)
} }

View File

@@ -134,7 +134,13 @@ type aProgram struct {
stringTy Type stringTy Type
uintptrTy Type uintptrTy Type
intTy Type intTy Type
uintTy Type
f64Ty Type f64Ty Type
byteTy Type
i32Ty Type
u32Ty Type
i64Ty Type
u64Ty Type
pyObjPtr Type pyObjPtr Type
pyObjPPtr Type pyObjPPtr Type
@@ -351,6 +357,14 @@ func (p Program) Int() Type {
return p.intTy return p.intTy
} }
// Uint returns uint type.
func (p Program) Uint() Type {
if p.uintTy == nil {
p.uintTy = p.rawType(types.Typ[types.Uint])
}
return p.uintTy
}
// Uintptr returns uintptr type. // Uintptr returns uintptr type.
func (p Program) Uintptr() Type { func (p Program) Uintptr() Type {
if p.uintptrTy == nil { if p.uintptrTy == nil {
@@ -367,6 +381,46 @@ func (p Program) Float64() Type {
return p.f64Ty return p.f64Ty
} }
// Byte returns byte type.
func (p Program) Byte() Type {
if p.byteTy == nil {
p.byteTy = p.rawType(types.Typ[types.Byte])
}
return p.byteTy
}
// Int32 returns int32 type.
func (p Program) Int32() Type {
if p.i32Ty == nil {
p.i32Ty = p.rawType(types.Typ[types.Int32])
}
return p.i32Ty
}
// Uint32 returns uint32 type.
func (p Program) Uint32() Type {
if p.u32Ty == nil {
p.u32Ty = p.rawType(types.Typ[types.Uint32])
}
return p.u32Ty
}
// Int64 returns int64 type.
func (p Program) Int64() Type {
if p.i64Ty == nil {
p.i64Ty = p.rawType(types.Typ[types.Int64])
}
return p.i64Ty
}
// Uint64 returns uint64 type.
func (p Program) Uint64() Type {
if p.u64Ty == nil {
p.u64Ty = p.rawType(types.Typ[types.Uint64])
}
return p.u64Ty
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A Package is a single analyzed Go package containing Members for // A Package is a single analyzed Go package containing Members for

View File

@@ -461,3 +461,28 @@ _llgo_0:
} }
`) `)
} }
func TestBasicType(t *testing.T) {
type typeInfo struct {
typ Type
kind types.BasicKind
}
prog := NewProgram(nil)
infos := []*typeInfo{
{prog.Bool(), types.Bool},
{prog.Byte(), types.Byte},
{prog.Int(), types.Int},
{prog.Uint(), types.Uint},
{prog.Int32(), types.Int32},
{prog.Int64(), types.Int64},
{prog.Uint32(), types.Uint32},
{prog.Uint64(), types.Uint64},
{prog.Uintptr(), types.Uintptr},
{prog.VoidPtr(), types.UnsafePointer},
}
for _, info := range infos {
if info.typ.RawType() != types.Typ[info.kind] {
t.Fatal("bad type", info)
}
}
}