diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 19 |
4 files changed, 62 insertions, 16 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 5ed973b1a8..161908e200 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1693,11 +1693,12 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, addAssociatedClassesAndNamespaces(Result, Arg.getAsType()); break; - case TemplateArgument::Template: { + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: { // [...] the namespaces in which any template template arguments are // defined; and the classes in which any member templates used as // template template arguments are defined. - TemplateName Template = Arg.getAsTemplate(); + TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) { DeclContext *Ctx = ClassTemplate->getDeclContext(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 9adcf1c81f..2c9a4307ed 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2256,10 +2256,12 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, break; case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: // We were given a template template argument. It may not be ill-formed; // see below. if (DependentTemplateName *DTN - = Arg.getArgument().getAsTemplate().getAsDependentTemplateName()) { + = Arg.getArgument().getAsTemplateOrTemplatePattern() + .getAsDependentTemplateName()) { // We have a template argument such as \c T::template X, which we // parsed as a template template argument. However, since we now // know that we need a non-type template argument, convert this @@ -2273,6 +2275,17 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, Arg.getTemplateQualifierRange(), NameInfo); + // If we parsed the template argument as a pack expansion, create a + // pack expansion expression. + if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ + ExprResult Expansion = ActOnPackExpansion(E, + Arg.getTemplateEllipsisLoc()); + if (Expansion.isInvalid()) + return true; + + E = Expansion.get(); + } + TemplateArgument Result; if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) return true; @@ -2348,6 +2361,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, return true; case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: if (CheckTemplateArgument(TempParm, Arg)) return true; diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index a72a29378a..5837ebd8e5 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -168,7 +168,16 @@ checkDeducedTemplateArguments(ASTContext &Context, // All other combinations are incompatible. return DeducedTemplateArgument(); - + + case TemplateArgument::TemplateExpansion: + if (Y.getKind() == TemplateArgument::TemplateExpansion && + Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(), + Y.getAsTemplateOrTemplatePattern())) + return X; + + // All other combinations are incompatible. + return DeducedTemplateArgument(); + case TemplateArgument::Expression: // If we deduced a dependent expression in one case and either an integral // constant or a declaration in another case, keep the integral constant @@ -934,7 +943,7 @@ DeduceTemplateArguments(Sema &S, Info.FirstArg = Param; Info.SecondArg = Arg; return Sema::TDK_NonDeducedMismatch; - + case TemplateArgument::Template: if (Arg.getKind() == TemplateArgument::Template) return DeduceTemplateArguments(S, TemplateParams, @@ -943,6 +952,10 @@ DeduceTemplateArguments(Sema &S, Info.FirstArg = Param; Info.SecondArg = Arg; return Sema::TDK_NonDeducedMismatch; + + case TemplateArgument::TemplateExpansion: + llvm_unreachable("caller should handle pack expansions"); + break; case TemplateArgument::Declaration: if (Arg.getKind() == TemplateArgument::Declaration && @@ -1282,10 +1295,11 @@ static bool isSameTemplateArg(ASTContext &Context, Y.getAsDecl()->getCanonicalDecl(); case TemplateArgument::Template: - return Context.getCanonicalTemplateName(X.getAsTemplate()) - .getAsVoidPointer() == - Context.getCanonicalTemplateName(Y.getAsTemplate()) - .getAsVoidPointer(); + case TemplateArgument::TemplateExpansion: + return Context.getCanonicalTemplateName( + X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() == + Context.getCanonicalTemplateName( + Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer(); case TemplateArgument::Integral: return *X.getAsIntegral() == *Y.getAsIntegral(); @@ -1356,9 +1370,11 @@ getTrivialTemplateArgumentLoc(Sema &S, } case TemplateArgument::Template: - return TemplateArgumentLoc(Arg, SourceRange(), Loc, - Arg.isPackExpansion()? Loc : SourceLocation()); - + return TemplateArgumentLoc(Arg, SourceRange(), Loc); + + case TemplateArgument::TemplateExpansion: + return TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc); + case TemplateArgument::Expression: return TemplateArgumentLoc(Arg, Arg.getAsExpr()); @@ -3244,7 +3260,9 @@ MarkUsedTemplateParameters(Sema &SemaRef, break; case TemplateArgument::Template: - MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsTemplate(), + case TemplateArgument::TemplateExpansion: + MarkUsedTemplateParameters(SemaRef, + TemplateArg.getAsTemplateOrTemplatePattern(), OnlyDeduced, Depth, Used); break; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 919f2c879c..d15f91a745 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2123,12 +2123,18 @@ public: } case TemplateArgument::Template: - llvm_unreachable("Unsupported pack expansion of templates"); + return TemplateArgumentLoc(TemplateArgument( + Pattern.getArgument().getAsTemplate(), + true), + Pattern.getTemplateQualifierRange(), + Pattern.getTemplateNameLoc(), + EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: case TemplateArgument::Declaration: case TemplateArgument::Pack: + case TemplateArgument::TemplateExpansion: llvm_unreachable("Pack expansion pattern has no parameter packs"); case TemplateArgument::Type: @@ -2531,7 +2537,11 @@ void TreeTransform<Derived>::InventTemplateArgumentLoc( case TemplateArgument::Template: Output = TemplateArgumentLoc(Arg, SourceRange(), Loc); break; - + + case TemplateArgument::TemplateExpansion: + Output = TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc); + break; + case TemplateArgument::Expression: Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); break; @@ -2600,7 +2610,10 @@ bool TreeTransform<Derived>::TransformTemplateArgument( Input.getTemplateNameLoc()); return false; } - + + case TemplateArgument::TemplateExpansion: + llvm_unreachable("Caller should expand pack expansions"); + case TemplateArgument::Expression: { // Template argument expressions are not potentially evaluated. EnterExpressionEvaluationContext Unevaluated(getSema(), |