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