Skip to content

Commit d0ac222

Browse files
committed
Update Rust version to match LLVM 20.1.8, drop support for Arm64EC mangling, bump dependencies, fix clippy warnings
1 parent 8e1522b commit d0ac222

14 files changed

+730
-187
lines changed

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "ar_archive_writer"
3-
version = "0.4.2"
4-
edition = "2021"
3+
version = "0.5.0"
4+
edition = "2024"
55
license = "Apache-2.0 WITH LLVM-exception"
66
description = "A writer for object file ar archives"
77
keywords = ["ar", "archive"]
@@ -11,12 +11,12 @@ repository = "https://github.com/rust-lang/ar_archive_writer"
1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

1313
[dependencies]
14-
object = { version = "0.36.2", default-features = false, features = ["std", "read"] }
14+
object = { version = "0.37.1", default-features = false, features = ["std", "read"] }
1515

1616
[dev-dependencies]
1717
cargo-binutils = "0.3.6"
18-
object = { version = "0.36.2", default-features = false, features = ["write", "xcoff"] }
19-
pretty_assertions = "1.4.0"
18+
object = { version = "0.37.1", default-features = false, features = ["write", "xcoff"] }
19+
pretty_assertions = "1.4.1"
2020

2121
[lints.rust]
2222
rust_2018_idioms = { level = "deny" }

reference/ManglerTest.cpp

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
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+
return Mangled;
24+
}
25+
26+
static std::string mangleFunc(StringRef IRName,
27+
GlobalValue::LinkageTypes Linkage,
28+
llvm::CallingConv::ID CC, Module &Mod,
29+
Mangler &Mang) {
30+
Type *VoidTy = Type::getVoidTy(Mod.getContext());
31+
Type *I32Ty = Type::getInt32Ty(Mod.getContext());
32+
FunctionType *FTy =
33+
FunctionType::get(VoidTy, {I32Ty, I32Ty, I32Ty}, /*isVarArg=*/false);
34+
Function *F = Function::Create(FTy, Linkage, IRName, &Mod);
35+
F->setCallingConv(CC);
36+
std::string Mangled;
37+
raw_string_ostream SS(Mangled);
38+
Mang.getNameWithPrefix(SS, F, false);
39+
F->eraseFromParent();
40+
return Mangled;
41+
}
42+
43+
namespace {
44+
45+
TEST(ManglerTest, MachO) {
46+
LLVMContext Ctx;
47+
DataLayout DL("m:o"); // macho
48+
Module Mod("test", Ctx);
49+
Mod.setDataLayout(DL);
50+
Mangler Mang;
51+
EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
52+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
53+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "_?foo");
54+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
55+
llvm::CallingConv::C, Mod, Mang),
56+
"_foo");
57+
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
58+
llvm::CallingConv::C, Mod, Mang),
59+
"_?foo");
60+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
61+
llvm::CallingConv::C, Mod, Mang),
62+
"L_foo");
63+
}
64+
65+
TEST(ManglerTest, WindowsX86) {
66+
LLVMContext Ctx;
67+
DataLayout DL("m:x-p:32:32"); // 32-bit windows
68+
Module Mod("test", Ctx);
69+
Mod.setDataLayout(DL);
70+
Mangler Mang;
71+
EXPECT_EQ(mangleStr("foo", Mang, DL), "_foo");
72+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
73+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
74+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
75+
llvm::CallingConv::C, Mod, Mang),
76+
"_foo");
77+
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
78+
llvm::CallingConv::C, Mod, Mang),
79+
"?foo");
80+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
81+
llvm::CallingConv::C, Mod, Mang),
82+
"L_foo");
83+
84+
// Test calling conv mangling.
85+
EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
86+
llvm::CallingConv::X86_StdCall, Mod, Mang),
87+
"_stdcall@12");
88+
EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
89+
llvm::CallingConv::X86_FastCall, Mod, Mang),
90+
"@fastcall@12");
91+
EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
92+
llvm::CallingConv::X86_VectorCall, Mod, Mang),
93+
"vectorcall@@12");
94+
95+
// Adding a '?' prefix blocks calling convention mangling.
96+
EXPECT_EQ(mangleFunc("?fastcall", llvm::GlobalValue::ExternalLinkage,
97+
llvm::CallingConv::X86_FastCall, Mod, Mang),
98+
"?fastcall");
99+
}
100+
101+
TEST(ManglerTest, WindowsX64) {
102+
LLVMContext Ctx;
103+
DataLayout DL("m:w-p:64:64"); // windows
104+
Module Mod("test", Ctx);
105+
Mod.setDataLayout(DL);
106+
Mangler Mang;
107+
EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
108+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
109+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
110+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
111+
llvm::CallingConv::C, Mod, Mang),
112+
"foo");
113+
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
114+
llvm::CallingConv::C, Mod, Mang),
115+
"?foo");
116+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
117+
llvm::CallingConv::C, Mod, Mang),
118+
".Lfoo");
119+
120+
// Test calling conv mangling.
121+
EXPECT_EQ(mangleFunc("stdcall", llvm::GlobalValue::ExternalLinkage,
122+
llvm::CallingConv::X86_StdCall, Mod, Mang),
123+
"stdcall");
124+
EXPECT_EQ(mangleFunc("fastcall", llvm::GlobalValue::ExternalLinkage,
125+
llvm::CallingConv::X86_FastCall, Mod, Mang),
126+
"fastcall");
127+
EXPECT_EQ(mangleFunc("vectorcall", llvm::GlobalValue::ExternalLinkage,
128+
llvm::CallingConv::X86_VectorCall, Mod, Mang),
129+
"vectorcall@@24");
130+
131+
// Adding a '?' prefix blocks calling convention mangling.
132+
EXPECT_EQ(mangleFunc("?vectorcall", llvm::GlobalValue::ExternalLinkage,
133+
llvm::CallingConv::X86_VectorCall, Mod, Mang),
134+
"?vectorcall");
135+
}
136+
137+
TEST(ManglerTest, UEFIX64) {
138+
LLVMContext Ctx;
139+
DataLayout DL("e-m:w-p270:32:32-p271:32:32-p272:64:64-"
140+
"i64:64-i128:128-f80:128-n8:16:32:64-S128"); // uefi X86_64
141+
Module Mod("test", Ctx);
142+
Mod.setDataLayout(DL);
143+
Mangler Mang;
144+
EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
145+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
146+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
147+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
148+
llvm::CallingConv::C, Mod, Mang),
149+
"foo");
150+
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
151+
llvm::CallingConv::C, Mod, Mang),
152+
"?foo");
153+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
154+
llvm::CallingConv::C, Mod, Mang),
155+
".Lfoo");
156+
}
157+
158+
TEST(ManglerTest, XCOFF) {
159+
LLVMContext Ctx;
160+
DataLayout DL("m:a"); // XCOFF/AIX
161+
Module Mod("test", Ctx);
162+
Mod.setDataLayout(DL);
163+
Mangler Mang;
164+
EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
165+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
166+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
167+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
168+
llvm::CallingConv::C, Mod, Mang),
169+
"foo");
170+
EXPECT_EQ(mangleFunc("?foo", llvm::GlobalValue::ExternalLinkage,
171+
llvm::CallingConv::C, Mod, Mang),
172+
"?foo");
173+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
174+
llvm::CallingConv::C, Mod, Mang),
175+
"L..foo");
176+
}
177+
178+
TEST(ManglerTest, GOFF) {
179+
LLVMContext Ctx;
180+
DataLayout DL("m:l"); // GOFF
181+
Module Mod("test", Ctx);
182+
Mod.setDataLayout(DL);
183+
Mangler Mang;
184+
185+
EXPECT_EQ(mangleStr("foo", Mang, DL), "foo");
186+
EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo");
187+
EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo");
188+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage,
189+
llvm::CallingConv::C, Mod, Mang),
190+
"foo");
191+
EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage,
192+
llvm::CallingConv::C, Mod, Mang),
193+
"L#foo");
194+
}
195+
196+
TEST(ManglerTest, Arm64EC) {
197+
constexpr std::string_view Arm64ECNames[] = {
198+
// Basic C name.
199+
"#Foo",
200+
201+
// Basic C++ name.
202+
"?foo@@$$hYAHXZ",
203+
204+
// Regression test: https://github.com/llvm/llvm-project/issues/115231
205+
"?GetValue@?$Wrapper@UA@@@@$$hQEBAHXZ",
206+
207+
// Symbols from:
208+
// ```
209+
// namespace A::B::C::D {
210+
// struct Base {
211+
// virtual int f() { return 0; }
212+
// };
213+
// }
214+
// struct Derived : public A::B::C::D::Base {
215+
// virtual int f() override { return 1; }
216+
// };
217+
// A::B::C::D::Base* MakeObj() { return new Derived(); }
218+
// ```
219+
// void * __cdecl operator new(unsigned __int64)
220+
"??2@$$hYAPEAX_K@Z",
221+
// public: virtual int __cdecl A::B::C::D::Base::f(void)
222+
"?f@Base@D@C@B@A@@$$hUEAAHXZ",
223+
// public: __cdecl A::B::C::D::Base::Base(void)
224+
"??0Base@D@C@B@A@@$$hQEAA@XZ",
225+
// public: virtual int __cdecl Derived::f(void)
226+
"?f@Derived@@$$hUEAAHXZ",
227+
// public: __cdecl Derived::Derived(void)
228+
"??0Derived@@$$hQEAA@XZ",
229+
// struct A::B::C::D::Base * __cdecl MakeObj(void)
230+
"?MakeObj@@$$hYAPEAUBase@D@C@B@A@@XZ",
231+
232+
// Symbols from:
233+
// ```
234+
// template <typename T> struct WW { struct Z{}; };
235+
// template <typename X> struct Wrapper {
236+
// int GetValue(typename WW<X>::Z) const;
237+
// };
238+
// struct A { };
239+
// template <typename X> int Wrapper<X>::GetValue(typename WW<X>::Z) const
240+
// { return 3; }
241+
// template class Wrapper<A>;
242+
// ```
243+
// public: int __cdecl Wrapper<struct A>::GetValue(struct WW<struct
244+
// A>::Z)const
245+
"?GetValue@?$Wrapper@UA@@@@$$hQEBAHUZ@?$WW@UA@@@@@Z",
246+
};
247+
248+
for (const auto &Arm64ECName : Arm64ECNames) {
249+
// Check that this is a mangled name.
250+
EXPECT_TRUE(isArm64ECMangledFunctionName(Arm64ECName))
251+
<< "Test case: " << Arm64ECName;
252+
// Refuse to mangle it again.
253+
EXPECT_FALSE(getArm64ECMangledFunctionName(Arm64ECName).has_value())
254+
<< "Test case: " << Arm64ECName;
255+
256+
// Demangle.
257+
auto Arm64Name = getArm64ECDemangledFunctionName(Arm64ECName);
258+
EXPECT_TRUE(Arm64Name.has_value()) << "Test case: " << Arm64ECName;
259+
// Check that it is not mangled.
260+
EXPECT_FALSE(isArm64ECMangledFunctionName(Arm64Name.value()))
261+
<< "Test case: " << Arm64ECName;
262+
// Refuse to demangle it again.
263+
EXPECT_FALSE(getArm64ECDemangledFunctionName(Arm64Name.value()).has_value())
264+
<< "Test case: " << Arm64ECName;
265+
266+
// Round-trip.
267+
auto RoundTripArm64ECName =
268+
getArm64ECMangledFunctionName(Arm64Name.value());
269+
EXPECT_EQ(RoundTripArm64ECName, Arm64ECName);
270+
}
271+
}
272+
273+
} // end anonymous namespace

reference/Readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ These files were originally located at:
1515
* `llvm/lib/IR/Mangler.cpp`
1616
* `llvm/lib/Object/ArchiveWriter.cpp`
1717
* `llvm/lib/Object/COFFImportFile.cpp`
18+
* `llvm/unittests/IR/ManglerTest.cpp`
1819

1920
When syncing, make sure to update these files and the commit above.
2021

0 commit comments

Comments
 (0)