diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 21 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 14 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 1 |
3 files changed, 34 insertions, 2 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7acc22abcc..d01e2a12ab 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -518,6 +518,24 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, = new (*this) MemberSpecializationInfo(Tmpl, TSK, PointOfInstantiation); } +FunctionDecl *ASTContext::getClassScopeSpecializationPattern( + const FunctionDecl *FD){ + assert(FD && "Specialization is 0"); + llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos + = ClassScopeSpecilizationPattern.find(FD); + if (Pos == ClassScopeSpecilizationPattern.end()) + return 0; + + return Pos->second; +} + +void ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD, + FunctionDecl *Pattern) { + assert(FD && "Specialization is 0"); + assert(Pattern && "Class scope specialization pattern is 0"); + ClassScopeSpecilizationPattern[FD] = Pattern; +} + NamedDecl * ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) { llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos @@ -6439,5 +6457,6 @@ size_t ASTContext::getSideTableAllocatedMemory() const { + llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) + llvm::capacity_in_bytes(OverriddenMethods) + llvm::capacity_in_bytes(Types) - + llvm::capacity_in_bytes(VariableArrayTypes); + + llvm::capacity_in_bytes(VariableArrayTypes) + + llvm::capacity_in_bytes(ClassScopeSpecilizationPattern); } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 6c7deca5fd..f917d32f5e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1922,13 +1922,17 @@ bool FunctionDecl::isImplicitlyInstantiable() const { switch (getTemplateSpecializationKind()) { case TSK_Undeclared: - case TSK_ExplicitSpecialization: case TSK_ExplicitInstantiationDefinition: return false; case TSK_ImplicitInstantiation: return true; + // It is possible to instantiate TSK_ExplicitSpecialization kind + // if the FunctionDecl has a class scope specialization pattern. + case TSK_ExplicitSpecialization: + return getClassScopeSpecializationPattern() != 0; + case TSK_ExplicitInstantiationDeclaration: // Handled below. break; @@ -1951,6 +1955,10 @@ bool FunctionDecl::isImplicitlyInstantiable() const { } FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { + // Handle class scope explicit specialization special case. + if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return getClassScopeSpecializationPattern(); + if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { while (Primary->getInstantiatedFromMemberTemplate()) { // If we have hit a point where the user provided a specialization of @@ -1976,6 +1984,10 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { return 0; } +FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const { + return getASTContext().getClassScopeSpecializationPattern(this); +} + const TemplateArgumentList * FunctionDecl::getTemplateSpecializationArgs() const { if (FunctionTemplateSpecializationInfo *Info diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 27d05baca2..5e5ec93e17 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -493,6 +493,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case UsingDirective: case ClassTemplateSpecialization: case ClassTemplatePartialSpecialization: + case ClassScopeFunctionSpecialization: case ObjCImplementation: case ObjCCategory: case ObjCCategoryImpl: |