aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-02-20 01:54:26 +0000
committerJohn McCall <rjmccall@apple.com>2013-02-20 01:54:26 +0000
commitd4c3d66be70ae2d0bd828329022dc428cc277a1c (patch)
treeb980077d0866c29bcf09476b73c6a1d234727872 /test
parent975d52c759a0da21461668bac840bb5d21061d1b (diff)
Add a new 'type_visibility' attribute to allow users to
control the visibility of a type for the purposes of RTTI and template argument restrictions independently of how visibility propagates to its non-type member declarations. Also fix r175326 to not ignore template argument visibility on a template explicit instantiation when a member has an explicit attribute but the instantiation does not. The type_visibility work is rdar://11880378 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175587 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CodeGenCXX/type_visibility.cpp170
-rw-r--r--test/CodeGenCXX/visibility.cpp12
-rw-r--r--test/Sema/attr-visibility.c4
3 files changed, 185 insertions, 1 deletions
diff --git a/test/CodeGenCXX/type_visibility.cpp b/test/CodeGenCXX/type_visibility.cpp
new file mode 100644
index 0000000000..5c45611991
--- /dev/null
+++ b/test/CodeGenCXX/type_visibility.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o %t.ll
+// RUN: FileCheck %s -check-prefix=FUNS < %t.ll
+// RUN: FileCheck %s -check-prefix=VARS < %t.ll
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o %t.ll
+// RUN: FileCheck %s -check-prefix=FUNS-HIDDEN < %t.ll
+// RUN: FileCheck %s -check-prefix=VARS-HIDDEN < %t.ll
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+#define TYPE_HIDDEN __attribute__((type_visibility("hidden")))
+#define TYPE_PROTECTED __attribute__((type_visibility("protected")))
+#define TYPE_DEFAULT __attribute__((type_visibility("default")))
+
+// type_visibility is rdar://11880378
+
+#if !__has_attribute(type_visibility)
+#error No type_visibility attribute!
+#endif
+
+// The template tests come first because IR-gen reorders RTTI wierdly.
+namespace temp0 {
+ struct A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS: define weak_odr void @_ZN5temp01BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp01BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
+ // FUNS-HIDDEN: define weak_odr hidden void @_ZN5temp01BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
+}
+
+namespace temp1 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS: define weak_odr void @_ZN5temp11BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+ // FUNS-HIDDEN: define weak_odr hidden void @_ZN5temp11BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+ // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+}
+
+namespace temp2 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS: define weak_odr void @_ZN5temp21BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp21BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
+ // FUNS-HIDDEN: define weak_odr hidden void @_ZN5temp21BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
+}
+
+namespace temp3 {
+ struct TYPE_HIDDEN A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+ // VARS: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // FUNS-HIDDEN: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+}
+
+namespace temp4 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct TYPE_HIDDEN B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS: define weak_odr void @_ZN5temp41BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+ // VARS: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // FUNS-HIDDEN: define weak_odr hidden void @_ZN5temp41BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+}
+
+namespace type0 {
+ struct TYPE_DEFAULT A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS: define void @_ZN5type01A3fooEv(
+ // VARS: @_ZTVN5type01AE = unnamed_addr constant
+ // VARS: @_ZTSN5type01AE = constant
+ // VARS: @_ZTIN5type01AE = unnamed_addr constant
+ // FUNS-HIDDEN: define hidden void @_ZN5type01A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type01AE = constant
+ // VARS-HIDDEN: @_ZTIN5type01AE = unnamed_addr constant
+}
+
+namespace type1 {
+ struct HIDDEN TYPE_DEFAULT A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS: define hidden void @_ZN5type11A3fooEv(
+ // VARS: @_ZTVN5type11AE = unnamed_addr constant
+ // VARS: @_ZTSN5type11AE = constant
+ // VARS: @_ZTIN5type11AE = unnamed_addr constant
+ // FUNS-HIDDEN: define hidden void @_ZN5type11A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type11AE = constant
+ // VARS-HIDDEN: @_ZTIN5type11AE = unnamed_addr constant
+}
+
+namespace type2 {
+ struct TYPE_HIDDEN A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS: define void @_ZN5type21A3fooEv(
+ // VARS: @_ZTVN5type21AE = hidden unnamed_addr constant
+ // VARS: @_ZTSN5type21AE = hidden constant
+ // VARS: @_ZTIN5type21AE = hidden unnamed_addr constant
+ // FUNS-HIDDEN: define hidden void @_ZN5type21A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type21AE = hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type21AE = hidden constant
+ // VARS-HIDDEN: @_ZTIN5type21AE = hidden unnamed_addr constant
+}
+
+namespace type3 {
+ struct DEFAULT TYPE_HIDDEN A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS: define void @_ZN5type31A3fooEv(
+ // VARS: @_ZTVN5type31AE = hidden unnamed_addr constant
+ // VARS: @_ZTSN5type31AE = hidden constant
+ // VARS: @_ZTIN5type31AE = hidden unnamed_addr constant
+ // FUNS-HIDDEN: define void @_ZN5type31A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant
+ // VARS-HIDDEN: @_ZTIN5type31AE = hidden unnamed_addr constant
+}
+
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 5564dc4019..cfddc8c0c2 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -1170,3 +1170,15 @@ namespace test63 {
// CHECK: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv()
// CHECK: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv()
}
+
+// Don't ignore the visibility of template arguments just because we
+// explicitly instantiated something.
+namespace test64 {
+ struct HIDDEN A {};
+ template <class P> struct B {
+ static DEFAULT void foo() {}
+ };
+
+ template class B<A>;
+ // CHECK: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv()
+}
diff --git a/test/Sema/attr-visibility.c b/test/Sema/attr-visibility.c
index 77bc39c9e6..7f7fd546f0 100644
--- a/test/Sema/attr-visibility.c
+++ b/test/Sema/attr-visibility.c
@@ -21,4 +21,6 @@ void test6() __attribute__((visibility("hidden"), // expected-note {{previous at
extern int test7 __attribute__((visibility("default"))); // expected-note {{previous attribute is here}}
extern int test7 __attribute__((visibility("hidden"))); // expected-error {{visibility does not match previous declaration}}
-typedef int __attribute__((visibility("default"))) bar; // expected-warning {{visibility attribute ignored}}
+typedef int __attribute__((visibility("default"))) bar; // expected-warning {{'visibility' attribute ignored}}
+
+int x __attribute__((type_visibility("default"))); // expected-error {{'type_visibility' attribute only applies to types and namespaces}}