[cfe-commits] r43268 - in /cfe/trunk: CodeGen/CodeGenTypes.cpp CodeGen/CodeGenTypes.h test/CodeGen/struct.c
Devang Patel
dpatel at apple.com
Tue Oct 23 16:26:47 PDT 2007
Author: dpatel
Date: Tue Oct 23 18:26:46 2007
New Revision: 43268
URL: http://llvm.org/viewvc/llvm-project?rev=43268&view=rev
Log:
Handle nested structs.
typdef struct A { int i; struct A *next; } A
Modified:
cfe/trunk/CodeGen/CodeGenTypes.cpp
cfe/trunk/CodeGen/CodeGenTypes.h
cfe/trunk/test/CodeGen/struct.c
Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=43268&r1=43267&r2=43268&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Tue Oct 23 18:26:46 2007
@@ -167,13 +167,36 @@
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);
Modified: cfe/trunk/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.h?rev=43268&r1=43267&r2=43268&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.h Tue Oct 23 18:26:46 2007
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <vector>
namespace llvm {
@@ -29,7 +30,8 @@
class TargetInfo;
class QualType;
class FunctionTypeProto;
- class FieldDecl;
+ class FieldDecl;
+ class RecordDecl;
namespace CodeGen {
class CodeGenTypes;
@@ -98,6 +100,11 @@
/// field no. This info is populated by record organizer.
llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
+ /// RecordTypesToResolve - This keeps track of record types that are not
+ /// yet incomplete. One llvm::OpaqueType is associated with each incomplete
+ /// record.
+ llvm::DenseMap<const RecordDecl *, llvm::Type *> RecordTypesToResolve;
+
public:
CodeGenTypes(ASTContext &Ctx, llvm::Module &M);
~CodeGenTypes();
Modified: cfe/trunk/test/CodeGen/struct.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/struct.c?rev=43268&r1=43267&r2=43268&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/struct.c (original)
+++ cfe/trunk/test/CodeGen/struct.c Tue Oct 23 18:26:46 2007
@@ -37,3 +37,21 @@
else
return 0;
}
+
+/* Nested structs */
+typedef struct NA {
+ int data;
+ struct NA *next;
+} NA;
+void f1() { A a; }
+
+typedef struct NB {
+ int d1;
+ struct _B2 {
+ int d2;
+ struct NB *n2;
+ } B2;
+} NB;
+
+void f2() { NB b; }
+
More information about the cfe-commits
mailing list