diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-07 23:56:10 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-07 23:56:10 +0000 |
commit | 2db323294ac02296125e1e0beb4c3595992e75bb (patch) | |
tree | 2fea63628d38b674cc418a164d002b1f1861bb7d /lib/AST/Decl.cpp | |
parent | e3af0235ce6548e221e04c2ae5aeb0fb413ba736 (diff) |
Keep track of whether a member function instantiated from a member
function of a class template was implicitly instantiated, explicitly
instantiated (declaration or definition), or explicitly
specialized. The same MemberSpecializationInfo structure will be used
for static data members and member classes as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83509 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index fe32c396c5..a5c9fa4bac 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -410,6 +410,16 @@ void FunctionDecl::Destroy(ASTContext& C) { for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) (*I)->Destroy(C); + FunctionTemplateSpecializationInfo *FTSInfo + = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); + if (FTSInfo) + C.Deallocate(FTSInfo); + + MemberSpecializationInfo *MSInfo + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); + if (MSInfo) + C.Deallocate(MSInfo); + C.Deallocate(ParamInfo); Decl::Destroy(C); @@ -670,6 +680,24 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { return OO_None; } +FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { + if (MemberSpecializationInfo *Info + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) + return cast<FunctionDecl>(Info->getInstantiatedFrom()); + + return 0; +} + +void +FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD, + TemplateSpecializationKind TSK) { + assert(TemplateOrSpecialization.isNull() && + "Member function is already a specialization"); + MemberSpecializationInfo *Info + = new (getASTContext()) MemberSpecializationInfo(FD, TSK); + TemplateOrSpecialization = Info; +} + FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { if (FunctionTemplateSpecializationInfo *Info = TemplateOrSpecialization @@ -727,32 +755,30 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { // For a function template specialization, query the specialization // information object. - FunctionTemplateSpecializationInfo *Info + FunctionTemplateSpecializationInfo *FTSInfo = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); - if (Info) - return Info->getTemplateSpecializationKind(); - - if (!getInstantiatedFromMemberFunction()) - return TSK_Undeclared; - - // Find the class template specialization corresponding to this instantiation - // of a member function. - const DeclContext *Parent = getDeclContext(); - while (Parent && !isa<ClassTemplateSpecializationDecl>(Parent)) - Parent = Parent->getParent(); - - if (!Parent) - return TSK_Undeclared; + if (FTSInfo) + return FTSInfo->getTemplateSpecializationKind(); - return cast<ClassTemplateSpecializationDecl>(Parent)->getSpecializationKind(); + MemberSpecializationInfo *MSInfo + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); + if (MSInfo) + return MSInfo->getTemplateSpecializationKind(); + + return TSK_Undeclared; } void FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { - FunctionTemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); - assert(Info && "Not a function template specialization"); - Info->setTemplateSpecializationKind(TSK); + if (FunctionTemplateSpecializationInfo *FTSInfo + = TemplateOrSpecialization.dyn_cast< + FunctionTemplateSpecializationInfo*>()) + FTSInfo->setTemplateSpecializationKind(TSK); + else if (MemberSpecializationInfo *MSInfo + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) + MSInfo->setTemplateSpecializationKind(TSK); + else + assert(false && "Function cannot have a template specialization kind"); } bool FunctionDecl::isOutOfLine() const { |