]> granicus.if.org Git - clang/commitdiff
Improve recovery in a wonky case where one tries to specialize a
authorDouglas Gregor <dgregor@apple.com>
Thu, 12 Nov 2009 00:46:20 +0000 (00:46 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 12 Nov 2009 00:46:20 +0000 (00:46 +0000)
template template parameter.

When building a template-id type, check whether the template-name
itself is dependent (even if the template arguments are not!) and
handle it as a template-id type.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.cpp
test/SemaTemplate/class-template-spec.cpp

index 26693aa78cf214217d610aa22dd7dc65a5cfec0c..2cc29caa0173b40c61af696cbded0265315b682f 100644 (file)
@@ -1012,6 +1012,9 @@ def err_template_spec_friend : Error<
 def err_template_spec_default_arg : Error<
   "default argument not permitted on an explicit "
   "%select{instantiation|specialization}0 of function %1">;
+def err_not_class_template_specialization : Error<
+  "cannot specialize a %select{dependent template|template template "
+  "parameter}0">;
 
 // C++ class template specializations and out-of-line definitions
 def err_template_spec_needs_header : Error<
index 9305d6ebb13e45d2a6cefaf128ec0fc13f35b25c..419347adcf6a4f569de937445b891d6daf641446 100644 (file)
@@ -1188,7 +1188,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
 
   if (TemplateSpecializationType::anyDependentTemplateArguments(
                                                       TemplateArgs,
-                                                      NumTemplateArgs)) {
+                                                      NumTemplateArgs) ||
+      isa<TemplateTemplateParmDecl>(Template) || 
+      Template->getDeclContext()->isDependentContext()) {
     // This class template specialization is a dependent
     // type. Therefore, its canonical type is another class template
     // specialization type that contains all of the converted
@@ -2935,7 +2937,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
   // Find the class template we're specializing
   TemplateName Name = TemplateD.getAsVal<TemplateName>();
   ClassTemplateDecl *ClassTemplate
-    = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
+    = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
+
+  if (!ClassTemplate) {
+    Diag(TemplateNameLoc, diag::err_not_class_template_specialization)
+      << (Name.getAsTemplateDecl() && 
+          isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()));
+    return true;
+  }
 
   bool isExplicitSpecialization = false;
   bool isPartialSpecialization = false;
index 4cd43b469ae0c32be72b918a193fed6c813916fd..5bc9a6cd67daa14c3d9266d96280f07fd41b7300 100644 (file)
@@ -104,3 +104,8 @@ Foo<int>* v;
 Foo<int>& F() { return *v; }
 template <typename T> class Foo {};
 Foo<int> x;
+
+
+// Template template parameters
+template<template<class T> class Wibble>
+class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}