diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-07 01:44:36 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-07 01:44:36 +0000 |
commit | 10d369d1a22fdeaeb044b3db8a9126f71cb0c7ad (patch) | |
tree | 7a187c4f68e07b6ffdefc1a9b3701b26cc8c69e8 /clang | |
parent | a7bcade22953fa390e95db0e4f7149a8532896e0 (diff) | |
download | bcm5719-llvm-10d369d1a22fdeaeb044b3db8a9126f71cb0c7ad.tar.gz bcm5719-llvm-10d369d1a22fdeaeb044b3db8a9126f71cb0c7ad.zip |
Improved handling of the visibility attribute. Declarations now inherit their parent's visibility.
(This is kind of a risky change, but I did a self-host build and everything appears to work fine!)
llvm-svn: 95511
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/visibility.cpp | 66 |
2 files changed, 70 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 644c5d0bf8c..c5d84d74db8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -132,6 +132,10 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const { } } + // This decl should have the same visibility as its parent. + if (const DeclContext *DC = D->getDeclContext()) + return getDeclVisibilityMode(cast<Decl>(DC)); + return getLangOptions().getVisibilityMode(); } diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp new file mode 100644 index 00000000000..5edd27b8b27 --- /dev/null +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +#define HIDDEN __attribute__((visibility("hidden"))) +#define PROTECTED __attribute__((visibility("protected"))) +#define DEFAULT __attribute__((visibility("default"))) + +// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 + +namespace Test1 { + // CHECK: define hidden void @_ZN5Test11fEv + void HIDDEN f() { } + +} + +namespace Test2 { + struct HIDDEN A { + void f(); + }; + + // A::f is a member function of a hidden class. + // CHECK: define hidden void @_ZN5Test21A1fEv + void A::f() { } +} + +namespace Test3 { + struct HIDDEN A { + struct B { + void f(); + }; + }; + + // B is a nested class where its parent class is hidden. + // CHECK: define hidden void @_ZN5Test31A1B1fEv + void A::B::f() { } +} + +namespace Test4 HIDDEN { + int VariableInHiddenNamespace = 10; + + // Test4::g is in a hidden namespace. + // CHECK: define hidden void @_ZN5Test41gEv + void g() { } + + struct DEFAULT A { + void f(); + }; + + // A has default visibility. + // CHECK: define void @_ZN5Test41A1fEv + void A::f() { } +} + +namespace Test5 { + + namespace NS HIDDEN { + // f is in NS which is hidden. + // CHECK: define hidden void @_ZN5Test52NS1fEv() + void f() { } + } + + namespace NS { + // g is in NS, but this NS decl is not hidden. + // CHECK: define void @_ZN5Test52NS1gEv + void g() { } + } +} |