Skip to content

Cherry pick next #9655

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lldb/include/lldb/API/SBFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,9 @@ class LLDB_API SBFrame {
// guess the language type from the mangled name.
lldb::LanguageType GuessLanguage() const;

LLDB_DEPRECATED("Use SBFrame::IsHidden() instead.")
bool IsSwiftThunk() const;

lldb::SBStructuredData GetLanguageSpecificData() const;

/// Return true if this frame represents an inlined function.
///
/// See also GetFunctionName().
Expand Down Expand Up @@ -126,6 +125,11 @@ class LLDB_API SBFrame {
lldb::SBValue EvaluateExpression(const char *expr,
const SBExpressionOptions &options);

/// Language plugins can use this API to report language-specific
/// runtime information about this compile unit, such as additional
/// language version details or feature flags.
SBStructuredData GetLanguageSpecificData() const;

/// Gets the lexical block that defines the stack frame. Another way to think
/// of this is it will return the block that contains all of the variables
/// for a stack frame. Inlined functions are represented as SBBlock objects
Expand Down
21 changes: 5 additions & 16 deletions lldb/include/lldb/Target/LanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,22 +230,6 @@ class LanguageRuntime : public Runtime, public PluginInterface {
virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
static char ID;

/// Query the runtime for language specific metadata about the given frame.
///
/// Properties that are common to all languages are exposed as dedicated APIs
/// of \c Frame and \c Function. This function complements those APIs by
/// producing a \c StructuredData instance that encapsulates non-common
/// properties about the frame and function.
///
/// \param[in] frame
/// The frame to compute metadata for.
///
/// \return
/// Returns a StructuredData containing the metadata.
virtual StructuredDataImpl *GetLanguageSpecificData(StackFrame &frame) {
return nullptr;
}

virtual void FindFunctionPointersInCall(StackFrame &frame,
std::vector<Address> &addresses,
bool debug_only = true,
Expand Down Expand Up @@ -285,6 +269,11 @@ class LanguageRuntime : public Runtime, public PluginInterface {
lldb_private::RegisterContext *regctx,
bool &behaves_like_zeroth_frame);

/// Language runtime plugins can use this API to report
/// language-specific runtime information about this compile unit,
/// such as additional language version details or feature flags.
virtual StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc);

protected:
// The static GetRuntimeUnwindPlan method above is only implemented in the
// base class; subclasses may override this protected member if they can
Expand Down
10 changes: 10 additions & 0 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
#include "lldb/ValueObject/ValueObjectList.h"

Expand Down Expand Up @@ -408,6 +409,15 @@ class StackFrame : public ExecutionContextScope,
/// system implementation details this way.
bool IsHidden();

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

/// Language plugins can use this API to report language-specific
/// runtime information about this compile unit, such as additional
/// language version details or feature flags.
StructuredData::ObjectSP GetLanguageSpecificData();

/// Get the frame's demangled name.
///
/// /// \return
Expand Down
29 changes: 15 additions & 14 deletions lldb/source/API/SBFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
return expr_result;
}

SBStructuredData SBFrame::GetLanguageSpecificData() const {
LLDB_INSTRUMENT_VA(this);

SBStructuredData sb_data;
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = exe_ctx.GetFramePtr();
if (!frame)
return sb_data;

StructuredData::ObjectSP data(frame->GetLanguageSpecificData());
sb_data.m_impl_up->SetObjectSP(data);
return sb_data;
}

bool SBFrame::IsInlined() {
LLDB_INSTRUMENT_VA(this);

Expand Down Expand Up @@ -1246,20 +1261,6 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
return eLanguageTypeUnknown;
}

lldb::SBStructuredData SBFrame::GetLanguageSpecificData() const {
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
auto *process = exe_ctx.GetProcessPtr();
auto *frame = exe_ctx.GetFramePtr();
if (process && frame)
if (auto *runtime = process->GetLanguageRuntime(
frame->GuessLanguage().AsLanguageType()))
if (auto *data = runtime->GetLanguageSpecificData(*frame))
return SBStructuredData(*data);

return {};
}

// BEGIN SWIFT
bool SBFrame::IsSwiftThunk() const {
std::unique_lock<std::recursive_mutex> lock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3411,6 +3411,14 @@ std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() {
return std::nullopt;
}

StructuredData::ObjectSP
AppleObjCRuntimeV2::GetLanguageSpecificData(SymbolContext sc) {
auto dict_up = std::make_unique<StructuredData::Dictionary>();
dict_up->AddItem("Objective-C runtime version",
std::make_unique<StructuredData::UnsignedInteger>(2));
return dict_up;
}

#pragma mark Frame recognizers

class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {

std::optional<uint64_t> GetSharedCacheImageHeaderVersion();

StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override;

protected:
lldb::BreakpointResolverSP
CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1179,20 +1179,32 @@ SwiftLanguageRuntimeImpl::GetObjectDescription(Stream &str,
return RunObjectDescriptionExpr(object, expr_string, str);
}

StructuredDataImpl *
SwiftLanguageRuntime::GetLanguageSpecificData(StackFrame &frame) {
auto sc = frame.GetSymbolContext(eSymbolContextFunction);
StructuredData::ObjectSP
SwiftLanguageRuntime::GetLanguageSpecificData(SymbolContext sc) {
if (!sc.function)
return nullptr;
return {};

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

auto *data = new StructuredDataImpl;
data->SetObjectSP(dict_sp);
return data;
if (!m_process)
return dict_sp;

auto type_system_or_err =
m_process->GetTarget().GetScratchTypeSystemForLanguage(
eLanguageTypeSwift);
if (!type_system_or_err)
return dict_sp;

if (auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
type_system_or_err->get()))
if (auto *swift_ast_ctx = ts->GetSwiftASTContextOrNull(sc))
dict_sp->AddBooleanItem("SwiftExplicitModules",
swift_ast_ctx->HasExplicitModules());

return dict_sp;
}

void SwiftLanguageRuntime::FindFunctionPointersInCall(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
bool stop_others) override;

StructuredDataImpl *GetLanguageSpecificData(StackFrame &frame) override;
StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override;

/// If you are at the initial instruction of the frame passed in,
/// then this will examine the call arguments, and if any of them is
Expand Down
21 changes: 13 additions & 8 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Plugins/TypeSystem/Swift/StoringDiagnosticConsumer.h"
#include "Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h"

#include "SwiftASTContext.h"
#include "TypeSystemSwift.h"
#include "TypeSystemSwiftTypeRef.h"
#include "lldb/Utility/Log.h"
Expand Down Expand Up @@ -1799,11 +1800,18 @@ void SwiftASTContext::AddExtraClangArgs(
const std::vector<std::string> &module_search_paths,
const std::vector<std::pair<std::string, bool>> framework_search_paths,
StringRef overrideOpts) {
swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
auto defer = llvm::make_scope_exit([&]() {
// Detect explicitly-built modules.
m_has_explicit_modules =
llvm::any_of(importer_options.ExtraArgs, [](const std::string &arg) {
return StringRef(arg).starts_with("-fmodule-file=");
});
});

if (ExtraArgs.empty())
return;

swift::ClangImporterOptions &importer_options = GetClangImporterOptions();

// Detect cc1 flags. When DirectClangCC1ModuleBuild is on then the
// clang arguments in the serialized invocation are clang cc1 flags,
// which are very specific to one compiler version and cannot
Expand Down Expand Up @@ -1834,12 +1842,6 @@ void SwiftASTContext::AddExtraClangArgs(
applyOverrideOptions(importer_options.ExtraArgs, overrideOpts);
if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
RemoveExplicitModules(importer_options.ExtraArgs);

// Detect explicitly-built modules.
m_has_explicit_modules =
llvm::any_of(importer_options.ExtraArgs, [](const std::string &arg) {
return StringRef(arg).starts_with("-fmodule-file=");
});
}

void SwiftASTContext::AddExtraClangCC1Args(
Expand Down Expand Up @@ -5484,6 +5486,9 @@ void SwiftASTContext::LogConfiguration(bool is_repl) {
if (!clang_importer_options.BridgingHeader.empty())
HEALTH_LOG_PRINTF(" Bridging Header : %s",
clang_importer_options.BridgingHeader.c_str());
if (auto *expr_ctx = llvm::dyn_cast<SwiftASTContextForExpressions>(this))
HEALTH_LOG_PRINTF(" Explicit modules : %s",
expr_ctx->HasExplicitModules() ? "true" : "false");

HEALTH_LOG_PRINTF(
" Extra clang arguments : (%llu items)",
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ class SwiftASTContext : public TypeSystemSwift {
void ClearModuleDependentCaches() override;
void LogConfiguration(bool is_repl = false);
bool HasTarget();
bool HasExplicitModules() const { return m_has_explicit_modules; }
bool CheckProcessChanged();

// FIXME: this should be removed once we figure out who should really own the
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Target/LanguageRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,
return UnwindPlanSP();
}

StructuredData::ObjectSP
LanguageRuntime::GetLanguageSpecificData(SymbolContext sc) {
return {};
}

void LanguageRuntime::InitializeCommands(CommandObject *parent) {
if (!parent)
return;
Expand Down
30 changes: 30 additions & 0 deletions lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrameRecognizer.h"
Expand Down Expand Up @@ -1237,6 +1238,35 @@ bool StackFrame::IsHidden() {
return false;
}

bool StackFrame::IsSwiftThunk() {
ThreadSP thread_sp = GetThread();
if (!thread_sp)
return false;
ProcessSP process_sp = thread_sp->GetProcess();
if (!process_sp)
return false;

SymbolContext sc = GetSymbolContext(eSymbolContextSymbol);
if (!sc.symbol)
return false;
auto *runtime = process_sp->GetLanguageRuntime(eLanguageTypeSwift);
if (!runtime)
return false;
return runtime->IsSymbolARuntimeThunk(*sc.symbol);
}

StructuredData::ObjectSP StackFrame::GetLanguageSpecificData() {
auto process_sp = CalculateProcess();
SourceLanguage language = GetLanguage();
if (!language)
return {};
if (auto runtime_sp =
process_sp->GetLanguageRuntime(language.AsLanguageType()))
return runtime_sp->GetLanguageSpecificData(
GetSymbolContext(eSymbolContextFunction));
return {};
}

const char *StackFrame::GetFunctionName() {
const char *name = nullptr;
SymbolContext sc = GetSymbolContext(
Expand Down
4 changes: 4 additions & 0 deletions lldb/test/API/lang/objc/languageinfo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
OBJC_SOURCES := main.m
LD_EXTRAS := -lobjc

include Makefile.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class ObjCiVarIMPTestCase(TestBase):
@skipUnlessDarwin
@no_debug_info_test
def test_imp_ivar_type(self):
self.build()
target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(self, "main")
frame = thread.GetFrameAtIndex(0)
lang_info = frame.GetLanguageSpecificData()
version = lang_info.GetValueForKey("Objective-C runtime version")
self.assertEqual(version.GetIntegerValue(), 2)
1 change: 1 addition & 0 deletions lldb/test/API/lang/objc/languageinfo/main.m
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int main(int argc, char const *argv[]) { return 0; }
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SWIFT_SOURCES := main.swift
SWIFT_ENABLE_EXPLICIT_MODULES := YES
SWIFTFLAGS_EXTRAS := -parse-as-library
include Makefile.rules
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class TestCase(lldbtest.TestBase):

mydir = lldbtest.TestBase.compute_mydir(__file__)

@no_debug_info_test
@swiftTest
@skipIf(oslist=['windows', 'linux'])
def test(self):
Expand All @@ -27,9 +28,13 @@ def test(self):
while process.state == lldb.eStateStopped:
thread = process.GetSelectedThread()
frame = thread.frames[0]
# Spin up the compiler so it can answer the explicit modules question.
self.expect("expression 1")
data = frame.GetLanguageSpecificData()
is_async = data.GetValueForKey("IsSwiftAsyncFunction").GetBooleanValue()
self.assertTrue(is_async)
is_explicit = data.GetValueForKey("SwiftExplicitModules").GetBooleanValue()
self.assertTrue(is_explicit)

process.Continue()

Expand Down