/// internal state before optimizations are
/// done.
unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
+ unsigned EmitDeclMetadata : 1; /// Emit special metadata indicating what Decl*
+ /// various IR entities came from. Only useful
+ /// when running CodeGen as a subroutine.
unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled
+ unsigned EmitWeakTemplatesHidden : 1; /// Emit weak vtables and typeinfo for
+ /// template classes with hidden visibility
unsigned InstrumentFunctions : 1; /// Set when -finstrument-functions is enabled
unsigned MergeAllConstants : 1; /// Merge identical constants.
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned UnwindTables : 1; /// Emit unwind tables.
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
- unsigned EmitDeclMetadata : 1; /// Emit special metadata indicating what Decl*
- /// various IR entities came from. Only useful
- /// when running CodeGen as a subroutine.
/// The code model to use (-mcmodel).
std::string CodeModel;
DisableFPElim = 0;
DisableLLVMOpts = 0;
DisableRedZone = 0;
+ EmitDeclMetadata = 0;
FunctionSections = 0;
+ EmitWeakTemplatesHidden = 0;
MergeAllConstants = 1;
NoCommon = 0;
NoImplicitFloat = 0;
UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;
- EmitDeclMetadata = 0;
Inlining = NoInlining;
RelocationModel = "pic";
#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"
// 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;
}
// 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)
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;
}
// Check mangling of Vtables, VTTs, and construction vtables that
// involve standard substitutions.
-// CHECK: @_ZTVSd = weak_odr hidden constant
+// CHECK: @_ZTVSd = weak_odr constant
// CHECK: @_ZTCSd0_Si = internal constant
// CHECK: @_ZTCSd16_So = internal constant
// CHECK: @_ZTTSd = weak_odr constant
-// CHECK: @_ZTVSo = weak_odr hidden constant
+// CHECK: @_ZTVSo = weak_odr constant
// CHECK: @_ZTTSo = weak_odr constant
-// CHECK: @_ZTVSi = weak_odr hidden constant
+// CHECK: @_ZTVSi = weak_odr constant
// CHECK: @_ZTTSi = weak_odr constant
namespace std {
struct A { A(); };
// CHECK: _ZTI1A = weak_odr hidden constant
// CHECK: _ZTI1B = constant
// CHECK: _ZTI1C = internal constant
-// CHECK: _ZTI1TILj0EE = weak_odr hidden constant
+// CHECK: _ZTI1TILj0EE = weak_odr constant
// CHECK: _ZTI1TILj1EE = weak_odr constant
// CHECK: _ZTI1TILj2EE = external constant
// CHECK: _ZTIA10_i = weak_odr hidden constant
// CHECK: @_ZTV1B = weak_odr hidden constant
// CHECK: @_ZTV1AIlE = weak_odr constant
// CHECK: @_ZTV1AIsE = weak_odr constant
-// CHECK: @_ZTV1AIiE = weak_odr hidden constant
+// CHECK: @_ZTV1AIiE = weak_odr constant
// CHECK-7: @_ZTI1EIlE = weak_odr constant
// F<long> is an implicit template instantiation with no key function,
-// so its vtable should have weak_odr linkage and hidden visibility.
-// CHECK-8: @_ZTV1FIlE = weak_odr hidden constant
+// so its vtable should have weak_odr linkage.
+// CHECK-8: @_ZTV1FIlE = weak_odr constant
// CHECK-8: @_ZTS1FIlE = weak_odr constant
-// CHECK-8: @_ZTI1FIlE = weak_odr hidden constant
+// CHECK-8: @_ZTI1FIlE = weak_odr constant
// F<int> is an explicit template instantiation declaration without a
// key function, so its vtable should have external linkage.
// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant
// F<char> is an explicit specialization without a key function, so
-// its vtable should have weak_odr linkage and hidden visibility.
-// CHECK-13: @_ZTV1FIcE = weak_odr hidden constant
+// its vtable should have weak_odr linkage.
+// CHECK-13: @_ZTV1FIcE = weak_odr constant
// CHECK-13: @_ZTS1FIcE = weak_odr constant
-// CHECK-13: @_ZTI1FIcE = weak_odr hidden constant
+// CHECK-13: @_ZTI1FIcE = weak_odr constant
// RUN: FileCheck --check-prefix=CHECK-G %s < %t
//