summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-03-12 21:09:16 +0000
committerDouglas Gregor <dgregor@apple.com>2012-03-12 21:09:16 +0000
commit8409ccd8f69483e35ae4cc0442fbdb9a85cbfbca (patch)
treed67cfcf44151767891884fe4fb22815e948bf465 /clang/lib
parent5b796ba1905bcf11dc93331b17abe2a6f71ceab7 (diff)
downloadbcm5719-llvm-8409ccd8f69483e35ae4cc0442fbdb9a85cbfbca.tar.gz
bcm5719-llvm-8409ccd8f69483e35ae4cc0442fbdb9a85cbfbca.zip
C++11 [temp.deduct.call]p6 tweak: when given a set of overlaoded
functions that includes an explicit template argument list, perform an inner deduction against each of the function templates in that list and, if successful, use the result of that deduction for the outer template argument deduction. Fixes PR11713. llvm-svn: 152575
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp48
1 files changed, 30 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 1d43b3fd4d5..9970005b691 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2709,36 +2709,48 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
if (R.IsAddressOfOperand)
TDF |= TDF_IgnoreQualifiers;
- // If there were explicit template arguments, we can only find
- // something via C++ [temp.arg.explicit]p3, i.e. if the arguments
- // unambiguously name a full specialization.
- if (Ovl->hasExplicitTemplateArgs()) {
- // But we can still look for an explicit specialization.
- if (FunctionDecl *ExplicitSpec
- = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
- return GetTypeOfFunction(S.Context, R, ExplicitSpec);
- return QualType();
- }
-
// C++0x [temp.deduct.call]p6:
// When P is a function type, pointer to function type, or pointer
// to member function type:
if (!ParamType->isFunctionType() &&
!ParamType->isFunctionPointerType() &&
- !ParamType->isMemberFunctionPointerType())
- return QualType();
+ !ParamType->isMemberFunctionPointerType()) {
+ if (Ovl->hasExplicitTemplateArgs()) {
+ // But we can still look for an explicit specialization.
+ if (FunctionDecl *ExplicitSpec
+ = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
+ return GetTypeOfFunction(S.Context, R, ExplicitSpec);
+ }
+ return QualType();
+ }
+
+ // Gather the explicit template arguments, if any.
+ TemplateArgumentListInfo ExplicitTemplateArgs;
+ if (Ovl->hasExplicitTemplateArgs())
+ Ovl->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
QualType Match;
for (UnresolvedSetIterator I = Ovl->decls_begin(),
E = Ovl->decls_end(); I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
- // - If the argument is an overload set containing one or more
- // function templates, the parameter is treated as a
- // non-deduced context.
- if (isa<FunctionTemplateDecl>(D))
- return QualType();
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
+ // - If the argument is an overload set containing one or more
+ // function templates, the parameter is treated as a
+ // non-deduced context.
+ if (!Ovl->hasExplicitTemplateArgs())
+ return QualType();
+
+ // Otherwise, see if we can resolve a function type
+ FunctionDecl *Specialization = 0;
+ TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
+ if (S.DeduceTemplateArguments(FunTmpl, &ExplicitTemplateArgs,
+ Specialization, Info))
+ continue;
+
+ D = Specialization;
+ }
FunctionDecl *Fn = cast<FunctionDecl>(D);
QualType ArgType = GetTypeOfFunction(S.Context, R, Fn);
OpenPOWER on IntegriCloud