summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CodeGenTypes.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-10-23 23:26:46 +0000
committerDevang Patel <dpatel@apple.com>2007-10-23 23:26:46 +0000
commit65c4afb9409441223ef2a78741025b30b1a3a38a (patch)
tree21679e2bbad1f614f25f22e17e7339fbf8a4992d /clang/CodeGen/CodeGenTypes.cpp
parent10f41524717d13f4c476da7cb2012fe008b37e1e (diff)
downloadbcm5719-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.cpp23
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);
OpenPOWER on IntegriCloud