Implement support for calling member function templates, which involves:
- Allowing one to name a member function template within a class
template and on the right-hand side of a member access expression.
- Template argument deduction for calls to member function templates.
- Registering specializations of member function templates (and
finding them later).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79581 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9f2be1c..5f16ef3 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -939,18 +939,35 @@
Ctx = Method->getParent();
MemberType = Method->getType();
}
+ } else if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(D)) {
+ if (CXXMethodDecl *Method
+ = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())) {
+ if (!Method->isStatic()) {
+ Ctx = Method->getParent();
+ MemberType = Context.OverloadTy;
+ }
+ }
} else if (OverloadedFunctionDecl *Ovl
= dyn_cast<OverloadedFunctionDecl>(D)) {
+ // FIXME: We need an abstraction for iterating over one or more function
+ // templates or functions. This code is far too repetitive!
for (OverloadedFunctionDecl::function_iterator
Func = Ovl->function_begin(),
FuncEnd = Ovl->function_end();
Func != FuncEnd; ++Func) {
- if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(*Func))
- if (!DMethod->isStatic()) {
- Ctx = Ovl->getDeclContext();
- MemberType = Context.OverloadTy;
- break;
- }
+ CXXMethodDecl *DMethod = 0;
+ if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(*Func))
+ DMethod = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ else
+ DMethod = dyn_cast<CXXMethodDecl>(*Func);
+
+ if (DMethod && !DMethod->isStatic()) {
+ Ctx = DMethod->getDeclContext();
+ MemberType = Context.OverloadTy;
+ break;
+ }
}
}
@@ -2112,6 +2129,13 @@
MemberFn, MemberLoc,
MemberFn->getType()));
}
+ if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(MemberDecl)) {
+ MarkDeclarationReferenced(MemberLoc, MemberDecl);
+ return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow,
+ FunTmpl, MemberLoc,
+ Context.OverloadTy));
+ }
if (OverloadedFunctionDecl *Ovl
= dyn_cast<OverloadedFunctionDecl>(MemberDecl))
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl,