]> granicus.if.org Git - clang/commitdiff
[modules] Avoid adding a redecl chain to the 'pending out of date' list as the
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 28 Feb 2015 05:57:02 +0000 (05:57 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 28 Feb 2015 05:57:02 +0000 (05:57 +0000)
very first step in updating it.

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

include/clang/AST/Redeclarable.h
lib/Serialization/ASTReaderDecl.cpp

index 7aa11d4034375ed61c00aec016597b5c987babe9..c798d708326a87a0fcbaaf5ef0623212e9d79891 100644 (file)
@@ -92,6 +92,13 @@ protected:
     }
 
     void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
+
+    Decl *getLatestNotUpdated() const {
+      assert(NextIsLatest() && "expected a canonical decl");
+      if (Next.is<NotKnownLatest>())
+        return nullptr;
+      return Next.get<KnownLatest>().getNotUpdated();
+    }
   };
 
   static DeclLink PreviousDeclLink(decl_type *D) {
index c5917b663408909f1ce9cff1cb6a72c04ec334c4..375bdfb392e7e83f8d57a7fb61cd2f10e7d6f956 100644 (file)
@@ -228,6 +228,11 @@ namespace clang {
           TypeIDForTypeDecl(0), NamedDeclForTagDecl(0),
           TypedefNameForLinkage(nullptr), HasPendingBody(false) {}
 
+    template <typename DeclT>
+    static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
+    static Decl *getMostRecentDeclImpl(...);
+    static Decl *getMostRecentDecl(Decl *D);
+
     template <typename DeclT>
     static void attachPreviousDeclImpl(ASTReader &Reader,
                                        Redeclarable<DeclT> *D, Decl *Previous);
@@ -2782,6 +2787,27 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
                             AnonymousDeclNumber, TypedefNameForLinkage);
 }
 
+template<typename DeclT>
+Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) {
+  return D->RedeclLink.getLatestNotUpdated();
+}
+Decl *ASTDeclReader::getMostRecentDeclImpl(...) {
+  llvm_unreachable("getMostRecentDecl on non-redeclarable declaration");
+}
+
+Decl *ASTDeclReader::getMostRecentDecl(Decl *D) {
+  assert(D);
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(TYPE)
+#define DECL(TYPE, BASE)                               \
+  case Decl::TYPE:                                     \
+    return getMostRecentDeclImpl(cast<TYPE##Decl>(D));
+#include "clang/AST/DeclNodes.inc"
+  }
+  llvm_unreachable("unknown decl kind");
+}
+
 template<typename DeclT>
 void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                            Redeclarable<DeclT> *D,
@@ -3359,9 +3385,14 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
   ArrayRef<Decl *> Chain = Visitor.getChain();
   if (Chain.empty())
     return;
-    
+
   // Hook up the chains.
-  Decl *MostRecent = CanonDecl->getMostRecentDecl();
+  //
+  // FIXME: We have three different dispatches on decl kind here; maybe
+  // we should instead generate one loop per kind and dispatch up-front?
+  Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
+  if (!MostRecent)
+    MostRecent = CanonDecl;
   for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
     if (Chain[I] == CanonDecl)
       continue;
@@ -3369,8 +3400,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
     ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent);
     MostRecent = Chain[I];
   }
-  
-  ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);  
+  ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);
 }
 
 namespace {