https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/155485

>From 4d47b8bdf579de65eb69c69381c98c85e7f5a8e5 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Mon, 4 Aug 2025 14:20:45 +0100
Subject: [PATCH 1/2] [clang][Mangle] Inject structor type into mangled name
 when mangling for LLDB JIT expressions

Part of https://github.com/llvm/llvm-project/pull/149827

This patch adds special handling for `AsmLabel`s created by LLDB. LLDB
uses `AsmLabel`s to encode information about a function declaration to
make it easier to locate function symbols when JITing C++ expressions.
For constructors/destructors LLDB doesn't know at the time of creating
the `AsmLabelAttr` which structor variant the expression evaluator will
need to call (this is decided when compiling the expression). So we make
the Clang mangler inject this information into our custom label when
we're JITting the expression.
---
 clang/lib/AST/Mangle.cpp         | 33 +++++++++++++-
 clang/unittests/AST/DeclTest.cpp | 75 ++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 0bfb51c11f0a5..1131477fa7200 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -152,6 +152,33 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl 
*D) {
   return shouldMangleCXXName(D);
 }
 
+static llvm::StringRef g_lldb_func_call_label_prefix = "$__lldb_func:";
+
+/// Given an LLDB function call label, this function prints the label
+/// into \c Out, together with the structor type of \c GD (if the
+/// decl is a constructor/destructor). LLDB knows how to handle mangled
+/// names with this encoding.
+///
+/// Example input label:
+///   $__lldb_func::123:456:~Foo
+///
+/// Example output:
+///   $__lldb_func:D1:123:456:~Foo
+///
+static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD,
+                             llvm::raw_ostream &Out) {
+  assert(label.starts_with(g_lldb_func_call_label_prefix));
+
+  Out << g_lldb_func_call_label_prefix;
+
+  if (llvm::isa<clang::CXXConstructorDecl>(GD.getDecl()))
+    Out << "C" << GD.getCtorType();
+  else if (llvm::isa<clang::CXXDestructorDecl>(GD.getDecl()))
+    Out << "D" << GD.getDtorType();
+
+  Out << label.substr(g_lldb_func_call_label_prefix.size());
+}
+
 void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
   const ASTContext &ASTContext = getASTContext();
   const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
@@ -185,7 +212,11 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream 
&Out) {
     if (!UserLabelPrefix.empty())
       Out << '\01'; // LLVM IR Marker for __asm("foo")
 
-    Out << ALA->getLabel();
+    if (ALA->getLabel().starts_with(g_lldb_func_call_label_prefix))
+      emitLLDBAsmLabel(ALA->getLabel(), GD, Out);
+    else
+      Out << ALA->getLabel();
+
     return;
   }
 
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 6b443918ec137..4bd7886ef9b35 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/Mangle.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/ABI.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TargetInfo.h"
@@ -102,6 +103,80 @@ TEST(Decl, AsmLabelAttr) {
                      "foo");
 }
 
+TEST(Decl, AsmLabelAttr_LLDB) {
+  StringRef Code = R"(
+    struct S {
+      void f() {}
+      S() = default;
+      ~S() = default;
+    };
+  )";
+  auto AST =
+      tooling::buildASTFromCodeWithArgs(Code, {"-target", 
"i386-apple-darwin"});
+  ASTContext &Ctx = AST->getASTContext();
+  assert(Ctx.getTargetInfo().getUserLabelPrefix() == StringRef("_") &&
+         "Expected target to have a global prefix");
+  DiagnosticsEngine &Diags = AST->getDiagnostics();
+
+  const auto *DeclS =
+      selectFirst<CXXRecordDecl>("d", match(cxxRecordDecl().bind("d"), Ctx));
+
+  auto *DeclF = *DeclS->method_begin();
+  auto *Ctor = *DeclS->ctor_begin();
+  auto *Dtor = DeclS->getDestructor();
+
+  ASSERT_TRUE(DeclF);
+  ASSERT_TRUE(Ctor);
+  ASSERT_TRUE(Dtor);
+
+  DeclF->addAttr(AsmLabelAttr::Create(Ctx, "$__lldb_func::123:123:_Z1fv"));
+  Ctor->addAttr(AsmLabelAttr::Create(Ctx, "$__lldb_func::123:123:S"));
+  Dtor->addAttr(AsmLabelAttr::Create(Ctx, "$__lldb_func::123:123:~S"));
+
+  std::unique_ptr<ItaniumMangleContext> MC(
+      ItaniumMangleContext::create(Ctx, Diags));
+
+  {
+    std::string Mangled;
+    llvm::raw_string_ostream OS_Mangled(Mangled);
+    MC->mangleName(DeclF, OS_Mangled);
+
+    ASSERT_EQ(Mangled, "\x01$__lldb_func::123:123:_Z1fv");
+  };
+
+  {
+    std::string Mangled;
+    llvm::raw_string_ostream OS_Mangled(Mangled);
+    MC->mangleName(GlobalDecl(Ctor, CXXCtorType::Ctor_Complete), OS_Mangled);
+
+    ASSERT_EQ(Mangled, "\x01$__lldb_func:C0:123:123:S");
+  };
+
+  {
+    std::string Mangled;
+    llvm::raw_string_ostream OS_Mangled(Mangled);
+    MC->mangleName(GlobalDecl(Ctor, CXXCtorType::Ctor_Base), OS_Mangled);
+
+    ASSERT_EQ(Mangled, "\x01$__lldb_func:C1:123:123:S");
+  };
+
+  {
+    std::string Mangled;
+    llvm::raw_string_ostream OS_Mangled(Mangled);
+    MC->mangleName(GlobalDecl(Dtor, CXXDtorType::Dtor_Deleting), OS_Mangled);
+
+    ASSERT_EQ(Mangled, "\x01$__lldb_func:D0:123:123:~S");
+  };
+
+  {
+    std::string Mangled;
+    llvm::raw_string_ostream OS_Mangled(Mangled);
+    MC->mangleName(GlobalDecl(Dtor, CXXDtorType::Dtor_Base), OS_Mangled);
+
+    ASSERT_EQ(Mangled, "\x01$__lldb_func:D2:123:123:~S");
+  };
+}
+
 TEST(Decl, MangleDependentSizedArray) {
   StringRef Code = R"(
     template <int ...N>

>From ea9d01d101f921e2e782b8b8b9b82b4a43536852 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Wed, 27 Aug 2025 14:55:46 +0200
Subject: [PATCH 2/2] fixup! fix LLDB test

---
 lldb/unittests/Symbol/TestTypeSystemClang.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp 
b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index b993b82612497..bfb64d44a280f 100644
--- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -1150,12 +1150,12 @@ TEST_F(TestTypeSystemClang, AsmLabel_CtorDtor) {
       is_explicit, is_attr_used, is_artificial);
 
   auto *ctor = m_ast->AddMethodToCXXRecordType(
-      t.GetOpaqueQualType(), "S", /*asm_label=*/"$__lldb_func:0x0:0x0:S",
+      t.GetOpaqueQualType(), "S", /*asm_label=*/"$__lldb_func::0x0:0x0:S",
       function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static,
       is_inline, is_explicit, is_attr_used, is_artificial);
 
   auto *dtor = m_ast->AddMethodToCXXRecordType(
-      t.GetOpaqueQualType(), "~S", /*asm_label=*/"$__lldb_func:0x0:0x0:~S",
+      t.GetOpaqueQualType(), "~S", /*asm_label=*/"$__lldb_func::0x0:0x0:~S",
       function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static,
       is_inline, is_explicit, is_attr_used, is_artificial);
 
@@ -1181,11 +1181,11 @@ TEST_F(TestTypeSystemClang, AsmLabel_CtorDtor) {
   EXPECT_STREQ(llvm::GlobalValue::dropLLVMManglingEscape(
                    m_ast->DeclGetMangledName(ctor).GetStringRef())
                    .data(),
-               "$__lldb_func:0x0:0x0:S");
+               "$__lldb_func:C0:0x0:0x0:S");
   EXPECT_STREQ(llvm::GlobalValue::dropLLVMManglingEscape(
                    m_ast->DeclGetMangledName(dtor).GetStringRef())
                    .data(),
-               "$__lldb_func:0x0:0x0:~S");
+               "$__lldb_func:D0:0x0:0x0:~S");
 }
 
 struct AsmLabelTestCase {

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to