aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-03-15 21:40:51 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-03-15 21:40:51 +0000
commit4b911e6536ed77524c3cef572cb0f6c8d9079e2e (patch)
tree2f2e89d70aeae5da506ad751054a7da359b0d90f /lib/Sema/SemaTemplateDeduction.cpp
parentafcd1954be90965d832ae56f1413beae836c3346 (diff)
Support deducing template arguments from nested initializer lists. PR12119.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152848 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 9970005b69..bc6138d559 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2905,6 +2905,40 @@ static bool hasDeducibleTemplateParameters(Sema &S,
FunctionTemplateDecl *FunctionTemplate,
QualType T);
+/// \brief Perform template argument deduction by matching a parameter type
+/// against a single expression, where the expression is an element of
+/// an initializer list that was originally matched against the argument
+/// type.
+static Sema::TemplateDeductionResult
+DeduceTemplateArgumentByListElement(Sema &S,
+ TemplateParameterList *TemplateParams,
+ QualType ParamType, Expr *Arg,
+ TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ unsigned TDF) {
+ // Handle the case where an init list contains another init list as the
+ // element.
+ if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
+ QualType X;
+ if (!S.isStdInitializerList(ParamType.getNonReferenceType(), &X))
+ return Sema::TDK_Success; // Just ignore this expression.
+
+ // Recurse down into the init list.
+ for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) {
+ if (Sema::TemplateDeductionResult Result =
+ DeduceTemplateArgumentByListElement(S, TemplateParams, X,
+ ILE->getInit(i),
+ Info, Deduced, TDF))
+ return Result;
+ }
+ return Sema::TDK_Success;
+ }
+
+ // For all other cases, just match by type.
+ return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
+ Arg->getType(), Info, Deduced, TDF);
+}
+
/// \brief Perform template argument deduction from a function call
/// (C++ [temp.deduct.call]).
///
@@ -3025,9 +3059,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) {
if (TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, X,
- ILE->getInit(i)->getType(),
- Info, Deduced, TDF))
+ DeduceTemplateArgumentByListElement(*this, TemplateParams, X,
+ ILE->getInit(i),
+ Info, Deduced, TDF))
return Result;
}
// Don't track the argument type, since an initializer list has none.