diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 16 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 19 |
2 files changed, 19 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index cd34d03cd77..494176a9063 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -15,6 +15,7 @@ #include "CodeGenFunction.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/RecordLayout.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SetVector.h" #include "llvm/Support/Compiler.h" @@ -2469,34 +2470,29 @@ static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, // emit its thunks with hidden visibility, since its thunks must be // emitted when the function is. - // This mostly follows CodeGenModule::setTypeVisibility. + // This follows CodeGenModule::setTypeVisibility; see the comments + // there for explanation. if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage && Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) || Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility) return; - // Don't override an explicit visibility attribute. if (MD->hasAttr<VisibilityAttr>()) return; switch (MD->getTemplateSpecializationKind()) { - // We have to disable the optimization if this is an EI definition - // because there might be EI declarations in other shared objects. case TSK_ExplicitInstantiationDefinition: case TSK_ExplicitInstantiationDeclaration: return; - // Every use of a non-template or explicitly-specialized class's - // type information has to emit it. - case TSK_ExplicitSpecialization: case TSK_Undeclared: break; - // Implicit instantiations can ignore the possibility of an - // explicit instantiation declaration because there necessarily - // must be an EI definition somewhere with default visibility. + case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: + if (!CGM.getCodeGenOpts().EmitWeakTemplatesHidden) + return; break; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 63384025799..297aa4524e3 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -229,6 +229,9 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, // This isn't possible if there might be unresolved references // elsewhere that rely on this symbol being visible. + // This should be kept roughly in sync with setThunkVisibility + // in CGVTables.cpp. + // Preconditions. if (GV->getLinkage() != llvm::GlobalVariable::WeakODRLinkage || GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility) @@ -245,16 +248,20 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, case TSK_ExplicitInstantiationDeclaration: return; - // Every use of a non-template or explicitly-specialized class's - // type information has to emit it. - case TSK_ExplicitSpecialization: + // Every use of a non-template class's type information has to emit it. case TSK_Undeclared: break; - // Implicit instantiations can ignore the possibility of an - // explicit instantiation declaration because there necessarily - // must be an EI definition somewhere with default visibility. + // In theory, implicit instantiations can ignore the possibility of + // an explicit instantiation declaration because there necessarily + // must be an EI definition somewhere with default visibility. In + // practice, it's possible to have an explicit instantiation for + // an arbitrary template class, and linkers aren't necessarily able + // to deal with mixed-visibility symbols. + case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: + if (!CodeGenOpts.EmitWeakTemplatesHidden) + return; break; } |