This revision was automatically updated to reflect the committed changes.
Closed by commit rG415f7ee88369: [Clang] Add the ability to map DLL storage 
class to visibility (authored by Ben Dunbobbin <ben.dunbob...@sony.com>).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D89970?vs=301803&id=302305#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89970/new/

https://reviews.llvm.org/D89970

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/PS4CPU.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
  clang/test/Driver/ps4-visibility-dllstorageclass.c
  clang/test/Driver/visibility-dllstorageclass.c

Index: clang/test/Driver/visibility-dllstorageclass.c
===================================================================
--- /dev/null
+++ clang/test/Driver/visibility-dllstorageclass.c
@@ -0,0 +1,87 @@
+// Check behaviour of -fvisibility-from-dllstorageclass options
+
+// RUN: %clang -target x86_64-unknown-windows-itanium -fdeclspec \
+// RUN:     -Werror -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: %clang -target x86_64-unknown-windows-itanium -fdeclspec \
+// RUN:     -fvisibility-from-dllstorageclass \
+// RUN:     -fno-visibility-from-dllstorageclass \
+// RUN:     -Werror -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: %clang -target x86_64-unknown-windows-itanium -fdeclspec \
+// RUN:     -fno-visibility-from-dllstorageclass \
+// RUN:     -fvisibility-from-dllstorageclass \
+// RUN:     -Werror -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: %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:     -Werror -S -### %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefixes=SET,ALL
+
+// 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"
Index: clang/test/Driver/ps4-visibility-dllstorageclass.c
===================================================================
--- /dev/null
+++ clang/test/Driver/ps4-visibility-dllstorageclass.c
@@ -0,0 +1,128 @@
+// Check behaviour of -fvisibility-from-dllstorageclass options for PS4
+
+// RUN: %clang -### -target x86_64-scei-ps4 %s -Werror -o - 2>&1 | \
+// RUN:   FileCheck %s -check-prefixes=DEFAULTS,DEFAULTS1 \
+// 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: %clang -### -target x86_64-scei-ps4 \
+// RUN:     -fno-visibility-from-dllstorageclass \
+// RUN:     -fvisibility-from-dllstorageclass \
+// RUN:     -Werror \
+// RUN:     %s -o - 2>&1 | \
+// RUN:   FileCheck %s -check-prefixes=DEFAULTS,DEFAULTS2 \
+// 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
+
+// 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=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:     -Werror \
+// 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
+
+// SOME1:      "-fvisibility-from-dllstorageclass"
+// SOME1-SAME: "-fvisibility-dllexport=protected"
+// SOME1-SAME: "-fvisibility-nodllstorageclass=protected"
+// SOME1-SAME: "-fvisibility-externs-dllimport=hidden"
+// SOME1-SAME: "-fvisibility-externs-nodllstorageclass=default"
+
+// RUN: %clang -### -target x86_64-scei-ps4 \
+// RUN:     -fvisibility-from-dllstorageclass \
+// RUN:     -fvisibility-nodllstorageclass=protected \
+// RUN:     -fvisibility-externs-dllimport=hidden \
+// RUN:     -Werror \
+// 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
+
+// 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:     -Werror \
+// 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: %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:     -Werror \
+// 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
+
+// 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"
Index: clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
@@ -0,0 +1,70 @@
+// REQUIRES: x86-registered-target
+
+// Test that -fvisibility-from-dllstorageclass maps DLL storage class to visibility
+// and that it overrides the effect of visibility options and annotations.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \
+// RUN:     -fvisibility hidden \
+// 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 hidden \
+// 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/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2814,6 +2814,38 @@
   if (Args.hasArg(OPT_fapply_global_visibility_to_externs))
     Opts.SetVisibilityForExternDecls = 1;
 
+  if (Args.hasArg(OPT_fvisibility_from_dllstorageclass)) {
+    Opts.VisibilityFromDLLStorageClass = 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 storage 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 storage 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/lib/Driver/ToolChains/PS4CPU.cpp
===================================================================
--- clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -239,9 +239,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);
@@ -250,4 +249,36 @@
   }
 
   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");
+  }
 }
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5317,6 +5317,21 @@
     }
   }
 
+  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 (const Arg *A = Args.getLastArg(options::OPT_mignore_xcoff_visibility)) {
     if (Triple.isOSAIX())
       CmdArgs.push_back("-mignore-xcoff-visibility");
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.VisibilityFromDLLStorageClass)
+    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();
@@ -688,6 +723,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/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1973,6 +1973,15 @@
 def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>,
   HelpText<"Generate verbose assembly output">;
 def dA : Flag<["-"], "dA">, Alias<fverbose_asm>;
+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<f_Group>, Flags<[CC1Option]>,
+  HelpText<"The visibility for dllexport defintions [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group<f_Group>, Flags<[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<f_Group>, Flags<[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<f_Group>, Flags<[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<f_Group>,
   HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">;
 def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -307,6 +307,16 @@
              "default visibility for types [-ftype-visibility]")
 LANGOPT(SetVisibilityForExternDecls, 1, 0,
         "apply global symbol visibility to external declarations without an explicit visibility")
+LANGOPT(VisibilityFromDLLStorageClass, 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,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to