diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 28 |
3 files changed, 45 insertions, 7 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ff0fe9d6b6..9adcf1c81f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -437,6 +437,17 @@ TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) { return 0; } +ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion( + SourceLocation EllipsisLoc) const { + assert(Kind == Template && + "Only template template arguments can be pack expansions here"); + assert(getAsTemplate().get().containsUnexpandedParameterPack() && + "Template template argument pack expansion without packs"); + ParsedTemplateArgument Result(*this); + Result.EllipsisLoc = EllipsisLoc; + return Result; +} + static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, const ParsedTemplateArgument &Arg) { @@ -456,9 +467,11 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, case ParsedTemplateArgument::Template: { TemplateName Template = Arg.getAsTemplate().get(); - return TemplateArgumentLoc(TemplateArgument(Template), + return TemplateArgumentLoc(TemplateArgument(Template, + Arg.getEllipsisLoc().isValid()), Arg.getScopeSpec().getRange(), - Arg.getLocation()); + Arg.getLocation(), + Arg.getEllipsisLoc()); } } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 18bfee301b..a72a29378a 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1344,19 +1344,20 @@ getTrivialTemplateArgumentLoc(Sema &S, case TemplateArgument::Declaration: { Expr *E - = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) + = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) .takeAs<Expr>(); return TemplateArgumentLoc(TemplateArgument(E), E); } case TemplateArgument::Integral: { Expr *E - = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>(); + = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>(); return TemplateArgumentLoc(TemplateArgument(E), E); } case TemplateArgument::Template: - return TemplateArgumentLoc(Arg, SourceRange(), Loc); + return TemplateArgumentLoc(Arg, SourceRange(), Loc, + Arg.isPackExpansion()? Loc : SourceLocation()); case TemplateArgument::Expression: return TemplateArgumentLoc(Arg, Arg.getAsExpr()); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index acb73144d9..fb88bd114b 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/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(); |