summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateVariadic.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-05 17:40:24 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-05 17:40:24 +0000
commiteb29d18e5da3452d57891135dcfadd5e8eac5102 (patch)
treea9b9cddde3be8bd7f545843354d43a53e74ab002 /clang/lib/Sema/SemaTemplateVariadic.cpp
parent07fd1efcfa6ac0b5f2abfb25df29b002180ab380 (diff)
downloadbcm5719-llvm-eb29d18e5da3452d57891135dcfadd5e8eac5102.tar.gz
bcm5719-llvm-eb29d18e5da3452d57891135dcfadd5e8eac5102.zip
Add semantic analysis for the creation of and an AST representation
for template template argument pack expansions. This allows fun such as: template<template<class> class ...> struct apply_impl { /*...*/ }; template<template<class> class ...Metafunctions> struct apply { typedef typename apply_impl<Metafunctions...>::type type; }; However, neither template argument deduction nor template instantiation is implemented for template template argument packs, so this functionality isn't useful yet. I'll probably replace the encoding of template template argument pack expansions in TemplateArgument so that it's harder to accidentally forget about the expansion. However, this is a step in the right general direction. llvm-svn: 122890
Diffstat (limited to 'clang/lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index acb73144d92..fb88bd114b4 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -130,6 +130,22 @@ namespace {
return true;
}
+
+ /// \brief Suppress traversal of template argument pack expansions.
+ bool TraverseTemplateArgument(const TemplateArgument &Arg) {
+ if (Arg.isPackExpansion())
+ return true;
+
+ return inherited::TraverseTemplateArgument(Arg);
+ }
+
+ /// \brief Suppress traversal of template argument pack expansions.
+ bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
+ if (ArgLoc.getArgument().isPackExpansion())
+ return true;
+
+ return inherited::TraverseTemplateArgumentLoc(ArgLoc);
+ }
};
}
@@ -335,8 +351,16 @@ Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
}
case ParsedTemplateArgument::Template:
- Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
- return ParsedTemplateArgument();
+ if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
+ SourceRange R(Arg.getLocation());
+ if (Arg.getScopeSpec().isValid())
+ R.setBegin(Arg.getScopeSpec().getBeginLoc());
+ Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
+ << R;
+ return ParsedTemplateArgument();
+ }
+
+ return Arg.getTemplatePackExpansion(EllipsisLoc);
}
llvm_unreachable("Unhandled template argument kind?");
return ParsedTemplateArgument();
OpenPOWER on IntegriCloud