The standard ARM C++ ABI dictates that inline functions are
never key functions. We did not implement that rule for the iOS ABI, which was driven by what was implemented in gcc-4.2. However, implement it now for other ARM-based platforms. llvm-svn: 173515
This commit is contained in:
@@ -371,7 +371,9 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
|
||||
// that don't have the key function's definition. But ignore
|
||||
// this if we're emitting RTTI under -fno-rtti.
|
||||
if (!(TVK != TVK_ForRTTI) || LangOpts.RTTI) {
|
||||
if (Context.getKeyFunction(RD))
|
||||
// FIXME: what should we do if we "lose" the key function during
|
||||
// the emission of the file?
|
||||
if (Context.getCurrentKeyFunction(RD))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -836,14 +838,19 @@ void CodeGenModule::EmitDeferred() {
|
||||
// previously unused static decl may become used during the generation of code
|
||||
// for a static function, iterate until no changes are made.
|
||||
|
||||
while (!DeferredDeclsToEmit.empty() || !DeferredVTables.empty()) {
|
||||
while (true) {
|
||||
if (!DeferredVTables.empty()) {
|
||||
const CXXRecordDecl *RD = DeferredVTables.back();
|
||||
DeferredVTables.pop_back();
|
||||
getCXXABI().EmitVTables(RD);
|
||||
continue;
|
||||
EmitDeferredVTables();
|
||||
|
||||
// Emitting a v-table doesn't directly cause more v-tables to
|
||||
// become deferred, although it can cause functions to be
|
||||
// emitted that then need those v-tables.
|
||||
assert(DeferredVTables.empty());
|
||||
}
|
||||
|
||||
// Stop if we're out of both deferred v-tables and deferred declarations.
|
||||
if (DeferredDeclsToEmit.empty()) break;
|
||||
|
||||
GlobalDecl D = DeferredDeclsToEmit.back();
|
||||
DeferredDeclsToEmit.pop_back();
|
||||
|
||||
@@ -1526,80 +1533,6 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
|
||||
EmitGlobalVarDefinition(D);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) {
|
||||
if (DefinitionRequired)
|
||||
getCXXABI().EmitVTables(Class);
|
||||
}
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes
|
||||
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
|
||||
if (RD->getLinkage() != ExternalLinkage)
|
||||
return llvm::GlobalVariable::InternalLinkage;
|
||||
|
||||
if (const CXXMethodDecl *KeyFunction
|
||||
= RD->getASTContext().getKeyFunction(RD)) {
|
||||
// If this class has a key function, use that to determine the linkage of
|
||||
// the vtable.
|
||||
const FunctionDecl *Def = 0;
|
||||
if (KeyFunction->hasBody(Def))
|
||||
KeyFunction = cast<CXXMethodDecl>(Def);
|
||||
|
||||
switch (KeyFunction->getTemplateSpecializationKind()) {
|
||||
case TSK_Undeclared:
|
||||
case TSK_ExplicitSpecialization:
|
||||
// When compiling with optimizations turned on, we emit all vtables,
|
||||
// even if the key function is not defined in the current translation
|
||||
// unit. If this is the case, use available_externally linkage.
|
||||
if (!Def && CodeGenOpts.OptimizationLevel)
|
||||
return llvm::GlobalVariable::AvailableExternallyLinkage;
|
||||
|
||||
if (KeyFunction->isInlined())
|
||||
return !Context.getLangOpts().AppleKext ?
|
||||
llvm::GlobalVariable::LinkOnceODRLinkage :
|
||||
llvm::Function::InternalLinkage;
|
||||
|
||||
return llvm::GlobalVariable::ExternalLinkage;
|
||||
|
||||
case TSK_ImplicitInstantiation:
|
||||
return !Context.getLangOpts().AppleKext ?
|
||||
llvm::GlobalVariable::LinkOnceODRLinkage :
|
||||
llvm::Function::InternalLinkage;
|
||||
|
||||
case TSK_ExplicitInstantiationDefinition:
|
||||
return !Context.getLangOpts().AppleKext ?
|
||||
llvm::GlobalVariable::WeakODRLinkage :
|
||||
llvm::Function::InternalLinkage;
|
||||
|
||||
case TSK_ExplicitInstantiationDeclaration:
|
||||
// FIXME: Use available_externally linkage. However, this currently
|
||||
// breaks LLVM's build due to undefined symbols.
|
||||
// return llvm::GlobalVariable::AvailableExternallyLinkage;
|
||||
return !Context.getLangOpts().AppleKext ?
|
||||
llvm::GlobalVariable::LinkOnceODRLinkage :
|
||||
llvm::Function::InternalLinkage;
|
||||
}
|
||||
}
|
||||
|
||||
if (Context.getLangOpts().AppleKext)
|
||||
return llvm::Function::InternalLinkage;
|
||||
|
||||
switch (RD->getTemplateSpecializationKind()) {
|
||||
case TSK_Undeclared:
|
||||
case TSK_ExplicitSpecialization:
|
||||
case TSK_ImplicitInstantiation:
|
||||
// FIXME: Use available_externally linkage. However, this currently
|
||||
// breaks LLVM's build due to undefined symbols.
|
||||
// return llvm::GlobalVariable::AvailableExternallyLinkage;
|
||||
case TSK_ExplicitInstantiationDeclaration:
|
||||
return llvm::GlobalVariable::LinkOnceODRLinkage;
|
||||
|
||||
case TSK_ExplicitInstantiationDefinition:
|
||||
return llvm::GlobalVariable::WeakODRLinkage;
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid TemplateSpecializationKind!");
|
||||
}
|
||||
|
||||
CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
|
||||
return Context.toCharUnitsFromBits(
|
||||
TheDataLayout.getTypeStoreSizeInBits(Ty));
|
||||
|
||||
Reference in New Issue
Block a user