[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