diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-01-17 22:49:58 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-01-17 22:49:58 +0000 |
commit | 43144e72b5197c2e17a5586a59d41afe177d5055 (patch) | |
tree | 249aae0d63ae399170f7236687925619db7757e9 /clang/lib/Sema/SemaTemplateDeduction.cpp | |
parent | fb0b1f1f1f4db6d9743c8284c01fe09d30b64770 (diff) | |
download | bcm5719-llvm-43144e72b5197c2e17a5586a59d41afe177d5055.tar.gz bcm5719-llvm-43144e72b5197c2e17a5586a59d41afe177d5055.zip |
Template argument deduction for std::initializer_list arguments from initializer lists.
llvm-svn: 148352
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index ab2c2a3e678..738e596ef38 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2971,6 +2971,28 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) continue; + // 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; + // Removing references was already done. + if (!isStdInitializerList(ParamType, &X)) + continue; + + 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; + } + // Don't track the argument type, since an initializer list has none. + continue; + } + // Keep track of the argument type and corresponding parameter index, // so we can check for compatibility between the deduced A and A. OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx-1, @@ -3042,17 +3064,35 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, break; } - // Keep track of the argument type and corresponding argument index, - // so we can check for compatibility between the deduced A and A. - if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) - OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, - ArgType)); + // As above, initializer lists need special handling. + if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { + QualType X; + if (!isStdInitializerList(ParamType, &X)) { + ++ArgIdx; + break; + } - if (TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, - ParamType, ArgType, Info, - Deduced, TDF)) - return Result; + 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; + } + } else { + + // Keep track of the argument type and corresponding argument index, + // so we can check for compatibility between the deduced A and A. + if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) + OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, + ArgType)); + + if (TemplateDeductionResult Result + = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, + ParamType, ArgType, Info, + Deduced, TDF)) + return Result; + } // Capture the deduced template arguments for each parameter pack expanded // by this pack expansion, add them to the list of arguments we've deduced |