diff options
author | Devang Patel <dpatel@apple.com> | 2007-10-23 23:26:46 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2007-10-23 23:26:46 +0000 |
commit | b1e3989731b69e692f9fa2ad080406850c772b40 (patch) | |
tree | 5ceb724fb6fa10fc14e015a766b7e748250ed4ed /CodeGen/CodeGenTypes.cpp | |
parent | c637e6b7afeebc6b4f751e4373715b6a8ea77272 (diff) |
Handle nested structs.
typdef struct A { int i; struct A *next; } A
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43268 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CodeGenTypes.cpp')
-rw-r--r-- | CodeGen/CodeGenTypes.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 35ed348a7b..626ebf96a8 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -167,13 +167,36 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { return ConvertType(cast<EnumDecl>(TD)->getIntegerType()); } else if (TD->getKind() == Decl::Struct) { const RecordDecl *RD = cast<const RecordDecl>(TD); + + // If this is nested record and this RecordDecl is already under + // process then return associated OpaqueType for now. + llvm::DenseMap<const RecordDecl *, llvm::Type *>::iterator + OpaqueI = RecordTypesToResolve.find(RD); + if (OpaqueI != RecordTypesToResolve.end()) + return OpaqueI->second; + + // Create new OpaqueType now for later use. + llvm::OpaqueType *OpaqueTy = llvm::OpaqueType::get(); + RecordTypesToResolve[RD] = OpaqueTy; + + // Layout fields. RecordOrganizer *RO = new RecordOrganizer(); for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) RO->addField(RD->getMember(i)); RO->layoutFields(*this); + + // Get llvm::StructType. RecordLayoutInfo *RLI = new RecordLayoutInfo(RO); ResultType = RLI->getLLVMType(); RecordLayouts[ResultType] = RLI; + + // Refine any OpaqueType associated with this RecordDecl. + OpaqueTy->refineAbstractTypeTo(ResultType); + OpaqueI = RecordTypesToResolve.find(RD); + assert (OpaqueI != RecordTypesToResolve.end() + && "Expected RecordDecl in RecordTypesToResolve"); + RecordTypesToResolve.erase(OpaqueI); + delete RO; } else if (TD->getKind() == Decl::Union) { const RecordDecl *RD = cast<const RecordDecl>(TD); |