llvm-project

Форк
0
/
ManglerTest.cpp 
177 строк · 6.5 Кб
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

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

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

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

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

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

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
TEST(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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.