@@ -174,4 +174,81 @@ TEST(ManglerTest, GOFF) {
174174 " L#foo" );
175175}
176176
177+ TEST (ManglerTest, Arm64EC) {
178+ constexpr std::string_view Arm64ECNames[] = {
179+ // Basic C name.
180+ " #Foo" ,
181+
182+ // Basic C++ name.
183+ " ?foo@@$$hYAHXZ" ,
184+
185+ // Regression test: https://github.com/llvm/llvm-project/issues/115231
186+ " ?GetValue@?$Wrapper@UA@@@@$$hQEBAHXZ" ,
187+
188+ // Symbols from:
189+ // ```
190+ // namespace A::B::C::D {
191+ // struct Base {
192+ // virtual int f() { return 0; }
193+ // };
194+ // }
195+ // struct Derived : public A::B::C::D::Base {
196+ // virtual int f() override { return 1; }
197+ // };
198+ // A::B::C::D::Base* MakeObj() { return new Derived(); }
199+ // ```
200+ // void * __cdecl operator new(unsigned __int64)
201+ " ??2@$$hYAPEAX_K@Z" ,
202+ // public: virtual int __cdecl A::B::C::D::Base::f(void)
203+ " ?f@Base@D@C@B@A@@$$hUEAAHXZ" ,
204+ // public: __cdecl A::B::C::D::Base::Base(void)
205+ " ??0Base@D@C@B@A@@$$hQEAA@XZ" ,
206+ // public: virtual int __cdecl Derived::f(void)
207+ " ?f@Derived@@$$hUEAAHXZ" ,
208+ // public: __cdecl Derived::Derived(void)
209+ " ??0Derived@@$$hQEAA@XZ" ,
210+ // struct A::B::C::D::Base * __cdecl MakeObj(void)
211+ " ?MakeObj@@$$hYAPEAUBase@D@C@B@A@@XZ" ,
212+
213+ // Symbols from:
214+ // ```
215+ // template <typename T> struct WW { struct Z{}; };
216+ // template <typename X> struct Wrapper {
217+ // int GetValue(typename WW<X>::Z) const;
218+ // };
219+ // struct A { };
220+ // template <typename X> int Wrapper<X>::GetValue(typename WW<X>::Z) const
221+ // { return 3; }
222+ // template class Wrapper<A>;
223+ // ```
224+ // public: int __cdecl Wrapper<struct A>::GetValue(struct WW<struct
225+ // A>::Z)const
226+ " ?GetValue@?$Wrapper@UA@@@@$$hQEBAHUZ@?$WW@UA@@@@@Z" ,
227+ };
228+
229+ for (const auto &Arm64ECName : Arm64ECNames) {
230+ // Check that this is a mangled name.
231+ EXPECT_TRUE (isArm64ECMangledFunctionName (Arm64ECName))
232+ << " Test case: " << Arm64ECName;
233+ // Refuse to mangle it again.
234+ EXPECT_FALSE (getArm64ECMangledFunctionName (Arm64ECName).has_value ())
235+ << " Test case: " << Arm64ECName;
236+
237+ // Demangle.
238+ auto Arm64Name = getArm64ECDemangledFunctionName (Arm64ECName);
239+ EXPECT_TRUE (Arm64Name.has_value ()) << " Test case: " << Arm64ECName;
240+ // Check that it is not mangled.
241+ EXPECT_FALSE (isArm64ECMangledFunctionName (Arm64Name.value ()))
242+ << " Test case: " << Arm64ECName;
243+ // Refuse to demangle it again.
244+ EXPECT_FALSE (getArm64ECDemangledFunctionName (Arm64Name.value ()).has_value ())
245+ << " Test case: " << Arm64ECName;
246+
247+ // Round-trip.
248+ auto RoundTripArm64ECName =
249+ getArm64ECMangledFunctionName (Arm64Name.value ());
250+ EXPECT_EQ (RoundTripArm64ECName, Arm64ECName);
251+ }
252+ }
253+
177254} // end anonymous namespace
0 commit comments