From: Argyrios Kyrtzidis Date: Tue, 10 Jun 2008 01:32:09 +0000 (+0000) Subject: -Add DeclChain member to DeclContext. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7643536c36b0449256d5ee2efc03a7e4a784a0b3;p=clang -Add DeclChain member to DeclContext. -ScopedDecls get chained to their DeclContext. -DeclContext's DeclChain replaces FunctionDecl's DeclChain and EnumDecl's ElementList. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52164 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 3e865f94c9..8b355e9f22 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -379,10 +379,6 @@ private: Stmt *Body; // Null if a prototype. - /// DeclChain - Linked list of declarations that are defined inside this - /// function. - ScopedDecl *DeclChain; - /// PreviousDeclaration - A link to the previous declaration of this /// same function, NULL if this is the first declaration. For /// example, in the following code, the PreviousDeclaration can be @@ -405,7 +401,7 @@ protected: StorageClass S, bool isInline, ScopedDecl *PrevDecl) : ValueDecl(DK, DC, L, Id, T, PrevDecl), DeclContext(DK), - ParamInfo(0), Body(0), DeclChain(0), PreviousDeclaration(0), + ParamInfo(0), Body(0), PreviousDeclaration(0), SClass(S), IsInline(isInline), IsImplicit(0) {} virtual ~FunctionDecl(); @@ -438,9 +434,6 @@ public: bool isImplicit() { return IsImplicit; } void setImplicit() { IsImplicit = true; } - - ScopedDecl *getDeclChain() const { return DeclChain; } - void setDeclChain(ScopedDecl *D) { DeclChain = D; } /// getPreviousDeclaration - Return the previous declaration of this /// function. @@ -720,10 +713,9 @@ protected: /// EnumDecl - Represents an enum. As an extension, we allow forward-declared /// enums. class EnumDecl : public TagDecl, public DeclContext { - /// ElementList - this is a linked list of EnumConstantDecl's which are linked - /// together through their getNextDeclarator pointers. - EnumConstantDecl *ElementList; - + // EnumDecl's DeclChain points to a linked list of EnumConstantDecl's which + // are linked together through their getNextDeclarator pointers. + /// IntegerType - This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. @@ -732,7 +724,6 @@ class EnumDecl : public TagDecl, public DeclContext { EnumDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) : TagDecl(Enum, DC, L, Id, PrevDecl), DeclContext(Enum) { - ElementList = 0; IntegerType = QualType(); } public: @@ -747,7 +738,7 @@ public: /// specified list of enums. void defineElements(EnumConstantDecl *ListHead, QualType NewType) { assert(!isDefinition() && "Cannot redefine enums!"); - ElementList = ListHead; + setDeclChain(ListHead); setDefinition(true); IntegerType = NewType; @@ -759,8 +750,12 @@ public: /// getEnumConstantList - Return the first EnumConstantDecl in the enum. /// - EnumConstantDecl *getEnumConstantList() { return ElementList; } - const EnumConstantDecl *getEnumConstantList() const { return ElementList; } + EnumConstantDecl *getEnumConstantList() { + return cast_or_null(getDeclChain()); + } + const EnumConstantDecl *getEnumConstantList() const { + return cast_or_null(getDeclChain()); + } static bool classof(const Decl *D) { return D->getKind() == Enum; } static bool classof(const EnumDecl *D) { return true; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 4bc2cc95a3..60387b1ad4 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -237,6 +237,10 @@ class DeclContext { /// DeclKind - This indicates which class this is. Decl::Kind DeclKind : 8; + /// DeclChain - Linked list of declarations that are defined inside this + /// declaration context. + ScopedDecl *DeclChain; + // Used in the CastTo template to get the DeclKind // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method // to avoid 'ambiguous access' compiler errors. @@ -271,7 +275,7 @@ class DeclContext { } protected: - DeclContext(Decl::Kind K) : DeclKind(K) {} + DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {} public: /// getParent - Returns the containing DeclContext if this is a ScopedDecl, @@ -289,6 +293,9 @@ public: } } + ScopedDecl *getDeclChain() const { return DeclChain; } + void setDeclChain(ScopedDecl *D) { DeclChain = D; } + /// ToDecl and FromDecl make Decl <-> DeclContext castings. /// They are intended to be used by the simplify_type and cast_convert_val /// templates. @@ -321,6 +328,12 @@ public: static bool classof(const EnumDecl *D) { return true; } static bool classof(const ObjCMethodDecl *D) { return true; } static bool classof(const ObjCInterfaceDecl *D) { return true; } + +private: + void EmitOutRec(llvm::Serializer& S) const; + void ReadOutRec(llvm::Deserializer& D, ASTContext& C); + + friend class Decl; }; template<> struct DeclContext::KindTrait { diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 47334f53cc..949d10072e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -116,7 +116,7 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, } void EnumDecl::Destroy(ASTContext& C) { - if (ElementList) ElementList->Destroy(C); + if (getEnumConstantList()) getEnumConstantList()->Destroy(C); Decl::Destroy(C); } diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index ca9a15224f..2ba891005a 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -30,10 +30,13 @@ using namespace clang; void Decl::Emit(Serializer& S) const { S.EmitInt(getKind()); EmitImpl(S); + if (const DeclContext *DC = dyn_cast(this)) + DC->EmitOutRec(S); } Decl* Decl::Create(Deserializer& D, ASTContext& C) { + Decl *Dcl; Kind k = static_cast(D.ReadInt()); switch (k) { @@ -42,39 +45,56 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) { break; case TranslationUnit: - return TranslationUnitDecl::CreateImpl(D, C); + Dcl = TranslationUnitDecl::CreateImpl(D, C); + break; case Namespace: - return NamespaceDecl::CreateImpl(D, C); + Dcl = NamespaceDecl::CreateImpl(D, C); + break; case Var: - return VarDecl::CreateImpl(D, C); + Dcl = VarDecl::CreateImpl(D, C); + break; case Enum: - return EnumDecl::CreateImpl(D, C); + Dcl = EnumDecl::CreateImpl(D, C); + break; case EnumConstant: - return EnumConstantDecl::CreateImpl(D, C); + Dcl = EnumConstantDecl::CreateImpl(D, C); + break; case Field: - return FieldDecl::CreateImpl(D, C); + Dcl = FieldDecl::CreateImpl(D, C); + break; case ParmVar: - return ParmVarDecl::CreateImpl(D, C); + Dcl = ParmVarDecl::CreateImpl(D, C); + break; case Function: - return FunctionDecl::CreateImpl(D, C); - + Dcl = FunctionDecl::CreateImpl(D, C); + break; + + case Class: case Union: case Struct: - return RecordDecl::CreateImpl(k, D, C); + Dcl = RecordDecl::CreateImpl(k, D, C); + break; case Typedef: - return TypedefDecl::CreateImpl(D, C); + Dcl = TypedefDecl::CreateImpl(D, C); + break; case FileScopeAsm: - return FileScopeAsmDecl::CreateImpl(D, C); + Dcl = FileScopeAsmDecl::CreateImpl(D, C); + break; } + + if (DeclContext *DC = dyn_cast(Dcl)) + DC->ReadOutRec(D, C); + + return Dcl; } //===----------------------------------------------------------------------===// @@ -89,6 +109,18 @@ void Decl::ReadInRec(Deserializer& D, ASTContext& C) { Loc = SourceLocation::ReadVal(D); // From Decl. } +//===----------------------------------------------------------------------===// +// Common serialization logic for subclasses of DeclContext. +//===----------------------------------------------------------------------===// + +void DeclContext::EmitOutRec(Serializer& S) const { + S.EmitPtr(DeclChain); +} + +void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) { + D.ReadPtr(DeclChain); +} + //===----------------------------------------------------------------------===// // Common serialization logic for subclasses of NamedDecl. //===----------------------------------------------------------------------===// @@ -283,7 +315,7 @@ void EnumDecl::EmitImpl(Serializer& S) const { ScopedDecl::EmitInRec(S); S.EmitBool(isDefinition()); S.Emit(IntegerType); - S.BatchEmitOwnedPtrs(ElementList,getNextDeclarator()); + S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator()); } EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) { @@ -299,7 +331,7 @@ EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) { D.BatchReadOwnedPtrs(Elist, next_declarator, C); - decl->ElementList = cast_or_null(Elist); + decl->setDeclChain(cast_or_null(Elist)); decl->setNextDeclarator(cast_or_null(next_declarator)); return decl; @@ -361,7 +393,6 @@ void FunctionDecl::EmitImpl(Serializer& S) const { S.EmitInt(SClass); // From FunctionDecl. S.EmitBool(IsInline); // From FunctionDecl. ValueDecl::EmitInRec(S); - S.EmitPtr(DeclChain); S.EmitPtr(PreviousDeclaration); // NOTE: We do not need to serialize out the number of parameters, because @@ -388,7 +419,6 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { QualType(), SClass, IsInline, 0); decl->ValueDecl::ReadInRec(D, C); - D.ReadPtr(decl->DeclChain); D.ReadPtr(decl->PreviousDeclaration); Decl* next_declarator; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ba005b2c60..2d6422fb00 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -17,6 +17,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Builtins.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/Parse/DeclSpec.h" @@ -90,34 +91,27 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (S->decl_empty()) return; assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!"); - // We only want to remove the decls from the identifier decl chains for local - // scopes, when inside a function/method. - if (S->getFnParent() == 0) - return; - for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end(); I != E; ++I) { Decl *TmpD = static_cast(*I); assert(TmpD && "This decl didn't get pushed??"); - ScopedDecl *D = dyn_cast(TmpD); - assert(D && "This decl isn't a ScopedDecl?"); + + if (isa(TmpD)) continue; + + assert(isa(TmpD) && "Decl isn't ScopedDecl?"); + ScopedDecl *D = cast(TmpD); IdentifierInfo *II = D->getIdentifier(); if (!II) continue; - // Unlink this decl from the identifier. - IdResolver.RemoveDecl(D); - - // This will have to be revisited for C++: there we want to nest stuff in - // namespace decls etc. Even for C, we might want a top-level translation - // unit decl or something. - if (!CurFunctionDecl) - continue; - - // Chain this decl to the containing function, it now owns the memory for - // the decl. - D->setNext(CurFunctionDecl->getDeclChain()); - CurFunctionDecl->setDeclChain(D); + // We only want to remove the decls from the identifier decl chains for local + // scopes, when inside a function/method. + if (S->getFnParent() != 0) + IdResolver.RemoveDecl(D); + + // Chain this decl to the containing DeclContext. + D->setNext(CurContext->getDeclChain()); + CurContext->setDeclChain(D); } }