Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / IR / ManglerTest.cpp
blobf2b78a1f9876946630c0d2a01d971ecef6ed1224
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 SS.flush();
24 return Mangled;
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;
45 namespace {
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");
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");
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");
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");
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");
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");
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");
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");
159 TEST(ManglerTest, GOFF) {
160 LLVMContext Ctx;
161 DataLayout DL("m:l"); // GOFF
162 Module Mod("test", Ctx);
163 Mod.setDataLayout(DL);
164 Mangler Mang;
166 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
167 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
168 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
169 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
170 llvm::CallingConv::C, Mod, Mang),
171 "foo");
172 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
173 llvm::CallingConv::C, Mod, Mang),
174 "L#foo");
177 } // end anonymous namespace