From 8b7afffa058b5156a39e39a1f6789dfb7e2c0992 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
Date: Sun, 12 Aug 2012 19:48:56 +0000
Subject: [PATCH] Update the existing patch instead of creating a new one.

git-svn-id: http://root.cern.ch/svn/root/trunk@45563 27541ba8-7e3a-0410-8455-c3a389f83636
---
 cint/cling/patches/clang-Modules.diff         | 347 +++++++++----
 .../current-state-of-pcms-in-clang.diff       | 472 ------------------
 2 files changed, 263 insertions(+), 556 deletions(-)
 delete mode 100644 cint/cling/patches/current-state-of-pcms-in-clang.diff

diff --git a/cint/cling/patches/clang-Modules.diff b/cint/cling/patches/clang-Modules.diff
index 0f4b2ae215a..a6251ffb29d 100644
--- a/cint/cling/patches/clang-Modules.diff
+++ b/cint/cling/patches/clang-Modules.diff
@@ -1,22 +1,115 @@
-Index: tools/clang/include/clang/Lex/HeaderSearch.h
+Index: tools/clang/test/Modules/redecl-templates.mm
 ===================================================================
---- tools/clang/include/clang/Lex/HeaderSearch.h	(revision 161101)
-+++ tools/clang/include/clang/Lex/HeaderSearch.h	(working copy)
-@@ -283,6 +283,11 @@
-   
-   /// \brief Retrieve the path to the module cache.
-   StringRef getModuleCachePath() const { return ModuleCachePath; }
+--- tools/clang/test/Modules/redecl-templates.mm	(revision 0)
++++ tools/clang/test/Modules/redecl-templates.mm	(revision 0)
+@@ -0,0 +1,30 @@
++// template <typename T> int foo(T);
++// int usesfootoo() { return foo((float)1); }
++// template <typename T> int foo(T) { return 0; }
 +
-+  /// \brief Consider modules when including files from this directory.
-+  void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
-+    DirectoryHasModuleMap[Dir] = true;
-+  }
-   
-   /// \brief Forget everything we know about headers so far.
-   void ClearFileInfo() {
++// class Redecl;
++// class RedeclImp { Redecl* p; };
++// class Redecl { public: int M; };
++
++@__experimental_modules_import redecl_templates_left;
++@__experimental_modules_import redecl_templates_right;
++
++int call() {
++   // L::AB b;
++
++   // Redecl r;
++
++//   L::usesfwddeclThenDefinedInLeftRight();
++//   L::usesfwddeclThenDefinedInLeftRightToo();
++  definedInLeft((double)0.);
++//   L::definedInLeftSpecializedInRight((float)0);
++//   L::definedInLeftSpecializedInRight((char)0);
++   return 0;
++}
++// RUN: rm -rf %t
++// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodule-cache-path %t -emit-module -fmodule-name=redecl_templates_left %S/Inputs/module.map
++// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodule-cache-path %t -emit-module -fmodule-name=redecl_templates_right %S/Inputs/module.map
++// RUN: %clang_cc1 -fmodules -fmodule-cache-path %t -w %s -emit-obj -o %t.obj
++// RUN: echo 'int call(); int main(int,char*[]) { return call(); }' | %clang -x objective-c++ - -c -o %t_main.obj
++// RUN: %clang -lstdc++ %t_main.obj %t.obj
++// XFAIL: *
+Index: tools/clang/test/Modules/Inputs/module.map
+===================================================================
+--- tools/clang/test/Modules/Inputs/module.map	(revision 161655)
++++ tools/clang/test/Modules/Inputs/module.map	(working copy)
+@@ -38,6 +38,8 @@
+ module redeclarations_right { header "redeclarations_right.h" }
+ module redecl_namespaces_left { header "redecl_namespaces_left.h" }
+ module redecl_namespaces_right { header "redecl_namespaces_right.h" }
++module redecl_templates_left { header "redecl_templates_left.h" }
++module redecl_templates_right { header "redecl_templates_right.h" }
+ module load_failure { header "load_failure.h" }
+ 
+ module decldef {
+Index: tools/clang/test/Modules/Inputs/redecl_templates_right.h
+===================================================================
+--- tools/clang/test/Modules/Inputs/redecl_templates_right.h	(revision 0)
++++ tools/clang/test/Modules/Inputs/redecl_templates_right.h	(revision 0)
+@@ -0,0 +1,21 @@
++//namespace L {
++   /*
++   template <typename T> class AA;
++   template <typename T> class AA {};
++   class AB: public virtual AA<char> {};
++   */
++
++   // template <typename T> int fwddeclThenDefinedInLeftRight(T);
++
++   // int usesfwddeclThenDefinedInLeftRightToo() {
++   //    return fwddeclThenDefinedInLeftRight((float)1); }
++
++   // template <typename T> int fwddeclThenDefinedInLeftRight(T) { return 0; }
++
++   template <typename T> int definedInLeft(T);
++
++   // template <typename T> int definedInLeftSpecializedInRight(T);
++   // template <> int definedInLeftSpecializedInRight<char>(char) { return 1; }
++   // int usesdefinedInLeftSpecializedInRightChar() {
++   //    return definedInLeftSpecializedInRight((char)0); }
++//}
+Index: tools/clang/test/Modules/Inputs/redecl_templates_left.h
+===================================================================
+--- tools/clang/test/Modules/Inputs/redecl_templates_left.h	(revision 0)
++++ tools/clang/test/Modules/Inputs/redecl_templates_left.h	(revision 0)
+@@ -0,0 +1,30 @@
++//namespace L {
++   // template <typename T> class AA;
++   // template <typename T> class AA {};
++   // class AB: public virtual AA<char> {};
++
++   // class Redecl;
++   // class RedeclImp { Redecl* p; };
++
++   // class Redecl { public: int M; };
++
++   // class Redecl;
++
++   // class RedeclUse { Redecl* use; };
++
++   // class Redecl;
++
++   // template <typename T> int fwddeclThenDefinedInLeftRight(T);
++
++   // int usesfwddeclThenDefinedInLeftRight() {
++   //    return fwddeclThenDefinedInLeftRight((char)1); }
++
++   // template <typename T> int fwddeclThenDefinedInLeftRight(T) { return 0; }
++
++   template <typename T> int definedInLeft(T) { return 1; }
++   //int usesdefinedInLeft() { return definedInLeft((int)0); }
++
++   // template <typename T> int definedInLeftSpecializedInRight(T) { return 2; }
++   // int usesdefinedInLeftSpecializedInRightInt() {
++   //    return definedInLeftSpecializedInRight((int)0); }
++  //}
 Index: tools/clang/include/clang/Serialization/ASTReader.h
 ===================================================================
---- tools/clang/include/clang/Serialization/ASTReader.h	(revision 161101)
+--- tools/clang/include/clang/Serialization/ASTReader.h	(revision 161655)
 +++ tools/clang/include/clang/Serialization/ASTReader.h	(working copy)
 @@ -686,7 +686,15 @@
    /// need to be emitted, such as inline function definitions or
@@ -52,62 +145,27 @@ Index: tools/clang/include/clang/Serialization/ASTReader.h
    /// \brief Produce an error diagnostic and return true.
    ///
    /// This routine should only be used for fatal errors that have to
-Index: tools/clang/lib/Serialization/ASTReader.cpp
+Index: tools/clang/include/clang/Lex/HeaderSearch.h
 ===================================================================
---- tools/clang/lib/Serialization/ASTReader.cpp	(revision 161101)
-+++ tools/clang/lib/Serialization/ASTReader.cpp	(working copy)
-@@ -4930,6 +4930,9 @@
-         if (!ND)
-           continue;
- 
-+        if (This->Reader.DeclsInFlight.count(ND))
-+          continue;
-+
-         if (ND->getDeclName() != This->Name) {
-           assert(!This->Name.getCXXNameType().isNull() && 
-                  "Name mismatch without a type");
-@@ -5571,7 +5574,11 @@
-     ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
-     SourceLocation Loc
-       = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
--    Pending.push_back(std::make_pair(D, Loc));
-+
-+    // For modules, find out whether an instantiation already exists
-+    if (!getContext().getLangOpts().Modules
-+        || needPendingInstantiation(D))
-+      Pending.push_back(std::make_pair(D, Loc));
-   }  
-   PendingInstantiations.clear();
- }
-@@ -6468,6 +6475,9 @@
- }
- 
- ASTReader::~ASTReader() {
-+  assert(DeclsInFlight.empty() && "DeclsInFlight not empty!");
-+  assert(RedeclsAddedToAST.empty() && "RedeclsAddedToAST not empty!");
+--- tools/clang/include/clang/Lex/HeaderSearch.h	(revision 161655)
++++ tools/clang/include/clang/Lex/HeaderSearch.h	(working copy)
+@@ -283,6 +283,11 @@
+   
+   /// \brief Retrieve the path to the module cache.
+   StringRef getModuleCachePath() const { return ModuleCachePath; }
 +
-   for (DeclContextVisibleUpdatesPending::iterator
-            I = PendingVisibleUpdates.begin(),
-            E = PendingVisibleUpdates.end();
++  /// \brief Consider modules when including files from this directory.
++  void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
++    DirectoryHasModuleMap[Dir] = true;
++  }
+   
+   /// \brief Forget everything we know about headers so far.
+   void ClearFileInfo() {
 Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
 ===================================================================
---- tools/clang/lib/Serialization/ASTReaderDecl.cpp	(revision 161101)
+--- tools/clang/lib/Serialization/ASTReaderDecl.cpp	(revision 161655)
 +++ tools/clang/lib/Serialization/ASTReaderDecl.cpp	(working copy)
-@@ -348,6 +348,13 @@
-     DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
-     // Avoid calling setLexicalDeclContext() directly because it uses
-     // Decl::getASTContext() internally which is unsafe during derialization.
-+    NamedDecl* ND = dyn_cast<NamedDecl>(D);
-+    if (ND && ND->getIdentifier()) {
-+      std::string N(ND->getNameAsString());
-+      if (N[1] == 'S' && N[2] == '_') {
-+        llvm::errs() << "FOO\n";
-+      }
-+    }
-     D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
-   }
-   D->setLocation(Reader.ReadSourceLocation(F, RawLocation));
-@@ -520,7 +527,9 @@
+@@ -520,7 +520,9 @@
    FD->IsConstexpr = Record[Idx++];
    FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
  
@@ -118,7 +176,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    case FunctionDecl::TK_NonTemplate:
      mergeRedeclarable(FD, Redecl);      
      break;
-@@ -623,6 +632,9 @@
+@@ -623,6 +625,9 @@
    for (unsigned I = 0; I != NumParams; ++I)
      Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
    FD->setParams(Reader.getContext(), Params);
@@ -128,7 +186,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
  }
  
  void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
-@@ -901,6 +913,7 @@
+@@ -901,6 +906,7 @@
    // Only true variables (not parameters or implicit parameters) can be merged.
    if (VD->getKind() == Decl::Var)
      mergeRedeclarable(VD, Redecl);
@@ -136,7 +194,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    
    if (uint64_t Val = Record[Idx++]) {
      VD->setInit(Reader.ReadExpr(F));
-@@ -1311,7 +1324,7 @@
+@@ -1311,7 +1317,7 @@
       
    VisitTemplateDecl(D);
    D->IdentifierNamespace = Record[Idx++];
@@ -145,7 +203,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    return Redecl;
  }
  
-@@ -1515,6 +1528,7 @@
+@@ -1515,6 +1521,7 @@
  template <typename T>
  ASTDeclReader::RedeclarableResult 
  ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
@@ -153,7 +211,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    DeclID FirstDeclID = ReadDeclID(Record, Idx);
    
    // 0 indicates that this declaration was the only declaration of its entity,
-@@ -1545,6 +1559,7 @@
+@@ -1545,6 +1552,7 @@
  void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, 
                                        RedeclarableResult &Redecl) {
    // If modules are not available, there is no reason to perform this merge.
@@ -161,7 +219,32 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    if (!Reader.getContext().getLangOpts().Modules)
      return;
    
-@@ -1750,14 +1765,20 @@
+@@ -1731,7 +1739,16 @@
+     return (FuncX->getLinkage() == FuncY->getLinkage()) &&
+       FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
+   }
+-  
++
++  if (const FunctionTemplateDecl* FTDX = dyn_cast<FunctionTemplateDecl>(X)) {
++    const FunctionTemplateDecl* FTDY = cast<FunctionTemplateDecl>(Y);
++    if (isSameEntity(FTDX->getTemplatedDecl(), FTDY->getTemplatedDecl())) {
++      return FTDX->getTemplatedDecl()->getNumParams() 
++        == FTDY->getTemplatedDecl()->getNumParams();
++
++    }
++  }
++    
+   // Variables with the same type and linkage match.
+   if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
+     VarDecl *VarY = cast<VarDecl>(Y);
+@@ -1744,20 +1761,26 @@
+     NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y);
+     return NamespaceX->isInline() == NamespaceY->isInline();
+   }
+-      
++
+   // FIXME: Many other cases to implement.
+   return false;
  }
  
  ASTDeclReader::FindExistingResult::~FindExistingResult() {
@@ -184,7 +267,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
    }
  }
  
-@@ -1779,7 +1800,7 @@
+@@ -1779,7 +1802,7 @@
      for (IdentifierResolver::iterator I = IdResolver.begin(Name), 
                                     IEnd = IdResolver.end();
           I != IEnd; ++I) {
@@ -193,7 +276,7 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
          return FindExistingResult(Reader, D, *I);
      }
    }
-@@ -1787,7 +1808,9 @@
+@@ -1787,7 +1810,9 @@
    if (DC->isNamespace()) {
      for (DeclContext::lookup_result R = DC->lookup(Name);
           R.first != R.second; ++R.first) {
@@ -204,7 +287,54 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
          return FindExistingResult(Reader, D, *R.first);
      }
    }
-@@ -2125,9 +2148,23 @@
+@@ -1798,22 +1823,38 @@
+ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
+   assert(D && previous);
+   if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+-    TD->RedeclLink.setNext(cast<TagDecl>(previous));
++    //TD->RedeclLink.setNext(cast<TagDecl>(previous));
++    TD->RedeclLink
++      = Redeclarable<TagDecl>::PreviousDeclLink(cast<TagDecl>(previous));    
+   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+-    FD->RedeclLink.setNext(cast<FunctionDecl>(previous));
++    //FD->RedeclLink.setNext(cast<FunctionDecl>(previous));
++    FD->RedeclLink
++      = Redeclarable<FunctionDecl>::PreviousDeclLink(cast<FunctionDecl>(previous));
+   } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+-    VD->RedeclLink.setNext(cast<VarDecl>(previous));
++    //VD->RedeclLink.setNext(cast<VarDecl>(previous));
++    VD->RedeclLink
++      = Redeclarable<VarDecl>::PreviousDeclLink(cast<VarDecl>(previous));
+   } else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+-    TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
++    //TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
++    TD->RedeclLink
++      = Redeclarable<TypedefNameDecl>::PreviousDeclLink(cast<TypedefNameDecl>(previous));
+   } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+-    ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
++    //ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
++    ID->RedeclLink
++      = Redeclarable<ObjCInterfaceDecl>::PreviousDeclLink(cast<ObjCInterfaceDecl>(previous));
+   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+-    PD->RedeclLink.setNext(cast<ObjCProtocolDecl>(previous));
++    //  PD->RedeclLink.setNext(cast<ObjCProtocolDecl>(previous));
++    PD->RedeclLink
++      = Redeclarable<ObjCProtocolDecl>::PreviousDeclLink(cast<ObjCProtocolDecl>(previous));
+   } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
+-    ND->RedeclLink.setNext(cast<NamespaceDecl>(previous));
++    // ND->RedeclLink.setNext(cast<NamespaceDecl>(previous));
++    ND->RedeclLink
++      = Redeclarable<NamespaceDecl>::PreviousDeclLink(cast<NamespaceDecl>(previous));
+   } else {
+     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
+-    TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous));
++    TD->RedeclLink
++      = Redeclarable<RedeclarableTemplateDecl>::PreviousDeclLink(cast<RedeclarableTemplateDecl>(previous));
++    //TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous));
+   }
+ }
+ 
+@@ -2125,9 +2166,16 @@
    // AST consumer might need to know about, queue it.
    // We don't pass it to the consumer immediately because we may be in recursive
    // loading, and some declarations may still be initializing.
@@ -219,18 +349,20 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
 +  } else if (isConsumerInterestedIn(D))
      InterestingDecls.push_back(D);
 -  
-+#ifdef AXEL_ORIG_WORKS
-+  if (!HaveModules || RedeclsAddedToAST.count(D)) {
-+    if (isConsumerInterestedIn(D))
-+      InterestingDecls.push_back(D);
-+    if (HaveModules)
-+      RedeclsAddedToAST.erase(D);
-+  }
-+#endif
++
    return D;
  }
  
-@@ -2478,3 +2515,60 @@
+@@ -2275,7 +2323,7 @@
+   }
+   MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID);
+   if (MergedPos != MergedDecls.end())
+-    SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());  
++    SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
+   
+   // Build up the list of redeclarations.
+   RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
+@@ -2478,3 +2526,60 @@
      }
    }
  }
@@ -291,3 +423,50 @@ Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
 +  }
 +  return FoundSpecialization && isSameEntity(FoundSpecialization, D);
 +}
+Index: tools/clang/lib/Serialization/ASTReader.cpp
+===================================================================
+--- tools/clang/lib/Serialization/ASTReader.cpp	(revision 161655)
++++ tools/clang/lib/Serialization/ASTReader.cpp	(working copy)
+@@ -4640,6 +4640,9 @@
+ }
+ 
+ Decl *ASTReader::GetDecl(DeclID ID) {
++  if (ID == 42710) 
++    printf("br cond here\n");
++
+   if (ID < NUM_PREDEF_DECL_IDS) {    
+     switch ((PredefinedDeclIDs)ID) {
+     case PREDEF_DECL_NULL_ID:
+@@ -4930,6 +4933,9 @@
+         if (!ND)
+           continue;
+ 
++        if (This->Reader.DeclsInFlight.count(ND))
++          continue;
++
+         if (ND->getDeclName() != This->Name) {
+           assert(!This->Name.getCXXNameType().isNull() && 
+                  "Name mismatch without a type");
+@@ -5571,7 +5577,11 @@
+     ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
+     SourceLocation Loc
+       = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
+-    Pending.push_back(std::make_pair(D, Loc));
++
++    // For modules, find out whether an instantiation already exists
++    if (!getContext().getLangOpts().Modules
++        || needPendingInstantiation(D))
++      Pending.push_back(std::make_pair(D, Loc));
+   }  
+   PendingInstantiations.clear();
+ }
+@@ -6468,6 +6478,9 @@
+ }
+ 
+ ASTReader::~ASTReader() {
++  assert(DeclsInFlight.empty() && "DeclsInFlight not empty!");
++  assert(RedeclsAddedToAST.empty() && "RedeclsAddedToAST not empty!");
++
+   for (DeclContextVisibleUpdatesPending::iterator
+            I = PendingVisibleUpdates.begin(),
+            E = PendingVisibleUpdates.end();
diff --git a/cint/cling/patches/current-state-of-pcms-in-clang.diff b/cint/cling/patches/current-state-of-pcms-in-clang.diff
deleted file mode 100644
index a6251ffb29d..00000000000
--- a/cint/cling/patches/current-state-of-pcms-in-clang.diff
+++ /dev/null
@@ -1,472 +0,0 @@
-Index: tools/clang/test/Modules/redecl-templates.mm
-===================================================================
---- tools/clang/test/Modules/redecl-templates.mm	(revision 0)
-+++ tools/clang/test/Modules/redecl-templates.mm	(revision 0)
-@@ -0,0 +1,30 @@
-+// template <typename T> int foo(T);
-+// int usesfootoo() { return foo((float)1); }
-+// template <typename T> int foo(T) { return 0; }
-+
-+// class Redecl;
-+// class RedeclImp { Redecl* p; };
-+// class Redecl { public: int M; };
-+
-+@__experimental_modules_import redecl_templates_left;
-+@__experimental_modules_import redecl_templates_right;
-+
-+int call() {
-+   // L::AB b;
-+
-+   // Redecl r;
-+
-+//   L::usesfwddeclThenDefinedInLeftRight();
-+//   L::usesfwddeclThenDefinedInLeftRightToo();
-+  definedInLeft((double)0.);
-+//   L::definedInLeftSpecializedInRight((float)0);
-+//   L::definedInLeftSpecializedInRight((char)0);
-+   return 0;
-+}
-+// RUN: rm -rf %t
-+// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodule-cache-path %t -emit-module -fmodule-name=redecl_templates_left %S/Inputs/module.map
-+// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodule-cache-path %t -emit-module -fmodule-name=redecl_templates_right %S/Inputs/module.map
-+// RUN: %clang_cc1 -fmodules -fmodule-cache-path %t -w %s -emit-obj -o %t.obj
-+// RUN: echo 'int call(); int main(int,char*[]) { return call(); }' | %clang -x objective-c++ - -c -o %t_main.obj
-+// RUN: %clang -lstdc++ %t_main.obj %t.obj
-+// XFAIL: *
-Index: tools/clang/test/Modules/Inputs/module.map
-===================================================================
---- tools/clang/test/Modules/Inputs/module.map	(revision 161655)
-+++ tools/clang/test/Modules/Inputs/module.map	(working copy)
-@@ -38,6 +38,8 @@
- module redeclarations_right { header "redeclarations_right.h" }
- module redecl_namespaces_left { header "redecl_namespaces_left.h" }
- module redecl_namespaces_right { header "redecl_namespaces_right.h" }
-+module redecl_templates_left { header "redecl_templates_left.h" }
-+module redecl_templates_right { header "redecl_templates_right.h" }
- module load_failure { header "load_failure.h" }
- 
- module decldef {
-Index: tools/clang/test/Modules/Inputs/redecl_templates_right.h
-===================================================================
---- tools/clang/test/Modules/Inputs/redecl_templates_right.h	(revision 0)
-+++ tools/clang/test/Modules/Inputs/redecl_templates_right.h	(revision 0)
-@@ -0,0 +1,21 @@
-+//namespace L {
-+   /*
-+   template <typename T> class AA;
-+   template <typename T> class AA {};
-+   class AB: public virtual AA<char> {};
-+   */
-+
-+   // template <typename T> int fwddeclThenDefinedInLeftRight(T);
-+
-+   // int usesfwddeclThenDefinedInLeftRightToo() {
-+   //    return fwddeclThenDefinedInLeftRight((float)1); }
-+
-+   // template <typename T> int fwddeclThenDefinedInLeftRight(T) { return 0; }
-+
-+   template <typename T> int definedInLeft(T);
-+
-+   // template <typename T> int definedInLeftSpecializedInRight(T);
-+   // template <> int definedInLeftSpecializedInRight<char>(char) { return 1; }
-+   // int usesdefinedInLeftSpecializedInRightChar() {
-+   //    return definedInLeftSpecializedInRight((char)0); }
-+//}
-Index: tools/clang/test/Modules/Inputs/redecl_templates_left.h
-===================================================================
---- tools/clang/test/Modules/Inputs/redecl_templates_left.h	(revision 0)
-+++ tools/clang/test/Modules/Inputs/redecl_templates_left.h	(revision 0)
-@@ -0,0 +1,30 @@
-+//namespace L {
-+   // template <typename T> class AA;
-+   // template <typename T> class AA {};
-+   // class AB: public virtual AA<char> {};
-+
-+   // class Redecl;
-+   // class RedeclImp { Redecl* p; };
-+
-+   // class Redecl { public: int M; };
-+
-+   // class Redecl;
-+
-+   // class RedeclUse { Redecl* use; };
-+
-+   // class Redecl;
-+
-+   // template <typename T> int fwddeclThenDefinedInLeftRight(T);
-+
-+   // int usesfwddeclThenDefinedInLeftRight() {
-+   //    return fwddeclThenDefinedInLeftRight((char)1); }
-+
-+   // template <typename T> int fwddeclThenDefinedInLeftRight(T) { return 0; }
-+
-+   template <typename T> int definedInLeft(T) { return 1; }
-+   //int usesdefinedInLeft() { return definedInLeft((int)0); }
-+
-+   // template <typename T> int definedInLeftSpecializedInRight(T) { return 2; }
-+   // int usesdefinedInLeftSpecializedInRightInt() {
-+   //    return definedInLeftSpecializedInRight((int)0); }
-+  //}
-Index: tools/clang/include/clang/Serialization/ASTReader.h
-===================================================================
---- tools/clang/include/clang/Serialization/ASTReader.h	(revision 161655)
-+++ tools/clang/include/clang/Serialization/ASTReader.h	(working copy)
-@@ -686,7 +686,15 @@
-   /// need to be emitted, such as inline function definitions or
-   /// Objective-C protocols.
-   std::deque<Decl *> InterestingDecls;
-+public:
-+  /// \brief Currently deserializing Decls
-+  ///
-+  /// Decls that are currently read but have not been completed yet.
-+  llvm::SmallPtrSet<Decl *, 16> DeclsInFlight;
- 
-+  llvm::SmallPtrSet<Decl *, 16> RedeclsAddedToAST;
-+
-+private:
-   /// \brief The set of redeclarable declaraations that have been deserialized
-   /// since the last time the declaration chains were linked.
-   llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized;
-@@ -738,7 +746,7 @@
-   /// the given canonical declaration.
-   MergedDeclsMap::iterator
-   combineStoredMergedDecls(Decl *Canon, serialization::GlobalDeclID CanonID);
--  
-+
-   /// \brief Ready to load the previous declaration of the given Decl.
-   void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID);
- 
-@@ -853,6 +861,8 @@
- 
-   void finishPendingActions();
- 
-+  bool needPendingInstantiation(ValueDecl* D) const;
-+
-   /// \brief Produce an error diagnostic and return true.
-   ///
-   /// This routine should only be used for fatal errors that have to
-Index: tools/clang/include/clang/Lex/HeaderSearch.h
-===================================================================
---- tools/clang/include/clang/Lex/HeaderSearch.h	(revision 161655)
-+++ tools/clang/include/clang/Lex/HeaderSearch.h	(working copy)
-@@ -283,6 +283,11 @@
-   
-   /// \brief Retrieve the path to the module cache.
-   StringRef getModuleCachePath() const { return ModuleCachePath; }
-+
-+  /// \brief Consider modules when including files from this directory.
-+  void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
-+    DirectoryHasModuleMap[Dir] = true;
-+  }
-   
-   /// \brief Forget everything we know about headers so far.
-   void ClearFileInfo() {
-Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
-===================================================================
---- tools/clang/lib/Serialization/ASTReaderDecl.cpp	(revision 161655)
-+++ tools/clang/lib/Serialization/ASTReaderDecl.cpp	(working copy)
-@@ -520,7 +520,9 @@
-   FD->IsConstexpr = Record[Idx++];
-   FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
- 
--  switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
-+  FunctionDecl::TemplatedKind TmpltKind
-+    = (FunctionDecl::TemplatedKind) Record[Idx++];
-+  switch (TmpltKind) {
-   case FunctionDecl::TK_NonTemplate:
-     mergeRedeclarable(FD, Redecl);      
-     break;
-@@ -623,6 +625,9 @@
-   for (unsigned I = 0; I != NumParams; ++I)
-     Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
-   FD->setParams(Reader.getContext(), Params);
-+
-+  if (TmpltKind != FunctionDecl::TK_NonTemplate)
-+    Reader.DeclsInFlight.erase(FD);
- }
- 
- void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
-@@ -901,6 +906,7 @@
-   // Only true variables (not parameters or implicit parameters) can be merged.
-   if (VD->getKind() == Decl::Var)
-     mergeRedeclarable(VD, Redecl);
-+  else Reader.DeclsInFlight.erase(VD);
-   
-   if (uint64_t Val = Record[Idx++]) {
-     VD->setInit(Reader.ReadExpr(F));
-@@ -1311,7 +1317,7 @@
-      
-   VisitTemplateDecl(D);
-   D->IdentifierNamespace = Record[Idx++];
--  
-+  mergeRedeclarable(D, Redecl);
-   return Redecl;
- }
- 
-@@ -1515,6 +1521,7 @@
- template <typename T>
- ASTDeclReader::RedeclarableResult 
- ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
-+  Reader.DeclsInFlight.insert(static_cast<T *>(D));
-   DeclID FirstDeclID = ReadDeclID(Record, Idx);
-   
-   // 0 indicates that this declaration was the only declaration of its entity,
-@@ -1545,6 +1552,7 @@
- void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, 
-                                       RedeclarableResult &Redecl) {
-   // If modules are not available, there is no reason to perform this merge.
-+  Reader.DeclsInFlight.erase(static_cast<T*>(D));
-   if (!Reader.getContext().getLangOpts().Modules)
-     return;
-   
-@@ -1731,7 +1739,16 @@
-     return (FuncX->getLinkage() == FuncY->getLinkage()) &&
-       FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
-   }
--  
-+
-+  if (const FunctionTemplateDecl* FTDX = dyn_cast<FunctionTemplateDecl>(X)) {
-+    const FunctionTemplateDecl* FTDY = cast<FunctionTemplateDecl>(Y);
-+    if (isSameEntity(FTDX->getTemplatedDecl(), FTDY->getTemplatedDecl())) {
-+      return FTDX->getTemplatedDecl()->getNumParams() 
-+        == FTDY->getTemplatedDecl()->getNumParams();
-+
-+    }
-+  }
-+    
-   // Variables with the same type and linkage match.
-   if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
-     VarDecl *VarY = cast<VarDecl>(Y);
-@@ -1744,20 +1761,26 @@
-     NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y);
-     return NamespaceX->isInline() == NamespaceY->isInline();
-   }
--      
-+
-   // FIXME: Many other cases to implement.
-   return false;
- }
- 
- ASTDeclReader::FindExistingResult::~FindExistingResult() {
--  if (!AddResult || Existing)
-+  if (!AddResult || Existing) {
-     return;
-+  }
-   
-   DeclContext *DC = New->getDeclContext()->getRedeclContext();
-   if (DC->isTranslationUnit() && Reader.SemaObj) {
--    Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName());
-+    if (Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()))
-+      Reader.RedeclsAddedToAST.insert(New);
-   } else if (DC->isNamespace()) {
-+    DeclContext* oldCtx = New->getLexicalDeclContext();
-+    New->setLexicalDeclContext(DC);
-     DC->addDecl(New);
-+    New->setLexicalDeclContext(oldCtx);
-+    Reader.RedeclsAddedToAST.insert(New);
-   }
- }
- 
-@@ -1779,7 +1802,7 @@
-     for (IdentifierResolver::iterator I = IdResolver.begin(Name), 
-                                    IEnd = IdResolver.end();
-          I != IEnd; ++I) {
--      if (isSameEntity(*I, D))
-+      if (*I != D && isSameEntity(*I, D))
-         return FindExistingResult(Reader, D, *I);
-     }
-   }
-@@ -1787,7 +1810,9 @@
-   if (DC->isNamespace()) {
-     for (DeclContext::lookup_result R = DC->lookup(Name);
-          R.first != R.second; ++R.first) {
--      if (isSameEntity(*R.first, D))
-+      if (*R.first != D
-+          && !Reader.DeclsInFlight.count(*R.first)
-+          && isSameEntity(*R.first, D))
-         return FindExistingResult(Reader, D, *R.first);
-     }
-   }
-@@ -1798,22 +1823,38 @@
- void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
-   assert(D && previous);
-   if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
--    TD->RedeclLink.setNext(cast<TagDecl>(previous));
-+    //TD->RedeclLink.setNext(cast<TagDecl>(previous));
-+    TD->RedeclLink
-+      = Redeclarable<TagDecl>::PreviousDeclLink(cast<TagDecl>(previous));    
-   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
--    FD->RedeclLink.setNext(cast<FunctionDecl>(previous));
-+    //FD->RedeclLink.setNext(cast<FunctionDecl>(previous));
-+    FD->RedeclLink
-+      = Redeclarable<FunctionDecl>::PreviousDeclLink(cast<FunctionDecl>(previous));
-   } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
--    VD->RedeclLink.setNext(cast<VarDecl>(previous));
-+    //VD->RedeclLink.setNext(cast<VarDecl>(previous));
-+    VD->RedeclLink
-+      = Redeclarable<VarDecl>::PreviousDeclLink(cast<VarDecl>(previous));
-   } else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
--    TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
-+    //TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
-+    TD->RedeclLink
-+      = Redeclarable<TypedefNameDecl>::PreviousDeclLink(cast<TypedefNameDecl>(previous));
-   } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
--    ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
-+    //ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
-+    ID->RedeclLink
-+      = Redeclarable<ObjCInterfaceDecl>::PreviousDeclLink(cast<ObjCInterfaceDecl>(previous));
-   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
--    PD->RedeclLink.setNext(cast<ObjCProtocolDecl>(previous));
-+    //  PD->RedeclLink.setNext(cast<ObjCProtocolDecl>(previous));
-+    PD->RedeclLink
-+      = Redeclarable<ObjCProtocolDecl>::PreviousDeclLink(cast<ObjCProtocolDecl>(previous));
-   } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
--    ND->RedeclLink.setNext(cast<NamespaceDecl>(previous));
-+    // ND->RedeclLink.setNext(cast<NamespaceDecl>(previous));
-+    ND->RedeclLink
-+      = Redeclarable<NamespaceDecl>::PreviousDeclLink(cast<NamespaceDecl>(previous));
-   } else {
-     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
--    TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous));
-+    TD->RedeclLink
-+      = Redeclarable<RedeclarableTemplateDecl>::PreviousDeclLink(cast<RedeclarableTemplateDecl>(previous));
-+    //TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous));
-   }
- }
- 
-@@ -2125,9 +2166,16 @@
-   // AST consumer might need to know about, queue it.
-   // We don't pass it to the consumer immediately because we may be in recursive
-   // loading, and some declarations may still be initializing.
--  if (isConsumerInterestedIn(D))
-+  bool HaveModules = getContext().getLangOpts().Modules;
-+  if (HaveModules) {
-+    if (RedeclsAddedToAST.count(D)) {
-+      RedeclsAddedToAST.erase(D);
-+      if (isConsumerInterestedIn(D))
-+        InterestingDecls.push_back(D);
-+    }
-+  } else if (isConsumerInterestedIn(D))
-     InterestingDecls.push_back(D);
--  
-+
-   return D;
- }
- 
-@@ -2275,7 +2323,7 @@
-   }
-   MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID);
-   if (MergedPos != MergedDecls.end())
--    SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());  
-+    SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
-   
-   // Build up the list of redeclarations.
-   RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
-@@ -2478,3 +2526,60 @@
-     }
-   }
- }
-+
-+/// \brief Return a template specialization of ND (should be a TemplateDecl)
-+///  that matches FD or TD.
-+static NamedDecl* findMatchingSpecialization(FunctionDecl* FD,
-+                                             ClassTemplateSpecializationDecl*TD,
-+                                             NamedDecl* ND) {
-+  TemplateDecl* Templt = dyn_cast<TemplateDecl>(ND);
-+  if (!Templt) return 0;
-+  if (FD) {
-+    FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(Templt);
-+    if (!FTD) return 0;
-+    const TemplateArgumentList* TmpltArgs = FD->getTemplateSpecializationArgs();
-+    assert(TmpltArgs || "Template without arguments");
-+    void* InsertionPoint;
-+    return FTD->findSpecialization(TmpltArgs->data(), TmpltArgs->size(),
-+                                   InsertionPoint);
-+  } else {
-+    ClassTemplateDecl* CTD = dyn_cast<ClassTemplateDecl>(Templt);
-+    if (!CTD) return 0;
-+    const TemplateArgumentList& TmpltArgs = TD->getTemplateArgs();
-+    void* InsertionPoint;
-+    return CTD->findSpecialization(TmpltArgs.data(), TmpltArgs.size(),
-+                                   InsertionPoint);
-+  }
-+  return 0;
-+}
-+
-+/// \brief Find out whether an instantiation (outside the module) already exists
-+bool ASTReader::needPendingInstantiation(ValueDecl* D) const {
-+  DeclContext *DC = D->getDeclContext()->getRedeclContext();
-+  DeclarationName Name = D->getDeclName();
-+  assert(Name && "unnamed template");
-+
-+  FunctionDecl* FD = dyn_cast<FunctionDecl>(D);
-+  ClassTemplateSpecializationDecl* CD
-+    = FD ? 0 : dyn_cast<ClassTemplateSpecializationDecl>(D);
-+
-+  NamedDecl* FoundSpecialization = 0;
-+  if (DC->isTranslationUnit() && SemaObj) {
-+    IdentifierResolver &IdResolver = SemaObj->IdResolver;
-+    for (IdentifierResolver::iterator I = IdResolver.begin(Name), 
-+           IEnd = IdResolver.end();
-+         I != IEnd && !FoundSpecialization; ++I)
-+      FoundSpecialization = findMatchingSpecialization(FD, CD, *I);
-+  } else {
-+    // templates are redeclarables, i.e. they must have been merged into
-+    // the primary context. Use localUncachedLookup to not pick up template
-+    // decls from modules again.
-+    llvm::SmallVector<NamedDecl*, 6> Results;
-+    DC->getPrimaryContext()->localUncachedLookup(Name, Results);
-+    for (llvm::SmallVector<NamedDecl *, 6>::const_iterator
-+           I = Results.begin(), E = Results.end();
-+         I != E && FoundSpecialization; ++I)
-+      FoundSpecialization = findMatchingSpecialization(FD, CD, *I);
-+  }
-+  return FoundSpecialization && isSameEntity(FoundSpecialization, D);
-+}
-Index: tools/clang/lib/Serialization/ASTReader.cpp
-===================================================================
---- tools/clang/lib/Serialization/ASTReader.cpp	(revision 161655)
-+++ tools/clang/lib/Serialization/ASTReader.cpp	(working copy)
-@@ -4640,6 +4640,9 @@
- }
- 
- Decl *ASTReader::GetDecl(DeclID ID) {
-+  if (ID == 42710) 
-+    printf("br cond here\n");
-+
-   if (ID < NUM_PREDEF_DECL_IDS) {    
-     switch ((PredefinedDeclIDs)ID) {
-     case PREDEF_DECL_NULL_ID:
-@@ -4930,6 +4933,9 @@
-         if (!ND)
-           continue;
- 
-+        if (This->Reader.DeclsInFlight.count(ND))
-+          continue;
-+
-         if (ND->getDeclName() != This->Name) {
-           assert(!This->Name.getCXXNameType().isNull() && 
-                  "Name mismatch without a type");
-@@ -5571,7 +5577,11 @@
-     ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
-     SourceLocation Loc
-       = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
--    Pending.push_back(std::make_pair(D, Loc));
-+
-+    // For modules, find out whether an instantiation already exists
-+    if (!getContext().getLangOpts().Modules
-+        || needPendingInstantiation(D))
-+      Pending.push_back(std::make_pair(D, Loc));
-   }  
-   PendingInstantiations.clear();
- }
-@@ -6468,6 +6478,9 @@
- }
- 
- ASTReader::~ASTReader() {
-+  assert(DeclsInFlight.empty() && "DeclsInFlight not empty!");
-+  assert(RedeclsAddedToAST.empty() && "RedeclsAddedToAST not empty!");
-+
-   for (DeclContextVisibleUpdatesPending::iterator
-            I = PendingVisibleUpdates.begin(),
-            E = PendingVisibleUpdates.end();
-- 
GitLab