[cfe-commits] r147450 - /cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 3 09:27:13 PST 2012


Author: dgregor
Date: Tue Jan  3 11:27:13 2012
New Revision: 147450

URL: http://llvm.org/viewvc/llvm-project?rev=147450&view=rev
Log:
Factor the merging of declarations in the AST reader out to a separate
member function template, since the behavior is identical for
ObjCInterfaceDecl and ObjCProtocolDecl. It's expected that all
redeclarable entities will have the same behavior.

Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=147450&r1=147449&r2=147450&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Jan  3 11:27:13 2012
@@ -269,9 +269,12 @@
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
     
-    template <typename T> 
+    template<typename T> 
     RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
 
+    template<typename T>
+    void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl);
+    
     // FIXME: Reorder according to DeclNodes.td?
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
@@ -655,44 +658,7 @@
   RedeclarableResult Redecl = VisitRedeclarable(ID);
   VisitObjCContainerDecl(ID);
   TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
-                  
-  // Determine whether we need to merge this declaration with another @interface
-  // with the same name.
-  // FIXME: Not needed unless the module file graph is a DAG.
-  if (FindExistingResult ExistingRes = findExisting(ID)) {
-    if (ObjCInterfaceDecl *Existing = ExistingRes) {
-      ObjCInterfaceDecl *ExistingCanon = Existing->getCanonicalDecl();
-      ObjCInterfaceDecl *IDCanon = ID->getCanonicalDecl();
-      if (ExistingCanon != IDCanon) {
-        // Have our redeclaration link point back at the canonical declaration
-        // of the existing declaration, so that this declaration has the 
-        // appropriate canonical declaration.
-        ID->RedeclLink = ObjCInterfaceDecl::PreviousDeclLink(ExistingCanon);
-        
-        // Don't introduce IDCanon into the set of pending declaration chains.
-        Redecl.suppress();
-        
-        // Introduce ExistingCanon into the set of pending declaration chains,
-        // if in fact it came from a module file.
-        if (ExistingCanon->isFromASTFile()) {
-          GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon];
-          assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
-          if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
-            Reader.PendingDeclChains.push_back(ExistingCanonID);
-        }
-        
-        // If this declaration was the canonical declaration, make a note of 
-        // that. We accept the linear algorithm here because the number of 
-        // unique canonical declarations of an entity should always be tiny.
-        if (IDCanon == ID) {
-          SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
-          if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
-                == Merged.end())
-            Merged.push_back(Redecl.getFirstID());
-        }
-      }
-    }
-  }
+  mergeRedeclarable(ID, Redecl);
   
   ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
   if (ID == Def) {
@@ -764,45 +730,7 @@
   
   RedeclarableResult Redecl = VisitRedeclarable(PD);
   VisitObjCContainerDecl(PD);
-  
-  // Determine whether we need to merge this declaration with another @protocol
-  // with the same name.
-  // FIXME: Not needed unless the module file graph is a DAG.
-  if (FindExistingResult ExistingRes = findExisting(PD)) {
-    if (ObjCProtocolDecl *Existing = ExistingRes) {
-      ObjCProtocolDecl *ExistingCanon = Existing->getCanonicalDecl();
-      ObjCProtocolDecl *PDCanon = PD->getCanonicalDecl();
-      if (ExistingCanon != PDCanon) {
-        // Have our redeclaration link point back at the canonical declaration
-        // of the existing declaration, so that this declaration has the 
-        // appropriate canonical declaration.
-        PD->RedeclLink = ObjCProtocolDecl::PreviousDeclLink(ExistingCanon);
-        
-        // Don't introduce IDCanon into the set of pending declaration chains.
-        Redecl.suppress();
-        
-        // Introduce ExistingCanon into the set of pending declaration chains,
-        // if in fact it came from a module file.
-        if (ExistingCanon->isFromASTFile()) {
-          GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon];
-          assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
-          if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
-            Reader.PendingDeclChains.push_back(ExistingCanonID);
-        }
-        
-        // If this declaration was the canonical declaration, make a note of 
-        // that. We accept the linear algorithm here because the number of 
-        // unique canonical declarations of an entity should always be tiny.
-        if (PDCanon == PD) {
-          SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
-          if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
-                == Merged.end())
-            Merged.push_back(Redecl.getFirstID());
-        }
-      }
-    }
-  }
-
+  mergeRedeclarable(PD, Redecl);
   
   ObjCProtocolDecl *Def = ReadDeclAs<ObjCProtocolDecl>(Record, Idx);
   if (PD == Def) {
@@ -1579,6 +1507,48 @@
   return RedeclarableResult(Reader, FirstDeclID);
 }
 
+/// \brief Attempts to merge the given declaration (D) with another declaration
+/// of the same entity.
+template<typename T>
+void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, 
+                                      RedeclarableResult &Redecl) {
+  if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) {
+    if (T *Existing = ExistingRes) {
+      T *ExistingCanon = Existing->getCanonicalDecl();
+      T *DCanon = static_cast<T*>(D)->getCanonicalDecl();
+      if (ExistingCanon != DCanon) {
+        // Have our redeclaration link point back at the canonical declaration
+        // of the existing declaration, so that this declaration has the 
+        // appropriate canonical declaration.
+        D->RedeclLink 
+          = typename Redeclarable<T>::PreviousDeclLink(ExistingCanon);
+        
+        // Don't introduce DCanon into the set of pending declaration chains.
+        Redecl.suppress();
+        
+        // Introduce ExistingCanon into the set of pending declaration chains,
+        // if in fact it came from a module file.
+        if (ExistingCanon->isFromASTFile()) {
+          GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon];
+          assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
+          if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
+            Reader.PendingDeclChains.push_back(ExistingCanonID);
+        }
+        
+        // If this declaration was the canonical declaration, make a note of 
+        // that. We accept the linear algorithm here because the number of 
+        // unique canonical declarations of an entity should always be tiny.
+        if (DCanon == static_cast<T*>(D)) {
+          SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
+          if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
+                == Merged.end())
+            Merged.push_back(Redecl.getFirstID());
+        }
+      }
+    }
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Attribute Reading
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list