compiler: support all kinds of recursive types
Previously we only supported recursive types in structs. But there can be other kinds of recursive types, like slices: type RecursiveSlice []RecursiveSlice This doesn't involve structs, so it led to infinite recursion in the compiler. This fix avoids recursion at the proper level: at the place where the named type is defined.
Этот коммит содержится в:
родитель
c5598630c9
коммит
5b42871baa
3 изменённых файлов: 17 добавлений и 9 удалений
|
@ -569,10 +569,19 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
|
|||
case *types.Map:
|
||||
return c.getDIType(types.NewPointer(c.program.ImportedPackage("runtime").Members["hashmap"].(*ssa.Type).Type()))
|
||||
case *types.Named:
|
||||
return c.dibuilder.CreateTypedef(llvm.DITypedef{
|
||||
// Placeholder metadata node, to be replaced afterwards.
|
||||
temporaryMDNode := c.dibuilder.CreateReplaceableCompositeType(llvm.Metadata{}, llvm.DIReplaceableCompositeType{
|
||||
Tag: dwarf.TagTypedef,
|
||||
SizeInBits: sizeInBytes * 8,
|
||||
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
|
||||
})
|
||||
c.ditypes[typ] = temporaryMDNode
|
||||
md := c.dibuilder.CreateTypedef(llvm.DITypedef{
|
||||
Type: c.getDIType(typ.Underlying()),
|
||||
Name: typ.String(),
|
||||
})
|
||||
temporaryMDNode.ReplaceAllUsesWith(md)
|
||||
return md
|
||||
case *types.Pointer:
|
||||
return c.dibuilder.CreatePointerType(llvm.DIPointerType{
|
||||
Pointee: c.getDIType(typ.Elem()),
|
||||
|
@ -634,13 +643,6 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
|
|||
},
|
||||
})
|
||||
case *types.Struct:
|
||||
// Placeholder metadata node, to be replaced afterwards.
|
||||
temporaryMDNode := c.dibuilder.CreateReplaceableCompositeType(llvm.Metadata{}, llvm.DIReplaceableCompositeType{
|
||||
Tag: dwarf.TagStructType,
|
||||
SizeInBits: sizeInBytes * 8,
|
||||
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
|
||||
})
|
||||
c.ditypes[typ] = temporaryMDNode
|
||||
elements := make([]llvm.Metadata, typ.NumFields())
|
||||
for i := range elements {
|
||||
field := typ.Field(i)
|
||||
|
@ -659,7 +661,6 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
|
|||
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
|
||||
Elements: elements,
|
||||
})
|
||||
temporaryMDNode.ReplaceAllUsesWith(md)
|
||||
return md
|
||||
case *types.TypeParam:
|
||||
return c.getDIType(typ.Underlying())
|
||||
|
|
6
testdata/slice.go
предоставленный
6
testdata/slice.go
предоставленный
|
@ -6,6 +6,8 @@ type MySlice [32]byte
|
|||
|
||||
type myUint8 uint8
|
||||
|
||||
type RecursiveSlice []RecursiveSlice
|
||||
|
||||
// Indexing into slice with named type (regression test).
|
||||
var array = [4]int{
|
||||
myUint8(2): 3,
|
||||
|
@ -160,6 +162,10 @@ func main() {
|
|||
for _, c := range named {
|
||||
assert(c == 0)
|
||||
}
|
||||
|
||||
// Test recursive slices.
|
||||
rs := []RecursiveSlice(nil)
|
||||
println("len:", len(rs))
|
||||
}
|
||||
|
||||
func printslice(name string, s []int) {
|
||||
|
|
1
testdata/slice.txt
предоставленный
1
testdata/slice.txt
предоставленный
|
@ -16,3 +16,4 @@ bytes: len=6 cap=6 data: 1 2 3 102 111 111
|
|||
slice to array pointer: 1 -2 20 4
|
||||
unsafe.Add array: 1 5 8 4
|
||||
unsafe.Slice array: 3 3 9 15 4
|
||||
len: 0
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче