diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-12 00:46:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-12 00:46:20 +0000 |
commit | 8b13c08b1a181b290600814c765f9f199a74f414 (patch) | |
tree | 59f604da0d01f6e82c7db0d96eb6c17c07937f12 | |
parent | 1144c218f5d74f2270ebcd5ddd82dc472790eaef (diff) |
Improve recovery in a wonky case where one tries to specialize a
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
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 13 | ||||
-rw-r--r-- | test/SemaTemplate/class-template-spec.cpp | 5 |
3 files changed, 19 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 26693aa78c..2cc29caa01 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 9305d6ebb1..419347adcf 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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; diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp index 4cd43b469a..5bc9a6cd67 100644 --- a/test/SemaTemplate/class-template-spec.cpp +++ b/test/SemaTemplate/class-template-spec.cpp @@ -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}} |