sunfish created this revision. Herald added subscribers: llvm-commits, dexonsmith, aheejin, jgravelle-google, sbc100, mehdi_amini, dschuff. Herald added projects: clang, LLVM.
WebAssembly enforces a rule that caller and callee signatures must match. This means that the traditional technique of passing `main` `argc` and `argv` even when it doesn't need them doesn't work. Currently the backend renames `main` to `__original_main`, however this doesn't interact well with LTO'ing libc, and the name isn't intuitive. This patch allows us to transition to `__main_argc_argv` instead. This is currently being discussed in https://github.com/WebAssembly/tool-conventions/pull/134. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70700 Files: clang/lib/AST/Mangle.cpp clang/lib/Frontend/InitHeaderSearch.cpp clang/test/CodeGen/wasm-call-main.c clang/test/CodeGen/wasm-main.c clang/test/CodeGen/wasm-main_argc_argv.c llvm/include/llvm/ADT/Triple.h
Index: llvm/include/llvm/ADT/Triple.h =================================================================== --- llvm/include/llvm/ADT/Triple.h +++ llvm/include/llvm/ADT/Triple.h @@ -730,6 +730,11 @@ return getArch() == Triple::riscv32 || getArch() == Triple::riscv64; } + /// Tests whether the target is wasm (32- and 64-bit). + bool isWasm() const { + return getArch() == Triple::wasm32 || getArch() == Triple::wasm64; + } + /// Tests whether the target supports comdat bool supportsCOMDAT() const { return !isOSBinFormatMachO(); Index: clang/test/CodeGen/wasm-main_argc_argv.c =================================================================== --- /dev/null +++ clang/test/CodeGen/wasm-main_argc_argv.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm %s | FileCheck %s + +// Mangle the argc/argv form of main. + +int main(int argc, char **argv) { + return 0; +} + +// CHECK-LABEL: define i32 @__main_argc_argv(i32 %argc, i8** %argv) Index: clang/test/CodeGen/wasm-main.c =================================================================== --- /dev/null +++ clang/test/CodeGen/wasm-main.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm %s | FileCheck %s + +// Don't mangle the no-arg form of main. + +int main(void) { + return 0; +} + +// CHECK-LABEL: define i32 @main() Index: clang/test/CodeGen/wasm-call-main.c =================================================================== --- /dev/null +++ clang/test/CodeGen/wasm-call-main.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm %s | FileCheck %s + +// Mangle argc/argv main even when it's not defined in this TU. + +#include <stddef.h> + +int main(int argc, char *argv[]); + +int foo(void) { + return main(0, NULL); +} + +// CHECK: call i32 @__main_argc_argv( Index: clang/lib/Frontend/InitHeaderSearch.cpp =================================================================== --- clang/lib/Frontend/InitHeaderSearch.cpp +++ clang/lib/Frontend/InitHeaderSearch.cpp @@ -435,8 +435,7 @@ break; case llvm::Triple::UnknownOS: - if (triple.getArch() == llvm::Triple::wasm32 || - triple.getArch() == llvm::Triple::wasm64) + if (triple.isWasm()) return; break; } Index: clang/lib/AST/Mangle.cpp =================================================================== --- clang/lib/AST/Mangle.cpp +++ clang/lib/AST/Mangle.cpp @@ -50,7 +50,8 @@ CCM_Fast, CCM_RegCall, CCM_Vector, - CCM_Std + CCM_Std, + CCM_WasmMainArgcArgv }; static bool isExternC(const NamedDecl *ND) { @@ -63,6 +64,14 @@ const NamedDecl *ND) { const TargetInfo &TI = Context.getTargetInfo(); const llvm::Triple &Triple = TI.getTriple(); + + // On wasm, the argc/argv form of "main" is renamed so that the startup code + // can call it with the correct function signature. + if (Triple.isWasm()) + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) + if (FD->isMain() && FD->hasPrototype() && FD->param_size() == 2) + return CCM_WasmMainArgcArgv; + if (!Triple.isOSWindows() || !(Triple.getArch() == llvm::Triple::x86 || Triple.getArch() == llvm::Triple::x86_64)) @@ -145,6 +154,12 @@ const ASTContext &ASTContext = getASTContext(); CCMangling CC = getCallingConvMangling(ASTContext, D); + + if (CC == CCM_WasmMainArgcArgv) { + Out << "__main_argc_argv"; + return; + } + bool MCXX = shouldMangleCXXName(D); const TargetInfo &TI = Context.getTargetInfo(); if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits