Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -306,6 +306,16 @@ "default visibility for types [-ftype-visibility]") LANGOPT(SetVisibilityForExternDecls, 1, 0, "apply global symbol visibility to external declarations without an explicit visibility") +LANGOPT(VisibilityDLLStorageClass, 1, 0, + "Set the visiblity of globals from their DLL storage class [-fvisibility-from-dllstorageclass]") +ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility, + "Visibility for functions and variables with dllexport annotations [-fvisibility-from-dllstorageclass]") +ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility, + "Visibility for functions and variables without an explicit DLL storage class [-fvisibility-from-dllstorageclass]") +ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility, + "Visibility for external declarations with dllimport annotations [-fvisibility-from-dllstorageclass]") +ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility, + "Visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]") BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition") BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic interposition") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1956,6 +1956,15 @@ def fverbose_asm : Flag<["-"], "fverbose-asm">, Group, HelpText<"Generate verbose assembly output">; def dA : Flag<["-"], "dA">, Alias; +defm visibility_from_dllstorageclass : OptInFFlag<"visibility-from-dllstorageclass", "Set the visiblity of symbols in the generated code from their DLL storage class">; +def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, Group, Flags<[DriverOption,CC1Option]>, + HelpText<"The visibility for dllexport defintions [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">; +def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group, Flags<[DriverOption,CC1Option]>, + HelpText<"The visibility for defintiions without an explicit DLL export class [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">; +def fvisibility_externs_dllimport_EQ : Joined<["-"], "fvisibility-externs-dllimport=">, Group, Flags<[DriverOption,CC1Option]>, + HelpText<"The visibility for dllimport external declarations [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">; +def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], "fvisibility-externs-nodllstorageclass=">, Group, Flags<[DriverOption,CC1Option]>, + HelpText<"The visibility for external declarations without an explicit DLL dllstorageclass [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">; 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, Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -401,6 +401,41 @@ } } +static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, + llvm::Module &M) { + if (!LO.VisibilityDLLStorageClass) + return; + + llvm::GlobalValue::VisibilityTypes DLLExportVisibility = + CodeGenModule::GetLLVMVisibility(LO.getDLLExportVisibility()); + llvm::GlobalValue::VisibilityTypes NoDLLStorageClassVisibility = + CodeGenModule::GetLLVMVisibility(LO.getNoDLLStorageClassVisibility()); + llvm::GlobalValue::VisibilityTypes ExternDeclDLLImportVisibility = + CodeGenModule::GetLLVMVisibility(LO.getExternDeclDLLImportVisibility()); + llvm::GlobalValue::VisibilityTypes ExternDeclNoDLLStorageClassVisibility = + CodeGenModule::GetLLVMVisibility( + LO.getExternDeclNoDLLStorageClassVisibility()); + + for (llvm::GlobalValue &GV : M.global_values()) { + if (GV.hasAppendingLinkage() || GV.hasLocalLinkage()) + return; + + if (GV.isDeclarationForLinker()) { + GV.setVisibility(GV.getDLLStorageClass() == + llvm::GlobalValue::DLLImportStorageClass + ? ExternDeclDLLImportVisibility + : ExternDeclNoDLLStorageClassVisibility); + } else { + GV.setVisibility(GV.getDLLStorageClass() == + llvm::GlobalValue::DLLExportStorageClass + ? DLLExportVisibility + : NoDLLStorageClassVisibility); + } + + GV.setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + } +} + void CodeGenModule::Release() { EmitDeferred(); EmitVTablesOpportunistically(); @@ -681,6 +716,12 @@ getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames); EmitBackendOptionsMetadata(getCodeGenOpts()); + + // Set visibility from DLL export class + // We do this at the end of LLVM IR generation; after any operation + // that might affect the DLL storage class or the visibility, and + // before anything that might act on these. + setVisibilityFromDLLStorageClass(LangOpts, getModule()); } void CodeGenModule::EmitOpenCLMetadata() { Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -5228,6 +5228,30 @@ } } + if (!RawTriple.isPS4()) + if (const Arg *A = + Args.getLastArg(options::OPT_fvisibility_from_dllstorageclass, + options::OPT_fno_visibility_from_dllstorageclass)) { + if (A->getOption().matches( + options::OPT_fvisibility_from_dllstorageclass)) { + CmdArgs.push_back("-fvisibility-from-dllstorageclass"); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_dllexport_EQ); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_nodllstorageclass_EQ); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_externs_dllimport_EQ); + Args.AddLastArg(CmdArgs, + options::OPT_fvisibility_externs_nodllstorageclass_EQ); + } + + if (Args.hasArgNoClaim( + options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat, + options::OPT_fvisibility_inlines_hidden, + options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fvisibility_global_new_delete_hidden)) + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fvisibility-from-dllstorageclass" + << "with other visibility options"; + } + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, options::OPT_fno_visibility_inlines_hidden_static_local_var); Index: clang/lib/Driver/ToolChains/PS4CPU.cpp =================================================================== --- clang/lib/Driver/ToolChains/PS4CPU.cpp +++ clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -237,9 +237,8 @@ } void toolchains::PS4CPU::addClangTargetOptions( - const ArgList &DriverArgs, - ArgStringList &CC1Args, - Action::OffloadKind DeviceOffloadingKind) const { + const ArgList &DriverArgs, ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadingKind) const { // PS4 does not use init arrays. if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); @@ -248,4 +247,45 @@ } CC1Args.push_back("-fno-use-init-array"); + + const Arg *A = + DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, + options::OPT_fno_visibility_from_dllstorageclass); + if (!A || + A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) { + CC1Args.push_back("-fvisibility-from-dllstorageclass"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ)) + DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ); + else + CC1Args.push_back("-fvisibility-dllexport=protected"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ)) + DriverArgs.AddLastArg(CC1Args, + options::OPT_fvisibility_nodllstorageclass_EQ); + else + CC1Args.push_back("-fvisibility-nodllstorageclass=hidden"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ)) + DriverArgs.AddLastArg(CC1Args, + options::OPT_fvisibility_externs_dllimport_EQ); + else + CC1Args.push_back("-fvisibility-externs-dllimport=default"); + + if (DriverArgs.hasArg( + options::OPT_fvisibility_externs_nodllstorageclass_EQ)) + DriverArgs.AddLastArg( + CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ); + else + CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); + + if (DriverArgs.hasArgNoClaim( + options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat, + options::OPT_fvisibility_inlines_hidden, + options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fvisibility_global_new_delete_hidden)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-fvisibility-from-dllstorageclass" + << "with other visibility options"; + } } Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2783,6 +2783,38 @@ if (Args.hasArg(OPT_fapply_global_visibility_to_externs)) Opts.SetVisibilityForExternDecls = 1; + if (Args.hasArg(OPT_fvisibility_from_dllstorageclass)) { + Opts.VisibilityDLLStorageClass = 1; + + // Translate dllexport defintions to default visibility, by default. + if (Arg *O = Args.getLastArg(OPT_fvisibility_dllexport_EQ)) + Opts.setDLLExportVisibility(parseVisibility(O, Args, Diags)); + else + Opts.setDLLExportVisibility(DefaultVisibility); + + // Translate defintions without an explict DLL export class to hidden + // visibility, by default. + if (Arg *O = Args.getLastArg(OPT_fvisibility_nodllstorageclass_EQ)) + Opts.setNoDLLStorageClassVisibility(parseVisibility(O, Args, Diags)); + else + Opts.setNoDLLStorageClassVisibility(HiddenVisibility); + + // Translate dllimport external declarations to default visibility, by + // default. + if (Arg *O = Args.getLastArg(OPT_fvisibility_externs_dllimport_EQ)) + Opts.setExternDeclDLLImportVisibility(parseVisibility(O, Args, Diags)); + else + Opts.setExternDeclDLLImportVisibility(DefaultVisibility); + + // Translate external declarations without an explicit DLL export class + // to hidden visibility, by default. + if (Arg *O = Args.getLastArg(OPT_fvisibility_externs_nodllstorageclass_EQ)) + Opts.setExternDeclNoDLLStorageClassVisibility( + parseVisibility(O, Args, Diags)); + else + Opts.setExternDeclNoDLLStorageClassVisibility(HiddenVisibility); + } + if (Args.hasArg(OPT_ftrapv)) { Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. Index: clang/test/CodeGenCXX/visibility-dllstorageclass.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/visibility-dllstorageclass.cpp @@ -0,0 +1,68 @@ +// REQUIRES: x86-registered-target + +// Test that -fvisibility-from-dllstorageclass maps DLL storage class to visibility +// and that it overrides the effect of visibility annotations. + +// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -x c++ %s -S -emit-llvm -o - | \ +// RUN: FileCheck %s --check-prefixes=DEFAULT + +// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: -x c++ %s -S -emit-llvm -o - | \ +// RUN: FileCheck %s --check-prefixes=EXPLICIT + +// Function +void f() {} +void __declspec(dllexport) exported_f() {} +// DEFAULT-DAG: define hidden void @_Z1fv() +// DEFAULT-DAG: define dso_local void @_Z10exported_fv() +// EXPLICIT-DAG: define protected void @_Z1fv() +// EXPLICIT-DAG: define hidden void @_Z10exported_fv() + +// Variable +int d = 123; +__declspec(dllexport) int exported_d = 123; +// DEFAULT-DAG: @d = hidden global +// DEFAULT-DAG: @exported_d = dso_local global +// EXPLICIT-DAG: @d = protected global +// EXPLICIT-DAG: @exported_d = hidden global + +// Alias +extern "C" void aliased() {} +void a() __attribute__((alias("aliased"))); +void __declspec(dllexport) a_exported() __attribute__((alias("aliased"))); +// DEFAULT-DAG: @_Z1av = hidden alias +// DEFAULT-DAG: @_Z10a_exportedv = dso_local alias +// EXPLICIT-DAG: @_Z1av = protected alias +// EXPLICIT-DAG: @_Z10a_exportedv = hidden alias + +// Declaration +extern void e(); +extern void __declspec(dllimport) imported_e(); +void use_declarations(){e(); imported_e();} +// DEFAULT-DAG: declare hidden void @_Z1ev() +// DEFAULT-DAG: declare void @_Z10imported_ev() +// EXPLICIT-DAG: declare protected void @_Z1ev() +// EXPLICIT-DAG: declare hidden void @_Z10imported_ev() + +// Show that -fvisibility-from-dllstorageclass overrides the effect of visibility annotations. + +struct __attribute__((type_visibility("protected"))) t { + virtual void foo(); +}; +void t::foo() {} +// DEFAULT-DAG: @_ZTV1t = hidden unnamed_addr constant + +int v __attribute__ ((__visibility__ ("protected"))) = 123; +// DEFAULT-DAG: @v = hidden global + +#pragma GCC visibility push(protected) +int p = 345; +#pragma GCC visibility pop +// DEFAULT-DAG: @p = hidden global Index: clang/test/Driver/ps4-visibility-dllstorageclass.c =================================================================== --- /dev/null +++ clang/test/Driver/ps4-visibility-dllstorageclass.c @@ -0,0 +1,190 @@ +// RUN: %clang -### -target x86_64-scei-ps4 %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=DEFAULTS \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=DEFAULTS \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// DEFAULTS: "-fvisibility-from-dllstorageclass" +// DEFAULTS-SAME: "-fvisibility-dllexport=protected" +// DEFAULTS-SAME: "-fvisibility-nodllstorageclass=hidden" +// DEFAULTS-SAME: "-fvisibility-externs-dllimport=default" +// DEFAULTS-SAME: "-fvisibility-externs-nodllstorageclass=default" + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=UNUSED \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// UNUSED: clang: warning: argument unused during compilation: '-fvisibility-dllexport=hidden' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-nodllstorageclass=protected' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-externs-dllimport=hidden' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-externs-nodllstorageclass=protected' + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=SOME \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=SOME \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// SOME: "-fvisibility-from-dllstorageclass" +// SOME-SAME: "-fvisibility-dllexport=protected" +// SOME-SAME: "-fvisibility-nodllstorageclass=protected" +// SOME-SAME: "-fvisibility-externs-dllimport=hidden" +// SOME-SAME: "-fvisibility-externs-nodllstorageclass=default" + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-dllexport=default \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=default \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=default \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=default \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ALL \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-dllexport=default \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=default \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=default \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=default \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ALL \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// ALL: "-fvisibility-from-dllstorageclass" +// ALL-SAME: "-fvisibility-dllexport=hidden" +// ALL-SAME: "-fvisibility-nodllstorageclass=protected" +// ALL-SAME: "-fvisibility-externs-dllimport=hidden" +// ALL-SAME: "-fvisibility-externs-nodllstorageclass=protected" + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility=hidden \ +// RUN: -fvisibility-ms-compat \ +// RUN: -fvisibility-inlines-hidden \ +// RUN: -fvisibility-inlines-hidden-static-local-var \ +// RUN: -fvisibility-global-new-delete-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility=hidden \ +// RUN: -fvisibility-ms-compat \ +// RUN: -fvisibility-inlines-hidden \ +// RUN: -fvisibility-inlines-hidden-static-local-var \ +// RUN: -fvisibility-global-new-delete-hidden \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility=hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-ms-compat \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-inlines-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-inlines-hidden-static-local-var \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-scei-ps4 \ +// RUN: -fvisibility-global-new-delete-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// ERROR: clang: error: invalid argument '-fvisibility-from-dllstorageclass' not allowed with 'with other visibility options' Index: clang/test/Driver/visibility-dllstorageclass.c =================================================================== --- /dev/null +++ clang/test/Driver/visibility-dllstorageclass.c @@ -0,0 +1,149 @@ +// Check behaviour of -fvisibility-from-dllstorageclass options + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=SET \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=UNUSED \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fno-visibility-from-dllstorageclass \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=UNUSED \ +// RUN: --implicit-check-not=fvisibility-from-dllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-dllexport \ +// RUN: --implicit-check-not=-fvisibility-nodllstorageclass \ +// RUN: --implicit-check-not=-fvisibility-externs-dllimport \ +// RUN: --implicit-check-not=-fvisibility-externs-nodllstorageclass \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// UNUSED: clang: warning: argument unused during compilation: '-fvisibility-dllexport=hidden' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-nodllstorageclass=protected' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-externs-dllimport=hidden' +// UNUSED-NEXT: clang: warning: argument unused during compilation: '-fvisibility-externs-nodllstorageclass=protected' + +// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-dllexport=default \ +// RUN: -fvisibility-dllexport=hidden \ +// RUN: -fvisibility-nodllstorageclass=default \ +// RUN: -fvisibility-nodllstorageclass=protected \ +// RUN: -fvisibility-externs-dllimport=default \ +// RUN: -fvisibility-externs-dllimport=hidden \ +// RUN: -fvisibility-externs-nodllstorageclass=default \ +// RUN: -fvisibility-externs-nodllstorageclass=protected \ +// RUN: -S -### %s 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=SET,ALL \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// SET: "-fvisibility-from-dllstorageclass" +// ALL-SAME: "-fvisibility-dllexport=hidden" +// ALL-SAME: "-fvisibility-nodllstorageclass=protected" +// ALL-SAME: "-fvisibility-externs-dllimport=hidden" +// ALL-SAME: "-fvisibility-externs-nodllstorageclass=protected" + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility=hidden \ +// RUN: -fvisibility-ms-compat \ +// RUN: -fvisibility-inlines-hidden \ +// RUN: -fvisibility-inlines-hidden-static-local-var \ +// RUN: -fvisibility-global-new-delete-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility=hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-ms-compat \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-inlines-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-inlines-hidden-static-local-var \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// RUN: %clang -### -target x86_64-unknown-windows-itanium -fdeclspec \ +// RUN: -fvisibility-from-dllstorageclass \ +// RUN: -fvisibility-global-new-delete-hidden \ +// RUN: %s -o - 2>&1 | \ +// RUN: FileCheck %s -check-prefix=ERROR \ +// RUN: --implicit-check-not=error: \ +// RUN: --implicit-check-not=warning: + +// ERROR: clang: error: invalid argument '-fvisibility-from-dllstorageclass' not allowed with 'with other visibility options'