[cfe-commits] r122774 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
Douglas Gregor
dgregor at apple.com
Mon Jan 3 13:13:47 PST 2011
Author: dgregor
Date: Mon Jan 3 15:13:47 2011
New Revision: 122774
URL: http://llvm.org/viewvc/llvm-project?rev=122774&view=rev
Log:
Unwrap template argument packs when checking the template arguments of
a class template partial specialiation, and look through pack
expansions when checking the conditions of C++0x [temp.class.spec]p8.
Added:
cfe/trunk/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=122774&r1=122773&r2=122774&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jan 3 15:13:47 2011
@@ -2910,10 +2910,6 @@
bool EnteringContext,
TemplateTy &Template);
- bool CheckClassTemplatePartialSpecializationArgs(
- TemplateParameterList *TemplateParams,
- llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs);
-
DeclResult
ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=122774&r1=122773&r2=122774&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jan 3 15:13:47 2011
@@ -3915,34 +3915,31 @@
return false;
}
-
-/// \brief Check the non-type template arguments of a class template
-/// partial specialization according to C++ [temp.class.spec]p9.
-///
-/// \param TemplateParams the template parameters of the primary class
-/// template.
-///
-/// \param TemplateArg the template arguments of the class template
-/// partial specialization.
-///
-/// \returns true if there was an error, false otherwise.
-bool Sema::CheckClassTemplatePartialSpecializationArgs(
- TemplateParameterList *TemplateParams,
- llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs) {
- const TemplateArgument *ArgList = TemplateArgs.data();
-
- for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
- NonTypeTemplateParmDecl *Param
- = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
- if (!Param)
+
+/// \brief Subroutine of Sema::CheckClassTemplatePartialSpecializationArgs
+/// that checks non-type template partial specialization arguments.
+static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S,
+ NonTypeTemplateParmDecl *Param,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ if (Args[I].getKind() == TemplateArgument::Pack) {
+ if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
+ Args[I].pack_begin(),
+ Args[I].pack_size()))
+ return true;
+
continue;
-
- Expr *ArgExpr = ArgList[I].getAsExpr();
+ }
+
+ Expr *ArgExpr = Args[I].getAsExpr();
if (!ArgExpr) {
continue;
}
- // FIXME: Variadic templates. Unwrap argument packs.
+ // We can have a pack expansion of any of the above.
+ if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(ArgExpr))
+ ArgExpr = Expansion->getPattern();
// C++ [temp.class.spec]p8:
// A non-type argument is non-specialized if it is the name of a
@@ -3964,24 +3961,53 @@
// specialization except when the argument expression is a
// simple identifier.
if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) {
- Diag(ArgExpr->getLocStart(),
+ S.Diag(ArgExpr->getLocStart(),
diag::err_dependent_non_type_arg_in_partial_spec)
<< ArgExpr->getSourceRange();
return true;
}
-
+
// -- The type of a template parameter corresponding to a
// specialized non-type argument shall not be dependent on a
// parameter of the specialization.
if (Param->getType()->isDependentType()) {
- Diag(ArgExpr->getLocStart(),
+ S.Diag(ArgExpr->getLocStart(),
diag::err_dependent_typed_non_type_arg_in_partial_spec)
<< Param->getType()
<< ArgExpr->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
+ S.Diag(Param->getLocation(), diag::note_template_param_here);
return true;
}
}
+
+ return false;
+}
+
+/// \brief Check the non-type template arguments of a class template
+/// partial specialization according to C++ [temp.class.spec]p9.
+///
+/// \param TemplateParams the template parameters of the primary class
+/// template.
+///
+/// \param TemplateArg the template arguments of the class template
+/// partial specialization.
+///
+/// \returns true if there was an error, false otherwise.
+static bool CheckClassTemplatePartialSpecializationArgs(Sema &S,
+ TemplateParameterList *TemplateParams,
+ llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs) {
+ const TemplateArgument *ArgList = TemplateArgs.data();
+
+ for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+ NonTypeTemplateParmDecl *Param
+ = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
+ if (!Param)
+ continue;
+
+ if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
+ &ArgList[I], 1))
+ return true;
+ }
return false;
}
@@ -4145,7 +4171,7 @@
// Find the class template (partial) specialization declaration that
// corresponds to these arguments.
if (isPartialSpecialization) {
- if (CheckClassTemplatePartialSpecializationArgs(
+ if (CheckClassTemplatePartialSpecializationArgs(*this,
ClassTemplate->getTemplateParameters(),
Converted))
return true;
Added: cfe/trunk/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp?rev=122774&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp Mon Jan 3 15:13:47 2011
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<int ...Values> struct X1;
+
+template<int ...Values>
+struct X1<0, Values+1 ...>; // expected-error{{non-type template argument depends on a template parameter of the partial specialization}}
+
+
More information about the cfe-commits
mailing list