blob: 04f1ca6cf9776fc206bf60bbe2daa614f8cc4d5f [file] [log] [blame]
Reid Kleckner025ee4f2018-03-16 20:13:32 +00001//===- llvm/unittest/IR/ManglerTest.cpp - Mangler unit tests --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/IR/Mangler.h"
11#include "llvm/IR/CallingConv.h"
12#include "llvm/IR/DataLayout.h"
13#include "llvm/IR/GlobalValue.h"
14#include "llvm/IR/Module.h"
15#include "gtest/gtest.h"
16
17using namespace llvm;
18
19static std::string mangleStr(StringRef IRName, Mangler &Mang,
20 const DataLayout &DL) {
21 std::string Mangled;
22 raw_string_ostream SS(Mangled);
23 Mang.getNameWithPrefix(SS, IRName, DL);
24 SS.flush();
25 return Mangled;
26}
27
28static std::string mangleFunc(StringRef IRName,
29 GlobalValue::LinkageTypes Linkage,
30 llvm::CallingConv::ID CC, Module &Mod,
31 Mangler &Mang) {
32 Type *VoidTy = Type::getVoidTy(Mod.getContext());
33 Type *I32Ty = Type::getInt32Ty(Mod.getContext());
34 FunctionType *FTy =
35 FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
36 Function *F = Function::Create(FTy, Linkage, IRName, &Mod);
37 F->setCallingConv(CC);
38 std::string Mangled;
39 raw_string_ostream SS(Mangled);
40 Mang.getNameWithPrefix(SS, F, false);
41 SS.flush();
42 F->eraseFromParent();
43 return Mangled;
44}
45
46namespace {
47
48TEST(ManglerTest, MachO) {
49 LLVMContext Ctx;
50 DataLayout DL("m:o"); // macho
51 Module Mod("test", Ctx);
52 Mod.setDataLayout(DL);
53 Mangler Mang;
54 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
55 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
56 EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");
57 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
58 llvm::CallingConv::C, Mod, Mang),
59 "_foo");
60 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
61 llvm::CallingConv::C, Mod, Mang),
62 "_?foo");
63 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
64 llvm::CallingConv::C, Mod, Mang),
65 "L_foo");
66}
67
68TEST(ManglerTest, WindowsX86) {
69 LLVMContext Ctx;
70 DataLayout DL("m:x-p:32:32"); // 32-bit windows
71 Module Mod("test", Ctx);
72 Mod.setDataLayout(DL);
73 Mangler Mang;
74 EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
75 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
76 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
77 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
78 llvm::CallingConv::C, Mod, Mang),
79 "_foo");
80 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
81 llvm::CallingConv::C, Mod, Mang),
82 "?foo");
83 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
84 llvm::CallingConv::C, Mod, Mang),
85 "L_foo");
86
87 // Test calling conv mangling.
88 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
89 llvm::CallingConv::X86_StdCall, Mod, Mang),
90 "_stdcall@12");
91 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
92 llvm::CallingConv::X86_FastCall, Mod, Mang),
93 "@fastcall@12");
94 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
95 llvm::CallingConv::X86_VectorCall, Mod, Mang),
96 "vectorcall@@12");
97
98 // Adding a '?' prefix blocks calling convention mangling.
99 EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,
100 llvm::CallingConv::X86_FastCall, Mod, Mang),
101 "?fastcall");
102}
103
104TEST(ManglerTest, WindowsX64) {
105 LLVMContext Ctx;
106 DataLayout DL("m:w-p:64:64"); // windows
107 Module Mod("test", Ctx);
108 Mod.setDataLayout(DL);
109 Mangler Mang;
110 EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
111 EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
112 EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
113 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
114 llvm::CallingConv::C, Mod, Mang),
115 "foo");
116 EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
117 llvm::CallingConv::C, Mod, Mang),
118 "?foo");
119 EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
120 llvm::CallingConv::C, Mod, Mang),
121 ".Lfoo");
122
123 // Test calling conv mangling.
124 EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
125 llvm::CallingConv::X86_StdCall, Mod, Mang),
126 "stdcall");
127 EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
128 llvm::CallingConv::X86_FastCall, Mod, Mang),
129 "fastcall");
130 EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
131 llvm::CallingConv::X86_VectorCall, Mod, Mang),
132 "vectorcall@@24");
133
134 // Adding a '?' prefix blocks calling convention mangling.
135 EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,
136 llvm::CallingConv::X86_VectorCall, Mod, Mang),
137 "?vectorcall");
138}
139
140} // end anonymous namespace