aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-12 19:43:02 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-12 19:43:02 +0000
commitba1ecb564c05c2b749193e8deef1df3b69ea3f54 (patch)
tree51e80f25ae47a7bf14cb8b4f2e4f0e1de9378dc1 /lib/Sema/SemaTemplate.cpp
parent7e8976b22e61ff8fb7a9c298df52dc12c0665a68 (diff)
Verify that the template parameters of a class template partial
specialization do not have default arguments (C++ [temp.class.spec]p10). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73245 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 7c1c7cf0e1..d08e268b63 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1731,7 +1731,12 @@ bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
// template template argument with the corresponding parameter;
// partial specializations are not considered even if their
// parameter lists match that of the template template parameter.
- if (!isa<ClassTemplateDecl>(Template)) {
+ //
+ // Note that we also allow template template parameters here, which
+ // will happen when we are dealing with, e.g., class template
+ // partial specializations.
+ if (!isa<ClassTemplateDecl>(Template) &&
+ !isa<TemplateTemplateParmDecl>(Template)) {
assert(isa<FunctionTemplateDecl>(Template) &&
"Only function templates are possible here");
Diag(Arg->getSourceRange().getBegin(),
@@ -2033,9 +2038,41 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
return true;
}
- // FIXME: We'll need more checks, here!
- if (TemplateParams->size() > 0)
+ if (TemplateParams->size() > 0) {
isPartialSpecialization = true;
+
+ // C++ [temp.class.spec]p10:
+ // The template parameter list of a specialization shall not
+ // contain default template argument values.
+ for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+ Decl *Param = TemplateParams->getParam(I);
+ if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+ if (TTP->hasDefaultArgument()) {
+ Diag(TTP->getDefaultArgumentLoc(),
+ diag::err_default_arg_in_partial_spec);
+ TTP->setDefaultArgument(QualType(), SourceLocation(), false);
+ }
+ } else if (NonTypeTemplateParmDecl *NTTP
+ = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ if (Expr *DefArg = NTTP->getDefaultArgument()) {
+ Diag(NTTP->getDefaultArgumentLoc(),
+ diag::err_default_arg_in_partial_spec)
+ << DefArg->getSourceRange();
+ NTTP->setDefaultArgument(0);
+ DefArg->Destroy(Context);
+ }
+ } else {
+ TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
+ if (Expr *DefArg = TTP->getDefaultArgument()) {
+ Diag(TTP->getDefaultArgumentLoc(),
+ diag::err_default_arg_in_partial_spec)
+ << DefArg->getSourceRange();
+ TTP->setDefaultArgument(0);
+ DefArg->Destroy(Context);
+ }
+ }
+ }
+ }
}
// Check that the specialization uses the same tag kind as the
@@ -2078,11 +2115,12 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
// Find the class template (partial) specialization declaration that
// corresponds to these arguments.
llvm::FoldingSetNodeID ID;
- if (isPartialSpecialization)
+ if (isPartialSpecialization) {
// FIXME: Template parameter list matters, too
ClassTemplatePartialSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.flatSize());
+ }
else
ClassTemplateSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.getFlatArgumentList(),