Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IR] Avoid the need to prefix MS C++ symbols with '\01'
Now the Windows mangling modes ('w' and 'x') do not do any mangling for symbols starting with '?'. This means that clang can stop adding the hideous '\01' leading escape. This means LLVM debug logs are less likely to contain ASCII escape characters and it will be easier to copy and paste MS symbol names from IR. Finally. For non-Windows platforms, names starting with '?' still get IR mangling, so once clang stops escaping MS C++ names, we will get extra '_' prefixing on MachO. That's fine, since it is currently impossible to construct a triple that uses the MS C++ ABI in clang and emits macho object files. Differential Revision: https://reviews.llvm.org/D7775 llvm-svn: 327734
- Loading branch information
Showing
8 changed files
with
230 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
//===- llvm/unittest/IR/ManglerTest.cpp - Mangler unit tests --------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/IR/Mangler.h" | ||
#include "llvm/IR/CallingConv.h" | ||
#include "llvm/IR/DataLayout.h" | ||
#include "llvm/IR/GlobalValue.h" | ||
#include "llvm/IR/Module.h" | ||
#include "gtest/gtest.h" | ||
|
||
using namespace llvm; | ||
|
||
static std::string mangleStr(StringRef IRName, Mangler &Mang, | ||
const DataLayout &DL) { | ||
std::string Mangled; | ||
raw_string_ostream SS(Mangled); | ||
Mang.getNameWithPrefix(SS, IRName, DL); | ||
SS.flush(); | ||
return Mangled; | ||
} | ||
|
||
static std::string mangleFunc(StringRef IRName, | ||
GlobalValue::LinkageTypes Linkage, | ||
llvm::CallingConv::ID CC, Module &Mod, | ||
Mangler &Mang) { | ||
Type *VoidTy = Type::getVoidTy(Mod.getContext()); | ||
Type *I32Ty = Type::getInt32Ty(Mod.getContext()); | ||
FunctionType *FTy = | ||
FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false); | ||
Function *F = Function::Create(FTy, Linkage, IRName, &Mod); | ||
F->setCallingConv(CC); | ||
std::string Mangled; | ||
raw_string_ostream SS(Mangled); | ||
Mang.getNameWithPrefix(SS, F, false); | ||
SS.flush(); | ||
F->eraseFromParent(); | ||
return Mangled; | ||
} | ||
|
||
namespace { | ||
|
||
TEST(ManglerTest, MachO) { | ||
LLVMContext Ctx; | ||
DataLayout DL("m:o"); // macho | ||
Module Mod("test", Ctx); | ||
Mod.setDataLayout(DL); | ||
Mangler Mang; | ||
EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo"); | ||
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo"); | ||
EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"_foo"); | ||
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"_?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"L_foo"); | ||
} | ||
|
||
TEST(ManglerTest, WindowsX86) { | ||
LLVMContext Ctx; | ||
DataLayout DL("m:x-p:32:32"); // 32-bit windows | ||
Module Mod("test", Ctx); | ||
Mod.setDataLayout(DL); | ||
Mangler Mang; | ||
EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo"); | ||
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo"); | ||
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"_foo"); | ||
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"L_foo"); | ||
|
||
// Test calling conv mangling. | ||
EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_StdCall, Mod, Mang), | ||
"_stdcall@12"); | ||
EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_FastCall, Mod, Mang), | ||
"@fastcall@12"); | ||
EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_VectorCall, Mod, Mang), | ||
"vectorcall@@12"); | ||
|
||
// Adding a '?' prefix blocks calling convention mangling. | ||
EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_FastCall, Mod, Mang), | ||
"?fastcall"); | ||
} | ||
|
||
TEST(ManglerTest, WindowsX64) { | ||
LLVMContext Ctx; | ||
DataLayout DL("m:w-p:64:64"); // windows | ||
Module Mod("test", Ctx); | ||
Mod.setDataLayout(DL); | ||
Mangler Mang; | ||
EXPECT_EQ(mangleStr("foo", Mang, DL), "foo"); | ||
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo"); | ||
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"foo"); | ||
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
"?foo"); | ||
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage, | ||
llvm::CallingConv::C, Mod, Mang), | ||
".Lfoo"); | ||
|
||
// Test calling conv mangling. | ||
EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_StdCall, Mod, Mang), | ||
"stdcall"); | ||
EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_FastCall, Mod, Mang), | ||
"fastcall"); | ||
EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_VectorCall, Mod, Mang), | ||
"vectorcall@@24"); | ||
|
||
// Adding a '?' prefix blocks calling convention mangling. | ||
EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage, | ||
llvm::CallingConv::X86_VectorCall, Mod, Mang), | ||
"?vectorcall"); | ||
} | ||
|
||
} // end anonymous namespace |