compiler: fix expanding zero-length structs

Этот коммит содержится в:
Ayke van Laethem 2018-09-25 13:44:32 +02:00
родитель d8f0ddf3fa
коммит 174b6333f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
3 изменённых файлов: 119 добавлений и 5 удалений

Просмотреть файл

@ -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, "")

104
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{})
}

9
testdata/structexpand.txt предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,9 @@
test1
test2
test3
test4
test5
test6
test7
test8
test9