mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-13 07:23:39 +00:00
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.
This commit is contained in:
committed by
Ron Evans
parent
c5598630c9
commit
5b42871baa
+10
-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())
|
||||
|
||||
Reference in New Issue
Block a user