aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/Decl.cpp4
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp13
2 files changed, 14 insertions, 3 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8526eccd65..19cfe9e119 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -456,7 +456,9 @@ static LVPair getLVForClassMember(const NamedDecl *D) {
// member functions get "hidden" visibility if they don't have an
// explicit visibility attribute.
if (!VA && MD->isInlined() && LV.second > HiddenVisibility &&
- D->getASTContext().getLangOptions().InlineVisibilityHidden)
+ D->getASTContext().getLangOptions().InlineVisibilityHidden &&
+ MD->getTemplateSpecializationKind()
+ != TSK_ExplicitInstantiationDeclaration)
LV.second = HiddenVisibility;
// Similarly for member class template specializations.
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index bb1574fe9d..69ce256025 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -1,4 +1,9 @@
-// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+
+// The trickery with optimization in the run line is to get IR
+// generation to emit available_externally function bodies, but not
+// actually inline them (and thus remove the emitted bodies).
+
struct X0 {
void __attribute__((visibility("default"))) f1() { }
void f2() { }
@@ -29,7 +34,9 @@ struct __attribute__((visibility("default"))) X2 {
void f2() { }
};
-void use(X0 *x0, X1<int> *x1, X2 *x2) {
+extern template struct X1<float>;
+
+void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
// CHECK: define linkonce_odr void @_ZN2X02f1Ev
x0->f1();
// CHECK: define linkonce_odr hidden void @_ZN2X02f2Ev
@@ -54,4 +61,6 @@ void use(X0 *x0, X1<int> *x1, X2 *x2) {
x1->X1::f6();
// CHECK: define linkonce_odr hidden void @_ZN2X22f2Ev
x2->f2();
+ // CHECK: define available_externally void @_ZN2X1IfE2f2Ev
+ x3->f2();
}