Misc key function fixes.

llvm-svn: 90831
This commit is contained in:
Eli Friedman 2009-12-08 03:56:49 +00:00
parent 4569f69558
commit f2c79b6b9c
3 changed files with 62 additions and 1 deletions

View File

@ -724,7 +724,13 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
// function.
if (RD->getTemplateSpecializationKind() != TSK_Undeclared)
return 0;
// A class inside an anonymous namespace doesn't have a key function. (Or
// at least, there's no point to assigning a key function to such a class;
// this doesn't affect the ABI.)
if (RD->isInAnonymousNamespace())
return 0;
for (CXXRecordDecl::method_iterator I = RD->method_begin(),
E = RD->method_end(); I != E; ++I) {
const CXXMethodDecl *MD = *I;
@ -734,6 +740,9 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
if (MD->isPure())
continue;
if (MD->isInlineSpecified())
continue;
// Ignore implicit member functions, they are always marked as inline, but
// they don't have a body until they're defined.

View File

@ -522,6 +522,16 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
FD->hasAttr<DestructorAttr>())
return false;
// The key function for a class must never be deferred.
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Global)) {
const CXXRecordDecl *RD = MD->getParent();
if (MD->isOutOfLine() && RD->isDynamicClass()) {
const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD);
if (KeyFunction == MD->getCanonicalDecl())
return false;
}
}
GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
// static, static inline, always_inline, and extern inline functions can

View File

@ -0,0 +1,42 @@
// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
// Simple key function test
struct testa { virtual void a(); };
void testa::a() {}
// Simple key function test
struct testb { virtual void a() {} };
testb *testbvar = new testb;
// Key function with out-of-line inline definition
struct testc { virtual void a(); };
inline void testc::a() {}
// Key functions with inline specifier (PR5705)
struct testd { inline virtual void a(); };
void testd::a() {}
// Key functions with inline specifier (PR5705)
struct teste { inline virtual void a(); };
teste *testevar = new teste;
// Key functions with namespace (PR5711)
namespace {
struct testf { virtual void a(); };
}
void testf::a() {}
// Key functions with namespace (PR5711)
namespace {
struct testg { virtual void a(); };
}
testg *testgvar = new testg;
// FIXME: The checks are extremely difficult to get right when the globals
// aren't alphabetized
// CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null
// CHECK: @_ZTV5testc = constant [3 x i8*] [i8* null
// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null
// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null
// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null