Index: docs/ClangCommandLineReference.rst =================================================================== --- docs/ClangCommandLineReference.rst +++ docs/ClangCommandLineReference.rst @@ -2010,7 +2010,12 @@ .. option:: -fvisibility= -Set the default symbol visibility for all global declarations +Set the default symbol visibility for all global definitions + +.. option:: -fset-visibility-for-decls, -fno-set-visibility-for-decls + +Apply global symbol visibility settings to declarations without a definition or +an explicit visibility, rather than always setting them to default visibility .. option:: -fwhole-program-vtables, -fno-whole-program-vtables Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -262,6 +262,8 @@ "value symbol visibility") ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, "type symbol visibility") +LANGOPT(SetVisibilityForDecls, 1, 0, + "apply global symbol visibility to declarations without an explicit visibility") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1771,6 +1771,11 @@ "variables 'hidden' visibility by default">; def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group, HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Flags<[CC1Option]>; +def fset_visibility_for_decls : Flag<["-"], "fset-visibility-for-decls">, Group, + HelpText<"Apply global symbol visibility to declarations without an explicit visibility">, + Flags<[CC1Option]>; +def fno_set_visibility_for_decls : Flag<["-"], "fno-set-visibility-for-decls">, Group, + HelpText<"Do not apply global symbol visibility to declarations without an explicit visibility">; def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group, Flags<[CoreOption, CC1Option]>, HelpText<"Enables whole-program vtable optimization. Requires -flto">; Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -731,9 +731,11 @@ } if (!D) return; - // Set visibility for definitions. + // Set visibility for definitions, and for declarations if requested globally + // or set explicitly. LinkageInfo LV = D->getLinkageAndVisibility(); - if (LV.isVisibilityExplicit() || !GV->isDeclarationForLinker()) + if (LV.isVisibilityExplicit() || getLangOpts().SetVisibilityForDecls || + !GV->isDeclarationForLinker()) GV->setVisibility(GetLLVMVisibility(LV.getVisibility())); } Index: lib/Driver/ToolChains/AMDGPU.cpp =================================================================== --- lib/Driver/ToolChains/AMDGPU.cpp +++ lib/Driver/ToolChains/AMDGPU.cpp @@ -110,4 +110,8 @@ CC1Args.push_back("-fvisibility"); CC1Args.push_back("hidden"); } + if (!DriverArgs.hasArg(options::OPT_fset_visibility_for_decls, + options::OPT_fno_set_visibility_for_decls)) { + CC1Args.push_back("-fset-visibility-for-decls"); + } } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4395,6 +4395,9 @@ Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); + if (Args.hasFlag(options::OPT_fset_visibility_for_decls, + options::OPT_fno_set_visibility_for_decls, false)) + CmdArgs.push_back("-fset-visibility-for-decls"); Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); Index: lib/Driver/ToolChains/HIP.cpp =================================================================== --- lib/Driver/ToolChains/HIP.cpp +++ lib/Driver/ToolChains/HIP.cpp @@ -296,6 +296,9 @@ if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat)) CC1Args.append({"-fvisibility", "hidden"}); + if (!DriverArgs.hasArg(options::OPT_fset_visibility_for_decls, + options::OPT_fno_set_visibility_for_decls)) + CC1Args.push_back("-fset-visibility-for-decls"); } llvm::opt::DerivedArgList * Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2502,6 +2502,10 @@ if (Args.hasArg(OPT_fvisibility_global_new_delete_hidden)) Opts.GlobalAllocationFunctionVisibilityHidden = 1; + if (Args.hasArg(OPT_fset_visibility_for_decls, + OPT_fno_set_visibility_for_decls, false)) + Opts.SetVisibilityForDecls = 1; + if (Args.hasArg(OPT_ftrapv)) { Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. Index: test/CodeGen/set-visibility-for-decls.c =================================================================== --- /dev/null +++ test/CodeGen/set-visibility-for-decls.c @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility hidden -fset-visibility-for-decls -emit-llvm -o - | FileCheck --check-prefix=CHECK-HIDDEN %s +// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility protected -fset-visibility-for-decls -emit-llvm -o - | FileCheck --check-prefix=CHECK-PROTECTED %s +// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility default -fset-visibility-for-decls -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEFAULT %s + +// CHECK-HIDDEN: @var_hidden = external hidden global +// CHECK-PROTECTED: @var_hidden = external hidden global +// CHECK-DEFAULT: @var_hidden = external hidden global +__attribute__((visibility("hidden"))) extern int var_hidden; +// CHECK-HIDDEN: @var_protected = external protected global +// CHECK-PROTECTED: @var_protected = external protected global +// CHECK-DEFAULT: @var_protected = external protected global +__attribute__((visibility("protected"))) extern int var_protected; +// CHECK-HIDDEN: @var_default = external global +// CHECK-PROTECTED: @var_default = external global +// CHECK-DEFAULT: @var_default = external global +__attribute__((visibility("default"))) extern int var_default; +// CHECK-HIDDEN: @var = external hidden global +// CHECK-PROTECTED: @var = external protected global +// CHECK-DEFAULT: @var = external global +extern int var; + +// CHECK-HIDDEN: declare hidden i32 @func_hidden() +// CHECK-PROTECTED: declare hidden i32 @func_hidden() +// CHECK-DEFAULT: declare hidden i32 @func_hidden() +__attribute__((visibility("hidden"))) int func_hidden(void); +// CHECK-HIDDEN: declare protected i32 @func_protected() +// CHECK-PROTECTED: declare protected i32 @func_protected() +// CHECK-DEFAULT: declare protected i32 @func_protected() +__attribute__((visibility("protected"))) int func_protected(void); +// CHECK-HIDDEN: declare i32 @func_default() +// CHECK-PROTECTED: declare i32 @func_default() +// CHECK-DEFAULT: declare i32 @func_default() +__attribute__((visibility("default"))) int func_default(void); +// CHECK-HIDDEN: declare hidden i32 @func() +// CHECK-PROTECTED: declare protected i32 @func() +// CHECK-DEFAULT: declare i32 @func() +int func(void); + +int use() { + return var_hidden + var_protected + var_default + var + + func_hidden() + func_protected() + func_default() + func(); +} Index: test/Driver/amdgpu-visibility.cl =================================================================== --- test/Driver/amdgpu-visibility.cl +++ test/Driver/amdgpu-visibility.cl @@ -1,7 +1,18 @@ // RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm %s 2>&1 | FileCheck -check-prefix=DEFAULT %s // RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=protected %s 2>&1 | FileCheck -check-prefix=OVERRIDE-PROTECTED %s // RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-ms-compat %s 2>&1 | FileCheck -check-prefix=OVERRIDE-MS %s +// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fno-set-visibility-for-decls -fno-unroll-loops %s 2>&1 | FileCheck -check-prefix=NO-SET-DECLS %s -// DEFAULT: "-fvisibility" "hidden" -// OVERRIDE-PROTECTED: "-fvisibility" "protected" -// OVERRIDE-MS: "-fvisibility" "hidden" "-ftype-visibility" "default" +// DEFAULT-DAG: "-fvisibility" "hidden" +// DEFAULT-DAG: "-fset-visibility-for-decls" + +// OVERRIDE-PROTECTED-DAG: "-fvisibility" "protected" +// OVERRIDE-PROTECTED-DAG: "-fset-visibility-for-decls" + +// OVERRIDE-MS-DAG: "-fvisibility" "hidden" +// OVERRIDE-MS-DAG: "-ftype-visibility" "default" +// OVERRIDE-MS-DAG: "-fset-visibility-for-decls" + +// NO-SET-DECLS-NOT: "-fset-visibility-for-decls" +// NO-SET-DECLS: "-fvisibility" "hidden" +// NO-SET-DECLS-NOT: "-fset-visibility-for-decls" Index: test/Driver/clang_f_opts.c =================================================================== --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -566,3 +566,10 @@ // CHECK-TRIVIAL-PATTERN-NOT: hasn't been enabled // CHECK-TRIVIAL-ZERO-GOOD-NOT: hasn't been enabled // CHECK-TRIVIAL-ZERO-BAD: hasn't been enabled + +// RUN: %clang -### -S -fset-visibility-for-decls %s 2>&1 | FileCheck -check-prefix=CHECK-SET-VISIBILITY-FOR-DECLS %s +// RUN: %clang -### -S -fno-set-visibility-for-decls %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SET-VISIBILITY-FOR-DECLS %s +// RUN: %clang -### -S -fno-set-visibility-for-decls -fset-visibility-for-decls %s 2>&1 | FileCheck -check-prefix=CHECK-SET-VISIBILITY-FOR-DECLS %s +// RUN: %clang -### -S -fset-visibility-for-decls -fno-set-visibility-for-decls %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SET-VISIBILITY-FOR-DECLS %s +// CHECK-SET-VISIBILITY-FOR-DECLS: "-fset-visibility-for-decls" +// CHECK-NO-SET-VISIBILITY-FOR-DECLS-NOT: "-fset-visibility-for-decls" Index: test/Driver/hip-toolchain-no-rdc.hip =================================================================== --- test/Driver/hip-toolchain-no-rdc.hip +++ test/Driver/hip-toolchain-no-rdc.hip @@ -20,6 +20,7 @@ // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803" // CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[A_BC_803:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] @@ -47,6 +48,7 @@ // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx900" // CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[A_BC_900:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[A_SRC]] @@ -89,6 +91,7 @@ // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803" // CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[B_BC_803:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]] @@ -116,6 +119,7 @@ // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx900" // CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[B_BC_900:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[B_SRC]] Index: test/Driver/hip-toolchain-rdc.hip =================================================================== --- test/Driver/hip-toolchain-rdc.hip +++ test/Driver/hip-toolchain-rdc.hip @@ -12,10 +12,11 @@ // RUN: %S/Inputs/hip_multiple_inputs/b.hip \ // RUN: 2>&1 | FileCheck %s -// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803" // CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] @@ -23,6 +24,7 @@ // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803" // CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" "-fvisibility" "hidden" +// CHECK-SAME: "-fset-visibility-for-decls" // CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip" // CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]