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 | 65c4afb9409441223ef2a78741025b30b1a3a38a (patch) | |
tree | 21679e2bbad1f614f25f22e17e7339fbf8a4992d /clang/CodeGen/CodeGenTypes.cpp | |
parent | 10f41524717d13f4c476da7cb2012fe008b37e1e (diff) | |
download | bcm5719-llvm-65c4afb9409441223ef2a78741025b30b1a3a38a.tar.gz bcm5719-llvm-65c4afb9409441223ef2a78741025b30b1a3a38a.zip |
Handle nested structs.
typdef struct A { int i; struct A *next; } A
llvm-svn: 43268
Diffstat (limited to 'clang/CodeGen/CodeGenTypes.cpp')
-rw-r--r-- | clang/CodeGen/CodeGenTypes.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/CodeGen/CodeGenTypes.cpp b/clang/CodeGen/CodeGenTypes.cpp index 35ed348a7b2..626ebf96a89 100644 --- a/clang/CodeGen/CodeGenTypes.cpp +++ b/clang/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); |