diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-21 00:16:32 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-21 00:16:32 +0000 |
commit | 6b906869527be40b0d38d755e9ef51b331b88162 (patch) | |
tree | 383418b55d313e27f7e21b20756b8f5347176355 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | c42a92aa1fbd24b7a26c7c29552d07478a8e2045 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 23256a853c..8d75ac463a 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -457,7 +457,26 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { } Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { - // FIXME: Look for existing, explicit specializations. + // Check whether there is already a function template specialization for + // this declaration. + FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); + void *InsertPos = 0; + if (FunctionTemplate) { + llvm::FoldingSetNodeID ID; + FunctionTemplateSpecializationInfo::Profile(ID, + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size(), + SemaRef.Context); + + FunctionTemplateSpecializationInfo *Info + = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID, + InsertPos); + + // If we already have a function template specialization, return it. + if (Info) + return Info->Function; + } + Sema::LocalInstantiationScope Scope(SemaRef); llvm::SmallVector<ParmVarDecl *, 4> Params; @@ -471,7 +490,9 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(), D->getDeclName(), T, D->getDeclaratorInfo(), D->isStatic(), D->isInline()); - Method->setInstantiationOfMemberFunction(D); + + if (!FunctionTemplate) + Method->setInstantiationOfMemberFunction(D); // If we are instantiating a member function defined // out-of-line, the instantiation will have the same lexical @@ -501,8 +522,14 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration, /*FIXME:*/OverloadableAttrRequired); - if (!Method->isInvalidDecl() || !PrevDecl) - Owner->addDecl(Method); + if (FunctionTemplate) + // Record this function template specialization. + Method->setFunctionTemplateSpecialization(SemaRef.Context, + FunctionTemplate, + &TemplateArgs, + InsertPos); + else if (!Method->isInvalidDecl() || !PrevDecl) + Owner->addDecl(Method); return Method; } |