]> granicus.if.org Git - clang/commitdiff
Implement [temp.deduct.type]p6: if the nested-name-specifier of a type is
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 30 Dec 2015 20:56:05 +0000 (20:56 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 30 Dec 2015 20:56:05 +0000 (20:56 +0000)
dependent, the type is a non-deduced context.

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

include/clang/AST/DeclarationName.h
lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/deduction.cpp

index ec0fb0b9715e5fa6bec92cbf9455affb0110123e..9482e83e81dc3c6285ed0da2e630fc947bbf574e 100644 (file)
@@ -395,7 +395,7 @@ struct DeclarationNameLoc {
   // Locations (if any) for the tilde (destructor) or operator keyword
   // (conversion) are stored elsewhere.
   struct NT {
-    TypeSourceInfoTInfo;
+    TypeSourceInfo *TInfo;
   };
 
   // The location (if any) of the operator keyword is stored elsewhere.
index de04c8a7f04279f941f18e2edff20cf8b17274a3..837e0de4038daa079fb730d33879d93408d8306d 100644 (file)
@@ -4887,19 +4887,23 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
     break;
 
   case Type::DependentTemplateSpecialization: {
+    // C++14 [temp.deduct.type]p5:
+    //   The non-deduced contexts are:
+    //     -- The nested-name-specifier of a type that was specified using a
+    //        qualified-id
+    //
+    // C++14 [temp.deduct.type]p6:
+    //   When a type name is specified in a way that includes a non-deduced
+    //   context, all of the types that comprise that type name are also
+    //   non-deduced.
+    if (OnlyDeduced)
+      break;
+
     const DependentTemplateSpecializationType *Spec
       = cast<DependentTemplateSpecializationType>(T);
-    if (!OnlyDeduced)
-      MarkUsedTemplateParameters(Ctx, Spec->getQualifier(),
-                                 OnlyDeduced, Depth, Used);
 
-    // C++0x [temp.deduct.type]p9:
-    //   If the template argument list of P contains a pack expansion that is not
-    //   the last template argument, the entire template argument list is a
-    //   non-deduced context.
-    if (OnlyDeduced &&
-        hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
-      break;
+    MarkUsedTemplateParameters(Ctx, Spec->getQualifier(),
+                               OnlyDeduced, Depth, Used);
 
     for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
       MarkUsedTemplateParameters(Ctx, Spec->getArg(I), OnlyDeduced, Depth,
index bf0812277d571e1a10eb588ceea17ec30f6af5aa..6826774a0020351859f293cc527917ef40ff2a3a 100644 (file)
@@ -207,3 +207,14 @@ namespace PR18645 {
   template<typename F> F Quux(F &&f);
   auto Baz = Quux(Quux<float>);
 }
+
+namespace NonDeducedNestedNameSpecifier {
+  template<typename T> struct A {
+    template<typename U> struct B {
+      B(int) {}
+    };
+  };
+
+  template<typename T> int f(A<T>, typename A<T>::template B<T>);
+  int k = f(A<int>(), 0);
+}