diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-27 20:53:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-27 20:53:28 +0000 |
commit | 3b846b6c252972a6f142aa226c1e65aebd0feeca (patch) | |
tree | a27f8e9f4d856ce94d5611cefeacb31f88e3a016 /lib/AST/Decl.cpp | |
parent | 82cac29c6ed3121c00845bd2ea84232061bd7dbf (diff) |
Explicit instantiation suppresses the instantiation of non-inline
function template specializations and member functions of class
template specializations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85300 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 38eb3371fe..7b0a84c397 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -753,6 +753,60 @@ FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD, TemplateOrSpecialization = Info; } +bool FunctionDecl::isImplicitlyInstantiable() const { + // If this function already has a definition or is invalid, it can't be + // implicitly instantiated. + if (isInvalidDecl() || getBody()) + return false; + + switch (getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDefinition: + return false; + + case TSK_ImplicitInstantiation: + return true; + + case TSK_ExplicitInstantiationDeclaration: + // Handled below. + break; + } + + // Find the actual template from which we will instantiate. + const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); + Stmt *Pattern = 0; + if (PatternDecl) + Pattern = PatternDecl->getBody(PatternDecl); + + // C++0x [temp.explicit]p9: + // Except for inline functions, other explicit instantiation declarations + // have the effect of suppressing the implicit instantiation of the entity + // to which they refer. + if (!Pattern || !PatternDecl) + return true; + + return PatternDecl->isInline() || + (isa<CXXMethodDecl>(PatternDecl) && !PatternDecl->isOutOfLine()); +} + +FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { + if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { + while (Primary->getInstantiatedFromMemberTemplate()) { + // If we have hit a point where the user provided a specialization of + // this template, we're done looking. + if (Primary->isMemberSpecialization()) + break; + + Primary = Primary->getInstantiatedFromMemberTemplate(); + } + + return Primary->getTemplatedDecl(); + } + + return getInstantiatedFromMemberFunction(); +} + FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { if (FunctionTemplateSpecializationInfo *Info = TemplateOrSpecialization |