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.
      

llvm-svn: 85340
This commit is contained in:
Douglas Gregor
2009-10-27 23:26:40 +00:00
parent 1bafa6de57
commit b7e5c847c4
3 changed files with 107 additions and 17 deletions

View File

@@ -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;
}