[cfe-commits] r84991 - in /cfe/trunk: lib/AST/Expr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp test/SemaTemplate/member-template-access-expr.cpp
Douglas Gregor
dgregor at apple.com
Fri Oct 23 21:59:54 PDT 2009
Author: dgregor
Date: Fri Oct 23 23:59:53 2009
New Revision: 84991
URL: http://llvm.org/viewvc/llvm-project?rev=84991&view=rev
Log:
Fix overload resolution when calling a member template or taking the
address of a member template when explicit template arguments are
provided.
Modified:
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaTemplate/member-template-access-expr.cpp
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=84991&r1=84990&r2=84991&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Oct 23 23:59:53 2009
@@ -1126,6 +1126,18 @@
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;
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=84991&r1=84990&r2=84991&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Oct 23 23:59:53 2009
@@ -2337,6 +2337,7 @@
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)
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=84991&r1=84990&r2=84991&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Oct 23 23:59:53 2009
@@ -4287,10 +4287,15 @@
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 @@
// 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 @@
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(),
Modified: cfe/trunk/test/SemaTemplate/member-template-access-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/member-template-access-expr.cpp?rev=84991&r1=84990&r2=84991&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/member-template-access-expr.cpp (original)
+++ cfe/trunk/test/SemaTemplate/member-template-access-expr.cpp Fri Oct 23 23:59:53 2009
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-
template<typename U, typename T>
U f0(T t) {
return t.template get<U>();
@@ -50,3 +49,29 @@
void do_destroy_B(B<int> b) {
b.destroy();
}
+
+struct X1 {
+ int* f1(int);
+ template<typename T> float* f1(T);
+
+ static int* f2(int);
+ template<typename T> static float* f2(T);
+};
+
+void test_X1(X1 x1) {
+ float *fp1 = x1.f1<>(17);
+ float *fp2 = x1.f1<int>(3.14);
+ int *ip1 = x1.f1(17);
+ float *ip2 = x1.f1(3.14);
+
+ float* (X1::*mf1)(int) = &X1::f1;
+ float* (X1::*mf2)(int) = &X1::f1<>;
+ float* (X1::*mf3)(float) = &X1::f1<float>;
+
+ float* (*fp3)(int) = &X1::f2;
+ float* (*fp4)(int) = &X1::f2<>;
+ float* (*fp5)(float) = &X1::f2<float>;
+ float* (*fp6)(int) = X1::f2;
+ float* (*fp7)(int) = X1::f2<>;
+ float* (*fp8)(float) = X1::f2<float>;
+}
More information about the cfe-commits
mailing list