mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 21:53:12 +08:00
[lldb] Add an API to derive language-specific runtime information (#116904)
This is motivated by exposing some Swift language-specific flags through the API, in the example here it is used to communicate the Objective-C runtime version. This could also be a meaningful extension point to get information about "embedded: languages, such as extracting the C++ version in an Objective-C++ frame or something along those lines.
This commit is contained in:
@@ -122,6 +122,11 @@ public:
|
||||
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 GetLanguageInfo();
|
||||
|
||||
/// 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
|
||||
|
||||
@@ -114,6 +114,7 @@ protected:
|
||||
friend class SBCommandReturnObject;
|
||||
friend class SBLaunchInfo;
|
||||
friend class SBDebugger;
|
||||
friend class SBFrame;
|
||||
friend class SBTarget;
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
|
||||
@@ -241,6 +241,11 @@ public:
|
||||
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 GetLanguageInfo(SymbolContext sc);
|
||||
|
||||
protected:
|
||||
// The static GetRuntimeUnwindPlan method above is only implemented in the
|
||||
// base class; subclasses may override this protected member if they can
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -408,6 +409,11 @@ public:
|
||||
/// system implementation details this way.
|
||||
bool IsHidden();
|
||||
|
||||
/// 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 GetLanguageInfo();
|
||||
|
||||
/// Get the frame's demangled name.
|
||||
///
|
||||
/// /// \return
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "lldb/API/SBExpressionOptions.h"
|
||||
#include "lldb/API/SBFormat.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
@@ -1154,6 +1155,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
|
||||
return expr_result;
|
||||
}
|
||||
|
||||
SBStructuredData SBFrame::GetLanguageInfo() {
|
||||
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->GetLanguageInfo());
|
||||
sb_data.m_impl_up->SetObjectSP(data);
|
||||
return sb_data;
|
||||
}
|
||||
|
||||
bool SBFrame::IsInlined() {
|
||||
LLDB_INSTRUMENT_VA(this);
|
||||
|
||||
|
||||
@@ -3398,6 +3398,13 @@ std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
StructuredData::ObjectSP AppleObjCRuntimeV2::GetLanguageInfo(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 {
|
||||
|
||||
@@ -106,6 +106,8 @@ public:
|
||||
|
||||
std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
|
||||
|
||||
StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc) override;
|
||||
|
||||
protected:
|
||||
lldb::BreakpointResolverSP
|
||||
CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
|
||||
|
||||
@@ -277,6 +277,10 @@ LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,
|
||||
return UnwindPlanSP();
|
||||
}
|
||||
|
||||
StructuredData::ObjectSP LanguageRuntime::GetLanguageInfo(SymbolContext sc) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void LanguageRuntime::InitializeCommands(CommandObject *parent) {
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
@@ -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"
|
||||
@@ -1230,6 +1231,18 @@ bool StackFrame::IsHidden() {
|
||||
return false;
|
||||
}
|
||||
|
||||
StructuredData::ObjectSP StackFrame::GetLanguageInfo() {
|
||||
auto process_sp = CalculateProcess();
|
||||
SourceLanguage language = GetLanguage();
|
||||
if (!language)
|
||||
return {};
|
||||
if (auto runtime_sp =
|
||||
process_sp->GetLanguageRuntime(language.AsLanguageType()))
|
||||
return runtime_sp->GetLanguageInfo(
|
||||
GetSymbolContext(eSymbolContextFunction));
|
||||
return {};
|
||||
}
|
||||
|
||||
const char *StackFrame::GetFunctionName() {
|
||||
const char *name = nullptr;
|
||||
SymbolContext sc = GetSymbolContext(
|
||||
|
||||
4
lldb/test/API/lang/objc/languageinfo/Makefile
Normal file
4
lldb/test/API/lang/objc/languageinfo/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
OBJC_SOURCES := main.m
|
||||
LD_EXTRAS := -lobjc
|
||||
|
||||
include Makefile.rules
|
||||
16
lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py
Normal file
16
lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py
Normal file
@@ -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.GetLanguageInfo()
|
||||
version = lang_info.GetValueForKey("Objective-C runtime version")
|
||||
self.assertEqual(version.GetIntegerValue(), 2)
|
||||
1
lldb/test/API/lang/objc/languageinfo/main.m
Normal file
1
lldb/test/API/lang/objc/languageinfo/main.m
Normal file
@@ -0,0 +1 @@
|
||||
int main(int argc, char const *argv[]) { return 0; }
|
||||
Reference in New Issue
Block a user