// NewArrayType returns a new array type based on the given length and element // type. func NewArrayType(lenToken, elem interface{}) (*types.Array, error) { if lenToken, ok := lenToken.(*token.Token); ok { n, err := strconv.Atoi(string(lenToken.Lit)) if err != nil { return nil, errutil.Err(err) } if elem, ok := elem.(types.Type); ok { return types.NewArray(elem, n) } return nil, errutil.Newf("invalid array element type; expected types.Type, got %T", elem) } return nil, errutil.Newf("invalid array length type; expected *token.Token, got %T", lenToken) }
// toIrType converts the given uC type to the corresponding LLVM IR type. func toIrType(n uctypes.Type) irtypes.Type { //TODO: implement, placeholder implementation var t irtypes.Type var err error switch ucType := n.(type) { case *uctypes.Basic: switch ucType.Kind { case uctypes.Int: //TODO: Get int width from compile env t, err = irtypes.NewInt(32) case uctypes.Char: t, err = irtypes.NewInt(8) case uctypes.Void: t = irtypes.NewVoid() } case *uctypes.Array: elem := toIrType(ucType.Elem) if ucType.Len == 0 { t, err = irtypes.NewPointer(elem) } else { t, err = irtypes.NewArray(elem, ucType.Len) } case *uctypes.Func: var params []*irtypes.Param variadic := false for _, p := range ucType.Params { //TODO: Add support for variadic if uctypes.IsVoid(p.Type) { break } pt := toIrType(p.Type) dbg.Printf("converting type %#v to %#v", p.Type, pt) params = append(params, irtypes.NewParam(pt, p.Name)) } result := toIrType(ucType.Result) t, err = irtypes.NewFunc(result, params, variadic) default: panic(fmt.Sprintf("support for translating type %T not yet implemented.", ucType)) } if err != nil { panic(errutil.Err(err)) } if t == nil { panic(errutil.Newf("Conversion failed: %#v", n)) } return t }
func init() { // i1 var err error i1Typ, err = types.NewInt(1) if err != nil { log.Fatalln(err) } // i3 i3Typ, err = types.NewInt(3) if err != nil { log.Fatalln(err) } // i5 i5Typ, err = types.NewInt(5) if err != nil { log.Fatalln(err) } // i8 i8Typ, err = types.NewInt(8) if err != nil { log.Fatalln(err) } // i32 i32Typ, err = types.NewInt(32) if err != nil { log.Fatalln(err) } // i64 i64Typ, err = types.NewInt(64) if err != nil { log.Fatalln(err) } // float f32Typ, err = types.NewFloat(types.Float32) if err != nil { log.Fatalln(err) } // double f64Typ, err = types.NewFloat(types.Float64) if err != nil { log.Fatalln(err) } // fp128 f128Typ, err = types.NewFloat(types.Float128) if err != nil { log.Fatalln(err) } // ppc_fp128 f128_ppcTyp, err = types.NewFloat(types.Float128_PPC) if err != nil { log.Fatalln(err) } // <2 x i32> i32x2VecTyp, err = types.NewVector(i32Typ, 2) if err != nil { log.Fatalln(err) } // <3 x i32> i32x3VecTyp, err = types.NewVector(i32Typ, 3) if err != nil { log.Fatalln(err) } // <2 x float> f32x2VecTyp, err = types.NewVector(f32Typ, 2) if err != nil { log.Fatalln(err) } // <3 x float> f32x3VecTyp, err = types.NewVector(f32Typ, 3) if err != nil { log.Fatalln(err) } // [2 x i32] i32x2ArrTyp, err = types.NewArray(i32Typ, 2) if err != nil { log.Fatalln(err) } // {i32, i8} i32i8StructTyp, err = types.NewStruct([]types.Type{i32Typ, i8Typ}, false) if err != nil { log.Fatalln(err) } // [2 x {i32, i8}] i32i8x2ArrTyp, err = types.NewArray(i32i8StructTyp, 2) if err != nil { log.Fatalln(err) } // i1 1 i1One, err = constant.NewInt(i1Typ, "1") if err != nil { log.Fatalln(err) } // i8 3 i8Three, err = constant.NewInt(i8Typ, "3") if err != nil { log.Fatalln(err) } // i8 4 i8Four, err = constant.NewInt(i8Typ, "4") if err != nil { log.Fatalln(err) } // i32 -13 i32MinusThirteen, err = constant.NewInt(i32Typ, "-13") if err != nil { log.Fatalln(err) } // i32 -4 i32MinusFour, err = constant.NewInt(i32Typ, "-4") if err != nil { log.Fatalln(err) } // i32 -3 i32MinusThree, err = constant.NewInt(i32Typ, "-3") if err != nil { log.Fatalln(err) } // i32 1 i32One, err = constant.NewInt(i32Typ, "1") if err != nil { log.Fatalln(err) } // i32 2 i32Two, err = constant.NewInt(i32Typ, "2") if err != nil { log.Fatalln(err) } // i32 3 i32Three, err = constant.NewInt(i32Typ, "3") if err != nil { log.Fatalln(err) } // i32 4 i32Four, err = constant.NewInt(i32Typ, "4") if err != nil { log.Fatalln(err) } // i32 15 i32Fifteen, err = constant.NewInt(i32Typ, "15") if err != nil { log.Fatalln(err) } // i32 42 i32FortyTwo, err = constant.NewInt(i32Typ, "42") if err != nil { log.Fatalln(err) } // float -3.0 f32MinusThree, err = constant.NewFloat(f32Typ, "-3.0") if err != nil { log.Fatalln(err) } // float -4.0 f32MinusFour, err = constant.NewFloat(f32Typ, "-4.0") if err != nil { log.Fatalln(err) } // float 1.0 f32One, err = constant.NewFloat(f32Typ, "1.0") if err != nil { log.Fatalln(err) } // float 2.0 f32Two, err = constant.NewFloat(f32Typ, "2.0") if err != nil { log.Fatalln(err) } // float 3.0 f32Three, err = constant.NewFloat(f32Typ, "3.0") if err != nil { log.Fatalln(err) } // float 4.0 f32Four, err = constant.NewFloat(f32Typ, "4.0") if err != nil { log.Fatalln(err) } // double 4.0 f64Four, err = constant.NewFloat(f64Typ, "4.0") if err != nil { log.Fatalln(err) } // TODO: Uncomment when fp128 and ppc_fp128 are supported. /* // fp128 3.0 f128Three, err = constant.NewFloat(f128Typ, "3.0") if err != nil { log.Fatalln(err) } // ppc_fp128 4.0 f128_ppcFour, err = constant.NewFloat(f128_ppcTyp, "4.0") if err != nil { log.Fatalln(err) } */ // <3 x i32> <i32 1, i32 2, i32 3> i32x3OneTwoThree, err = constant.NewVector(i32x3VecTyp, []constant.Constant{i32One, i32Two, i32Three}) if err != nil { log.Fatalln(err) } // <2 x i32> <i32 3, i32 42> i32x2VecThreeFortyTwo, err = constant.NewVector(i32x2VecTyp, []constant.Constant{i32Three, i32FortyTwo}) if err != nil { log.Fatalln(err) } // <2 x i32> <i32 -3, i32 15> i32x2VecMinusThreeFifteen, err = constant.NewVector(i32x2VecTyp, []constant.Constant{i32MinusThree, i32Fifteen}) if err != nil { log.Fatalln(err) } // <2 x float> <float 3.0, float 4.0> f32x2VecThreeFour, err = constant.NewVector(f32x2VecTyp, []constant.Constant{f32Three, f32Four}) if err != nil { log.Fatalln(err) } // <2 x float> <float -3.0, float 4.0> f32x2VecMinusThreeFour, err = constant.NewVector(f32x2VecTyp, []constant.Constant{f32MinusThree, f32Four}) if err != nil { log.Fatalln(err) } // <3 x float> <float 3.0, float 2.0, float 1.0> f32x3VecThreeFourFifteen, err = constant.NewVector(f32x3VecTyp, []constant.Constant{f32Three, f32Two, f32One}) if err != nil { log.Fatalln(err) } // {i32, i8} {i32 4, i8 3} i32i8FourThree, err = constant.NewStruct(i32i8StructTyp, []constant.Constant{i32Four, i8Three}) if err != nil { log.Fatalln(err) } // {i32, i8} {i32 3, i8 4} i32i8ThreeFour, err = constant.NewStruct(i32i8StructTyp, []constant.Constant{i32Three, i8Four}) if err != nil { log.Fatalln(err) } }
func TestArrayString(t *testing.T) { golden := []struct { elem types.Type n int want string err string }{ // i=0 { elem: i32Typ, n: 1, want: "[1 x i32]", }, // i=1 { elem: i8PtrTyp, n: 5, want: "[5 x i8*]", }, // i=2 { elem: i8Typ, n: 10, want: "[10 x i8]", }, // i=3 { elem: f64Typ, n: 6, want: "[6 x double]", }, // i=4 { elem: mmxTyp, n: 7, want: "[7 x x86_mmx]", }, // i=5 { elem: i8Typ, n: -1, // [-1 x i8] want: "", err: "invalid array length (-1)", }, // i=6 { elem: voidTyp, n: 5, // [5 x void] want: "", err: "invalid array element type; void type only allowed for function results", }, // i=7 { elem: labelTyp, n: 3, // [3 x label] want: "", err: `invalid array element type "label"`, }, // i=8 { elem: funcTyp, n: 2, // [2 x i32 (i32)] want: "", err: `invalid array element type "i32 (i32)"`, }, } for i, g := range golden { typ, err := types.NewArray(g.elem, g.n) if !sameError(err, g.err) { t.Errorf("i=%d: error mismatch; expected %v, got %v", i, g.err, err) continue } else if err != nil { // Expected error match, check next test case. continue } got := typ.String() if got != g.want { t.Errorf("i=%d: string mismatch; expected %v, got %v", i, g.want, got) } } }
func init() { var err error // Void type. // void voidTyp = types.NewVoid() // Integer types. // i1 i1Typ, err = types.NewInt(1) if err != nil { log.Fatalln(err) } // i8 i8Typ, err = types.NewInt(8) if err != nil { log.Fatalln(err) } // i32 i32Typ, err = types.NewInt(32) if err != nil { log.Fatalln(err) } // i64 i64Typ, err = types.NewInt(64) if err != nil { log.Fatalln(err) } // Floating point types. // half f16Typ, err = types.NewFloat(types.Float16) if err != nil { log.Fatalln(err) } // float f32Typ, err = types.NewFloat(types.Float32) if err != nil { log.Fatalln(err) } // double f64Typ, err = types.NewFloat(types.Float64) if err != nil { log.Fatalln(err) } // fp128 f128Typ, err = types.NewFloat(types.Float128) if err != nil { log.Fatalln(err) } // x86_fp80 f80_x86Typ, err = types.NewFloat(types.Float80_x86) if err != nil { log.Fatalln(err) } // ppc_fp128 f128_ppcTyp, err = types.NewFloat(types.Float128_PPC) // MMX type. // x86_mmx mmxTyp = types.NewMMX() // Label type. // label labelTyp = types.NewLabel() // Metadata type. // metadata metadataTyp = types.NewMetadata() // Function types. // void () voidFuncTyp, err = types.NewFunc(voidTyp, nil, false) if err != nil { log.Fatalln(err) } // i32 () i32FuncTyp, err = types.NewFunc(i32Typ, nil, false) if err != nil { log.Fatalln(err) } // void (i32) i32Param := types.NewParam(i32Typ, "") i32Params := []*types.Param{i32Param} voidFunci32Typ, err = types.NewFunc(voidTyp, i32Params, false) if err != nil { log.Fatalln(err) } // void (float) f32Param := types.NewParam(f32Typ, "") f32Params := []*types.Param{f32Param} voidFuncf32Typ, err = types.NewFunc(voidTyp, f32Params, false) if err != nil { log.Fatalln(err) } // void (i32, ...) voidFunci32EllipsisTyp, err = types.NewFunc(voidTyp, i32Params, true) if err != nil { log.Fatalln(err) } // i32 (i32) funcTyp, err = types.NewFunc(i32Typ, i32Params, false) if err != nil { log.Fatalln(err) } // Pointer types. // i8* i8PtrTyp, err = types.NewPointer(i8Typ) if err != nil { log.Fatalln(err) } // half* f16PtrTyp, err = types.NewPointer(f16Typ) if err != nil { log.Fatalln(err) } // x86_mmx* mmxPtrTyp, err = types.NewPointer(mmxTyp) if err != nil { log.Fatalln(err) } // i32 (i32)* funcPtrTyp, err = types.NewPointer(funcTyp) if err != nil { log.Fatalln(err) } // Vector types. // <1 x i8> i8x1VecTyp, err = types.NewVector(i8Typ, 1) if err != nil { log.Fatalln(err) } // <2 x i32> i32x2VecTyp, err = types.NewVector(i32Typ, 2) if err != nil { log.Fatalln(err) } // <3 x i32> i32x3VecTyp, err = types.NewVector(i32Typ, 3) if err != nil { log.Fatalln(err) } // <3 x half> f16x3VecTyp, err = types.NewVector(f16Typ, 3) if err != nil { log.Fatalln(err) } // <4 x float> f32x4VecTyp, err = types.NewVector(f32Typ, 4) if err != nil { log.Fatalln(err) } // <5 x double> f64x5VecTyp, err = types.NewVector(f64Typ, 5) if err != nil { log.Fatalln(err) } // <6 x fp128> f128x6VecTyp, err = types.NewVector(f128Typ, 6) if err != nil { log.Fatalln(err) } // <7 x x86_fp80> f80_x86x7VecTyp, err = types.NewVector(f80_x86Typ, 7) if err != nil { log.Fatalln(err) } // <8 x ppc_fp128> f128_ppcx8VecTyp, err = types.NewVector(f128_ppcTyp, 8) if err != nil { log.Fatalln(err) } // <9 x i8*> i8Ptrx9VecTyp, err = types.NewVector(i8PtrTyp, 9) if err != nil { log.Fatalln(err) } // <10 x half*> f16Ptrx10VecTyp, err = types.NewVector(f16PtrTyp, 10) if err != nil { log.Fatalln(err) } // Array types. // [1 x i8] i8x1ArrTyp, err = types.NewArray(i8Typ, 1) if err != nil { log.Fatalln(err) } // [2 x i32] i32x2ArrTyp, err = types.NewArray(i32Typ, 2) if err != nil { log.Fatalln(err) } // [3 x i32] i32x3ArrTyp, err = types.NewArray(i32Typ, 3) if err != nil { log.Fatalln(err) } // [3 x half] f16x3ArrTyp, err = types.NewArray(f16Typ, 3) if err != nil { log.Fatalln(err) } // [4 x float] f32x4ArrTyp, err = types.NewArray(f32Typ, 4) if err != nil { log.Fatalln(err) } // [5 x double] f64x5ArrTyp, err = types.NewArray(f64Typ, 5) if err != nil { log.Fatalln(err) } // [6 x fp128] f128x6ArrTyp, err = types.NewArray(f128Typ, 6) if err != nil { log.Fatalln(err) } // [7 x x86_fp80] f80_x86x7ArrTyp, err = types.NewArray(f80_x86Typ, 7) if err != nil { log.Fatalln(err) } // [8 x ppc_fp128] f128_ppcx8ArrTyp, err = types.NewArray(f128_ppcTyp, 8) if err != nil { log.Fatalln(err) } // [9 x i8*] i8Ptrx9ArrTyp, err = types.NewArray(i8PtrTyp, 9) if err != nil { log.Fatalln(err) } // [10 x half*] f16Ptrx10ArrTyp, err = types.NewArray(f16PtrTyp, 10) if err != nil { log.Fatalln(err) } // Structure types. // {i32, i8} fields := []types.Type{i32Typ, i8Typ} i32i8structTyp, err = types.NewStruct(fields, false) if err != nil { log.Fatalln(err) } // {i32, i32} fields = []types.Type{i32Typ, i32Typ} i32i32structTyp, err = types.NewStruct(fields, false) if err != nil { log.Fatalln(err) } // {i32, i8, i8} fields = []types.Type{i32Typ, i8Typ, i8Typ} i32i8i8structTyp, err = types.NewStruct(fields, false) if err != nil { log.Fatalln(err) } // {i1, float, x86_mmx, i32 (i32)*, <1 x i8>, [3 x half]} fields = []types.Type{i1Typ, f32Typ, mmxTyp, funcPtrTyp, i8x1VecTyp, f16x3ArrTyp} structTyp, err = types.NewStruct(fields, false) if err != nil { log.Fatalln(err) } }