diff --git a/ssa/expr.go b/ssa/expr.go index b1a050ac..49e353d2 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -1250,7 +1250,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) { conv := func(v llvm.Value) llvm.Value { switch kind { 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, "") case types.Float64: 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 return 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.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), 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(" ")) } var fn string - var typ types.Type + var typ Type switch arg.kind { case vkBool: fn = "PrintBool" case vkSigned: fn = "PrintInt" - typ = types.Typ[types.Int64] + typ = b.Prog.Int64() case vkUnsigned: fn = "PrintUint" - typ = types.Typ[types.Uint64] + typ = b.Prog.Uint64() case vkFloat: fn = "PrintFloat" - typ = types.Typ[types.Float64] + typ = b.Prog.Float64() case vkSlice: fn = "PrintSlice" case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef: fn = "PrintPointer" - typ = types.Typ[types.UnsafePointer] + typ = b.Prog.VoidPtr() case vkString: fn = "PrintString" case vkInterface: @@ -1447,8 +1447,8 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) { default: panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType())) } - if typ != nil && typ != arg.raw.Type { - arg = b.Convert(b.Prog.Type(typ, InGo), arg) + if typ != nil && typ != arg.Type { + arg = b.Convert(typ, arg) } b.InlineCall(b.Func.Pkg.rtFunc(fn), arg) } diff --git a/ssa/package.go b/ssa/package.go index bcfe246e..57caaef9 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -134,7 +134,13 @@ type aProgram struct { stringTy Type uintptrTy Type intTy Type + uintTy Type f64Ty Type + byteTy Type + i32Ty Type + u32Ty Type + i64Ty Type + u64Ty Type pyObjPtr Type pyObjPPtr Type @@ -351,6 +357,14 @@ func (p Program) Int() Type { 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. func (p Program) Uintptr() Type { if p.uintptrTy == nil { @@ -367,6 +381,46 @@ func (p Program) Float64() Type { 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 diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index daac56f2..05496769 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -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) + } + } +}