1 //===- llvm/unittest/IR/ManglerTest.cpp - Mangler unit tests --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/IR/Mangler.h"
10 #include "llvm/IR/CallingConv.h"
11 #include "llvm/IR/DataLayout.h"
12 #include "llvm/IR/GlobalValue.h"
13 #include "llvm/IR/Module.h"
14 #include "gtest/gtest.h"
15
16 using namespace llvm;
17
mangleStr(StringRef IRName,Mangler & Mang,const DataLayout & DL)18 static std::string mangleStr(StringRef IRName, Mangler &Mang,
19 const DataLayout &DL) {
20 std::string Mangled;
21 raw_string_ostream SS(Mangled);
22 Mang.getNameWithPrefix(SS, IRName, DL);
23 SS.flush();
24 return Mangled;
25 }
26
mangleFunc(StringRef IRName,GlobalValue::LinkageTypes Linkage,llvm::CallingConv::ID CC,Module & Mod,Mangler & Mang)27 static std::string mangleFunc(StringRef IRName,
28 GlobalValue::LinkageTypes Linkage,
29 llvm::CallingConv::ID CC, Module &Mod,
30 Mangler &Mang) {
31 Type *VoidTy = Type::getVoidTy(Mod.getContext());
32 Type *I32Ty = Type::getInt32Ty(Mod.getContext());
33 FunctionType *FTy =
34 FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
35 Function *F = Function::Create(FTy, Linkage, IRName, &Mod);
36 F->setCallingConv(CC);
37 std::string Mangled;
38 raw_string_ostream SS(Mangled);
39 Mang.getNameWithPrefix(SS, F, false);
40 SS.flush();
41 F->eraseFromParent();
42 return Mangled;
43 }
44
45 namespace {
46
TEST(ManglerTest,MachO)47 TEST(ManglerTest, MachO) {
48 LLVMContext Ctx;
49 DataLayout DL("m:o"); // macho
50 Module Mod("test", Ctx);
51 Mod.setDataLayout(DL);
52 Mangler Mang;
53 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
54 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
55 EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");
56 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
57 llvm::CallingConv::C, Mod, Mang),
58 "_foo");
59 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
60 llvm::CallingConv::C, Mod, Mang),
61 "_?foo");
62 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
63 llvm::CallingConv::C, Mod, Mang),
64 "L_foo");
65 }
66
TEST(ManglerTest,WindowsX86)67 TEST(ManglerTest, WindowsX86) {
68 LLVMContext Ctx;
69 DataLayout DL("m:x-p:32:32"); // 32-bit windows
70 Module Mod("test", Ctx);
71 Mod.setDataLayout(DL);
72 Mangler Mang;
73 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
74 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
75 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
76 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
77 llvm::CallingConv::C, Mod, Mang),
78 "_foo");
79 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
80 llvm::CallingConv::C, Mod, Mang),
81 "?foo");
82 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
83 llvm::CallingConv::C, Mod, Mang),
84 "L_foo");
85
86 // Test calling conv mangling.
87 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
88 llvm::CallingConv::X86_StdCall, Mod, Mang),
89 "_stdcall@12");
90 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
91 llvm::CallingConv::X86_FastCall, Mod, Mang),
92 "@fastcall@12");
93 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
94 llvm::CallingConv::X86_VectorCall, Mod, Mang),
95 "vectorcall@@12");
96
97 // Adding a '?' prefix blocks calling convention mangling.
98 EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,
99 llvm::CallingConv::X86_FastCall, Mod, Mang),
100 "?fastcall");
101 }
102
TEST(ManglerTest,WindowsX64)103 TEST(ManglerTest, WindowsX64) {
104 LLVMContext Ctx;
105 DataLayout DL("m:w-p:64:64"); // windows
106 Module Mod("test", Ctx);
107 Mod.setDataLayout(DL);
108 Mangler Mang;
109 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
110 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
111 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
112 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
113 llvm::CallingConv::C, Mod, Mang),
114 "foo");
115 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
116 llvm::CallingConv::C, Mod, Mang),
117 "?foo");
118 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
119 llvm::CallingConv::C, Mod, Mang),
120 ".Lfoo");
121
122 // Test calling conv mangling.
123 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
124 llvm::CallingConv::X86_StdCall, Mod, Mang),
125 "stdcall");
126 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
127 llvm::CallingConv::X86_FastCall, Mod, Mang),
128 "fastcall");
129 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
130 llvm::CallingConv::X86_VectorCall, Mod, Mang),
131 "vectorcall@@24");
132
133 // Adding a '?' prefix blocks calling convention mangling.
134 EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,
135 llvm::CallingConv::X86_VectorCall, Mod, Mang),
136 "?vectorcall");
137 }
138
TEST(ManglerTest,XCOFF)139 TEST(ManglerTest, XCOFF) {
140 LLVMContext Ctx;
141 DataLayout DL("m:a"); // XCOFF/AIX
142 Module Mod("test", Ctx);
143 Mod.setDataLayout(DL);
144 Mangler Mang;
145 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
146 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
147 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
148 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
149 llvm::CallingConv::C, Mod, Mang),
150 "foo");
151 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
152 llvm::CallingConv::C, Mod, Mang),
153 "?foo");
154 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
155 llvm::CallingConv::C, Mod, Mang),
156 "L..foo");
157 }
158
159 } // end anonymous namespace
160