compiler: fix expanding zero-length structs
Этот коммит содержится в:
родитель
d8f0ddf3fa
коммит
174b6333f8
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
предоставленный
Обычный файл
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
предоставленный
Обычный файл
9
testdata/structexpand.txt
предоставленный
Обычный файл
|
@ -0,0 +1,9 @@
|
|||
test1
|
||||
test2
|
||||
test3
|
||||
test4
|
||||
test5
|
||||
test6
|
||||
test7
|
||||
test8
|
||||
test9
|
Загрузка…
Создание таблицы
Сослаться в новой задаче