diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-27 23:26:40 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-27 23:26:40 +0000 |
commit | 7d9c3c92c90ae36d58ec21bc53c4c08e02ac3555 (patch) | |
tree | 66200812f0e8c8a2deabc239201de742f8e3e944 /lib/CodeGen/CodeGenModule.cpp | |
parent | db07b3f7cdcb505329c1280d7cf70791739a7cad (diff) |
Implement proper linkage for explicit instantiation declarations of
inlined functions. For example, given
template<typename T>
class string {
unsigned Len;
public:
unsigned size() const { return Len; }
};
extern template class string<char>;
we now give the instantiation of string<char>::size
available_externally linkage (if it is ever instantiated!), as
permitted by the C++0x standard.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85340 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index a40701851e..db609f6245 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -253,6 +253,10 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD, if (FD->isInAnonymousNamespace()) return CodeGenModule::GVA_Internal; + // "static" functions get internal linkage. + if (FD->getStorageClass() == FunctionDecl::Static && !isa<CXXMethodDecl>(FD)) + return CodeGenModule::GVA_Internal; + // The kind of external linkage this function will have, if it is not // inline or static. CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal; @@ -260,18 +264,6 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD, FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) External = CodeGenModule::GVA_TemplateInstantiation; - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - // C++ member functions defined inside the class are always inline. - if (MD->isInlined()) - return CodeGenModule::GVA_CXXInline; - - return External; - } - - // "static" functions get internal linkage. - if (FD->getStorageClass() == FunctionDecl::Static) - return CodeGenModule::GVA_Internal; - if (!FD->isInlined()) return External; @@ -285,8 +277,16 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD, return CodeGenModule::GVA_C99Inline; } - // C++ inline semantics - assert(Features.CPlusPlus && "Must be in C++ mode"); + // C++0x [temp.explicit]p9: + // [ Note: The intent is that an inline function that is the subject of + // an explicit instantiation declaration will still be implicitly + // instantiated when used so that the body can be considered for + // inlining, but that no out-of-line copy of the inline function would be + // generated in the translation unit. -- end note ] + if (FD->getTemplateSpecializationKind() + == TSK_ExplicitInstantiationDeclaration) + return CodeGenModule::GVA_C99Inline; + return CodeGenModule::GVA_CXXInline; } |