llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-driver

Author: Saleem Abdulrasool (compnerd)

<details>
<summary>Changes</summary>

When building on Windows, dealing with the BlocksRuntime is slightly more 
complicated. As we are not guaranteed a formward declaration for the blocks 
runtime ABI symbols, we may generate the declarations for them. In order to 
properly link against the well-known types, we always annotated them as 
`__declspec(dllimport)`. This would require the dynamic linking of the blocks 
runtime under all conditions. However, this is the only the only possible way 
to us the library. We may be building a fully sealed (static) executable. In 
such a case, the well known symbols should not be marked as `dllimport` as they 
are assumed to be statically available with the static linking to the 
BlocksRuntime.

Introduce a new driver/cc1 option `-static-libclosure` which mirrors the myriad 
of similar options (`-static-libgcc`, `-static-libstdc++`, -static-libsan`, 
etc).

---
Full diff: https://github.com/llvm/llvm-project/pull/125384.diff


6 Files Affected:

- (modified) clang/include/clang/Basic/CodeGenOptions.def (+4) 
- (modified) clang/include/clang/Driver/Options.td (+2) 
- (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-2) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+2) 
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (+5) 
- (modified) clang/test/CodeGen/blocks-windows.c (+7) 


``````````diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 386652d2efa9e1..9ca1fe6566d6ad 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -469,6 +469,10 @@ CODEGENOPT(CtorDtorReturnThis, 1, 0)
 /// by the Windows kernel to enable import call optimization.
 CODEGENOPT(ImportCallOptimization, 1, 0)
 
+/// Controls whether we generate code for static linking of libclosure
+/// (BlocksRuntime) on Windows.
+CODEGENOPT(StaticClosure, 1, 0)
+
 /// FIXME: Make DebugOptions its own top-level .def file.
 #include "DebugOptions.def"
 
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 0ab923fcdd5838..7f2b8b74bce79c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5825,6 +5825,8 @@ def start_no_unused_arguments : Flag<["--"], 
"start-no-unused-arguments">,
   HelpText<"Don't emit warnings about unused arguments for the following 
arguments">;
 def static_libgcc : Flag<["-"], "static-libgcc">;
 def static_libstdcxx : Flag<["-"], "static-libstdc++">;
+def static_libclosure : Flag<["-"], "static-libclosure">,
+    Visibility<[ClangOption, CC1Option]>;
 def static : Flag<["-", "--"], "static">, Group<Link_Group>,
   Visibility<[ClangOption, FlangOption]>,
   Flags<[NoArgumentUnused]>;
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index a7584a95c8ca7b..aaba354c08547d 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -2800,7 +2800,8 @@ static void configureBlocksRuntimeObject(CodeGenModule 
&CGM,
                                          llvm::Constant *C) {
   auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
 
-  if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) {
+  if (!CGM.getCodeGenOpts().StaticClosure &&
+      CGM.getTarget().getTriple().isOSBinFormatCOFF()) {
     const IdentifierInfo &II = CGM.getContext().Idents.get(C->getName());
     TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
     DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
@@ -2815,7 +2816,6 @@ static void configureBlocksRuntimeObject(CodeGenModule 
&CGM,
           (ND = dyn_cast<VarDecl>(Result)))
         break;
 
-    // TODO: support static blocks runtime
     if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
       GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
       GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 9b5132c5625faa..ad73ac4dd8f73d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5580,6 +5580,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   if (Args.hasArg(options::OPT_static))
     CmdArgs.push_back("-static-define");
 
+  Args.AddLastArg(CmdArgs, options::OPT_static_libclosure);
+
   if (Args.hasArg(options::OPT_municode))
     CmdArgs.push_back("-DUNICODE");
 
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 11fd6ab7f52a79..de31c3c40fecf0 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1843,6 +1843,9 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const 
CodeGenOptions &Opts,
     GenerateArg(Consumer, OPT_fno_finite_loops);
     break;
   }
+
+  if (Opts.StaticClosure)
+    GenerateArg(Consumer, OPT_static_libclosure);
 }
 
 bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
@@ -2330,6 +2333,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions 
&Opts, ArgList &Args,
   if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
     Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
 
+  Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure);
+
   return Diags.getNumErrors() == NumErrorsBefore;
 }
 
diff --git a/clang/test/CodeGen/blocks-windows.c 
b/clang/test/CodeGen/blocks-windows.c
index 3da5f3d99bd23d..7c6b5cc85fdff4 100644
--- a/clang/test/CodeGen/blocks-windows.c
+++ b/clang/test/CodeGen/blocks-windows.c
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -emit-llvm %s 
-o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -8,6 +9,7 @@
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -Os -emit-llvm 
%s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -Os 
-static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -15,6 +17,7 @@
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -emit-llvm %s -o - 
| FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -static-libclosure 
-emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -22,6 +25,7 @@
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -Os -emit-llvm %s 
-o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -Os 
-static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -29,6 +33,7 @@
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -emit-llvm %s -o 
- | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -36,6 +41,7 @@
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DECL
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-IN-BLOCKS-DEFN
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -Os -emit-llvm 
%s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS
+// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -Os 
-static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix 
CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT
 // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec 
-DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s 
-check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT
@@ -70,6 +76,7 @@ int (*g(void))(void) {
 // CHECK-BLOCKS-IN-BLOCKS-DECL: @_NSConcreteStackBlock = external dso_local 
dllexport global ptr
 // CHECK-BLOCKS-IN-BLOCKS-DEFN: @_NSConcreteStackBlock = dso_local dllexport 
global [5 x i32]
 // CHECK-BLOCKS-NOT-IN-BLOCKS: @_NSConcreteStackBlock = external dllimport 
global ptr
+// CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS: @_NSConcreteStackBlock = external global 
ptr
 // CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN: @_NSConcreteStackBlock = external 
dllimport global ptr
 // CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT: @_NSConcreteStackBlock = 
external dllimport global ptr
 // CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT: @_NSConcreteStackBlock = external 
dllimport global ptr

``````````

</details>


https://github.com/llvm/llvm-project/pull/125384
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to