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
16using namespace llvm;
17
18static std::string mangleStr(StringRef IRName, Mangler &Mang,
19 const DataLayout &DL) {
20 std::string Mangled;
21 raw_string_ostream SS(Mangled);
22 Mang.getNameWithPrefix(OS&: SS, GVName: IRName, DL);
23 SS.flush();
24 return Mangled;
25}
26
27static std::string mangleFunc(StringRef IRName,
28 GlobalValue::LinkageTypes Linkage,
29 llvm::CallingConv::ID CC, Module &Mod,
30 Mangler &Mang) {
31 Type *VoidTy = Type::getVoidTy(C&: Mod.getContext());
32 Type *I32Ty = Type::getInt32Ty(C&: Mod.getContext());
33 FunctionType *FTy =
34 FunctionType::get(Result: VoidTy, Params: {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
35 Function *F = Function::Create(Ty: FTy, Linkage, N: IRName, M: &Mod);
36 F->setCallingConv(CC);
37 std::string Mangled;
38 raw_string_ostream SS(Mangled);
39 Mang.getNameWithPrefix(OS&: SS, GV: F, CannotUsePrivateLabel: false);
40 SS.flush();
41 F->eraseFromParent();
42 return Mangled;
43}
44
45namespace {
46
47TEST(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
67TEST(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
103TEST(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
139TEST(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
159TEST(ManglerTest, GOFF) {
160 LLVMContext Ctx;
161 DataLayout DL("m:l"); // GOFF
162 Module Mod("test", Ctx);
163 Mod.setDataLayout(DL);
164 Mangler Mang;
165
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");
175}
176
177} // end anonymous namespace
178

source code of llvm/unittests/IR/ManglerTest.cpp