diff --git a/compiler/calls.go b/compiler/calls.go index c64f83e1..76368fe7 100644 --- a/compiler/calls.go +++ b/compiler/calls.go @@ -14,6 +14,7 @@ import ( // {i8*, i32} -> i8*, i32 // {{i8*, i32}, i16} -> i8*, i32, i16 // {{i64}} -> i64 +// {} -> // {i8*, i32, i8, i8} -> {i8*, i32, i8, i8} // Note that all native Go data types that don't exist in LLVM (string, // slice, interface, fat function pointer) can be expanded this way, making @@ -92,8 +93,8 @@ func (c *Compiler) expandFormalParam(v llvm.Value) []llvm.Value { func (c *Compiler) flattenAggregateType(t llvm.Type) []llvm.Type { switch t.TypeKind() { case llvm.StructTypeKind: - fields := make([]llvm.Type, 0, len(t.Subtypes())) - for _, subfield := range t.Subtypes() { + fields := make([]llvm.Type, 0, t.StructElementTypesCount()) + for _, subfield := range t.StructElementTypes() { subfields := c.flattenAggregateType(subfield) fields = append(fields, subfields...) } @@ -108,8 +109,8 @@ func (c *Compiler) flattenAggregateType(t llvm.Type) []llvm.Type { func (c *Compiler) flattenAggregate(v llvm.Value) []llvm.Value { switch v.Type().TypeKind() { case llvm.StructTypeKind: - fields := make([]llvm.Value, 0, len(v.Type().Subtypes())) - for i := range v.Type().Subtypes() { + fields := make([]llvm.Value, 0, v.Type().StructElementTypesCount()) + for i := range v.Type().StructElementTypes() { subfield := c.builder.CreateExtractValue(v, i, "") subfields := c.flattenAggregate(subfield) fields = append(fields, subfields...) @@ -138,7 +139,7 @@ func (c *Compiler) collapseFormalParamInternal(t llvm.Type, fields []llvm.Value) if err != nil { panic("could not get zero value of struct: " + err.Error()) } - for i, subtyp := range t.Subtypes() { + for i, subtyp := range t.StructElementTypes() { structField, remaining := c.collapseFormalParamInternal(subtyp, fields) fields = remaining value = c.builder.CreateInsertValue(value, structField, i, "") diff --git a/testdata/structexpand.go b/testdata/structexpand.go new file mode 100644 index 00000000..66cf0a63 --- /dev/null +++ b/testdata/structexpand.go @@ -0,0 +1,104 @@ +package main + +// TODO: add .ll test files to check the output + +type s0 struct { +} + +type s1 struct { + a byte +} + +type s2 struct { + a byte + b byte +} + +type s3 struct { + a byte + b byte + c byte +} + +// should not be expanded +type s4 struct { + a byte + b byte + c byte + d byte +} + +type s5 struct { + a struct { + aa byte + ab byte + } + b byte +} + +type s6 struct { + a string + b byte +} + +type s7 struct { + a interface{} + b byte +} + +// should not be expanded +type s8 struct { + a []byte // 3 elements + b byte // 1 element +} + +type s9 struct { +} + +func test1(s s1) { + println("test1") +} + +func test2(s s2) { + println("test2") +} + +func test3(s s3) { + println("test3") +} + +func test4(s s4) { + println("test4") +} + +func test5(s s5) { + println("test5") +} + +func test6(s s6) { + println("test6") +} + +func test7(s s7) { + println("test7") +} + +func test8(s s8) { + println("test8") +} + +func test9(s s9) { + println("test9") +} + +func main() { + test1(s1{}) + test2(s2{}) + test3(s3{}) + test4(s4{}) + test5(s5{}) + test6(s6{}) + test7(s7{}) + test8(s8{}) + test9(s9{}) +} diff --git a/testdata/structexpand.txt b/testdata/structexpand.txt new file mode 100644 index 00000000..d9614671 --- /dev/null +++ b/testdata/structexpand.txt @@ -0,0 +1,9 @@ +test1 +test2 +test3 +test4 +test5 +test6 +test7 +test8 +test9