aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-24 04:59:53 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-24 04:59:53 +0000
commit3eefb1c4bd2c562e43f25e0dba657bb32361dd14 (patch)
treedeb707e1fac14d534b44d44e0bf818f6f5088c03 /lib
parent4d0d85c3370f2726c74ba0ece0a5e712830a1d82 (diff)
Fix overload resolution when calling a member template or taking the
address of a member template when explicit template arguments are provided. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84991 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp12
-rw-r--r--lib/Sema/SemaExprCXX.cpp1
-rw-r--r--lib/Sema/SemaOverload.cpp20
3 files changed, 30 insertions, 3 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 47df95dc71..ad9c9cbe10 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1126,6 +1126,18 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
return LV_Valid;
}
+ case TemplateIdRefExprClass: {
+ const TemplateIdRefExpr *TID = cast<TemplateIdRefExpr>(this);
+ TemplateName Template = TID->getTemplateName();
+ NamedDecl *ND = Template.getAsTemplateDecl();
+ if (!ND)
+ ND = Template.getAsOverloadedFunctionDecl();
+ if (ND && DeclCanBeLvalue(ND, Ctx))
+ return LV_Valid;
+
+ break;
+ }
+
default:
break;
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 6f26ea1eee..3aac415c04 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2337,6 +2337,7 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D,
if (!Method && (FunTmpl = dyn_cast<FunctionTemplateDecl>(*Ovl)))
Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ // FIXME: Do we have to know if there are explicit template arguments?
if (Method && !Method->isStatic()) {
Ctx = Method->getParent();
if (isa<CXXMethodDecl>(D) && !FunTmpl)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 7ed79f3073..fbb50aea87 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4287,10 +4287,15 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr)) {
Ovl = dyn_cast<OverloadedFunctionDecl>(DR->getDecl());
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl());
+ HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList();
+ ExplicitTemplateArgs = DR->getTemplateArgs();
+ NumExplicitTemplateArgs = DR->getNumTemplateArgs();
} else if (MemberExpr *ME = dyn_cast<MemberExpr>(OvlExpr)) {
Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl());
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl());
- // FIXME: Explicit template arguments
+ HasExplicitTemplateArgs = ME->hasExplicitTemplateArgumentList();
+ ExplicitTemplateArgs = ME->getTemplateArgs();
+ NumExplicitTemplateArgs = ME->getNumTemplateArgs();
} else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(OvlExpr)) {
TemplateName Name = TIRE->getTemplateName();
Ovl = Name.getAsOverloadedFunctionDecl();
@@ -4367,6 +4372,10 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
// when converting to member pointer.
if (Method->isStatic() == IsMember)
continue;
+
+ // If we have explicit template arguments, skip non-templates.
+ if (HasExplicitTemplateArgs)
+ continue;
} else if (IsMember)
continue;
@@ -4967,10 +4976,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
for (OverloadIterator Func(MemExpr->getMemberDecl()), FuncEnd;
Func != FuncEnd; ++Func) {
- if ((Method = dyn_cast<CXXMethodDecl>(*Func)))
+ if ((Method = dyn_cast<CXXMethodDecl>(*Func))) {
+ // If explicit template arguments were provided, we can't call a
+ // non-template member function.
+ if (MemExpr->hasExplicitTemplateArgumentList())
+ continue;
+
AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/false);
- else
+ } else
AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
MemExpr->hasExplicitTemplateArgumentList(),
MemExpr->getTemplateArgs(),