diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-06-30 23:57:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-06-30 23:57:56 +0000 |
commit | 6db8ed4498b83fe9336e3855a4ba1a298b04ee00 (patch) | |
tree | c2fa0c5100146fd311425d5da61323dc6a7955b2 /lib/Sema/SemaExpr.cpp | |
parent | bcfad54a43e5570e09daddd976bd4545933e75b1 (diff) |
When explicit template arguments are provided for a function call,
substitute those template arguments into the function parameter types
prior to template argument deduction. There's still a bit of work to
do to make this work properly when only some of the template arguments
are specified.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74576 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2ee3c992b6..e9c88d7f6e 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2635,8 +2635,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, } // If we're directly calling a function, get the appropriate declaration. + // Also, in C++, keep track of whether we should perform argument-dependent + // lookup and whether there were any explicitly-specified template arguments. Expr *FnExpr = Fn; bool ADL = true; + bool HasExplicitTemplateArgs = 0; + const TemplateArgument *ExplicitTemplateArgs = 0; + unsigned NumExplicitTemplateArgs = 0; while (true) { if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr)) FnExpr = IcExpr->getSubExpr(); @@ -2661,6 +2666,28 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, } else if (TemplateIdRefExpr *TemplateIdRef = dyn_cast<TemplateIdRefExpr>(FnExpr)) { NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl(); + HasExplicitTemplateArgs = true; + ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs(); + NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs(); + + // C++ [temp.arg.explicit]p6: + // [Note: For simple function names, argument dependent lookup (3.4.2) + // applies even when the function name is not visible within the + // scope of the call. This is because the call still has the syntactic + // form of a function call (3.4.1). But when a function template with + // explicit template arguments is used, the call does not have the + // correct syntactic form unless there is a function template with + // that name visible at the point of the call. If no such name is + // visible, the call is not syntactically well-formed and + // argument-dependent lookup does not apply. If some such name is + // visible, argument dependent lookup applies and additional function + // templates may be found in other namespaces. + // + // The summary of this paragraph is that, if we get to this point and the + // template-id was not a qualified name, then argument-dependent lookup + // is still possible. + if (TemplateIdRef->getQualifier()) + ADL = false; break; } else { // Any kind of name that does not refer to a declaration (or @@ -2692,8 +2719,12 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, ADL = false; if (Ovl || FunctionTemplate || ADL) { - FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName, LParenLoc, - Args, NumArgs, CommaLocs, RParenLoc, ADL); + FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName, + HasExplicitTemplateArgs, + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + LParenLoc, Args, NumArgs, CommaLocs, + RParenLoc, ADL); if (!FDecl) return ExprError(); |