Skip to content

Commit 25ea17b

Browse files
authored
Merge pull request llvm#11298 from swiftlang/lldb/func-call-labels-to-21.x
🍒[lldb] Cherry-pick FunctionCallLabel support to 21.x
2 parents 0921557 + 3e1d574 commit 25ea17b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1130
-408
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,22 +1084,13 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
10841084
def AsmLabel : InheritableAttr {
10851085
let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
10861086
let Args = [
1087-
// Label specifies the mangled name for the decl.
1088-
StringArgument<"Label">,
1089-
1090-
// IsLiteralLabel specifies whether the label is literal (i.e. suppresses
1091-
// the global C symbol prefix) or not. If not, the mangle-suppression prefix
1092-
// ('\01') is omitted from the decl name at the LLVM IR level.
1093-
//
1094-
// Non-literal labels are used by some external AST sources like LLDB.
1095-
BoolArgument<"IsLiteralLabel", /*optional=*/0, /*fake=*/1>
1096-
];
1087+
// Label specifies the mangled name for the decl.
1088+
StringArgument<"Label">, ];
10971089
let SemaHandler = 0;
10981090
let Documentation = [AsmLabelDocs];
1099-
let AdditionalMembers =
1100-
[{
1091+
let AdditionalMembers = [{
11011092
bool isEquivalent(AsmLabelAttr *Other) const {
1102-
return getLabel() == Other->getLabel() && getIsLiteralLabel() == Other->getIsLiteralLabel();
1093+
return getLabel() == Other->getLabel();
11031094
}
11041095
}];
11051096
}

clang/lib/AST/Mangle.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
161161
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
162162
// If we have an asm name, then we use it as the mangling.
163163

164-
// If the label isn't literal, or if this is an alias for an LLVM intrinsic,
164+
// If the label is an alias for an LLVM intrinsic,
165165
// do not add a "\01" prefix.
166-
if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) {
166+
if (ALA->getLabel().starts_with("llvm.")) {
167167
Out << ALA->getLabel();
168168
return;
169169
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8951,9 +8951,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
89518951
}
89528952
}
89538953

8954-
NewVD->addAttr(AsmLabelAttr::Create(Context, Label,
8955-
/*IsLiteralLabel=*/true,
8956-
SE->getStrTokenLoc(0)));
8954+
NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
89578955
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
89588956
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
89598957
ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -11254,9 +11252,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1125411252
if (Expr *E = D.getAsmLabel()) {
1125511253
// The parser guarantees this is a string.
1125611254
StringLiteral *SE = cast<StringLiteral>(E);
11257-
NewFD->addAttr(AsmLabelAttr::Create(Context, SE->getString(),
11258-
/*IsLiteralLabel=*/true,
11259-
SE->getStrTokenLoc(0)));
11255+
NewFD->addAttr(
11256+
AsmLabelAttr::Create(Context, SE->getString(), SE->getStrTokenLoc(0)));
1126011257
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
1126111258
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
1126211259
ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -21737,8 +21734,8 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
2173721734
LookupOrdinaryName);
2173821735
AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc),
2173921736
AttributeCommonInfo::Form::Pragma());
21740-
AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit(
21741-
Context, AliasName->getName(), /*IsLiteralLabel=*/true, Info);
21737+
AsmLabelAttr *Attr =
21738+
AsmLabelAttr::CreateImplicit(Context, AliasName->getName(), Info);
2174221739

2174321740
// If a declaration that:
2174421741
// 1) declares a function or a variable

clang/unittests/AST/DeclTest.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ TEST(Decl, AsmLabelAttr) {
131131
StringRef Code = R"(
132132
struct S {
133133
void f() {}
134-
void g() {}
135134
};
136135
)";
137136
auto AST =
@@ -144,26 +143,20 @@ TEST(Decl, AsmLabelAttr) {
144143
const auto *DeclS =
145144
selectFirst<CXXRecordDecl>("d", match(cxxRecordDecl().bind("d"), Ctx));
146145
NamedDecl *DeclF = *DeclS->method_begin();
147-
NamedDecl *DeclG = *(++DeclS->method_begin());
148146

149-
// Attach asm labels to the decls: one literal, and one not.
150-
DeclF->addAttr(AsmLabelAttr::Create(Ctx, "foo", /*LiteralLabel=*/true));
151-
DeclG->addAttr(AsmLabelAttr::Create(Ctx, "goo", /*LiteralLabel=*/false));
147+
DeclF->addAttr(AsmLabelAttr::Create(Ctx, "foo"));
152148

153149
// Mangle the decl names.
154150
std::string MangleF, MangleG;
155151
std::unique_ptr<ItaniumMangleContext> MC(
156152
ItaniumMangleContext::create(Ctx, Diags));
157153
{
158154
llvm::raw_string_ostream OS_F(MangleF);
159-
llvm::raw_string_ostream OS_G(MangleG);
160155
MC->mangleName(DeclF, OS_F);
161-
MC->mangleName(DeclG, OS_G);
162156
}
163157

164158
ASSERT_EQ(MangleF, "\x01"
165159
"foo");
166-
ASSERT_EQ(MangleG, "goo");
167160
}
168161

169162
TEST(Decl, MangleDependentSizedArray) {

lldb/include/lldb/Core/Module.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ struct ModuleFunctionSearchOptions {
8888
///
8989
/// The module will parse more detailed information as more queries are made.
9090
class Module : public std::enable_shared_from_this<Module>,
91-
public SymbolContextScope {
91+
public SymbolContextScope,
92+
public UserID {
9293
public:
9394
class LookupInfo;
9495
// Static functions that can track the lifetime of module objects. This is

lldb/include/lldb/Core/ModuleList.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "lldb/Utility/Status.h"
1919
#include "lldb/lldb-enumerations.h"
2020
#include "lldb/lldb-forward.h"
21+
#include "lldb/lldb-private-enumerations.h"
2122
#include "lldb/lldb-types.h"
2223

2324
#include "llvm/ADT/DenseSet.h"
@@ -374,6 +375,14 @@ class ModuleList {
374375
// UUID values is very efficient and accurate.
375376
lldb::ModuleSP FindModule(const UUID &uuid) const;
376377

378+
/// Find a module by LLDB-specific unique identifier.
379+
///
380+
/// \param[in] uid The UID of the module assigned to it on construction.
381+
///
382+
/// \returns ModuleSP of module with \c uid. Returns nullptr if no such
383+
/// module could be found.
384+
lldb::ModuleSP FindModule(lldb::user_id_t uid) const;
385+
377386
/// Finds the first module whose file specification matches \a module_spec.
378387
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const;
379388

@@ -530,8 +539,9 @@ class ModuleList {
530539
/// be non-null.
531540
///
532541
/// This function is thread-safe.
533-
void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
534-
&callback) const;
542+
void
543+
ForEach(std::function<IterationAction(const lldb::ModuleSP &module_sp)> const
544+
&callback) const;
535545

536546
void ClearModuleDependentCaches();
537547

lldb/include/lldb/Expression/Expression.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <string>
1414
#include <vector>
1515

16+
#include "llvm/Support/FormatProviders.h"
1617

1718
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
1819
#include "lldb/lldb-forward.h"
@@ -96,6 +97,62 @@ class Expression {
9697
///invalid.
9798
};
9899

100+
/// Holds parsed information about a function call label that
101+
/// LLDB attaches as an AsmLabel to function AST nodes it parses
102+
/// from debug-info.
103+
///
104+
/// The format being:
105+
///
106+
/// <prefix>:<module uid>:<symbol uid>:<name>
107+
///
108+
/// The label string needs to stay valid for the entire lifetime
109+
/// of this object.
110+
struct FunctionCallLabel {
111+
/// Unique identifier of the lldb_private::Module
112+
/// which contains the symbol identified by \c symbol_id.
113+
lldb::user_id_t module_id;
114+
115+
/// Unique identifier of the function symbol on which to
116+
/// perform the function call. For example, for DWARF this would
117+
/// be the DIE UID.
118+
lldb::user_id_t symbol_id;
119+
120+
/// Name to use when searching for the function symbol in
121+
/// \c module_id. For most function calls this will be a
122+
/// mangled name. In cases where a mangled name can't be used,
123+
/// this will be the function name.
124+
///
125+
/// NOTE: kept as last element so we don't have to worry about
126+
/// ':' in the mangled name when parsing the label.
127+
llvm::StringRef lookup_name;
128+
129+
/// Decodes the specified function \c label into a \c FunctionCallLabel.
130+
static llvm::Expected<FunctionCallLabel> fromString(llvm::StringRef label);
131+
132+
/// Encode this FunctionCallLabel into its string representation.
133+
///
134+
/// The representation roundtrips through \c fromString:
135+
/// \code{.cpp}
136+
/// llvm::StringRef encoded = "$__lldb_func:0x0:0x0:_Z3foov";
137+
/// FunctionCallLabel label = *fromString(label);
138+
///
139+
/// assert (label.toString() == encoded);
140+
/// assert (*fromString(label.toString()) == label);
141+
/// \endcode
142+
std::string toString() const;
143+
};
144+
145+
/// LLDB attaches this prefix to mangled names of functions that get called
146+
/// from JITted expressions.
147+
inline constexpr llvm::StringRef FunctionCallLabelPrefix = "$__lldb_func";
148+
99149
} // namespace lldb_private
100150

151+
namespace llvm {
152+
template <> struct format_provider<lldb_private::FunctionCallLabel> {
153+
static void format(const lldb_private::FunctionCallLabel &label,
154+
raw_ostream &OS, StringRef Style);
155+
};
156+
} // namespace llvm
157+
101158
#endif // LLDB_EXPRESSION_EXPRESSION_H

lldb/include/lldb/Symbol/SymbolFile.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,18 @@ class SymbolFile : public PluginInterface {
349349
GetMangledNamesForFunction(const std::string &scope_qualified_name,
350350
std::vector<ConstString> &mangled_names);
351351

352+
/// Resolves the function corresponding to the specified LLDB function
353+
/// call \c label.
354+
///
355+
/// \param[in] label The FunctionCallLabel to be resolved.
356+
///
357+
/// \returns An llvm::Error if the specified \c label couldn't be resolved.
358+
/// Returns the resolved function (as a SymbolContext) otherwise.
359+
virtual llvm::Expected<SymbolContext>
360+
ResolveFunctionCallLabel(const FunctionCallLabel &label) {
361+
return llvm::createStringError("Not implemented");
362+
}
363+
352364
virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope,
353365
lldb::TypeClass type_mask,
354366
lldb_private::TypeList &type_list) = 0;

lldb/source/Commands/CommandCompletions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ void CommandCompletions::ModuleUUIDs(CommandInterpreter &interpreter,
570570
lldb::eDescriptionLevelInitial);
571571
request.TryCompleteCurrentArg(module->GetUUID().GetAsString(),
572572
strm.GetString());
573-
return true;
573+
return IterationAction::Continue;
574574
});
575575
}
576576

lldb/source/Core/Module.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
135135
return nullptr;
136136
}
137137

138+
static std::atomic<lldb::user_id_t> g_unique_id = 1;
139+
138140
Module::Module(const ModuleSpec &module_spec)
139-
: m_unwind_table(*this), m_file_has_changed(false),
141+
: UserID(g_unique_id++), m_unwind_table(*this), m_file_has_changed(false),
140142
m_first_file_changed_log(false) {
141143
// Scope for locker below...
142144
{
@@ -241,7 +243,8 @@ Module::Module(const ModuleSpec &module_spec)
241243
Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
242244
ConstString object_name, lldb::offset_t object_offset,
243245
const llvm::sys::TimePoint<> &object_mod_time)
244-
: m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
246+
: UserID(g_unique_id++),
247+
m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
245248
m_arch(arch), m_file(file_spec), m_object_name(object_name),
246249
m_object_offset(object_offset), m_object_mod_time(object_mod_time),
247250
m_unwind_table(*this), m_file_has_changed(false),
@@ -262,7 +265,7 @@ Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
262265
}
263266

264267
Module::Module()
265-
: m_unwind_table(*this), m_file_has_changed(false),
268+
: UserID(g_unique_id++), m_unwind_table(*this), m_file_has_changed(false),
266269
m_first_file_changed_log(false) {
267270
std::lock_guard<std::recursive_mutex> guard(
268271
GetAllocationModuleCollectionMutex());

0 commit comments

Comments
 (0)