]> granicus.if.org Git - clang/commitdiff
During name lookup, use redecl_iterator to walk over the redeclaration
authorDouglas Gregor <dgregor@apple.com>
Fri, 6 Jan 2012 22:05:37 +0000 (22:05 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 6 Jan 2012 22:05:37 +0000 (22:05 +0000)
chain to determine whether any declaration of the given entity is
visible, eliminating the redundant (and less efficient)
getPreviousDeclaration() implementation.

This tweak uncovered an omission in the handling of
RedeclarableTemplateDecl, where we weren't making sure to search for
additional redeclarations of a template in other module files. Things
would be cleaner if RedeclarableTemplateDecl actually used Redeclarable.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147687 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp
lib/Serialization/ASTReaderDecl.cpp

index 7ee50e3a4c1517b603308da07c83673c85dcdb04..984184b9c9844eefc38245d76523f44e41253537 100644 (file)
@@ -1053,26 +1053,6 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
   return !R.empty();
 }
 
-/// \brief Retrieve the previous declaration of D.
-static NamedDecl *getPreviousDeclaration(NamedDecl *D) {
-  if (TagDecl *TD = dyn_cast<TagDecl>(D))
-    return TD->getPreviousDeclaration();
-  if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->getPreviousDeclaration();
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    return FD->getPreviousDeclaration();
-  if (RedeclarableTemplateDecl *RTD = dyn_cast<RedeclarableTemplateDecl>(D))
-    return RTD->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();
-  
-  return 0;
-}
-
 /// \brief Retrieve the visible declaration corresponding to D, if any.
 ///
 /// This routine determines whether the declaration D is visible in the current
@@ -1085,9 +1065,12 @@ static NamedDecl *getVisibleDecl(NamedDecl *D) {
   if (LookupResult::isVisible(D))
     return D;
   
-  while ((D = getPreviousDeclaration(D))) {
-    if (LookupResult::isVisible(D))
-      return D;
+  for (Decl::redecl_iterator RD = D->redecls_begin(), RDEnd = D->redecls_end();
+       RD != RDEnd; ++RD) {
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(*RD)) {
+      if (LookupResult::isVisible(ND))
+        return ND;
+    }
   }
   
   return 0;
index 51a275ad070375410403e7e6bb7362b04f078297..24ac976c108622b58bd22cf8032e9e4a30e9155b 100644 (file)
@@ -255,7 +255,7 @@ namespace clang {
     void VisitParmVarDecl(ParmVarDecl *PD);
     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
     void VisitTemplateDecl(TemplateDecl *D);
-    void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
+    RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
     void VisitClassTemplateDecl(ClassTemplateDecl *D);
     void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
@@ -1219,7 +1219,8 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
   D->init(TemplatedDecl, TemplateParams);
 }
 
-void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
+ASTDeclReader::RedeclarableResult 
+ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
   // can be used while this is still initializing.
   enum RedeclKind { FirstDeclaration, FirstInFile, PointsToPrevious };
@@ -1278,6 +1279,8 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   
   VisitTemplateDecl(D);
   D->IdentifierNamespace = Record[Idx++];
+  
+  return RedeclarableResult(Reader, FirstDeclID);
 }
 
 void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {