r240612 - Consolidate and unify initializer list deduction
Hubert Tong
hubert.reinterpretcast at gmail.com
Wed Jun 24 17:25:49 PDT 2015
Author: hubert.reinterpretcast
Date: Wed Jun 24 19:25:49 2015
New Revision: 240612
URL: http://llvm.org/viewvc/llvm-project?rev=240612&view=rev
Log:
Consolidate and unify initializer list deduction
Summary:
This patch reduces duplication in the template argument deduction code
for handling deduction from initializer lists in a function call. This
extends the fix for PR12119 to also apply to the case where the
corresponding parameter is a trailing parameter pack.
Test Plan:
A test for deduction from nested initializer lists where the
corresponding parameter is a trailing parameter pack is added in
`clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp`.
Reviewers: fraggamuffin, rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D10681
Modified:
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=240612&r1=240611&r2=240612&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Jun 24 19:25:49 2015
@@ -3190,6 +3190,40 @@ static bool
hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate,
QualType T);
+static Sema::TemplateDeductionResult DeduceTemplateArgumentByListElement(
+ Sema &S, TemplateParameterList *TemplateParams, QualType ParamType,
+ Expr *Arg, TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF);
+
+/// \brief Attempt template argument deduction from an initializer list
+/// deemed to be an argument in a function call.
+static bool
+DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams,
+ QualType AdjustedParamType, InitListExpr *ILE,
+ TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ unsigned TDF, Sema::TemplateDeductionResult &Result) {
+ // If the argument is an initializer list then the parameter is an undeduced
+ // context, unless the parameter type is (reference to cv)
+ // std::initializer_list<P'>, in which case deduction is done for each element
+ // of the initializer list as-if it were an argument in a function call, and
+ // the result is the deduced type if it's the same for all elements.
+ QualType X;
+ if (!S.isStdInitializerList(AdjustedParamType, &X))
+ return false;
+
+ Result = Sema::TDK_Success;
+
+ // Recurse down into the init list.
+ for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) {
+ if ((Result = DeduceTemplateArgumentByListElement(
+ S, TemplateParams, X, ILE->getInit(i), Info, Deduced, TDF)))
+ return true;
+ }
+
+ return true;
+}
+
/// \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 a parameter
@@ -3204,19 +3238,13 @@ DeduceTemplateArgumentByListElement(Sema
// 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))
+ Sema::TemplateDeductionResult Result;
+ if (!DeduceFromInitializerList(S, TemplateParams,
+ ParamType.getNonReferenceType(), ILE, Info,
+ Deduced, TDF, Result))
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;
+ return Result;
}
// For all other cases, just match by type.
@@ -3335,22 +3363,14 @@ Sema::TemplateDeductionResult Sema::Dedu
// If the argument is an initializer list ...
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
- // ... then the parameter is an undeduced context, unless the parameter
- // type is (reference to cv) std::initializer_list<P'>, in which case
- // deduction is done for each element of the initializer list, and the
- // result is the deduced type if it's the same for all elements.
- QualType X;
+ TemplateDeductionResult Result;
// Removing references was already done.
- if (!isStdInitializerList(ParamType, &X))
+ if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE,
+ Info, Deduced, TDF, Result))
continue;
- for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) {
- if (TemplateDeductionResult Result =
- DeduceTemplateArgumentByListElement(*this, TemplateParams, X,
- ILE->getInit(i),
- Info, Deduced, TDF))
- return Result;
- }
+ if (Result)
+ return Result;
// Don't track the argument type, since an initializer list has none.
continue;
}
@@ -3406,19 +3426,15 @@ Sema::TemplateDeductionResult Sema::Dedu
// As above, initializer lists need special handling.
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
- QualType X;
- if (!isStdInitializerList(ParamType, &X)) {
+ TemplateDeductionResult Result;
+ if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE,
+ Info, Deduced, TDF, Result)) {
++ArgIdx;
break;
}
- for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) {
- if (TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, X,
- ILE->getInit(i)->getType(),
- Info, Deduced, TDF))
- return Result;
- }
+ if (Result)
+ return Result;
} else {
// Keep track of the argument type and corresponding argument index,
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=240612&r1=240611&r2=240612&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Wed Jun 24 19:25:49 2015
@@ -275,3 +275,10 @@ namespace TemporaryInitListSourceRange_P
{0}
);
}
+
+namespace ParameterPackNestedInitializerLists_PR23904c3 {
+ template <typename ...T>
+ void f(std::initializer_list<std::initializer_list<T>> ...tt);
+
+ void foo() { f({{0}}, {{'\0'}}); }
+}
More information about the cfe-commits
mailing list