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

>From 809925d0fcb99f919b3a443a9b5fb22e4173a504 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Sun, 3 Aug 2025 11:38:07 +0100
Subject: [PATCH 1/3] [clang][Attr] Remove 'literal label' form of AsmLabelAttr

This was added purely for the needs of LLDB. However, starting with
https://github.com/llvm/llvm-project/pull/151355 and 
https://github.com/llvm/llvm-project/pull/148877 we no longer create literal 
AsmLabels in LLDB either. So this is unused and we can get rid of it.

In the near future LLDB will want to add special support for mangling 
`AsmLabel`s, and the "literal label" codepath in the mangler made this more 
cumbersome.

(cherry picked from commit 342f0d5cd722ae7ec3f48f136472923ce38f9981)
---
 clang/include/clang/Basic/Attr.td               | 17 ++++-------------
 clang/lib/AST/Mangle.cpp                        |  4 ++--
 clang/lib/Sema/SemaDecl.cpp                     | 13 +++++--------
 clang/unittests/AST/DeclTest.cpp                |  9 +--------
 .../TypeSystem/Clang/TypeSystemClang.cpp        |  7 +++----
 5 files changed, 15 insertions(+), 35 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index b3ff45b3e90a3..a0efb21218312 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1059,22 +1059,13 @@ def AVRSignal : InheritableAttr, 
TargetSpecificAttr<TargetAVR> {
 def AsmLabel : InheritableAttr {
   let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
   let Args = [
-    // Label specifies the mangled name for the decl.
-    StringArgument<"Label">,
-
-    // IsLiteralLabel specifies whether the label is literal (i.e. suppresses
-    // the global C symbol prefix) or not. If not, the mangle-suppression 
prefix
-    // ('\01') is omitted from the decl name at the LLVM IR level.
-    //
-    // Non-literal labels are used by some external AST sources like LLDB.
-    BoolArgument<"IsLiteralLabel", /*optional=*/0, /*fake=*/1>
-  ];
+      // Label specifies the mangled name for the decl.
+      StringArgument<"Label">, ];
   let SemaHandler = 0;
   let Documentation = [AsmLabelDocs];
-  let AdditionalMembers =
-[{
+  let AdditionalMembers = [{
 bool isEquivalent(AsmLabelAttr *Other) const {
-  return getLabel() == Other->getLabel() && getIsLiteralLabel() == 
Other->getIsLiteralLabel();
+  return getLabel() == Other->getLabel();
 }
 }];
 }
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 9652fdbc4e125..0bfb51c11f0a5 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -161,9 +161,9 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream 
&Out) {
   if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
     // If we have an asm name, then we use it as the mangling.
 
-    // If the label isn't literal, or if this is an alias for an LLVM 
intrinsic,
+    // If the label is an alias for an LLVM intrinsic,
     // do not add a "\01" prefix.
-    if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) {
+    if (ALA->getLabel().starts_with("llvm.")) {
       Out << ALA->getLabel();
       return;
     }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 20fdf2de59cb1..9c6153ad99475 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8113,9 +8113,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
       }
     }
 
-    NewVD->addAttr(AsmLabelAttr::Create(Context, Label,
-                                        /*IsLiteralLabel=*/true,
-                                        SE->getStrTokenLoc(0)));
+    NewVD->addAttr(AsmLabelAttr::Create(Context, Label, 
SE->getStrTokenLoc(0)));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -10345,9 +10343,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
   if (Expr *E = D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewFD->addAttr(AsmLabelAttr::Create(Context, SE->getString(),
-                                        /*IsLiteralLabel=*/true,
-                                        SE->getStrTokenLoc(0)));
+    NewFD->addAttr(
+        AsmLabelAttr::Create(Context, SE->getString(), SE->getStrTokenLoc(0)));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -20599,8 +20596,8 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* 
Name,
                                          LookupOrdinaryName);
   AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc),
                            AttributeCommonInfo::Form::Pragma());
-  AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit(
-      Context, AliasName->getName(), /*IsLiteralLabel=*/true, Info);
+  AsmLabelAttr *Attr =
+      AsmLabelAttr::CreateImplicit(Context, AliasName->getName(), Info);
 
   // If a declaration that:
   // 1) declares a function or a variable
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index ed635da683aab..afaf413493299 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -74,7 +74,6 @@ TEST(Decl, AsmLabelAttr) {
   StringRef Code = R"(
     struct S {
       void f() {}
-      void g() {}
     };
   )";
   auto AST =
@@ -87,11 +86,8 @@ TEST(Decl, AsmLabelAttr) {
   const auto *DeclS =
       selectFirst<CXXRecordDecl>("d", match(cxxRecordDecl().bind("d"), Ctx));
   NamedDecl *DeclF = *DeclS->method_begin();
-  NamedDecl *DeclG = *(++DeclS->method_begin());
 
-  // Attach asm labels to the decls: one literal, and one not.
-  DeclF->addAttr(AsmLabelAttr::Create(Ctx, "foo", /*LiteralLabel=*/true));
-  DeclG->addAttr(AsmLabelAttr::Create(Ctx, "goo", /*LiteralLabel=*/false));
+  DeclF->addAttr(AsmLabelAttr::Create(Ctx, "foo"));
 
   // Mangle the decl names.
   std::string MangleF, MangleG;
@@ -99,14 +95,11 @@ TEST(Decl, AsmLabelAttr) {
       ItaniumMangleContext::create(Ctx, Diags));
   {
     llvm::raw_string_ostream OS_F(MangleF);
-    llvm::raw_string_ostream OS_G(MangleG);
     MC->mangleName(DeclF, OS_F);
-    MC->mangleName(DeclG, OS_G);
   }
 
   ASSERT_EQ(MangleF, "\x01"
                      "foo");
-  ASSERT_EQ(MangleG, "goo");
 }
 
 TEST(Decl, MangleDependentSizedArray) {
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 9301f92b710ec..eae1c5183ccbb 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2183,8 +2183,7 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
   // This is done separately for member functions in
   // AddMethodToCXXRecordType.
   if (!asm_label.empty())
-    func_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(ast, asm_label,
-                                                           /*literal=*/true));
+    func_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(ast, asm_label));
 
   SetOwningModule(func_decl, owning_module);
   decl_ctx->addDecl(func_decl);
@@ -7823,8 +7822,8 @@ clang::CXXMethodDecl 
*TypeSystemClang::AddMethodToCXXRecordType(
     cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext()));
 
   if (!asm_label.empty())
-    cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
-        getASTContext(), asm_label, /*literal=*/true));
+    cxx_method_decl->addAttr(
+        clang::AsmLabelAttr::CreateImplicit(getASTContext(), asm_label));
 
   // Parameters on member function declarations in DWARF generally don't
   // have names, so we omit them when creating the ParmVarDecls.

>From 7eb66b00800c5f03c4c786c04b44913b1873fde6 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Sun, 3 Aug 2025 22:51:05 +0100
Subject: [PATCH 2/3] Demangler

---
 libcxxabi/src/demangle/ItaniumDemangle.h     |  2 ++
 llvm/include/llvm/Demangle/Demangle.h        |  3 +++
 llvm/include/llvm/Demangle/ItaniumDemangle.h |  2 ++
 llvm/lib/Demangle/ItaniumDemangle.cpp        | 10 +++++++---
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h 
b/libcxxabi/src/demangle/ItaniumDemangle.h
index 6f27da7b9cadf..7b3983bc89367 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -1766,6 +1766,8 @@ class CtorDtorName final : public Node {
 
   template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); 
}
 
+  int getVariant() const { return Variant; }
+
   void printLeft(OutputBuffer &OB) const override {
     if (IsDtor)
       OB += "~";
diff --git a/llvm/include/llvm/Demangle/Demangle.h 
b/llvm/include/llvm/Demangle/Demangle.h
index d9b08b2d856dc..6af8fad9ceb86 100644
--- a/llvm/include/llvm/Demangle/Demangle.h
+++ b/llvm/include/llvm/Demangle/Demangle.h
@@ -127,6 +127,9 @@ struct ItaniumPartialDemangler {
   /// If this symbol describes a constructor or destructor.
   DEMANGLE_ABI bool isCtorOrDtor() const;
 
+  /// If this symbol describes a constructor or destructor.
+  std::optional<int> getCtorOrDtorVariant() const;
+
   /// If this symbol describes a function.
   DEMANGLE_ABI bool isFunction() const;
 
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h 
b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 62d427c3966bb..c0db02f8e7fef 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -1766,6 +1766,8 @@ class CtorDtorName final : public Node {
 
   template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); 
}
 
+  int getVariant() const { return Variant; }
+
   void printLeft(OutputBuffer &OB) const override {
     if (IsDtor)
       OB += "~";
diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp 
b/llvm/lib/Demangle/ItaniumDemangle.cpp
index 1009cc91ca12a..a5d7a5576fccf 100644
--- a/llvm/lib/Demangle/ItaniumDemangle.cpp
+++ b/llvm/lib/Demangle/ItaniumDemangle.cpp
@@ -560,13 +560,17 @@ bool ItaniumPartialDemangler::hasFunctionQualifiers() 
const {
 }
 
 bool ItaniumPartialDemangler::isCtorOrDtor() const {
+  return getCtorOrDtorVariant().has_value();
+}
+
+std::optional<int> ItaniumPartialDemangler::getCtorOrDtorVariant() const {
   const Node *N = static_cast<const Node *>(RootNode);
   while (N) {
     switch (N->getKind()) {
     default:
-      return false;
+      return std::nullopt;
     case Node::KCtorDtorName:
-      return true;
+      return static_cast<const CtorDtorName *>(N)->getVariant();
 
     case Node::KAbiTagAttr:
       N = static_cast<const AbiTagAttr *>(N)->Base;
@@ -588,7 +592,7 @@ bool ItaniumPartialDemangler::isCtorOrDtor() const {
       break;
     }
   }
-  return false;
+  return std::nullopt;
 }
 
 bool ItaniumPartialDemangler::isFunction() const {

>From 23bd8fcb00aa4ad2df1d5951cc2c49046f1be53e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Sun, 3 Aug 2025 22:51:16 +0100
Subject: [PATCH 3/3] Structors init

---
 clang/lib/AST/Mangle.cpp                      | 20 +++-
 lldb/include/lldb/Expression/Expression.h     |  6 +-
 lldb/source/Expression/Expression.cpp         | 22 +++--
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 34 ++++++-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      | 95 +++++++++++++++++--
 5 files changed, 157 insertions(+), 20 deletions(-)

diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 0bfb51c11f0a5..58029476572c5 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -152,6 +152,20 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl 
*D) {
   return shouldMangleCXXName(D);
 }
 
+static llvm::StringRef g_lldb_func_call_label_prefix = "$__lldb_func";
+
+static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD,
+                             llvm::raw_ostream &Out) {
+  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() + 1);
+}
+
 void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
   const ASTContext &ASTContext = getASTContext();
   const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
@@ -185,7 +199,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/lldb/include/lldb/Expression/Expression.h 
b/lldb/include/lldb/Expression/Expression.h
index 20067f469895b..c2702bd9dca96 100644
--- a/lldb/include/lldb/Expression/Expression.h
+++ b/lldb/include/lldb/Expression/Expression.h
@@ -103,7 +103,7 @@ class Expression {
 ///
 /// The format being:
 ///
-///   <prefix>:<module uid>:<symbol uid>:<name>
+///   <prefix>:<module uid>:<symbol uid>:<discriminator>:<name>
 ///
 /// The label string needs to stay valid for the entire lifetime
 /// of this object.
@@ -126,6 +126,8 @@ struct FunctionCallLabel {
   /// ':' in the mangled name when parsing the label.
   llvm::StringRef lookup_name;
 
+  llvm::StringRef discriminator;
+
   /// Decodes the specified function \c label into a \c FunctionCallLabel.
   static llvm::Expected<FunctionCallLabel> fromString(llvm::StringRef label);
 
@@ -133,7 +135,7 @@ struct FunctionCallLabel {
   ///
   /// The representation roundtrips through \c fromString:
   /// \code{.cpp}
-  /// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:_Z3foov";
+  /// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:_Z3foov:";
   /// FunctionCallLabel label = *fromString(label);
   ///
   /// assert (label.toString() == encoded);
diff --git a/lldb/source/Expression/Expression.cpp 
b/lldb/source/Expression/Expression.cpp
index 796851ff15ca3..c9baa228fe888 100644
--- a/lldb/source/Expression/Expression.cpp
+++ b/lldb/source/Expression/Expression.cpp
@@ -34,10 +34,10 @@ Expression::Expression(ExecutionContextScope &exe_scope)
 
 llvm::Expected<FunctionCallLabel>
 lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
-  llvm::SmallVector<llvm::StringRef, 4> components;
-  label.split(components, ":", /*MaxSplit=*/3);
+  llvm::SmallVector<llvm::StringRef, 5> components;
+  label.split(components, ":", /*MaxSplit=*/4);
 
-  if (components.size() != 4)
+  if (components.size() != 5)
     return llvm::createStringError("malformed function call label.");
 
   if (components[0] != FunctionCallLabelPrefix)
@@ -47,6 +47,10 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef 
label) {
 
   llvm::StringRef module_label = components[1];
   llvm::StringRef die_label = components[2];
+  llvm::StringRef lookup_name =
+      components[3]; // TODO: mangled name should come last...clang should
+                     // splice it into the label?
+  llvm::StringRef discriminator = components[4];
 
   lldb::user_id_t module_id = 0;
   if (!llvm::to_integer(module_label, module_id))
@@ -60,18 +64,20 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef 
label) {
 
   return FunctionCallLabel{/*.module_id=*/module_id,
                            /*.symbol_id=*/die_id,
-                           /*.lookup_name=*/components[3]};
+                           /*.lookup_name=*/lookup_name,
+                           /*.discriminator=*/discriminator};
 }
 
 std::string lldb_private::FunctionCallLabel::toString() const {
-  return llvm::formatv("{0}:{1:x}:{2:x}:{3}", FunctionCallLabelPrefix,
-                       module_id, symbol_id, lookup_name)
+  return llvm::formatv("{0}:{1:x}:{2:x}:{3}:{4}", FunctionCallLabelPrefix,
+                       module_id, symbol_id, lookup_name, discriminator)
       .str();
 }
 
 void llvm::format_provider<FunctionCallLabel>::format(
     const FunctionCallLabel &label, raw_ostream &OS, StringRef Style) {
   OS << llvm::formatv("FunctionCallLabel{ module_id: {0:x}, symbol_id: {1:x}, "
-                      "lookup_name: {2} }",
-                      label.module_id, label.symbol_id, label.lookup_name);
+                      "lookup_name: {2}, discriminator: {3} }",
+                      label.module_id, label.symbol_id, label.lookup_name,
+                      label.discriminator);
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 781c1c6c5745d..3a7c34f545a2e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -250,8 +250,36 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE 
&subprogram,
   return cv_quals;
 }
 
+static const char *GetMangledOrStructorName(const DWARFDIE &die) {
+  const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);
+  if (name)
+    return name;
+
+  name = die.GetName();
+  if (!name)
+    return nullptr;
+
+  DWARFDIE parent = die.GetParent();
+  if (!parent.IsStructUnionOrClass())
+    return nullptr;
+
+  const char *parent_name = parent.GetName();
+  if (!parent_name)
+    return nullptr;
+
+  // Constructor.
+  if (::strcmp(parent_name, name) == 0)
+    return name;
+
+  // Destructor.
+  if (name[0] == '~' && ::strcmp(parent_name, name + 1))
+    return name;
+
+  return nullptr;
+}
+
 static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
-  char const *name = die.GetMangledName(/*substitute_name_allowed*/ false);
+  char const *name = GetMangledOrStructorName(die);
   if (!name)
     return {};
 
@@ -285,9 +313,11 @@ static std::string MakeLLDBFuncAsmLabel(const DWARFDIE 
&die) {
   if (die_id == LLDB_INVALID_UID)
     return {};
 
+  // Note, discriminator is added by Clang during mangling.
   return FunctionCallLabel{/*module_id=*/module_id,
                            /*symbol_id=*/die_id,
-                           /*.lookup_name=*/name}
+                           /*.lookup_name=*/name,
+                           /*discriminator=*/{}}
       .toString();
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index a3ba061424cc1..de9668bcc588d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -7,7 +7,9 @@
 
//===----------------------------------------------------------------------===//
 
 #include "SymbolFileDWARF.h"
+#include "clang/Basic/ABI.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/Support/Casting.h"
@@ -78,6 +80,7 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/Demangle/Demangle.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
 
@@ -2476,6 +2479,56 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE 
&orig_die,
   return false;
 }
 
+static uint8_t ClangToItaniumCtorKind(clang::CXXCtorType kind) {
+  switch (kind) {
+  case clang::CXXCtorType::Ctor_Complete:
+    return 1;
+  case clang::CXXCtorType::Ctor_Base:
+    return 2;
+  case clang::CXXCtorType::Ctor_CopyingClosure:
+  case clang::CXXCtorType::Ctor_DefaultClosure:
+  case clang::CXXCtorType::Ctor_Comdat:
+    llvm_unreachable("Unexpected constructor kind.");
+  }
+}
+
+static uint8_t ClangToItaniumDtorKind(clang::CXXDtorType kind) {
+  switch (kind) {
+  case clang::CXXDtorType::Dtor_Deleting:
+    return 0;
+  case clang::CXXDtorType::Dtor_Complete:
+    return 1;
+  case clang::CXXDtorType::Dtor_Base:
+    return 2;
+  case clang::CXXDtorType::Dtor_Comdat:
+    llvm_unreachable("Unexpected destructor kind.");
+  }
+}
+
+static std::optional<uint8_t>
+GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {
+  const bool is_ctor = discriminator.consume_front("C");
+  if (!is_ctor && !discriminator.consume_front("D"))
+    return std::nullopt;
+
+  uint64_t structor_kind;
+  if (!llvm::to_integer(discriminator, structor_kind))
+    return std::nullopt;
+
+  if (is_ctor) {
+    if (structor_kind > clang::CXXCtorType::Ctor_DefaultClosure)
+      return std::nullopt;
+
+    return ClangToItaniumCtorKind(
+        static_cast<clang::CXXCtorType>(structor_kind));
+  }
+
+  if (structor_kind > clang::CXXDtorType::Dtor_Deleting)
+    return std::nullopt;
+
+  return 
ClangToItaniumDtorKind(static_cast<clang::CXXDtorType>(structor_kind));
+}
+
 llvm::Expected<SymbolContext>
 SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -2488,21 +2541,49 @@ SymbolFileDWARF::ResolveFunctionCallLabel(const 
FunctionCallLabel &label) {
   // Label was created using a declaration DIE. Need to fetch the definition
   // to resolve the function call.
   if (die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0)) {
+    // eFunctionNameTypeFull for mangled name lookup.
+    // eFunctionNameTypeMethod is required for structor lookups (since we look
+    // those up by DW_AT_name).
     Module::LookupInfo info(ConstString(label.lookup_name),
-                            lldb::eFunctionNameTypeFull,
+                            lldb::eFunctionNameTypeFull |
+                                lldb::eFunctionNameTypeMethod,
                             lldb::eLanguageTypeUnknown);
 
     m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
       if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
         return IterationAction::Continue;
 
-      // We don't check whether the specification DIE for this function
-      // corresponds to the declaration DIE because the declaration might be in
-      // a type-unit but the definition in the compile-unit (and it's
-      // specifcation would point to the declaration in the compile-unit). We
-      // rely on the mangled name within the module to be enough to find us the
-      // unique definition.
+      // TODO: this specification check doesn't work if declaration DIE was in 
a
+      // type-unit (we should only encode DIEs from .debug_info).
+      auto spec = entry.GetAttributeValueAsReferenceDIE(DW_AT_specification);
+      if (!spec)
+        return IterationAction::Continue;
+
+      if (spec != die)
+        return IterationAction::Continue;
+
+      // We're not picking a specific structor variant DIE, so we're done here.
+      if (label.discriminator.empty()) {
+        die = entry;
+        return IterationAction::Stop;
+      }
+
+      const char *mangled =
+          entry.GetMangledName(/*substitute_name_allowed=*/false);
+      if (!mangled)
+        return IterationAction::Continue;
+
+      llvm::ItaniumPartialDemangler D;
+      if (D.partialDemangle(mangled))
+        return IterationAction::Continue;
+
+      // TODO: account for constructor alias (only an issue on Linux)
+      if (D.getCtorOrDtorVariant() !=
+          GetItaniumCtorDtorVariant(label.discriminator).value_or(-1))
+        return IterationAction::Continue;
+
       die = entry;
+
       return IterationAction::Stop;
     });
 

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

Reply via email to