From df91eca19bd9738abd9a3b84791f39750e27ad36 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 2 Sep 2008 20:13:32 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55640 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Decl.h | 17 +++++++++------ include/clang/AST/DeclCXX.h | 6 +++--- lib/AST/Decl.cpp | 43 +++++++++++++++++++++++++++++++------ lib/AST/DeclCXX.cpp | 2 +- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 973c6a76a9..eda74f399f 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -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(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); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 10ff6feec8..a4f522eaf5 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -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(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(RecordDecl::getMember(i)); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 3cc12c9a86..c2ae5d91ab 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -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(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(); 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, diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 56ff76680f..2fe69fced5 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -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!"); -- 2.40.0