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