diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2307,6 +2307,10 @@ Give inline C++ member functions hidden visibility by default +.. option:: -fnovisibility + +Ignore all the visibility pragmas and attributes in source code + .. option:: -fvisibility-ms-compat Give global types 'default' visibility and global functions and variables 'hidden' visibility by default diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -297,6 +297,7 @@ "type's inheritance model would be determined under the Microsoft ABI") ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode") +BENIGN_LANGOPT(NoVisibility, 1, 0, "All the visibility pragmas and attributes that are specified in the source are ignored.") ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility, "default visibility for functions and variables [-fvisibility]") ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1936,6 +1936,9 @@ def fverbose_asm : Flag<["-"], "fverbose-asm">, Group, HelpText<"Generate verbose assembly output">; def dA : Flag<["-"], "dA">, Alias; +def fnovisibility : Flag<["-"], "fnovisibility">, Group, + HelpText<"Ignore all the visibility pragmas and attributes in source code">, + Flags<[CC1Option]>; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group, HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">; def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group, diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1477,10 +1477,14 @@ } LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) { - return getLVForDecl(D, - LVComputationKind(usesTypeVisibility(D) - ? NamedDecl::VisibilityForType - : NamedDecl::VisibilityForValue)); + NamedDecl::ExplicitVisibilityKind EK = usesTypeVisibility(D) + ? NamedDecl::VisibilityForType + : NamedDecl::VisibilityForValue; + LVComputationKind CK(EK); + + return getLVForDecl(D, D->getASTContext().getLangOpts().NoVisibility + ? CK.forLinkageOnly() + : CK); } Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5198,6 +5198,9 @@ } } + if (Args.getLastArg(options::OPT_fnovisibility)) + CmdArgs.push_back("-fnovisibility"); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2752,6 +2752,9 @@ Opts.setValueVisibilityMode(parseVisibility(visOpt, Args, Diags)); } else { Opts.setValueVisibilityMode(DefaultVisibility); + // In AIX oS, the -fnovisibility is enable by default. + if (T.isOSAIX() || Args.hasArg(OPT_fnovisibility)) + Opts.NoVisibility = 1; } // The type-visibility mode defaults to the value-visibility mode. diff --git a/clang/test/Driver/fnovisibility.cpp b/clang/test/Driver/fnovisibility.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/fnovisibility.cpp @@ -0,0 +1,81 @@ +// RUN: %clang -target powerpc-unknown-aix -emit-llvm -o - -S %s |\ +// RUN: FileCheck --check-prefixes=NOVISIBILITY,AIX-NOVISIBILITY %s + +// RUN: %clang -fnovisibility -target powerpc-unknown-aix -emit-llvm -o - -S %s | \ +// RUN: FileCheck -check-prefixes=NOVISIBILITY,AIX-NOVISIBILITY %s + +// RUN: %clang -fnovisibility -target powerpc-unknown-linux -emit-llvm -o - -S %s | \ +// RUN: FileCheck -check-prefixes=NOVISIBILITY,LINUX-NOVISIBILITY %s + +// RUN: %clang -fnovisibility -fvisibility=default -target powerpc-unknown-aix -emit-llvm -o - -S %s | \ +// RUN: FileCheck -check-prefix=VISIBILITY %s + +// RUN: %clang -target powerpc-unknown-linux -emit-llvm -o - -S %s | \ +// RUN: FileCheck -check-prefix=VISIBILITY %s + +// RUN: %clang -fnovisibility -fvisibility=default -target powerpc-unknown-linux -emit-llvm -o - -S %s | \ +// RUN: FileCheck -check-prefix=VISIBILITY %s + +__attribute__((visibility("hidden"))) void foo_h(int *p) { + (*p)++; +} + +__attribute__((visibility("protected"))) int b; + +extern __attribute__((visibility("hidden"))) void zoo_extern_h(void); + +void (*foo_p)(void) = zoo_extern_h; + +__attribute__((visibility("protected"))) void bar() { + foo_h(&b); + foo_p(); +} + +class TestClass { +public: + __attribute__((__visibility__("hidden"))) int value() const noexcept { return 0; } +}; + +int main() { + TestClass TC; + return TC.value(); +} + +template +class basic { +public: + __attribute__((__visibility__("protected"))) int getdata() { return 1; } +}; + +template class basic; + +#pragma GCC visibility push(hidden) + int pramb; + void prambar() {} +#pragma GCC visibility pop + + +// AIX-NOVISIBILITY: @b = global i32 0 +// LINUX-NOVISIBILITY: @b = dso_local global i32 0 +// AIX-NOVISIBILITY: @pramb = global i32 0 +// LINUX-NOVISIBILITY: @pramb = dso_local global i32 0 +// AIX-NOVISIBILITY: define void @_Z5foo_hPi(i32* %p) +// LINUX-NOVISIBILITY: define dso_local void @_Z5foo_hPi(i32* %p) +// NOVISIBILITY: declare void @_Z12zoo_extern_hv() +// AIX-NOVISIBILITY: define void @_Z3barv() +// LINUX-NOVISIBILITY: define dso_local void @_Z3barv() +// AIX-NOVISIBILITY: define linkonce_odr i32 @_ZNK9TestClass5valueEv(%class.TestClass* %this) +// LINUX-NOVISIBILITY: define linkonce_odr dso_local i32 @_ZNK9TestClass5valueEv(%class.TestClass* %this) +// AIX-NOVISIBILITY: define weak_odr i32 @_ZN5basicIiE7getdataEv(%class.basic* %this) +// LINUX-NOVISIBILITY: define weak_odr dso_local i32 @_ZN5basicIiE7getdataEv(%class.basic* %this) +// AIX-NOVISIBILITY: define void @_Z7prambarv() +// LINUX-NOVISIBILITY: define dso_local void @_Z7prambarv() + +// VISIBILITY: @b = protected global i32 0 +// VISIBILITY: @pramb = hidden global i32 0 +// VISIBILITY: define hidden void @_Z5foo_hPi(i32* %p) +// VISIBILITY: declare hidden void @_Z12zoo_extern_hv() +// VISIBILITY: define protected void @_Z3barv() +// VISIBILITY: define linkonce_odr hidden i32 @_ZNK9TestClass5valueEv(%class.TestClass* %this) +// VISIBILITY: define weak_odr protected i32 @_ZN5basicIiE7getdataEv(%class.basic* %this) +// VISIBILITY: define hidden void @_Z7prambarv()