summaryrefslogtreecommitdiff
path: root/unittests/IR
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-03-16 20:13:32 +0000
committerReid Kleckner <rnk@google.com>2018-03-16 20:13:32 +0000
commit025ee4f9cce917b199e3b42b07b99ec1144cdda6 (patch)
tree17f0dd89363616e6215142a889638944a909bda3 /unittests/IR
parentf6f2e196818fca6c179ac08dff763772478e687a (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/IR')
-rw-r--r--unittests/IR/CMakeLists.txt1
-rw-r--r--unittests/IR/ManglerTest.cpp140
2 files changed, 141 insertions, 0 deletions
diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt
index 15f869c6bd4..b2782a930f8 100644
--- a/unittests/IR/CMakeLists.txt
+++ b/unittests/IR/CMakeLists.txt
@@ -25,6 +25,7 @@ set(IRSources
IntrinsicsTest.cpp
LegacyPassManagerTest.cpp
MDBuilderTest.cpp
+ ManglerTest.cpp
MetadataTest.cpp
ModuleTest.cpp
PassManagerTest.cpp
diff --git a/unittests/IR/ManglerTest.cpp b/unittests/IR/ManglerTest.cpp
new file mode 100644
index 00000000000..04f1ca6cf97
--- /dev/null
+++ b/unittests/IR/ManglerTest.cpp
@@ -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