llvm-project
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
16using namespace llvm;17
18static std::string mangleStr(StringRef IRName, Mangler &Mang,19const DataLayout &DL) {20std::string Mangled;21raw_string_ostream SS(Mangled);22Mang.getNameWithPrefix(SS, IRName, DL);23SS.flush();24return Mangled;25}
26
27static std::string mangleFunc(StringRef IRName,28GlobalValue::LinkageTypes Linkage,29llvm::CallingConv::ID CC, Module &Mod,30Mangler &Mang) {31Type *VoidTy = Type::getVoidTy(Mod.getContext());32Type *I32Ty = Type::getInt32Ty(Mod.getContext());33FunctionType *FTy =34FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);35Function *F = Function::Create(FTy, Linkage, IRName, &Mod);36F->setCallingConv(CC);37std::string Mangled;38raw_string_ostream SS(Mangled);39Mang.getNameWithPrefix(SS, F, false);40SS.flush();41F->eraseFromParent();42return Mangled;43}
44
45namespace {46
47TEST(ManglerTest, MachO) {48LLVMContext Ctx;49DataLayout DL("m:o"); // macho50Module Mod("test", Ctx);51Mod.setDataLayout(DL);52Mangler Mang;53EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");54EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");55EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");56EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,57llvm::CallingConv::C, Mod, Mang),58"_foo");59EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,60llvm::CallingConv::C, Mod, Mang),61"_?foo");62EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,63llvm::CallingConv::C, Mod, Mang),64"L_foo");65}
66
67TEST(ManglerTest, WindowsX86) {68LLVMContext Ctx;69DataLayout DL("m:x-p:32:32"); // 32-bit windows70Module Mod("test", Ctx);71Mod.setDataLayout(DL);72Mangler Mang;73EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");74EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");75EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");76EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,77llvm::CallingConv::C, Mod, Mang),78"_foo");79EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,80llvm::CallingConv::C, Mod, Mang),81"?foo");82EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,83llvm::CallingConv::C, Mod, Mang),84"L_foo");85
86// Test calling conv mangling.87EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,88llvm::CallingConv::X86_StdCall, Mod, Mang),89"_stdcall@12");90EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,91llvm::CallingConv::X86_FastCall, Mod, Mang),92"@fastcall@12");93EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,94llvm::CallingConv::X86_VectorCall, Mod, Mang),95"vectorcall@@12");96
97// Adding a '?' prefix blocks calling convention mangling.98EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,99llvm::CallingConv::X86_FastCall, Mod, Mang),100"?fastcall");101}
102
103TEST(ManglerTest, WindowsX64) {104LLVMContext Ctx;105DataLayout DL("m:w-p:64:64"); // windows106Module Mod("test", Ctx);107Mod.setDataLayout(DL);108Mangler Mang;109EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");110EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");111EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");112EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,113llvm::CallingConv::C, Mod, Mang),114"foo");115EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,116llvm::CallingConv::C, Mod, Mang),117"?foo");118EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,119llvm::CallingConv::C, Mod, Mang),120".Lfoo");121
122// Test calling conv mangling.123EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,124llvm::CallingConv::X86_StdCall, Mod, Mang),125"stdcall");126EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,127llvm::CallingConv::X86_FastCall, Mod, Mang),128"fastcall");129EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,130llvm::CallingConv::X86_VectorCall, Mod, Mang),131"vectorcall@@24");132
133// Adding a '?' prefix blocks calling convention mangling.134EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,135llvm::CallingConv::X86_VectorCall, Mod, Mang),136"?vectorcall");137}
138
139TEST(ManglerTest, XCOFF) {140LLVMContext Ctx;141DataLayout DL("m:a"); // XCOFF/AIX142Module Mod("test", Ctx);143Mod.setDataLayout(DL);144Mangler Mang;145EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");146EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");147EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");148EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,149llvm::CallingConv::C, Mod, Mang),150"foo");151EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,152llvm::CallingConv::C, Mod, Mang),153"?foo");154EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,155llvm::CallingConv::C, Mod, Mang),156"L..foo");157}
158
159TEST(ManglerTest, GOFF) {160LLVMContext Ctx;161DataLayout DL("m:l"); // GOFF162Module Mod("test", Ctx);163Mod.setDataLayout(DL);164Mangler Mang;165
166EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");167EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");168EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");169EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,170llvm::CallingConv::C, Mod, Mang),171"foo");172EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,173llvm::CallingConv::C, Mod, Mang),174"L#foo");175}
176
177} // end anonymous namespace178