https://github.com/hmelder updated 
https://github.com/llvm/llvm-project/pull/169043

>From 38fb99534154f37f43a69318407550db2dbe45f5 Mon Sep 17 00:00:00 2001
From: hmelder <[email protected]>
Date: Fri, 21 Nov 2025 10:42:47 +0000
Subject: [PATCH 1/5] [clang] Whitelist wasm when targeting GNUstep 2.x

---
 clang/lib/Driver/ToolChains/Clang.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index ab671d032644b..6f583af41999e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8091,7 +8091,8 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
     if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
         (runtime.getVersion() >= VersionTuple(2, 0)))
       if (!getToolChain().getTriple().isOSBinFormatELF() &&
-          !getToolChain().getTriple().isOSBinFormatCOFF()) {
+          !getToolChain().getTriple().isOSBinFormatCOFF() &&
+          !getToolChain().getTriple().isOSBinFormatWasm()) {
         getToolChain().getDriver().Diag(
             diag::err_drv_gnustep_objc_runtime_incompatible_binary)
           << runtime.getVersion().getMajor();

>From 6e135cdab416fb5c03ab3f78a61a575a1a6644ed Mon Sep 17 00:00:00 2001
From: hmelder <[email protected]>
Date: Fri, 21 Nov 2025 10:50:35 +0000
Subject: [PATCH 2/5] [CodeGen][ObjC] Mangle public symbols for wasm

Emscripten requires that exported symbols. See
https://github.com/emscripten-core/emscripten/pull/23563.
---
 clang/lib/CodeGen/CGObjCGNU.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 32fd6b760ed11..698fe16df7b85 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -179,8 +179,16 @@ class CGObjCGNU : public CGObjCRuntime {
       (R.getVersion() >= VersionTuple(major, minor));
   }
 
-  std::string ManglePublicSymbol(StringRef Name) {
-    return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + 
Name).str();
+  const std::string ManglePublicSymbol(StringRef Name) {
+    StringRef prefix = "._";
+
+    // Exported symbols in Emscripten must be a valid Javascript identifier.
+    auto triple = CGM.getTriple();
+    if (triple.isOSBinFormatCOFF() || triple.isOSBinFormatWasm()) {
+      prefix = "$_";
+    }
+
+    return (prefix + Name).str();
   }
 
   std::string SymbolForProtocol(Twine Name) {

>From 90ce962fd0b450eef7670fc2ad07165cff2a555a Mon Sep 17 00:00:00 2001
From: hmelder <[email protected]>
Date: Fri, 21 Nov 2025 13:04:33 +0000
Subject: [PATCH 3/5] [CodeGen][ObjC] Fix class_registerAlias_np signature

---
 clang/lib/CodeGen/CGObjCGNU.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 698fe16df7b85..080b263e5fd4d 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -4119,8 +4119,7 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
   if (!ClassAliases.empty()) {
     llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
     llvm::FunctionType *RegisterAliasTy =
-      llvm::FunctionType::get(Builder.getVoidTy(),
-                              ArgTypes, false);
+        llvm::FunctionType::get(BoolTy, ArgTypes, false);
     llvm::Function *RegisterAlias = llvm::Function::Create(
       RegisterAliasTy,
       llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np",

>From 2a9692a67daf099e97d10daa3c5e7c691717e81f Mon Sep 17 00:00:00 2001
From: hmelder <[email protected]>
Date: Fri, 28 Nov 2025 16:28:35 +0000
Subject: [PATCH 4/5] [CodeGen][ObjC] Add WASM symbol mangling test

---
 .../CodeGenObjC/gnustep2-wasm32-symbols.m     | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 clang/test/CodeGenObjC/gnustep2-wasm32-symbols.m

diff --git a/clang/test/CodeGenObjC/gnustep2-wasm32-symbols.m 
b/clang/test/CodeGenObjC/gnustep2-wasm32-symbols.m
new file mode 100644
index 0000000000000..7da73b8f1903e
--- /dev/null
+++ b/clang/test/CodeGenObjC/gnustep2-wasm32-symbols.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-emscripten -emit-llvm 
-fobjc-runtime=gnustep-2.2 -o - %s | FileCheck %s
+
+@class NSString;
+
+@protocol AProtocol
+- (void) meth;
+@end
+
+@interface AClass <AProtocol>
+@end
+
+@implementation AClass
+- (void) meth {}
+@end
+
+// Make sure that all public symbols are mangled correctly. All exported 
symbols
+// must be valid Javascript identifiers in Emscripten.
+// CHECK: $"$_OBJC_PROTOCOL_AProtocol" = comdat any
+// CHECK: @"$_OBJC_METACLASS_AClass"
+// CHECK: @"$_OBJC_PROTOCOL_AProtocol"
+// CHECK: @"$_OBJC_CLASS_AClass"
+// CHECK: @"$_OBJC_REF_CLASS_AClass"
+// CHECK: @"$_OBJC_INIT_CLASS_AClass"

>From 912f59824d1b4ec4b96fbe85c62d8782e1f3d516 Mon Sep 17 00:00:00 2001
From: hmelder <[email protected]>
Date: Wed, 14 Jan 2026 10:23:18 +0000
Subject: [PATCH 5/5] [CodeGen][ObjC] Use C++-based EH for WASM targets

The Wasm EH implementation in Clang pretty much hard-codes
__gxx_wasm_personality_v0 by calling the veneer function
_Unwind_CallPersonality instead of calling the personality function
directly.

While it is possible to remove _Unwind_CallPersonality and instead
generate its body in CG, this will add a couple of instructions in each
catch block. Doable, but we can also do the following:

Since we already have C++-based EH for MinGW in CGObjCGNU, reusing it
for Wasm saves us from implementing our own personality function
and objc_begin_catch/objc_end_catch functions.
---
 clang/lib/CodeGen/CGException.cpp | 13 ++++++++++---
 clang/lib/CodeGen/CGObjCGNU.cpp   |  9 ++++-----
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGException.cpp 
b/clang/lib/CodeGen/CGException.cpp
index e9d20672ce185..749dde5a92dcd 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -161,6 +161,8 @@ static const EHPersonality &getObjCPersonality(const 
TargetInfo &Target,
   case ObjCRuntime::GNUstep:
     if (T.isOSCygMing())
       return EHPersonality::GNU_CPlusPlus_SEH;
+    else if (T.isWasm())
+      return EHPersonality::GNU_Wasm_CPlusPlus;
     else if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
       return EHPersonality::GNUstep_ObjC;
     [[fallthrough]];
@@ -200,7 +202,8 @@ static const EHPersonality &getCXXPersonality(const 
TargetInfo &Target,
 static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
                                                  const CodeGenOptions &CGOpts,
                                                  const LangOptions &L) {
-  if (Target.getTriple().isWindowsMSVCEnvironment())
+  auto Triple = Target.getTriple();
+  if (Triple.isWindowsMSVCEnvironment())
     return EHPersonality::MSVC_CxxFrameHandler3;
 
   switch (L.ObjCRuntime.getKind()) {
@@ -218,8 +221,12 @@ static const EHPersonality &getObjCXXPersonality(const 
TargetInfo &Target,
     return getObjCPersonality(Target, CGOpts, L);
 
   case ObjCRuntime::GNUstep:
-    return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
-                                            : EHPersonality::GNU_ObjCXX;
+    if (Triple.isWasm())
+      return EHPersonality::GNU_Wasm_CPlusPlus;
+    else if (Triple.isOSCygMing())
+      return EHPersonality::GNU_CPlusPlus_SEH;
+    else
+      return EHPersonality::GNU_ObjCXX;
 
   // The GCC runtime's personality function inherently doesn't support
   // mixed EH.  Use the ObjC personality just to avoid returning null.
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 080b263e5fd4d..f9835703a68a9 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -2368,12 +2368,11 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned 
runtimeABIVersion,
     MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
     ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
 
+  auto Triple = cgm.getContext().getTargetInfo().getTriple();
+
   msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
-  usesSEHExceptions =
-      cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment();
-  usesCxxExceptions =
-      cgm.getContext().getTargetInfo().getTriple().isOSCygMing() &&
-      isRuntime(ObjCRuntime::GNUstep, 2);
+  usesSEHExceptions = Triple.isWindowsMSVCEnvironment();
+  usesCxxExceptions = (Triple.isOSCygMing() && isRuntime(ObjCRuntime::GNUstep, 
2)) || Triple.isWasm();
 
   CodeGenTypes &Types = CGM.getTypes();
   IntTy = cast<llvm::IntegerType>(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to