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 | 1918166de779a3270131f6468533d229bb4ef106 (patch) | |
| tree | ebf51c408ab7104684d8d70453f72d28051dc105 /clang/lib | |
| parent | 01cecbffd677df87fceb1675ce6bd29056f7421e (diff) | |
| download | bcm5719-llvm-1918166de779a3270131f6468533d229bb4ef106.tar.gz bcm5719-llvm-1918166de779a3270131f6468533d229bb4ef106.zip  | |
Support deducing template arguments from nested initializer lists. PR12119.
llvm-svn: 152848
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 40 | 
1 files changed, 37 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 9970005b691..bc6138d559f 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/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.  | 

