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
