• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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