CXXRecordDecl and RecordDecl:

- Change constructor and create methods to accept a CXXRecordDecl* (RecordDecl*)
  instead of a ScopedDecl* for PrevDecl.  This causes the type checking
  to be more tight and doesn't break any code.
  
RecordDecl:

- Don't use the NextDeclarator field in ScopedDecl to represent the previous
  declaration. This is a conflated use of the NextDeclarator field, which will
  be removed anyway when DeclGroups are fully implemented.

- Instead, represent (a soon to be implemented) chain of RecordDecls using a
  NextDecl field.  The last RecordDecl in the chain is always the 'defining'
  RecordDecl that owns the FieldDecls.  The other RecordDecls in the chain
  are forward declarations.

llvm-svn: 55640
This commit is contained in:
Ted Kremenek
2008-09-02 20:13:32 +00:00
parent c84e8b779e
commit 123f025b29
4 changed files with 51 additions and 17 deletions

View File

@@ -796,25 +796,28 @@ class RecordDecl : public TagDecl {
/// If so, this cannot be contained in arrays or other structs as a member.
bool HasFlexibleArrayMember : 1;
/// NextDecl - A pointer to the next RecordDecl in a chain of RecordDecls
/// for the same struct/union. By construction, the last RecordDecl in
/// the chain is the one that provides the definition of the struct/union
/// (i.e., all forward declarations appear first in the chain). Note that
/// one should make no other assumption about the order of the RecordDecl's
/// within this chain with respect to the original source.
RecordDecl* NextDecl;
/// Members/NumMembers - This is a new[]'d array of pointers to Decls.
FieldDecl **Members; // Null if not defined.
int NumMembers; // -1 if not defined.
protected:
RecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) : TagDecl(DK, DC, L, Id, PrevDecl) {
HasFlexibleArrayMember = false;
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
Members = 0;
NumMembers = -1;
}
RecordDecl *PrevDecl);
virtual ~RecordDecl();
public:
static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl);
RecordDecl *PrevDecl);
virtual void Destroy(ASTContext& C);

View File

@@ -44,14 +44,14 @@ public:
class CXXRecordDecl : public RecordDecl, public DeclContext {
protected:
CXXRecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) : RecordDecl(DK, DC, L, Id, PrevDecl),
CXXRecordDecl *PrevDecl) : RecordDecl(DK, DC, L, Id, PrevDecl),
DeclContext(DK) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
}
public:
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl);
SourceLocation L, IdentifierInfo *Id,
CXXRecordDecl *PrevDecl);
const CXXFieldDecl *getMember(unsigned i) const {
return cast<const CXXFieldDecl>(RecordDecl::getMember(i));

View File

@@ -109,9 +109,45 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
return new (Mem) EnumDecl(DC, L, Id, PrevDecl);
}
void EnumDecl::Destroy(ASTContext& C) {
if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
Decl::Destroy(C);
}
//==------------------------------------------------------------------------==//
// RecordDecl methods.
//==------------------------------------------------------------------------==//
RecordDecl::RecordDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, RecordDecl *PrevDecl)
: TagDecl(DK, DC, L, Id, 0), NextDecl(0) {
HasFlexibleArrayMember = false;
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
Members = 0;
NumMembers = -1;
// Hook up the RecordDecl chain.
if (PrevDecl) {
RecordDecl* Tmp = PrevDecl->NextDecl;
// 'Tmp' might be non-NULL if it is the RecordDecl that provides the
// definition of the struct/union. By construction, the last RecordDecl
// in the chain is the 'defining' RecordDecl.
if (Tmp) {
assert (Tmp->NextDecl == 0);
assert (Tmp->Members && "Previous RecordDecl has a NextDecl that is "
"not the 'defining' RecordDecl");
NextDecl = Tmp;
}
PrevDecl->NextDecl = this;
}
}
RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
RecordDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<RecordDecl>();
Kind DK;
switch (TK) {
@@ -124,11 +160,6 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
return new (Mem) RecordDecl(DK, DC, L, Id, PrevDecl);
}
void EnumDecl::Destroy(ASTContext& C) {
if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
Decl::Destroy(C);
}
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
SourceLocation L,

View File

@@ -28,7 +28,7 @@ CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
CXXRecordDecl *PrevDecl) {
Kind DK;
switch (TK) {
default: assert(0 && "Invalid TagKind!");