summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-15 06:45:20 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-15 06:45:20 +0000
commit5590be0491cb6a88146c1580d35dc67b68719c33 (patch)
tree5dbc9b9153276969ba28dacb4961354aa7dc6188 /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent9c10d587f6fd445becdd0a5fa62af0d8de9adabd (diff)
downloadbcm5719-llvm-5590be0491cb6a88146c1580d35dc67b68719c33.tar.gz
bcm5719-llvm-5590be0491cb6a88146c1580d35dc67b68719c33.zip
Introduce a new kind of TemplateName that captures a substituted
template template parameter pack that cannot be fully expanded because its enclosing pack expansion could not be expanded. This form of TemplateName plays the same role as SubstTemplateTypeParmPackType and SubstNonTypeTemplateParmPackExpr do for template type parameter packs and non-type template parameter packs, respectively. We should now handle these multi-level pack expansion substitutions anywhere. The largest remaining gap in our variadic-templates support is that we cannot cope with non-type template parameter packs whose type is a pack expansion. llvm-svn: 123521
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp65
1 files changed, 59 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8943daa3698..98fa390febc 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -697,6 +697,10 @@ namespace {
ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType T);
+ TemplateName TransformTemplateName(TemplateName Name,
+ QualType ObjectType = QualType(),
+ NamedDecl *FirstQualifierInScope = 0);
+
ExprResult TransformPredefinedExpr(PredefinedExpr *E);
ExprResult TransformDeclRefExpr(DeclRefExpr *E);
ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
@@ -762,12 +766,7 @@ Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
- if (getSema().ArgumentPackSubstitutionIndex == -1) {
- // FIXME: Variadic templates fun case.
- getSema().Diag(Loc, diag::err_pack_expansion_mismatch_unsupported);
- return 0;
- }
-
+ assert(getSema().ArgumentPackSubstitutionIndex >= 0);
assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
}
@@ -887,6 +886,60 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
NNS, T);
}
+TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name,
+ QualType ObjectType,
+ NamedDecl *FirstQualifierInScope) {
+ if (TemplateTemplateParmDecl *TTP
+ = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
+ if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
+ // If the corresponding template argument is NULL or non-existent, it's
+ // because we are performing instantiation from explicitly-specified
+ // template arguments in a function template, but there were some
+ // arguments left unspecified.
+ if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
+ TTP->getPosition()))
+ return Name;
+
+ TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
+
+ if (TTP->isParameterPack()) {
+ assert(Arg.getKind() == TemplateArgument::Pack &&
+ "Missing argument pack");
+
+ if (getSema().ArgumentPackSubstitutionIndex == -1) {
+ // We have the template argument pack to substitute, but we're not
+ // actually expanding the enclosing pack expansion yet. So, just
+ // keep the entire argument pack.
+ return getSema().Context.getSubstTemplateTemplateParmPack(TTP, Arg);
+ }
+
+ assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
+ Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+ }
+
+ TemplateName Template = Arg.getAsTemplate();
+ assert(!Template.isNull() && Template.getAsTemplateDecl() &&
+ "Wrong kind of template template argument");
+ return Template;
+ }
+ }
+
+ if (SubstTemplateTemplateParmPackStorage *SubstPack
+ = Name.getAsSubstTemplateTemplateParmPack()) {
+ if (getSema().ArgumentPackSubstitutionIndex == -1)
+ return Name;
+
+ const TemplateArgument &ArgPack = SubstPack->getArgumentPack();
+ assert(getSema().ArgumentPackSubstitutionIndex < (int)ArgPack.pack_size() &&
+ "Pack substitution index out-of-range");
+ return ArgPack.pack_begin()[getSema().ArgumentPackSubstitutionIndex]
+ .getAsTemplate();
+ }
+
+ return inherited::TransformTemplateName(Name, ObjectType,
+ FirstQualifierInScope);
+}
+
ExprResult
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
OpenPOWER on IntegriCloud