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. llvm-svn: 86913
This commit is contained in:
parent
0cfa3c4875
commit
dd6c0356ba
|
@ -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<
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue