From 0bc8a21dba8731f186ee78607a5876c220f620e3 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 14 Jan 2012 15:55:47 +0000 Subject: [PATCH] Introduce Decl::getPreviousDecl() and Decl::getMostRecentDecl(), virtual functions that provide previous/most recent redeclaration information for any declaration. Use this to eliminate the redundant, less efficient getPreviousDecl() functions. llvm-svn: 148184 --- clang/include/clang/AST/Decl.h | 40 +++++++++++++++++++++ clang/include/clang/AST/DeclBase.h | 8 +++++ clang/include/clang/AST/DeclObjC.h | 18 +++++++++- clang/include/clang/AST/DeclTemplate.h | 8 +++++ clang/lib/Sema/SemaTemplate.cpp | 31 ++++------------ clang/lib/Serialization/ASTReaderDecl.cpp | 44 ++--------------------- 6 files changed, 82 insertions(+), 67 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a5e5fcd39be3..c85894d96fbb 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -461,6 +461,14 @@ public: return AnonOrFirstNamespaceAndInline.getPointer(); } + virtual NamespaceDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual NamespaceDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + virtual SourceRange getSourceRange() const { return SourceRange(LocStart, RBraceLoc); } @@ -790,6 +798,14 @@ public: return redeclarable_base::redecls_end(); } + virtual VarDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual VarDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, @@ -1499,6 +1515,14 @@ public: return redeclarable_base::redecls_end(); } + virtual FunctionDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual FunctionDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, @@ -2281,6 +2305,14 @@ public: return redeclarable_base::redecls_end(); } + virtual TypedefNameDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual TypedefNameDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + TypeSourceInfo *getTypeSourceInfo() const { return TInfo; } @@ -2449,6 +2481,14 @@ public: return redeclarable_base::redecls_end(); } + virtual TagDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual TagDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 2964d8cf0acb..210511e0dec4 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -716,6 +716,14 @@ public: } redecl_iterator redecls_end() const { return redecl_iterator(); } + /// \brief Retrieve the previous declaration that declares the same entity + /// as this declaration, or NULL if there is no previous declaration. + virtual Decl *getPreviousDecl() { return 0; } + + /// \brief Retrieve the most recent declaration that declares the same entity + /// as this declaration (which may be this declaration). + virtual Decl *getMostRecentDecl() { return this; } + /// getBody - If this Decl represents a declaration for a body of code, /// such as a function or method definition, this method returns the /// top-level Stmt* of that body. Otherwise this method returns null. diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index e2063cfc43d3..a8a5c06deaac 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -938,6 +938,14 @@ public: return redeclarable_base::redecls_end(); } + virtual ObjCInterfaceDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual ObjCInterfaceDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + /// Retrieves the canonical declaration of this Objective-C class. ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDeclaration(); @@ -1218,7 +1226,15 @@ public: redecl_iterator redecls_end() const { return redeclarable_base::redecls_end(); } - + + virtual ObjCProtocolDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual ObjCProtocolDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + /// Retrieves the canonical declaration of this Objective-C protocol. ObjCProtocolDecl *getCanonicalDecl() { return getFirstDeclaration(); diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index c5fa5d308f79..d0e76ecb09b7 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -630,6 +630,14 @@ public: return redeclarable_base::redecls_end(); } + virtual RedeclarableTemplateDecl *getPreviousDecl() { + return redeclarable_base::getPreviousDeclaration(); + } + + virtual RedeclarableTemplateDecl *getMostRecentDecl() { + return redeclarable_base::getMostRecentDeclaration(); + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const RedeclarableTemplateDecl *D) { return true; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d8aab823f79f..f190b31a0ea0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4489,7 +4489,7 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) { /// \brief Determine what kind of template specialization the given declaration /// is. -static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) { +static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D) { if (!D) return TSK_Undeclared; @@ -4767,23 +4767,6 @@ static bool CheckClassTemplatePartialSpecializationArgs(Sema &S, return false; } -/// \brief Retrieve the previous declaration of the given declaration. -static NamedDecl *getPreviousDecl(NamedDecl *ND) { - if (VarDecl *VD = dyn_cast(ND)) - return VD->getPreviousDeclaration(); - if (FunctionDecl *FD = dyn_cast(ND)) - return FD->getPreviousDeclaration(); - if (TagDecl *TD = dyn_cast(ND)) - return TD->getPreviousDeclaration(); - if (TypedefNameDecl *TD = dyn_cast(ND)) - return TD->getPreviousDeclaration(); - if (FunctionTemplateDecl *FTD = dyn_cast(ND)) - return FTD->getPreviousDeclaration(); - if (ClassTemplateDecl *CTD = dyn_cast(ND)) - return CTD->getPreviousDeclaration(); - return 0; -} - DeclResult Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, @@ -5114,7 +5097,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // use occurs; no diagnostic is required. if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) { bool Okay = false; - for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { // Is there any previous explicit specialization declaration? if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { Okay = true; @@ -5248,13 +5231,13 @@ static void StripImplicitInstantiation(NamedDecl *D) { /// \brief Compute the diagnostic location for an explicit instantiation // declaration or definition. static SourceLocation DiagLocForExplicitInstantiation( - NamedDecl* Decl, SourceLocation PointOfInstantiation) { + NamedDecl* D, SourceLocation PointOfInstantiation) { // Explicit instantiations following a specialization have no effect and // hence no PointOfInstantiation. In that case, walk decl backwards // until a valid name loc is found. SourceLocation PrevDiagLoc = PointOfInstantiation; - for (NamedDecl *Prev = Decl; Prev && !PrevDiagLoc.isValid(); - Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = D; Prev && !PrevDiagLoc.isValid(); + Prev = Prev->getPreviousDecl()) { PrevDiagLoc = Prev->getLocation(); } assert(PrevDiagLoc.isValid() && @@ -5328,7 +5311,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // before the first use of that specialization that would cause an // implicit instantiation to take place, in every translation unit in // which such a use occurs; no diagnostic is required. - for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { // Is there any previous explicit specialization declaration? if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) return false; @@ -5419,7 +5402,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // of a template appears after a declaration of an explicit // specialization for that template, the explicit instantiation has no // effect. - for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { // Is there any previous explicit specialization declaration? if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { HasNoEffect = true; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 21a0fb06a9c3..94c3ef0a58de 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2211,46 +2211,6 @@ namespace { }; } -/// \brief Retrieve the previous declaration to D. -static Decl *getPreviousDecl(Decl *D) { - if (TagDecl *TD = dyn_cast(D)) - return TD->getPreviousDeclaration(); - if (FunctionDecl *FD = dyn_cast(D)) - return FD->getPreviousDeclaration(); - if (VarDecl *VD = dyn_cast(D)) - return VD->getPreviousDeclaration(); - if (TypedefNameDecl *TD = dyn_cast(D)) - return TD->getPreviousDeclaration(); - if (ObjCInterfaceDecl *ID = dyn_cast(D)) - return ID->getPreviousDeclaration(); - if (ObjCProtocolDecl *PD = dyn_cast(D)) - return PD->getPreviousDeclaration(); - if (NamespaceDecl *ND = dyn_cast(D)) - return ND->getPreviousDeclaration(); - - return cast(D)->getPreviousDeclaration(); -} - -/// \brief Retrieve the most recent declaration of D. -static Decl *getMostRecentDecl(Decl *D) { - if (TagDecl *TD = dyn_cast(D)) - return TD->getMostRecentDeclaration(); - if (FunctionDecl *FD = dyn_cast(D)) - return FD->getMostRecentDeclaration(); - if (VarDecl *VD = dyn_cast(D)) - return VD->getMostRecentDeclaration(); - if (TypedefNameDecl *TD = dyn_cast(D)) - return TD->getMostRecentDeclaration(); - if (ObjCInterfaceDecl *ID = dyn_cast(D)) - return ID->getMostRecentDeclaration(); - if (ObjCProtocolDecl *PD = dyn_cast(D)) - return PD->getMostRecentDeclaration(); - if (NamespaceDecl *ND = dyn_cast(D)) - return ND->getMostRecentDeclaration(); - - return cast(D)->getMostRecentDeclaration(); -} - void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { Decl *D = GetDecl(ID); Decl *CanonDecl = D->getCanonicalDecl(); @@ -2276,11 +2236,11 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { return; // Capture all of the parsed declarations and put them at the end. - Decl *MostRecent = getMostRecentDecl(CanonDecl); + Decl *MostRecent = CanonDecl->getMostRecentDecl(); Decl *FirstParsed = MostRecent; if (CanonDecl != MostRecent && !MostRecent->isFromASTFile()) { Decl *Current = MostRecent; - while (Decl *Prev = getPreviousDecl(Current)) { + while (Decl *Prev = Current->getPreviousDecl()) { if (Prev == CanonDecl) break;