Skip to content

Commit 2a70642

Browse files
committed
Structors Init
1 parent f1e3ce1 commit 2a70642

File tree

11 files changed

+130
-20
lines changed

11 files changed

+130
-20
lines changed

clang/lib/AST/Mangle.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
152152
return shouldMangleCXXName(D);
153153
}
154154

155+
static void tryEmitDebugStructorVariant(GlobalDecl GD, raw_ostream &Out) {
156+
if (llvm::isa<clang::CXXConstructorDecl>(GD.getDecl()))
157+
Out << "C" << GD.getCtorType();
158+
else if (llvm::isa<clang::CXXDestructorDecl>(GD.getDecl()))
159+
Out << "D" << GD.getDtorType();
160+
}
161+
155162
void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
156163
const ASTContext &ASTContext = getASTContext();
157164
const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
@@ -165,6 +172,11 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
165172
// do not add a "\01" prefix.
166173
if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) {
167174
Out << ALA->getLabel();
175+
176+
// TODO: ideally should have separate attribute for this?
177+
if (ASTContext.getLangOpts().DebuggerSupport)
178+
tryEmitDebugStructorVariant(GD, Out);
179+
168180
return;
169181
}
170182

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,8 @@ class CtorDtorName final : public Node {
17661766

17671767
template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
17681768

1769+
int getVariant() const { return Variant; }
1770+
17691771
void printLeft(OutputBuffer &OB) const override {
17701772
if (IsDtor)
17711773
OB += "~";

lldb/include/lldb/Expression/Expression.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class Expression {
103103
///
104104
/// The format being:
105105
///
106-
/// <prefix>:<module uid>:<symbol uid>:<name>
106+
/// <prefix>:<module uid>:<symbol uid>:<discriminator>:<name>
107107
///
108108
/// The label string needs to stay valid for the entire lifetime
109109
/// of this object.
@@ -126,14 +126,16 @@ struct FunctionCallLabel {
126126
/// ':' in the mangled name when parsing the label.
127127
llvm::StringRef lookup_name;
128128

129+
uint64_t discriminator = 0;
130+
129131
/// Decodes the specified function \c label into a \c FunctionCallLabel.
130132
static llvm::Expected<FunctionCallLabel> fromString(llvm::StringRef label);
131133

132134
/// Encode this FunctionCallLabel into its string representation.
133135
///
134136
/// The representation roundtrips through \c fromString:
135137
/// \code{.cpp}
136-
/// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:_Z3foov";
138+
/// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:0x0:_Z3foov";
137139
/// FunctionCallLabel label = *fromString(label);
138140
///
139141
/// assert (label.toString() == encoded);

lldb/source/Expression/Expression.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ Expression::Expression(ExecutionContextScope &exe_scope)
3434

3535
llvm::Expected<FunctionCallLabel>
3636
lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
37-
llvm::SmallVector<llvm::StringRef, 4> components;
38-
label.split(components, ":", /*MaxSplit=*/3);
37+
llvm::SmallVector<llvm::StringRef, 5> components;
38+
label.split(components, ":", /*MaxSplit=*/4);
3939

40-
if (components.size() != 4)
40+
if (components.size() != 5)
4141
return llvm::createStringError("malformed function call label.");
4242

4343
if (components[0] != FunctionCallLabelPrefix)
@@ -47,6 +47,8 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
4747

4848
llvm::StringRef module_label = components[1];
4949
llvm::StringRef die_label = components[2];
50+
llvm::StringRef discriminator_label = components[3];
51+
llvm::StringRef lookup_name = components[4];
5052

5153
lldb::user_id_t module_id = 0;
5254
if (!llvm::to_integer(module_label, module_id))
@@ -58,20 +60,26 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
5860
return llvm::createStringError(
5961
llvm::formatv("failed to parse symbol ID from '{0}'.", die_label));
6062

63+
uint64_t discriminator = 0;
64+
if (!llvm::to_integer(discriminator_label, discriminator))
65+
return llvm::createStringError(
66+
llvm::formatv("failed to parse discriminator from '{0}'.", discriminator_label));
67+
6168
return FunctionCallLabel{/*.module_id=*/module_id,
6269
/*.symbol_id=*/die_id,
63-
/*.lookup_name=*/components[3]};
70+
/*.lookup_name=*/lookup_name,
71+
/*.discriminator=*/discriminator};
6472
}
6573

6674
std::string lldb_private::FunctionCallLabel::toString() const {
67-
return llvm::formatv("{0}:{1:x}:{2:x}:{3}", FunctionCallLabelPrefix,
75+
return llvm::formatv("{0}:{1:x}:{2:x}:{3}:", FunctionCallLabelPrefix,
6876
module_id, symbol_id, lookup_name)
6977
.str();
7078
}
7179

7280
void llvm::format_provider<FunctionCallLabel>::format(
7381
const FunctionCallLabel &label, raw_ostream &OS, StringRef Style) {
7482
OS << llvm::formatv("FunctionCallLabel{ module_id: {0:x}, symbol_id: {1:x}, "
75-
"lookup_name: {2} }",
76-
label.module_id, label.symbol_id, label.lookup_name);
83+
"lookup_name: {3}, discriminator: {2} }",
84+
label.module_id, label.symbol_id, label.lookup_name, label.discriminator);
7785
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,36 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
250250
return cv_quals;
251251
}
252252

253+
static const char *GetMangledOrStructorName(const DWARFDIE &die) {
254+
const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);
255+
if (name)
256+
return name;
257+
258+
name = die.GetName();
259+
if (!name)
260+
return nullptr;
261+
262+
DWARFDIE parent = die.GetParent();
263+
if (!parent.IsStructUnionOrClass())
264+
return nullptr;
265+
266+
const char *parent_name = parent.GetName();
267+
if (!parent_name)
268+
return nullptr;
269+
270+
// Constructor.
271+
if (::strcmp(parent_name, name) == 0)
272+
return name;
273+
274+
// Destructor.
275+
if (name[0] == '~' && ::strcmp(parent_name, name + 1))
276+
return name;
277+
278+
return nullptr;
279+
}
280+
253281
static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
254-
char const *name = die.GetMangledName(/*substitute_name_allowed*/ false);
282+
char const *name = GetMangledOrStructorName(die);
255283
if (!name)
256284
return {};
257285

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777

7878
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
7979
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
80+
#include "llvm/Demangle/Demangle.h"
8081
#include "llvm/Support/FileSystem.h"
8182
#include "llvm/Support/FormatVariadic.h"
8283

@@ -2475,6 +2476,28 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
24752476
return false;
24762477
}
24772478

2479+
static std::optional<uint8_t>
2480+
GetItaniumCtorDtorVariant(uint16_t discriminator) {
2481+
const uint8_t kind_tag = discriminator >> 1;
2482+
const uint8_t variant_tag = discriminator & 0xf;
2483+
const bool is_ctor = kind_tag & 0x1;
2484+
2485+
if (!kind_tag && !(kind_tag & 0x2))
2486+
return std::nullopt;
2487+
2488+
if (is_ctor) {
2489+
if (variant_tag > clang::CXXCtorType::Ctor_DefaultClosure)
2490+
return std::nullopt;
2491+
2492+
return static_cast<clang::CXXCtorType>(variant_tag);
2493+
}
2494+
2495+
if (variant_tag > clang::CXXDtorType::Dtor_Deleting)
2496+
return std::nullopt;
2497+
2498+
return static_cast<clang::CXXDtorType>(variant_tag);
2499+
}
2500+
24782501
llvm::Expected<SymbolContext>
24792502
SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
24802503
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -2487,6 +2510,9 @@ SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
24872510
// Label was created using a declaration DIE. Need to fetch the definition
24882511
// to resolve the function call.
24892512
if (die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0)) {
2513+
// eFunctionNameTypeFull for mangled name lookup.
2514+
// eFunctionNameTypeMethod is required for structor lookups (since we look
2515+
// those up by DW_AT_name).
24902516
Module::LookupInfo info(ConstString(label.lookup_name),
24912517
lldb::eFunctionNameTypeFull,
24922518
lldb::eLanguageTypeUnknown);
@@ -2495,13 +2521,33 @@ SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
24952521
if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
24962522
return true;
24972523

2498-
// We don't check whether the specification DIE for this function
2499-
// corresponds to the declaration DIE because the declaration might be in
2500-
// a type-unit but the definition in the compile-unit (and it's
2501-
// specifcation would point to the declaration in the compile-unit). We
2502-
// rely on the mangled name within the module to be enough to find us the
2503-
// unique definition.
2504-
die = entry;
2524+
// TODO: this specification check doesn't work if declaration DIE was in a
2525+
// type-unit (we should only encode DIEs from .debug_info).
2526+
auto spec = entry.GetAttributeValueAsReferenceDIE(DW_AT_specification);
2527+
if (!spec)
2528+
return true;
2529+
2530+
if (spec != die)
2531+
return true;
2532+
2533+
// We're not picking a specific structor variant DIE, so we're done here.
2534+
if (!label.discriminator) {
2535+
die = entry;
2536+
return false;
2537+
}
2538+
2539+
const char *mangled =
2540+
entry.GetMangledName(/*substitute_name_allowed=*/false);
2541+
if (!mangled)
2542+
return true;
2543+
2544+
llvm::ItaniumPartialDemangler D;
2545+
if (D.partialDemangle(mangled))
2546+
return true;
2547+
2548+
if (D.getCtorOrDtorVariant() != GetItaniumCtorDtorVariant(label.discriminator).value_or(-1))
2549+
return true;
2550+
25052551
return false;
25062552
});
25072553

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "clang/AST/DeclBase.h"
1212
#include "clang/AST/ExprCXX.h"
13+
#include "clang/Basic/ABI.h"
1314
#include "clang/Frontend/ASTConsumers.h"
1415
#include "llvm/Support/Casting.h"
1516
#include "llvm/Support/FormatAdapters.h"

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <set>
1919
#include <string>
2020
#include <utility>
21+
#include <variant>
2122
#include <vector>
2223

2324
#include "clang/AST/ASTContext.h"
@@ -26,6 +27,7 @@
2627
#include "clang/AST/Decl.h"
2728
#include "clang/AST/TemplateBase.h"
2829
#include "clang/AST/Type.h"
30+
#include "clang/Basic/ABI.h"
2931
#include "clang/Basic/TargetInfo.h"
3032
#include "llvm/ADT/APSInt.h"
3133
#include "llvm/ADT/SmallVector.h"

llvm/include/llvm/Demangle/Demangle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ struct ItaniumPartialDemangler {
127127
/// If this symbol describes a constructor or destructor.
128128
DEMANGLE_ABI bool isCtorOrDtor() const;
129129

130+
/// If this symbol describes a constructor or destructor.
131+
std::optional<int> getCtorOrDtorVariant() const;
132+
130133
/// If this symbol describes a function.
131134
DEMANGLE_ABI bool isFunction() const;
132135

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,8 @@ class CtorDtorName final : public Node {
17661766

17671767
template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
17681768

1769+
int getVariant() const { return Variant; }
1770+
17691771
void printLeft(OutputBuffer &OB) const override {
17701772
if (IsDtor)
17711773
OB += "~";

0 commit comments

Comments
 (0)