ManglerTest.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #include "llvm/IR/Mangler.h"
  9. #include "llvm/IR/CallingConv.h"
  10. #include "llvm/IR/DataLayout.h"
  11. #include "llvm/IR/GlobalValue.h"
  12. #include "llvm/IR/Module.h"
  13. #include "gtest/gtest.h"
  14. using namespace llvm;
  15. static std::string mangleStr(StringRef IRName, Mangler &Mang,
  16. const DataLayout &DL) {
  17. std::string Mangled;
  18. raw_string_ostream SS(Mangled);
  19. Mang.getNameWithPrefix(SS, IRName, DL);
  20. SS.flush();
  21. return Mangled;
  22. }
  23. static std::string mangleFunc(StringRef IRName,
  24. GlobalValue::LinkageTypes Linkage,
  25. llvm::CallingConv::ID CC, Module &Mod,
  26. Mangler &Mang) {
  27. Type *VoidTy = Type::getVoidTy(Mod.getContext());
  28. Type *I32Ty = Type::getInt32Ty(Mod.getContext());
  29. FunctionType *FTy =
  30. FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
  31. Function *F = Function::Create(FTy, Linkage, IRName, &Mod);
  32. F->setCallingConv(CC);
  33. std::string Mangled;
  34. raw_string_ostream SS(Mangled);
  35. Mang.getNameWithPrefix(SS, F, false);
  36. SS.flush();
  37. F->eraseFromParent();
  38. return Mangled;
  39. }
  40. namespace {
  41. TEST(ManglerTest, MachO) {
  42. LLVMContext Ctx;
  43. DataLayout DL("m:o"); // macho
  44. Module Mod("test", Ctx);
  45. Mod.setDataLayout(DL);
  46. Mangler Mang;
  47. EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
  48. EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
  49. EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");
  50. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
  51. llvm::CallingConv::C, Mod, Mang),
  52. "_foo");
  53. EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
  54. llvm::CallingConv::C, Mod, Mang),
  55. "_?foo");
  56. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
  57. llvm::CallingConv::C, Mod, Mang),
  58. "L_foo");
  59. }
  60. TEST(ManglerTest, WindowsX86) {
  61. LLVMContext Ctx;
  62. DataLayout DL("m:x-p:32:32"); // 32-bit windows
  63. Module Mod("test", Ctx);
  64. Mod.setDataLayout(DL);
  65. Mangler Mang;
  66. EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
  67. EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
  68. EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
  69. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
  70. llvm::CallingConv::C, Mod, Mang),
  71. "_foo");
  72. EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
  73. llvm::CallingConv::C, Mod, Mang),
  74. "?foo");
  75. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
  76. llvm::CallingConv::C, Mod, Mang),
  77. "L_foo");
  78. // Test calling conv mangling.
  79. EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
  80. llvm::CallingConv::X86_StdCall, Mod, Mang),
  81. "_stdcall@12");
  82. EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
  83. llvm::CallingConv::X86_FastCall, Mod, Mang),
  84. "@fastcall@12");
  85. EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
  86. llvm::CallingConv::X86_VectorCall, Mod, Mang),
  87. "vectorcall@@12");
  88. // Adding a '?' prefix blocks calling convention mangling.
  89. EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,
  90. llvm::CallingConv::X86_FastCall, Mod, Mang),
  91. "?fastcall");
  92. }
  93. TEST(ManglerTest, WindowsX64) {
  94. LLVMContext Ctx;
  95. DataLayout DL("m:w-p:64:64"); // windows
  96. Module Mod("test", Ctx);
  97. Mod.setDataLayout(DL);
  98. Mangler Mang;
  99. EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
  100. EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
  101. EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
  102. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
  103. llvm::CallingConv::C, Mod, Mang),
  104. "foo");
  105. EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
  106. llvm::CallingConv::C, Mod, Mang),
  107. "?foo");
  108. EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
  109. llvm::CallingConv::C, Mod, Mang),
  110. ".Lfoo");
  111. // Test calling conv mangling.
  112. EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
  113. llvm::CallingConv::X86_StdCall, Mod, Mang),
  114. "stdcall");
  115. EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
  116. llvm::CallingConv::X86_FastCall, Mod, Mang),
  117. "fastcall");
  118. EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
  119. llvm::CallingConv::X86_VectorCall, Mod, Mang),
  120. "vectorcall@@24");
  121. // Adding a '?' prefix blocks calling convention mangling.
  122. EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,
  123. llvm::CallingConv::X86_VectorCall, Mod, Mang),
  124. "?vectorcall");
  125. }
  126. } // end anonymous namespace