[modules] Don't try to merge template specializations by performing name lookup
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 11 Jul 2014 00:20:06 +0000 (00:20 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 11 Jul 2014 00:20:06 +0000 (00:20 +0000)
into their container; we won't find them there. These things are already being
merged when they're added to their primary template's folding set, so this
merging is redundant (and causes us to reject-valid because we think we've
found an odr violation).

llvm-svn: 212788

clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/Inputs/cxx-templates-a.h
clang/test/Modules/Inputs/cxx-templates-b.h
clang/test/Modules/Inputs/cxx-templates-common.h
clang/test/Modules/cxx-templates.cpp

index d8495da..f9fed46 100644 (file)
@@ -1017,7 +1017,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
   switch ((VarKind)Record[Idx++]) {
   case VarNotTemplate:
     // Only true variables (not parameters or implicit parameters) can be merged
-    if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam)
+    if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam &&
+        !isa<VarTemplateSpecializationDecl>(VD))
       mergeRedeclarable(VD, Redecl);
     break;
   case VarTemplate:
@@ -1438,7 +1439,9 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
   };
   switch ((CXXRecKind)Record[Idx++]) {
   case CXXRecNotTemplate:
-    mergeRedeclarable(D, Redecl);
+    // Merged when we merge the folding set entry in the primary template.
+    if (!isa<ClassTemplateSpecializationDecl>(D))
+      mergeRedeclarable(D, Redecl);
     break;
   case CXXRecTemplate: {
     // Merged when we merge the template.
index 12b647b..5ac1697 100644 (file)
@@ -63,3 +63,7 @@ template<> struct WithExplicitSpecialization<int> {
     return n;
   }
 };
+
+template<typename T> template<typename U>
+constexpr int Outer<T>::Inner<U>::f() { return 1; }
+static_assert(Outer<int>::Inner<int>::f() == 1, "");
index a682855..efd07c6 100644 (file)
@@ -20,6 +20,10 @@ extern DefinedInCommon &defined_in_common;
 template<int> struct MergeTemplates;
 MergeTemplates<0> *merge_templates_b;
 
+template<typename T> template<typename U>
+constexpr int Outer<T>::Inner<U>::g() { return 2; }
+static_assert(Outer<int>::Inner<int>::g() == 2, "");
+
 @import cxx_templates_b_impl;
 
 template<typename T, typename> struct Identity { typedef T type; };
index 986c52b..682ef93 100644 (file)
@@ -26,8 +26,8 @@ template<typename T> struct TemplateInstantiationVisibility { typedef int type;
 
 template<typename T> struct Outer {
   template<typename U> struct Inner {
-    void f();
-    void g();
+    static constexpr int f();
+    static constexpr int g();
   };
 };
 
index f68bc72..679d7d1 100644 (file)
@@ -107,6 +107,9 @@ void g() {
   int &q = WithExplicitSpecializationUse().inner_template<int>();
 }
 
+static_assert(Outer<int>::Inner<int>::f() == 1, "");
+static_assert(Outer<int>::Inner<int>::g() == 2, "");
+
 RedeclaredAsFriend<int> raf1;
 RedeclareTemplateAsFriend<double> rtaf;
 RedeclaredAsFriend<double> raf2;