Skip to content

Commit e676df4

Browse files
Merge pull request #9649 from adrian-prantl/139841554-api
[lldb] Expose explicit modules as language specific data
2 parents 9cc0276 + 5155fae commit e676df4

File tree

17 files changed

+117
-62
lines changed

17 files changed

+117
-62
lines changed

lldb/include/lldb/API/SBFrame.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ class LLDB_API SBFrame {
9393
// guess the language type from the mangled name.
9494
lldb::LanguageType GuessLanguage() const;
9595

96+
LLDB_DEPRECATED("Use SBFrame::IsHidden() instead.")
9697
bool IsSwiftThunk() const;
9798

98-
lldb::SBStructuredData GetLanguageSpecificData() const;
99-
10099
/// Return true if this frame represents an inlined function.
101100
///
102101
/// See also GetFunctionName().
@@ -126,6 +125,11 @@ class LLDB_API SBFrame {
126125
lldb::SBValue EvaluateExpression(const char *expr,
127126
const SBExpressionOptions &options);
128127

128+
/// Language plugins can use this API to report language-specific
129+
/// runtime information about this compile unit, such as additional
130+
/// language version details or feature flags.
131+
SBStructuredData GetLanguageSpecificData() const;
132+
129133
/// Gets the lexical block that defines the stack frame. Another way to think
130134
/// of this is it will return the block that contains all of the variables
131135
/// for a stack frame. Inlined functions are represented as SBBlock objects

lldb/include/lldb/Target/LanguageRuntime.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -230,22 +230,6 @@ class LanguageRuntime : public Runtime, public PluginInterface {
230230
virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
231231
static char ID;
232232

233-
/// Query the runtime for language specific metadata about the given frame.
234-
///
235-
/// Properties that are common to all languages are exposed as dedicated APIs
236-
/// of \c Frame and \c Function. This function complements those APIs by
237-
/// producing a \c StructuredData instance that encapsulates non-common
238-
/// properties about the frame and function.
239-
///
240-
/// \param[in] frame
241-
/// The frame to compute metadata for.
242-
///
243-
/// \return
244-
/// Returns a StructuredData containing the metadata.
245-
virtual StructuredDataImpl *GetLanguageSpecificData(StackFrame &frame) {
246-
return nullptr;
247-
}
248-
249233
virtual void FindFunctionPointersInCall(StackFrame &frame,
250234
std::vector<Address> &addresses,
251235
bool debug_only = true,
@@ -285,6 +269,11 @@ class LanguageRuntime : public Runtime, public PluginInterface {
285269
lldb_private::RegisterContext *regctx,
286270
bool &behaves_like_zeroth_frame);
287271

272+
/// Language runtime plugins can use this API to report
273+
/// language-specific runtime information about this compile unit,
274+
/// such as additional language version details or feature flags.
275+
virtual StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc);
276+
288277
protected:
289278
// The static GetRuntimeUnwindPlan method above is only implemented in the
290279
// base class; subclasses may override this protected member if they can

lldb/include/lldb/Target/StackFrame.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Utility/Scalar.h"
2323
#include "lldb/Utility/Status.h"
2424
#include "lldb/Utility/StreamString.h"
25+
#include "lldb/Utility/StructuredData.h"
2526
#include "lldb/Utility/UserID.h"
2627
#include "lldb/ValueObject/ValueObjectList.h"
2728

@@ -413,14 +414,13 @@ class StackFrame : public ExecutionContextScope,
413414
bool IsHidden();
414415

415416
/// Query whether this frame is a Swift Thunk.
417+
LLDB_DEPRECATED("Use IsHidden() instead.")
416418
bool IsSwiftThunk();
417419

418-
/// Get this frame language specific data.
419-
///
420-
/// \return
421-
/// The StructuredDataImpl object containing the language specific data. Can
422-
/// be null.
423-
StructuredDataImpl *GetLanguageSpecificData();
420+
/// Language plugins can use this API to report language-specific
421+
/// runtime information about this compile unit, such as additional
422+
/// language version details or feature flags.
423+
StructuredData::ObjectSP GetLanguageSpecificData();
424424

425425
/// Get the frame's demangled name.
426426
///

lldb/source/API/SBFrame.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
11561156
return expr_result;
11571157
}
11581158

1159+
SBStructuredData SBFrame::GetLanguageSpecificData() const {
1160+
LLDB_INSTRUMENT_VA(this);
1161+
1162+
SBStructuredData sb_data;
1163+
std::unique_lock<std::recursive_mutex> lock;
1164+
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1165+
StackFrame *frame = exe_ctx.GetFramePtr();
1166+
if (!frame)
1167+
return sb_data;
1168+
1169+
StructuredData::ObjectSP data(frame->GetLanguageSpecificData());
1170+
sb_data.m_impl_up->SetObjectSP(data);
1171+
return sb_data;
1172+
}
1173+
11591174
bool SBFrame::IsInlined() {
11601175
LLDB_INSTRUMENT_VA(this);
11611176

@@ -1239,17 +1254,6 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
12391254
return eLanguageTypeUnknown;
12401255
}
12411256

1242-
lldb::SBStructuredData SBFrame::GetLanguageSpecificData() const {
1243-
std::unique_lock<std::recursive_mutex> lock;
1244-
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1245-
auto *frame = exe_ctx.GetFramePtr();
1246-
if (frame)
1247-
if (StructuredDataImpl *data = frame->GetLanguageSpecificData())
1248-
return SBStructuredData(*data);
1249-
1250-
return {};
1251-
}
1252-
12531257
// BEGIN SWIFT
12541258
bool SBFrame::IsSwiftThunk() const {
12551259
std::unique_lock<std::recursive_mutex> lock;

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,6 +3411,14 @@ std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() {
34113411
return std::nullopt;
34123412
}
34133413

3414+
StructuredData::ObjectSP
3415+
AppleObjCRuntimeV2::GetLanguageSpecificData(SymbolContext sc) {
3416+
auto dict_up = std::make_unique<StructuredData::Dictionary>();
3417+
dict_up->AddItem("Objective-C runtime version",
3418+
std::make_unique<StructuredData::UnsignedInteger>(2));
3419+
return dict_up;
3420+
}
3421+
34143422
#pragma mark Frame recognizers
34153423

34163424
class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
106106

107107
std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
108108

109+
StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override;
110+
109111
protected:
110112
lldb::BreakpointResolverSP
111113
CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,20 +1179,32 @@ SwiftLanguageRuntimeImpl::GetObjectDescription(Stream &str,
11791179
return RunObjectDescriptionExpr(object, expr_string, str);
11801180
}
11811181

1182-
StructuredDataImpl *
1183-
SwiftLanguageRuntime::GetLanguageSpecificData(StackFrame &frame) {
1184-
auto sc = frame.GetSymbolContext(eSymbolContextFunction);
1182+
StructuredData::ObjectSP
1183+
SwiftLanguageRuntime::GetLanguageSpecificData(SymbolContext sc) {
11851184
if (!sc.function)
1186-
return nullptr;
1185+
return {};
11871186

11881187
auto dict_sp = std::make_shared<StructuredData::Dictionary>();
11891188
auto symbol = sc.function->GetMangled().GetMangledName().GetStringRef();
11901189
auto is_async = SwiftLanguageRuntime::IsAnySwiftAsyncFunctionSymbol(symbol);
11911190
dict_sp->AddBooleanItem("IsSwiftAsyncFunction", is_async);
11921191

1193-
auto *data = new StructuredDataImpl;
1194-
data->SetObjectSP(dict_sp);
1195-
return data;
1192+
if (!m_process)
1193+
return dict_sp;
1194+
1195+
auto type_system_or_err =
1196+
m_process->GetTarget().GetScratchTypeSystemForLanguage(
1197+
eLanguageTypeSwift);
1198+
if (!type_system_or_err)
1199+
return dict_sp;
1200+
1201+
if (auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
1202+
type_system_or_err->get()))
1203+
if (auto *swift_ast_ctx = ts->GetSwiftASTContextOrNull(sc))
1204+
dict_sp->AddBooleanItem("SwiftExplicitModules",
1205+
swift_ast_ctx->HasExplicitModules());
1206+
1207+
return dict_sp;
11961208
}
11971209

11981210
void SwiftLanguageRuntime::FindFunctionPointersInCall(

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
431431
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
432432
bool stop_others) override;
433433

434-
StructuredDataImpl *GetLanguageSpecificData(StackFrame &frame) override;
434+
StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override;
435435

436436
/// If you are at the initial instruction of the frame passed in,
437437
/// then this will examine the call arguments, and if any of them is

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Plugins/TypeSystem/Swift/StoringDiagnosticConsumer.h"
1616
#include "Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h"
1717

18+
#include "SwiftASTContext.h"
1819
#include "TypeSystemSwift.h"
1920
#include "TypeSystemSwiftTypeRef.h"
2021
#include "lldb/Utility/Log.h"
@@ -1800,11 +1801,18 @@ void SwiftASTContext::AddExtraClangArgs(
18001801
const std::vector<std::string> &module_search_paths,
18011802
const std::vector<std::pair<std::string, bool>> framework_search_paths,
18021803
StringRef overrideOpts) {
1804+
swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
1805+
auto defer = llvm::make_scope_exit([&]() {
1806+
// Detect explicitly-built modules.
1807+
m_has_explicit_modules =
1808+
llvm::any_of(importer_options.ExtraArgs, [](const std::string &arg) {
1809+
return StringRef(arg).starts_with("-fmodule-file=");
1810+
});
1811+
});
1812+
18031813
if (ExtraArgs.empty())
18041814
return;
18051815

1806-
swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
1807-
18081816
// Detect cc1 flags. When DirectClangCC1ModuleBuild is on then the
18091817
// clang arguments in the serialized invocation are clang cc1 flags,
18101818
// which are very specific to one compiler version and cannot
@@ -1835,12 +1843,6 @@ void SwiftASTContext::AddExtraClangArgs(
18351843
applyOverrideOptions(importer_options.ExtraArgs, overrideOpts);
18361844
if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
18371845
RemoveExplicitModules(importer_options.ExtraArgs);
1838-
1839-
// Detect explicitly-built modules.
1840-
m_has_explicit_modules =
1841-
llvm::any_of(importer_options.ExtraArgs, [](const std::string &arg) {
1842-
return StringRef(arg).starts_with("-fmodule-file=");
1843-
});
18441846
}
18451847

18461848
void SwiftASTContext::AddExtraClangCC1Args(
@@ -5488,6 +5490,9 @@ void SwiftASTContext::LogConfiguration(bool is_repl) {
54885490
if (!clang_importer_options.BridgingHeader.empty())
54895491
HEALTH_LOG_PRINTF(" Bridging Header : %s",
54905492
clang_importer_options.BridgingHeader.c_str());
5493+
if (auto *expr_ctx = llvm::dyn_cast<SwiftASTContextForExpressions>(this))
5494+
HEALTH_LOG_PRINTF(" Explicit modules : %s",
5495+
expr_ctx->HasExplicitModules() ? "true" : "false");
54915496

54925497
HEALTH_LOG_PRINTF(
54935498
" Extra clang arguments : (%llu items)",

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ class SwiftASTContext : public TypeSystemSwift {
535535
void ClearModuleDependentCaches() override;
536536
void LogConfiguration(bool is_repl = false);
537537
bool HasTarget();
538+
bool HasExplicitModules() const { return m_has_explicit_modules; }
538539
bool CheckProcessChanged();
539540

540541
// FIXME: this should be removed once we figure out who should really own the

lldb/source/Target/LanguageRuntime.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,
277277
return UnwindPlanSP();
278278
}
279279

280+
StructuredData::ObjectSP
281+
LanguageRuntime::GetLanguageSpecificData(SymbolContext sc) {
282+
return {};
283+
}
284+
280285
void LanguageRuntime::InitializeCommands(CommandObject *parent) {
281286
if (!parent)
282287
return;

lldb/source/Target/StackFrame.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Symbol/VariableList.h"
2323
#include "lldb/Target/ABI.h"
2424
#include "lldb/Target/ExecutionContext.h"
25+
#include "lldb/Target/LanguageRuntime.h"
2526
#include "lldb/Target/Process.h"
2627
#include "lldb/Target/RegisterContext.h"
2728
#include "lldb/Target/StackFrameRecognizer.h"
@@ -1237,18 +1238,15 @@ bool StackFrame::IsSwiftThunk() {
12371238
return runtime->IsSymbolARuntimeThunk(*sc.symbol);
12381239
}
12391240

1240-
StructuredDataImpl *StackFrame::GetLanguageSpecificData() {
1241-
ThreadSP thread_sp = GetThread();
1242-
if (!thread_sp)
1241+
StructuredData::ObjectSP StackFrame::GetLanguageSpecificData() {
1242+
auto process_sp = CalculateProcess();
1243+
SourceLanguage language = GetLanguage();
1244+
if (!language)
12431245
return {};
1244-
ProcessSP process_sp = thread_sp->GetProcess();
1245-
if (!process_sp)
1246-
return {};
1247-
1248-
if (auto *runtime =
1249-
process_sp->GetLanguageRuntime(GuessLanguage().AsLanguageType()))
1250-
if (auto *data = runtime->GetLanguageSpecificData(*this))
1251-
return data;
1246+
if (auto runtime_sp =
1247+
process_sp->GetLanguageRuntime(language.AsLanguageType()))
1248+
return runtime_sp->GetLanguageSpecificData(
1249+
GetSymbolContext(eSymbolContextFunction));
12521250
return {};
12531251
}
12541252

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
OBJC_SOURCES := main.m
2+
LD_EXTRAS := -lobjc
3+
4+
include Makefile.rules
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class ObjCiVarIMPTestCase(TestBase):
8+
@skipUnlessDarwin
9+
@no_debug_info_test
10+
def test_imp_ivar_type(self):
11+
self.build()
12+
target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(self, "main")
13+
frame = thread.GetFrameAtIndex(0)
14+
lang_info = frame.GetLanguageSpecificData()
15+
version = lang_info.GetValueForKey("Objective-C runtime version")
16+
self.assertEqual(version.GetIntegerValue(), 2)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int main(int argc, char const *argv[]) { return 0; }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
SWIFT_SOURCES := main.swift
2+
SWIFT_ENABLE_EXPLICIT_MODULES := YES
23
SWIFTFLAGS_EXTRAS := -parse-as-library
34
include Makefile.rules

lldb/test/API/lang/swift/async/frame/language_specific_data/TestSwiftAsyncLanguageSpecificData.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class TestCase(lldbtest.TestBase):
77

88
mydir = lldbtest.TestBase.compute_mydir(__file__)
99

10+
@no_debug_info_test
1011
@swiftTest
1112
@skipIf(oslist=['windows', 'linux'])
1213
def test(self):
@@ -27,9 +28,13 @@ def test(self):
2728
while process.state == lldb.eStateStopped:
2829
thread = process.GetSelectedThread()
2930
frame = thread.frames[0]
31+
# Spin up the compiler so it can answer the explicit modules question.
32+
self.expect("expression 1")
3033
data = frame.GetLanguageSpecificData()
3134
is_async = data.GetValueForKey("IsSwiftAsyncFunction").GetBooleanValue()
3235
self.assertTrue(is_async)
36+
is_explicit = data.GetValueForKey("SwiftExplicitModules").GetBooleanValue()
37+
self.assertTrue(is_explicit)
3338

3439
process.Continue()
3540

0 commit comments

Comments
 (0)