Fix test failures introduced by PR #113697 (#116941)
[llvm-project.git] / llvm / unittests / IR / ManglerTest.cpp
bloba2b4e81690310bf4d72670c9f1e6ab54cf78deab
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 //===----------------------------------------------------------------------===//
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"
16 using namespace llvm;
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 return Mangled;
26 static std::string mangleFunc(StringRef IRName,
27 GlobalValue::LinkageTypes Linkage,
28 llvm::CallingConv::ID CC, Module &Mod,
29 Mangler &Mang) {
30 Type *VoidTy = Type::getVoidTy(Mod.getContext());
31 Type *I32Ty = Type::getInt32Ty(Mod.getContext());
32 FunctionType *FTy =
33 FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
34 Function *F = Function::Create(FTy, Linkage, IRName, &Mod);
35 F->setCallingConv(CC);
36 std::string Mangled;
37 raw_string_ostream SS(Mangled);
38 Mang.getNameWithPrefix(SS, F, false);
39 F->eraseFromParent();
40 return Mangled;
43 namespace {
45 TEST(ManglerTest, MachO) {
46 LLVMContext Ctx;
47 DataLayout DL("m:o"); // macho
48 Module Mod("test", Ctx);
49 Mod.setDataLayout(DL);
50 Mangler Mang;
51 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
52 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
53 EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");
54 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
55 llvm::CallingConv::C, Mod, Mang),
56 "_foo");
57 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
58 llvm::CallingConv::C, Mod, Mang),
59 "_?foo");
60 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
61 llvm::CallingConv::C, Mod, Mang),
62 "L_foo");
65 TEST(ManglerTest, WindowsX86) {
66 LLVMContext Ctx;
67 DataLayout DL("m:x-p:32:32"); // 32-bit windows
68 Module Mod("test", Ctx);
69 Mod.setDataLayout(DL);
70 Mangler Mang;
71 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
72 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
73 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
74 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
75 llvm::CallingConv::C, Mod, Mang),
76 "_foo");
77 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
78 llvm::CallingConv::C, Mod, Mang),
79 "?foo");
80 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
81 llvm::CallingConv::C, Mod, Mang),
82 "L_foo");
84 // Test calling conv mangling.
85 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
86 llvm::CallingConv::X86_StdCall, Mod, Mang),
87 "_stdcall@12");
88 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
89 llvm::CallingConv::X86_FastCall, Mod, Mang),
90 "@fastcall@12");
91 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
92 llvm::CallingConv::X86_VectorCall, Mod, Mang),
93 "vectorcall@@12");
95 // Adding a '?' prefix blocks calling convention mangling.
96 EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,
97 llvm::CallingConv::X86_FastCall, Mod, Mang),
98 "?fastcall");
101 TEST(ManglerTest, WindowsX64) {
102 LLVMContext Ctx;
103 DataLayout DL("m:w-p:64:64"); // windows
104 Module Mod("test", Ctx);
105 Mod.setDataLayout(DL);
106 Mangler Mang;
107 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
108 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
109 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
110 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
111 llvm::CallingConv::C, Mod, Mang),
112 "foo");
113 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
114 llvm::CallingConv::C, Mod, Mang),
115 "?foo");
116 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
117 llvm::CallingConv::C, Mod, Mang),
118 ".Lfoo");
120 // Test calling conv mangling.
121 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
122 llvm::CallingConv::X86_StdCall, Mod, Mang),
123 "stdcall");
124 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
125 llvm::CallingConv::X86_FastCall, Mod, Mang),
126 "fastcall");
127 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
128 llvm::CallingConv::X86_VectorCall, Mod, Mang),
129 "vectorcall@@24");
131 // Adding a '?' prefix blocks calling convention mangling.
132 EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,
133 llvm::CallingConv::X86_VectorCall, Mod, Mang),
134 "?vectorcall");
137 TEST(ManglerTest, XCOFF) {
138 LLVMContext Ctx;
139 DataLayout DL("m:a"); // XCOFF/AIX
140 Module Mod("test", Ctx);
141 Mod.setDataLayout(DL);
142 Mangler Mang;
143 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
144 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
145 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
146 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
147 llvm::CallingConv::C, Mod, Mang),
148 "foo");
149 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
150 llvm::CallingConv::C, Mod, Mang),
151 "?foo");
152 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
153 llvm::CallingConv::C, Mod, Mang),
154 "L..foo");
157 TEST(ManglerTest, GOFF) {
158 LLVMContext Ctx;
159 DataLayout DL("m:l"); // GOFF
160 Module Mod("test", Ctx);
161 Mod.setDataLayout(DL);
162 Mangler Mang;
164 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
165 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
166 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
167 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
168 llvm::CallingConv::C, Mod, Mang),
169 "foo");
170 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
171 llvm::CallingConv::C, Mod, Mang),
172 "L#foo");
175 TEST(ManglerTest, Arm64EC) {
176 constexpr std::string_view Arm64ECNames[] = {
177 // Basic C name.
178 "#Foo",
180 // Basic C++ name.
181 "?foo@@$$hYAHXZ",
183 // Regression test: https://github.com/llvm/llvm-project/issues/115231
184 "?GetValue@?$Wrapper@UA@@@@$$hQEBAHXZ",
186 // Symbols from:
187 // ```
188 // namespace A::B::C::D {
189 // struct Base {
190 // virtual int f() { return 0; }
191 // };
192 // }
193 // struct Derived : public A::B::C::D::Base {
194 // virtual int f() override { return 1; }
195 // };
196 // A::B::C::D::Base* MakeObj() { return new Derived(); }
197 // ```
198 // void * __cdecl operator new(unsigned __int64)
199 "??2@$$hYAPEAX_K@Z",
200 // public: virtual int __cdecl A::B::C::D::Base::f(void)
201 "?f@Base@D@C@B@A@@$$hUEAAHXZ",
202 // public: __cdecl A::B::C::D::Base::Base(void)
203 "??0Base@D@C@B@A@@$$hQEAA@XZ",
204 // public: virtual int __cdecl Derived::f(void)
205 "?f@Derived@@$$hUEAAHXZ",
206 // public: __cdecl Derived::Derived(void)
207 "??0Derived@@$$hQEAA@XZ",
208 // struct A::B::C::D::Base * __cdecl MakeObj(void)
209 "?MakeObj@@$$hYAPEAUBase@D@C@B@A@@XZ",
211 // Symbols from:
212 // ```
213 // template <typename T> struct WW { struct Z{}; };
214 // template <typename X> struct Wrapper {
215 // int GetValue(typename WW<X>::Z) const;
216 // };
217 // struct A { };
218 // template <typename X> int Wrapper<X>::GetValue(typename WW<X>::Z) const
219 // { return 3; }
220 // template class Wrapper<A>;
221 // ```
222 // public: int __cdecl Wrapper<struct A>::GetValue(struct WW<struct
223 // A>::Z)const
224 "?GetValue@?$Wrapper@UA@@@@$$hQEBAHUZ@?$WW@UA@@@@@Z",
227 for (const auto &Arm64ECName : Arm64ECNames) {
228 // Check that this is a mangled name.
229 EXPECT_TRUE(isArm64ECMangledFunctionName(Arm64ECName))
230 << "Test case: " << Arm64ECName;
231 // Refuse to mangle it again.
232 EXPECT_FALSE(getArm64ECMangledFunctionName(Arm64ECName).has_value())
233 << "Test case: " << Arm64ECName;
235 // Demangle.
236 auto Arm64Name = getArm64ECDemangledFunctionName(Arm64ECName);
237 EXPECT_TRUE(Arm64Name.has_value()) << "Test case: " << Arm64ECName;
238 // Check that it is not mangled.
239 EXPECT_FALSE(isArm64ECMangledFunctionName(Arm64Name.value()))
240 << "Test case: " << Arm64ECName;
241 // Refuse to demangle it again.
242 EXPECT_FALSE(getArm64ECDemangledFunctionName(Arm64Name.value()).has_value())
243 << "Test case: " << Arm64ECName;
245 // Round-trip.
246 auto RoundTripArm64ECName =
247 getArm64ECMangledFunctionName(Arm64Name.value());
248 EXPECT_EQ(RoundTripArm64ECName, Arm64ECName);
252 } // end anonymous namespace