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
This commit is contained in:
Douglas Gregor 2012-01-14 15:55:47 +00:00
parent 9abeca16e5
commit 0bc8a21dba
6 changed files with 82 additions and 67 deletions

View File

@ -461,6 +461,14 @@ public:
return AnonOrFirstNamespaceAndInline.getPointer(); return AnonOrFirstNamespaceAndInline.getPointer();
} }
virtual NamespaceDecl *getPreviousDecl() {
return redeclarable_base::getPreviousDeclaration();
}
virtual NamespaceDecl *getMostRecentDecl() {
return redeclarable_base::getMostRecentDeclaration();
}
virtual SourceRange getSourceRange() const { virtual SourceRange getSourceRange() const {
return SourceRange(LocStart, RBraceLoc); return SourceRange(LocStart, RBraceLoc);
} }
@ -790,6 +798,14 @@ public:
return redeclarable_base::redecls_end(); 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, static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc, SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
@ -1499,6 +1515,14 @@ public:
return redeclarable_base::redecls_end(); 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, static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation NLoc, SourceLocation StartLoc, SourceLocation NLoc,
DeclarationName N, QualType T, DeclarationName N, QualType T,
@ -2281,6 +2305,14 @@ public:
return redeclarable_base::redecls_end(); return redeclarable_base::redecls_end();
} }
virtual TypedefNameDecl *getPreviousDecl() {
return redeclarable_base::getPreviousDeclaration();
}
virtual TypedefNameDecl *getMostRecentDecl() {
return redeclarable_base::getMostRecentDeclaration();
}
TypeSourceInfo *getTypeSourceInfo() const { TypeSourceInfo *getTypeSourceInfo() const {
return TInfo; return TInfo;
} }
@ -2449,6 +2481,14 @@ public:
return redeclarable_base::redecls_end(); return redeclarable_base::redecls_end();
} }
virtual TagDecl *getPreviousDecl() {
return redeclarable_base::getPreviousDeclaration();
}
virtual TagDecl *getMostRecentDecl() {
return redeclarable_base::getMostRecentDeclaration();
}
SourceLocation getRBraceLoc() const { return RBraceLoc; } SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }

View File

@ -716,6 +716,14 @@ public:
} }
redecl_iterator redecls_end() const { return redecl_iterator(); } 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, /// getBody - If this Decl represents a declaration for a body of code,
/// such as a function or method definition, this method returns the /// such as a function or method definition, this method returns the
/// top-level Stmt* of that body. Otherwise this method returns null. /// top-level Stmt* of that body. Otherwise this method returns null.

View File

@ -938,6 +938,14 @@ public:
return redeclarable_base::redecls_end(); 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. /// Retrieves the canonical declaration of this Objective-C class.
ObjCInterfaceDecl *getCanonicalDecl() { ObjCInterfaceDecl *getCanonicalDecl() {
return getFirstDeclaration(); return getFirstDeclaration();
@ -1218,7 +1226,15 @@ public:
redecl_iterator redecls_end() const { redecl_iterator redecls_end() const {
return redeclarable_base::redecls_end(); 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. /// Retrieves the canonical declaration of this Objective-C protocol.
ObjCProtocolDecl *getCanonicalDecl() { ObjCProtocolDecl *getCanonicalDecl() {
return getFirstDeclaration(); return getFirstDeclaration();

View File

@ -630,6 +630,14 @@ public:
return redeclarable_base::redecls_end(); return redeclarable_base::redecls_end();
} }
virtual RedeclarableTemplateDecl *getPreviousDecl() {
return redeclarable_base::getPreviousDeclaration();
}
virtual RedeclarableTemplateDecl *getMostRecentDecl() {
return redeclarable_base::getMostRecentDeclaration();
}
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const RedeclarableTemplateDecl *D) { return true; } static bool classof(const RedeclarableTemplateDecl *D) { return true; }

View File

@ -4489,7 +4489,7 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
/// \brief Determine what kind of template specialization the given declaration /// \brief Determine what kind of template specialization the given declaration
/// is. /// is.
static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) { static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D) {
if (!D) if (!D)
return TSK_Undeclared; return TSK_Undeclared;
@ -4767,23 +4767,6 @@ static bool CheckClassTemplatePartialSpecializationArgs(Sema &S,
return false; return false;
} }
/// \brief Retrieve the previous declaration of the given declaration.
static NamedDecl *getPreviousDecl(NamedDecl *ND) {
if (VarDecl *VD = dyn_cast<VarDecl>(ND))
return VD->getPreviousDeclaration();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
return FD->getPreviousDeclaration();
if (TagDecl *TD = dyn_cast<TagDecl>(ND))
return TD->getPreviousDeclaration();
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND))
return TD->getPreviousDeclaration();
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getPreviousDeclaration();
if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
return CTD->getPreviousDeclaration();
return 0;
}
DeclResult DeclResult
Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TagUseKind TUK, TagUseKind TUK,
@ -5114,7 +5097,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// use occurs; no diagnostic is required. // use occurs; no diagnostic is required.
if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) { if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) {
bool Okay = false; 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? // Is there any previous explicit specialization declaration?
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) {
Okay = true; Okay = true;
@ -5248,13 +5231,13 @@ static void StripImplicitInstantiation(NamedDecl *D) {
/// \brief Compute the diagnostic location for an explicit instantiation /// \brief Compute the diagnostic location for an explicit instantiation
// declaration or definition. // declaration or definition.
static SourceLocation DiagLocForExplicitInstantiation( static SourceLocation DiagLocForExplicitInstantiation(
NamedDecl* Decl, SourceLocation PointOfInstantiation) { NamedDecl* D, SourceLocation PointOfInstantiation) {
// Explicit instantiations following a specialization have no effect and // Explicit instantiations following a specialization have no effect and
// hence no PointOfInstantiation. In that case, walk decl backwards // hence no PointOfInstantiation. In that case, walk decl backwards
// until a valid name loc is found. // until a valid name loc is found.
SourceLocation PrevDiagLoc = PointOfInstantiation; SourceLocation PrevDiagLoc = PointOfInstantiation;
for (NamedDecl *Prev = Decl; Prev && !PrevDiagLoc.isValid(); for (Decl *Prev = D; Prev && !PrevDiagLoc.isValid();
Prev = getPreviousDecl(Prev)) { Prev = Prev->getPreviousDecl()) {
PrevDiagLoc = Prev->getLocation(); PrevDiagLoc = Prev->getLocation();
} }
assert(PrevDiagLoc.isValid() && assert(PrevDiagLoc.isValid() &&
@ -5328,7 +5311,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
// before the first use of that specialization that would cause an // before the first use of that specialization that would cause an
// implicit instantiation to take place, in every translation unit in // implicit instantiation to take place, in every translation unit in
// which such a use occurs; no diagnostic is required. // 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? // Is there any previous explicit specialization declaration?
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization)
return false; return false;
@ -5419,7 +5402,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
// of a template appears after a declaration of an explicit // of a template appears after a declaration of an explicit
// specialization for that template, the explicit instantiation has no // specialization for that template, the explicit instantiation has no
// effect. // effect.
for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) {
// Is there any previous explicit specialization declaration? // Is there any previous explicit specialization declaration?
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) {
HasNoEffect = true; HasNoEffect = true;

View File

@ -2211,46 +2211,6 @@ namespace {
}; };
} }
/// \brief Retrieve the previous declaration to D.
static Decl *getPreviousDecl(Decl *D) {
if (TagDecl *TD = dyn_cast<TagDecl>(D))
return TD->getPreviousDeclaration();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return FD->getPreviousDeclaration();
if (VarDecl *VD = dyn_cast<VarDecl>(D))
return VD->getPreviousDeclaration();
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
return TD->getPreviousDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getPreviousDeclaration();
if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
return PD->getPreviousDeclaration();
if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D))
return ND->getPreviousDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getPreviousDeclaration();
}
/// \brief Retrieve the most recent declaration of D.
static Decl *getMostRecentDecl(Decl *D) {
if (TagDecl *TD = dyn_cast<TagDecl>(D))
return TD->getMostRecentDeclaration();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return FD->getMostRecentDeclaration();
if (VarDecl *VD = dyn_cast<VarDecl>(D))
return VD->getMostRecentDeclaration();
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
return TD->getMostRecentDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getMostRecentDeclaration();
if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
return PD->getMostRecentDeclaration();
if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D))
return ND->getMostRecentDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getMostRecentDeclaration();
}
void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
Decl *D = GetDecl(ID); Decl *D = GetDecl(ID);
Decl *CanonDecl = D->getCanonicalDecl(); Decl *CanonDecl = D->getCanonicalDecl();
@ -2276,11 +2236,11 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
return; return;
// Capture all of the parsed declarations and put them at the end. // Capture all of the parsed declarations and put them at the end.
Decl *MostRecent = getMostRecentDecl(CanonDecl); Decl *MostRecent = CanonDecl->getMostRecentDecl();
Decl *FirstParsed = MostRecent; Decl *FirstParsed = MostRecent;
if (CanonDecl != MostRecent && !MostRecent->isFromASTFile()) { if (CanonDecl != MostRecent && !MostRecent->isFromASTFile()) {
Decl *Current = MostRecent; Decl *Current = MostRecent;
while (Decl *Prev = getPreviousDecl(Current)) { while (Decl *Prev = Current->getPreviousDecl()) {
if (Prev == CanonDecl) if (Prev == CanonDecl)
break; break;