[cfe-commits] r152848 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Thu Mar 15 14:40:51 PDT 2012
Author: cornedbee
Date: Thu Mar 15 16:40:51 2012
New Revision: 152848
URL: http://llvm.org/viewvc/llvm-project?rev=152848&view=rev
Log:
Support deducing template arguments from nested initializer lists. PR12119.
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=152848&r1=152847&r2=152848&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Mar 15 16:40:51 2012
@@ -2905,6 +2905,40 @@
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 @@
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.
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=152848&r1=152847&r2=152848&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Thu Mar 15 16:40:51 2012
@@ -137,3 +137,16 @@
haslist1::haslist1()
: il{1, 2, 3} // expected-warning{{at the end of the constructor}}
{}
+
+namespace PR12119 {
+ // Deduction with nested initializer lists.
+ template<typename T> void f(std::initializer_list<T>);
+ template<typename T> void g(std::initializer_list<std::initializer_list<T>>);
+
+ void foo() {
+ f({0, {1}});
+ g({{0, 1}, {2, 3}});
+ std::initializer_list<int> il = {1, 2};
+ g({il, {2, 3}});
+ }
+}
More information about the cfe-commits
mailing list