https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/149827
>From a61eb43dd47463a817e2899ec81bab23d5bdc9bc Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Mon, 4 Aug 2025 07:49:19 +0100 Subject: [PATCH 1/3] Clang --- clang/include/clang/Basic/Attr.td | 17 ++++------------- clang/lib/AST/Mangle.cpp | 26 ++++++++++++++++++++++---- clang/lib/Sema/SemaDecl.cpp | 13 +++++-------- clang/unittests/AST/DeclTest.cpp | 4 ++-- 4 files changed, 33 insertions(+), 27 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..940a04112df40 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()); @@ -161,10 +175,10 @@ 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, - // do not add a "\01" prefix. - if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) { + // If is an alias for an LLVM intrinsic, do not add a "\01" prefix. + if (ALA->getLabel().starts_with("llvm.")) { Out << ALA->getLabel(); + return; } @@ -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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e2ac648320c0f..885d04b9ab926 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()); @@ -20598,8 +20595,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..c19ecab646c2a 100644 --- a/clang/unittests/AST/DeclTest.cpp +++ b/clang/unittests/AST/DeclTest.cpp @@ -90,8 +90,8 @@ TEST(Decl, AsmLabelAttr) { 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", /*IsLLDBFuncLabel=*/false)); + DeclG->addAttr(AsmLabelAttr::Create(Ctx, "goo", /*IsLLDBFuncLabel=*/true)); // Mangle the decl names. std::string MangleF, MangleG; >From 859670495da0778dc2da0b2b68430ad3b896404e Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Mon, 4 Aug 2025 07:49:40 +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 9261a5ecb4cf873fce74c2f5ade35fbc99e19eb2 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Mon, 4 Aug 2025 07:49:47 +0100 Subject: [PATCH 3/3] LLDB --- lldb/include/lldb/Expression/Expression.h | 8 +- lldb/source/Expression/Expression.cpp | 29 +++--- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 34 ++++++- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 95 +++++++++++++++++-- .../TypeSystem/Clang/TypeSystemClang.cpp | 8 +- .../TypeSystem/Clang/TypeSystemClang.h | 2 + lldb/unittests/Expression/ExpressionTest.cpp | 37 +++++--- lldb/unittests/Symbol/TestTypeSystemClang.cpp | 14 +-- 8 files changed, 178 insertions(+), 49 deletions(-) diff --git a/lldb/include/lldb/Expression/Expression.h b/lldb/include/lldb/Expression/Expression.h index 20067f469895b..847226167d584 100644 --- a/lldb/include/lldb/Expression/Expression.h +++ b/lldb/include/lldb/Expression/Expression.h @@ -103,11 +103,15 @@ class Expression { /// /// The format being: /// -/// <prefix>:<module uid>:<symbol uid>:<name> +/// <prefix>:<discriminator>:<module uid>:<symbol uid>:<name> /// /// The label string needs to stay valid for the entire lifetime /// of this object. struct FunctionCallLabel { + /// Arbitrary string which language plugins can interpret for their + /// own needs. + llvm::StringRef discriminator; + /// Unique identifier of the lldb_private::Module /// which contains the symbol identified by \c symbol_id. lldb::user_id_t module_id; @@ -133,7 +137,7 @@ struct FunctionCallLabel { /// /// The representation roundtrips through \c fromString: /// \code{.cpp} - /// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:_Z3foov"; + /// llvm::StringRef encoded = "$__lldb_func:blah: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..16ecb1d7deef8 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) @@ -45,8 +45,10 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) { "expected function call label prefix '{0}' but found '{1}' instead.", FunctionCallLabelPrefix, components[0])); - llvm::StringRef module_label = components[1]; - llvm::StringRef die_label = components[2]; + llvm::StringRef discriminator = components[1]; + llvm::StringRef module_label = components[2]; + llvm::StringRef die_label = components[3]; + llvm::StringRef lookup_name = components[4]; lldb::user_id_t module_id = 0; if (!llvm::to_integer(module_label, module_id)) @@ -58,20 +60,23 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) { return llvm::createStringError( llvm::formatv("failed to parse symbol ID from '{0}'.", die_label)); - return FunctionCallLabel{/*.module_id=*/module_id, + return FunctionCallLabel{/*.discriminator=*/discriminator, + /*.module_id=*/module_id, /*.symbol_id=*/die_id, - /*.lookup_name=*/components[3]}; + /*.lookup_name=*/lookup_name}; } 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}:{2:x}:{3:x}:{4}", FunctionCallLabelPrefix, + discriminator, module_id, symbol_id, lookup_name) .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); + OS << llvm::formatv("FunctionCallLabel{ discriminator: {0}, module_id: " + "{1:x}, symbol_id: {2:x}, " + "lookup_name: {3} }", + label.discriminator, label.module_id, label.symbol_id, + label.lookup_name); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 781c1c6c5745d..d079d09e1049a 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,7 +313,9 @@ static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) { if (die_id == LLDB_INVALID_UID) return {}; - return FunctionCallLabel{/*module_id=*/module_id, + // Note, discriminator is added by Clang during mangling. + return FunctionCallLabel{/*discriminator=*/{}, + /*module_id=*/module_id, /*symbol_id=*/die_id, /*.lookup_name=*/name} .toString(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 42a66ce75d6d6..c40d0a2600ae8 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" @@ -2482,6 +2485,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()); @@ -2494,21 +2547,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::Continue; + } + + 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; }); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 8dd6aa08ba2aa..77ed1a0ad3e39 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -10,6 +10,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/ExprCXX.h" +#include "clang/Basic/ABI.h" #include "clang/Frontend/ASTConsumers.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" @@ -2183,8 +2184,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 +7823,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. diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 70d613d47f93a..09f3a11eaf7bc 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -18,6 +18,7 @@ #include <set> #include <string> #include <utility> +#include <variant> #include <vector> #include "clang/AST/ASTContext.h" @@ -26,6 +27,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" +#include "clang/Basic/ABI.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" diff --git a/lldb/unittests/Expression/ExpressionTest.cpp b/lldb/unittests/Expression/ExpressionTest.cpp index 12f6dd515fd11..ceb567c28ab99 100644 --- a/lldb/unittests/Expression/ExpressionTest.cpp +++ b/lldb/unittests/Expression/ExpressionTest.cpp @@ -23,15 +23,15 @@ struct LabelTestCase { static LabelTestCase g_label_test_cases[] = { // Failure modes - {"bar:0x0:0x0:_Z3foov", + {"bar:blah:0x0:0x0:_Z3foov", {}, {"expected function call label prefix '$__lldb_func' but found 'bar' " "instead."}}, - {"$__lldb_func :0x0:0x0:_Z3foov", + {"$__lldb_func :blah:0x0:0x0:_Z3foov", {}, {"expected function call label prefix '$__lldb_func' but found " "'$__lldb_func ' instead."}}, - {"$__lldb_funcc:0x0:0x0:_Z3foov", + {"$__lldb_funcc:blah:0x0:0x0:_Z3foov", {}, {"expected function call label prefix '$__lldb_func' but found " "'$__lldb_funcc' instead."}}, @@ -39,47 +39,52 @@ static LabelTestCase g_label_test_cases[] = { {"foo", {}, {"malformed function call label."}}, {"$__lldb_func", {}, {"malformed function call label."}}, {"$__lldb_func:", {}, {"malformed function call label."}}, - {"$__lldb_func:0x0:0x0", {}, {"malformed function call label."}}, - {"$__lldb_func:abc:0x0:_Z3foov", + {"$__lldb_func:blah", {}, {"malformed function call label."}}, + {"$__lldb_func:blah:0x0", {}, {"malformed function call label."}}, + {"$__lldb_func:111:0x0:0x0", {}, {"malformed function call label."}}, + {"$__lldb_func:111:abc:0x0:_Z3foov", {}, {"failed to parse module ID from 'abc'."}}, - {"$__lldb_func:-1:0x0:_Z3foov", + {"$__lldb_func:111:-1:0x0:_Z3foov", {}, {"failed to parse module ID from '-1'."}}, - {"$__lldb_func:0x0invalid:0x0:_Z3foov", + {"$__lldb_func:111:0x0invalid:0x0:_Z3foov", {}, {"failed to parse module ID from '0x0invalid'."}}, - {"$__lldb_func:0x0 :0x0:_Z3foov", + {"$__lldb_func:111:0x0 :0x0:_Z3foov", {}, {"failed to parse module ID from '0x0 '."}}, - {"$__lldb_func:0x0:abc:_Z3foov", + {"$__lldb_func:blah:0x0:abc:_Z3foov", {}, {"failed to parse symbol ID from 'abc'."}}, - {"$__lldb_func:0x5:-1:_Z3foov", + {"$__lldb_func:blah:0x5:-1:_Z3foov", {}, {"failed to parse symbol ID from '-1'."}}, - {"$__lldb_func:0x5:0x0invalid:_Z3foov", + {"$__lldb_func:blah:0x5:0x0invalid:_Z3foov", {}, {"failed to parse symbol ID from '0x0invalid'."}}, - {"$__lldb_func:0x5:0x0 :_Z3foov", + {"$__lldb_func:blah:0x5:0x0 :_Z3foov", {}, {"failed to parse symbol ID from '0x0 '."}}, - {"$__lldb_func:0x0:0x0:_Z3foov", + {"$__lldb_func:blah:0x0:0x0:_Z3foov", { + /*.discriminator=*/"blah", /*.module_id=*/0x0, /*.symbol_id=*/0x0, /*.lookup_name=*/"_Z3foov", }, {}}, - {"$__lldb_func:0x0:0x0:abc:def:::a", + {"$__lldb_func::0x0:0x0:abc:def:::a", { + /*.discriminator=*/"", /*.module_id=*/0x0, /*.symbol_id=*/0x0, /*.lookup_name=*/"abc:def:::a", }, {}}, - {"$__lldb_func:0xd2:0xf0:$__lldb_func", + {"$__lldb_func:0x45:0xd2:0xf0:$__lldb_func", { + /*.discriminator=*/"0x45", /*.module_id=*/0xd2, /*.symbol_id=*/0xf0, /*.lookup_name=*/"$__lldb_func", @@ -106,6 +111,7 @@ TEST_P(ExpressionTestFixture, FunctionCallLabel) { EXPECT_EQ(decoded_or_err->toString(), encoded); EXPECT_EQ(label_str, encoded); + EXPECT_EQ(decoded_or_err->discriminator, label.discriminator); EXPECT_EQ(decoded_or_err->module_id, label.module_id); EXPECT_EQ(decoded_or_err->symbol_id, label.symbol_id); EXPECT_EQ(decoded_or_err->lookup_name, label.lookup_name); @@ -113,6 +119,7 @@ TEST_P(ExpressionTestFixture, FunctionCallLabel) { auto roundtrip_or_err = FunctionCallLabel::fromString(label_str); EXPECT_THAT_EXPECTED(roundtrip_or_err, llvm::Succeeded()); + EXPECT_EQ(roundtrip_or_err->discriminator, label.discriminator); EXPECT_EQ(roundtrip_or_err->module_id, label.module_id); EXPECT_EQ(roundtrip_or_err->symbol_id, label.symbol_id); EXPECT_EQ(roundtrip_or_err->lookup_name, label.lookup_name); diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp index b993b82612497..f673cceae00dd 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:D1:0x0:0x0:~S"); } struct AsmLabelTestCase { @@ -1215,10 +1215,10 @@ class TestTypeSystemClangAsmLabel }; static AsmLabelTestCase g_asm_label_test_cases[] = { - {/*mangled=*/"$__lldb_func:0x0:0x0:_Z3foov", + {/*mangled=*/"$__lldb_func::0x0:0x0:_Z3foov", /*expected=*/"_Z3foov"}, - {/*mangled=*/"$__lldb_func:0x0:0x0:foo", - /*expected=*/"$__lldb_func:0x0:0x0:foo"}, + {/*mangled=*/"$__lldb_func::0x0:0x0:foo", + /*expected=*/"$__lldb_func::0x0:0x0:foo"}, {/*mangled=*/"foo", /*expected=*/"foo"}, {/*mangled=*/"_Z3foov", _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits