diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-03-15 21:40:51 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-03-15 21:40:51 +0000 |
commit | 4b911e6536ed77524c3cef572cb0f6c8d9079e2e (patch) | |
tree | 2f2e89d70aeae5da506ad751054a7da359b0d90f /lib/Sema/SemaTemplateDeduction.cpp | |
parent | afcd1954be90965d832ae56f1413beae836c3346 (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.cpp | 40 |
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. |