Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -1940,17 +1940,22 @@ ``a::`` This specifies the alignment for an object of aggregate type. ``m:`` - If present, specifies that llvm names are mangled in the output. The + If present, specifies that llvm names are mangled in the output. Symbols + prefixed with the mangling escape character ``\01`` are passed through + directly to the assembler without the escape character. The mangling style options are * ``e``: ELF mangling: Private symbols get a ``.L`` prefix. * ``m``: Mips mangling: Private symbols get a ``$`` prefix. * ``o``: Mach-O mangling: Private symbols get ``L`` prefix. Other symbols get a ``_`` prefix. - * ``w``: Windows COFF prefix: Similar to Mach-O, but stdcall and fastcall - functions also get a suffix based on the frame size. - * ``x``: Windows x86 COFF prefix: Similar to Windows COFF, but use a ``_`` - prefix for ``__cdecl`` functions. + * ``x``: Windows x86 COFF mangling: Private symbols get the usual prefix. + Regular C symbols get a ``_`` prefix. Functions with ``__stdcall``, + ``__fastcall``, and ``__vectorcall`` have custom mangling that appends + ``@N`` where N is the number of bytes used to pass parameters. C++ symbols + starting with ``?`` are not mangled in any way. + * ``w``: Windows COFF mangling: Similar to ``x``, except that normal C + symbols do not receive a ``_`` prefix. ``n::...`` This specifies a set of native integer widths for the target CPU in bits. For example, it might contain ``n32`` for 32-bit PowerPC, Index: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -42,6 +42,9 @@ * The LoopInstSimplify pass (-loop-instsimplify) has been removed. +* Symbols starting with ``?`` are no longer mangled by LLVM when using the + Windows ``x`` or ``w`` IR mangling schemes. + * Note.. .. NOTE Index: llvm/include/llvm/IR/DataLayout.h =================================================================== --- llvm/include/llvm/IR/DataLayout.h +++ llvm/include/llvm/IR/DataLayout.h @@ -263,6 +263,12 @@ return ManglingMode == MM_WinCOFFX86; } + /// Returns true if symbols with leading question marks should receive IR + /// mangling. True for Windows mangling modes. + bool shouldMangleLeadingQuestionMark() const { + return ManglingMode == MM_WinCOFF || ManglingMode == MM_WinCOFFX86; + } + bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; } StringRef getLinkerPrivateGlobalPrefix() const { Index: llvm/lib/IR/Mangler.cpp =================================================================== --- llvm/lib/IR/Mangler.cpp +++ llvm/lib/IR/Mangler.cpp @@ -135,8 +135,14 @@ // Mangle functions with Microsoft calling conventions specially. Only do // this mangling for x86_64 vectorcall and 32-bit x86. const Function *MSFunc = dyn_cast(GV); - if (Name.startswith("\01")) - MSFunc = nullptr; // Don't mangle when \01 is present. + + // Don't mangle when '\01' or '?' are in the first character. + if (Name.startswith("\01") || + (DL.shouldMangleLeadingQuestionMark() && Name.startswith("?"))) { + MSFunc = nullptr; + Prefix = '\0'; + } + CallingConv::ID CC = MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C; if (!DL.hasMicrosoftFastStdCallMangling() && Index: llvm/test/CodeGen/X86/mangle-question-mark.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/mangle-question-mark.ll @@ -0,0 +1,60 @@ +; Test that symbols starting with '?' are not affected by IR mangling. + +; RUN: llc -mtriple i686-pc-win32 < %s | FileCheck %s --check-prefix=COFF +; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s --check-prefix=COFF64 +; RUN: llc -mtriple i686-linux-gnu < %s | FileCheck %s --check-prefix=ELF +; RUN: llc -mtriple i686-apple-darwin < %s | FileCheck %s --check-prefix=MACHO + +; Currently all object files allow escaping private symbols, but eventually we +; might want to reject that. + +; COFF: calll "?withescape@A@@QBEXXZ" +; COFF: calll "?withquestion@A@@QBEXXZ" +; COFF: calll "L?privatequestion@A@@QBEXXZ" +; COFF: calll "L?privatequestionfast@A@@QBEXXZ" +; COFF: calll "?escapedprivate@A@@QBEXXZ" + +; COFF64: callq "?withescape@A@@QBEXXZ" +; COFF64: callq "?withquestion@A@@QBEXXZ" +; COFF64: callq ".L?privatequestion@A@@QBEXXZ" +; COFF64: callq ".L?privatequestionfast@A@@QBEXXZ" +; COFF64: callq "?escapedprivate@A@@QBEXXZ" + +; ELF: calll "?withescape@A@@QBEXXZ" +; ELF: calll "?withquestion@A@@QBEXXZ" +; ELF: calll ".L?privatequestion@A@@QBEXXZ" +; ELF: calll ".L?privatequestionfast@A@@QBEXXZ" +; ELF: calll "?escapedprivate@A@@QBEXXZ" + +; MACHO: calll "?withescape@A@@QBEXXZ" +; MACHO: calll "_?withquestion@A@@QBEXXZ" +; MACHO: calll "l_?privatequestion@A@@QBEXXZ" +; MACHO: calll "l_?privatequestionfast@A@@QBEXXZ" +; MACHO: calll "?escapedprivate@A@@QBEXXZ" + +%struct.A = type {} + +define i32 @main() { +entry: + tail call void @"\01?withescape@A@@QBEXXZ"(%struct.A* null) + tail call void @"?withquestion@A@@QBEXXZ"(%struct.A* null) + tail call void @"?privatequestion@A@@QBEXXZ"(%struct.A* null) + tail call x86_fastcallcc void @"?privatequestionfast@A@@QBEXXZ"(%struct.A* null) + tail call void @"\01?escapedprivate@A@@QBEXXZ"(%struct.A* null) + ret i32 0 +} + +declare void @"\01?withescape@A@@QBEXXZ"(%struct.A*) +declare void @"?withquestion@A@@QBEXXZ"(%struct.A*) + +define private void @"?privatequestion@A@@QBEXXZ"(%struct.A*) { + ret void +} + +define private x86_fastcallcc void @"?privatequestionfast@A@@QBEXXZ"(%struct.A*) { + ret void +} + +define private void @"\01?escapedprivate@A@@QBEXXZ"(%struct.A*) { + ret void +} Index: llvm/test/MC/COFF/symbol-mangling.ll =================================================================== --- llvm/test/MC/COFF/symbol-mangling.ll +++ /dev/null @@ -1,17 +0,0 @@ -; The purpose of this test is to see if the MC layer properly handles symbol -; names needing quoting on MS/Windows. This code is generated by clang when -; using -cxx-abi microsoft. - -; RUN: llc -filetype=asm -mtriple i686-pc-win32 %s -o - | FileCheck %s - -; CHECK: ?sayhi@A@@QBEXXZ - -%struct.A = type {} - -define i32 @main() { -entry: - tail call void @"\01?sayhi@A@@QBEXXZ"(%struct.A* null) - ret i32 0 -} - -declare void @"\01?sayhi@A@@QBEXXZ"(%struct.A*)