[lldb/script] Add class-based summary providers via ScriptedStringSummaryInterface#210469
[lldb/script] Add class-based summary providers via ScriptedStringSummaryInterface#210469medismailben wants to merge 1 commit into
Conversation
|
@llvm/pr-subscribers-lldb Author: Med Ismail Bennani (medismailben) ChangesAdd ScriptedSummaryFormat is a new Patch is 30.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210469.diff 21 Files Affected:
diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt
index d29b143c1408c..902f20d4f0b41 100644
--- a/lldb/bindings/python/CMakeLists.txt
+++ b/lldb/bindings/python/CMakeLists.txt
@@ -120,6 +120,7 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_breakpoint.py"
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_hook.py"
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_stackframe_recognizer.py"
+ "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_string_summary.py"
)
if(APPLE)
diff --git a/lldb/docs/CMakeLists.txt b/lldb/docs/CMakeLists.txt
index dd091836dc1aa..760991c5a68b5 100644
--- a/lldb/docs/CMakeLists.txt
+++ b/lldb/docs/CMakeLists.txt
@@ -33,6 +33,7 @@ if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND)
COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_breakpoint.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_hook.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_stackframe_recognizer.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_string_summary.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
COMMENT "Copying lldb.py to pretend its a Python package.")
add_dependencies(lldb-python-doc-package swig_wrapper_python)
diff --git a/lldb/examples/python/templates/scripted_string_summary.py b/lldb/examples/python/templates/scripted_string_summary.py
new file mode 100644
index 0000000000000..217c3bb6a8e25
--- /dev/null
+++ b/lldb/examples/python/templates/scripted_string_summary.py
@@ -0,0 +1,40 @@
+from abc import ABCMeta, abstractmethod
+
+import lldb
+
+
+class ScriptedStringSummary(metaclass=ABCMeta):
+ """
+ The base class for a scripted string summary provider.
+
+ A summary provider produces the one-line string shown next to a value in
+ `frame variable`/`expression` output. Register it with
+ `type summary add -l <ClassName> <TypeName>`.
+
+ Most of the base class methods are `@abstractmethod` that need to be
+ overwritten by the inheriting class.
+ """
+
+ def __init__(self):
+ """Construct a scripted summary provider.
+
+ Summary providers are constructed with no arguments and are shared
+ across every value they're asked to summarize.
+ """
+ pass
+
+ @abstractmethod
+ def get_summary(
+ self, valobj: lldb.SBValue, options: lldb.SBTypeSummaryOptions
+ ) -> str:
+ """Get the summary string for a value.
+
+ Args:
+ valobj (lldb.SBValue): The value to summarize.
+ options (lldb.SBTypeSummaryOptions): The options to use when
+ producing the summary.
+
+ Returns:
+ str: The summary string for `valobj`.
+ """
+ pass
diff --git a/lldb/include/lldb/API/SBTypeSummary.h b/lldb/include/lldb/API/SBTypeSummary.h
index b6869e53a39e7..9ca26532d8156 100644
--- a/lldb/include/lldb/API/SBTypeSummary.h
+++ b/lldb/include/lldb/API/SBTypeSummary.h
@@ -81,6 +81,10 @@ class SBTypeSummary {
CreateWithScriptCode(const char *data,
uint32_t options = 0); // see lldb::eTypeOption values
+ static SBTypeSummary
+ CreateWithClassName(const char *data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
#ifndef SWIG
static SBTypeSummary CreateWithCallback(FormatCallback cb,
uint32_t options = 0,
diff --git a/lldb/include/lldb/DataFormatters/TypeSummary.h b/lldb/include/lldb/DataFormatters/TypeSummary.h
index a0938556e0174..4abf18c9c39a3 100644
--- a/lldb/include/lldb/DataFormatters/TypeSummary.h
+++ b/lldb/include/lldb/DataFormatters/TypeSummary.h
@@ -48,7 +48,14 @@ class TypeSummaryOptions {
class TypeSummaryImpl {
public:
- enum class Kind { eSummaryString, eScript, eBytecode, eCallback, eInternal };
+ enum class Kind {
+ eSummaryString,
+ eScript,
+ eBytecode,
+ eCallback,
+ eInternal,
+ eScriptedClass
+ };
virtual ~TypeSummaryImpl() = default;
@@ -423,6 +430,51 @@ struct ScriptSummaryFormat : public TypeSummaryImpl {
const ScriptSummaryFormat &operator=(const ScriptSummaryFormat &) = delete;
};
+// Python-based summaries backed by a class, running an instance's
+// `get_summary` method to show data. Unlike ScriptSummaryFormat (a bare
+// function resolved once and cached), the Python object here is itself the
+// cache: it's created lazily on the first call to FormatObject (since this
+// format can be constructed via SBTypeSummary::CreateWithClassName before
+// any debugger/target context exists) and then reused across every
+// subsequent call, for every value of the matching type.
+struct ScriptedSummaryFormat : public TypeSummaryImpl {
+ std::string m_class_name;
+ lldb::ScriptedStringSummaryInterfaceSP m_interface_sp;
+
+ ScriptedSummaryFormat(const TypeSummaryImpl::Flags &flags,
+ const char *class_name, uint32_t ptr_match_depth = 1);
+
+ ~ScriptedSummaryFormat() override = default;
+
+ const char *GetClassName() const { return m_class_name.c_str(); }
+
+ void SetClassName(const char *class_name) {
+ if (class_name)
+ m_class_name.assign(class_name);
+ else
+ m_class_name.clear();
+ m_interface_sp.reset();
+ }
+
+ bool FormatObject(ValueObject *valobj, std::string &dest,
+ const TypeSummaryOptions &options) override;
+
+ std::string GetDescription() override;
+
+ std::string GetName() override;
+
+ static bool classof(const TypeSummaryImpl *S) {
+ return S->GetKind() == Kind::eScriptedClass;
+ }
+
+ typedef std::shared_ptr<ScriptedSummaryFormat> SharedPointer;
+
+private:
+ ScriptedSummaryFormat(const ScriptedSummaryFormat &) = delete;
+ const ScriptedSummaryFormat &
+ operator=(const ScriptedSummaryFormat &) = delete;
+};
+
/// A summary formatter that is defined in LLDB formmater bytecode.
///
/// See `BytecodeSyntheticChildren` for the corresponding synthetic formatter.
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStringSummaryInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStringSummaryInterface.h
new file mode 100644
index 0000000000000..a0bc59d82f750
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStringSummaryInterface.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTRINGSUMMARYINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTRINGSUMMARYINTERFACE_H
+
+#include "ScriptedInterface.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+class ScriptedStringSummaryInterface : virtual public ScriptedInterface {
+public:
+ virtual llvm::Expected<StructuredData::GenericSP>
+ CreatePluginObject(llvm::StringRef class_name) = 0;
+
+ virtual std::optional<std::string>
+ GetSummary(ValueObject &valobj, const TypeSummaryOptions &options) {
+ return std::nullopt;
+ }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTRINGSUMMARYINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 0e65cb4b8ac4a..98ff3a353d405 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -586,6 +586,11 @@ class ScriptInterpreter : public PluginInterface {
return {};
}
+ virtual lldb::ScriptedStringSummaryInterfaceSP
+ CreateScriptedStringSummaryInterface() {
+ return {};
+ }
+
virtual StructuredData::ObjectSP
CreateStructuredDataFromScriptObject(ScriptObject obj) {
return {};
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 93c252b55de99..773152d1dc13b 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -268,7 +268,8 @@ enum ScriptedExtension {
eScriptedExtensionScriptedThread,
eScriptedExtensionScriptedFrame,
eScriptedExtensionScriptedStackFrameRecognizer,
- kLastScriptedExtension = eScriptedExtensionScriptedStackFrameRecognizer
+ eScriptedExtensionScriptedStringSummary,
+ kLastScriptedExtension = eScriptedExtensionScriptedStringSummary
};
/// Register numbering types.
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 157aa5743f016..075a033253b1c 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -199,6 +199,7 @@ class ScriptedProcessInterface;
class ScriptedThreadInterface;
class ScriptedThreadPlanInterface;
class ScriptedStackFrameRecognizerInterface;
+class ScriptedStringSummaryInterface;
class ScriptedSyntheticChildren;
class SearchFilter;
class Section;
@@ -438,6 +439,8 @@ typedef std::shared_ptr<lldb_private::ScriptedBreakpointInterface>
ScriptedBreakpointInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedStackFrameRecognizerInterface>
ScriptedStackFrameRecognizerInterfaceSP;
+typedef std::shared_ptr<lldb_private::ScriptedStringSummaryInterface>
+ ScriptedStringSummaryInterfaceSP;
typedef std::shared_ptr<lldb_private::Section> SectionSP;
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
typedef std::weak_ptr<lldb_private::Section> SectionWP;
diff --git a/lldb/source/API/SBTypeSummary.cpp b/lldb/source/API/SBTypeSummary.cpp
index 58ec068ab9600..a424394d2768f 100644
--- a/lldb/source/API/SBTypeSummary.cpp
+++ b/lldb/source/API/SBTypeSummary.cpp
@@ -135,6 +135,17 @@ SBTypeSummary SBTypeSummary::CreateWithScriptCode(const char *data,
TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
}
+SBTypeSummary SBTypeSummary::CreateWithClassName(const char *data,
+ uint32_t options) {
+ LLDB_INSTRUMENT_VA(data, options);
+
+ if (!data || data[0] == 0)
+ return SBTypeSummary();
+
+ return SBTypeSummary(
+ TypeSummaryImplSP(new ScriptedSummaryFormat(options, data)));
+}
+
SBTypeSummary SBTypeSummary::CreateWithCallback(FormatCallback cb,
uint32_t options,
const char *description) {
@@ -372,6 +383,16 @@ bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) {
return GetOptions() == rhs.GetOptions();
case TypeSummaryImpl::Kind::eInternal:
return (m_opaque_sp.get() == rhs.m_opaque_sp.get());
+ case TypeSummaryImpl::Kind::eScriptedClass: {
+ ScriptedSummaryFormat *lhs_ptr =
+ llvm::dyn_cast<ScriptedSummaryFormat>(m_opaque_sp.get());
+ ScriptedSummaryFormat *rhs_ptr =
+ llvm::dyn_cast<ScriptedSummaryFormat>(rhs.m_opaque_sp.get());
+ if (!lhs_ptr || !rhs_ptr)
+ return false;
+ return strcmp(lhs_ptr->GetClassName(), rhs_ptr->GetClassName()) == 0 &&
+ GetOptions() == rhs.GetOptions();
+ }
}
return false;
@@ -417,6 +438,10 @@ bool SBTypeSummary::CopyOnWrite_Impl() {
llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) {
new_sp = TypeSummaryImplSP(new StringSummaryFormat(
GetOptions(), current_summary_ptr->GetSummaryString()));
+ } else if (ScriptedSummaryFormat *current_summary_ptr =
+ llvm::dyn_cast<ScriptedSummaryFormat>(m_opaque_sp.get())) {
+ new_sp = TypeSummaryImplSP(new ScriptedSummaryFormat(
+ GetOptions(), current_summary_ptr->GetClassName()));
}
SetSP(new_sp);
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp
index c1dc949a7b815..e7c4f55bef04d 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -146,7 +146,9 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed,
ConstString m_name;
std::string m_python_script;
std::string m_python_function;
+ std::string m_class_name;
bool m_is_add_script = false;
+ bool m_is_class_based = false;
std::string m_category;
uint32_t m_ptr_match_depth = 1;
};
@@ -157,6 +159,8 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed,
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result);
+ bool Execute_PythonClassSummary(Args &command, CommandReturnObject &result);
+
bool Execute_StringSummary(Args &command, CommandReturnObject &result);
public:
@@ -1229,6 +1233,10 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue(
case 'P':
m_is_add_script = true;
break;
+ case 'l':
+ m_class_name = std::string(option_arg);
+ m_is_class_based = true;
+ break;
case 'w':
m_category = std::string(option_arg);
break;
@@ -1254,8 +1262,10 @@ void CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting(
m_name.Clear();
m_python_script = "";
m_python_function = "";
+ m_class_name = "";
m_format_string = "";
m_is_add_script = false;
+ m_is_class_based = false;
m_category = "default";
}
@@ -1374,6 +1384,48 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary(
return result.Succeeded();
}
+bool CommandObjectTypeSummaryAdd::Execute_PythonClassSummary(
+ Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1 && !m_options.m_name) {
+ result.AppendErrorWithFormat("%s takes one or more args",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ if (m_options.m_class_name.empty()) {
+ result.AppendError("must provide a Python class name");
+ return false;
+ }
+
+ TypeSummaryImplSP script_format = std::make_shared<ScriptedSummaryFormat>(
+ m_options.m_flags, m_options.m_class_name.c_str(),
+ m_options.m_ptr_match_depth);
+
+ Status error;
+
+ for (auto &entry : command.entries()) {
+ AddSummary(ConstString(entry.ref()), script_format, m_options.m_match_type,
+ m_options.m_category, &error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ return false;
+ }
+ }
+
+ if (m_options.m_name) {
+ AddNamedSummary(m_options.m_name, script_format, &error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.AppendError("added to types, but not given a name");
+ return false;
+ }
+ }
+
+ return result.Succeeded();
+}
+
#endif
bool CommandObjectTypeSummaryAdd::Execute_StringSummary(
@@ -1553,7 +1605,13 @@ void CommandObjectTypeSummaryAdd::DoExecute(Args &command,
CommandReturnObject &result) {
WarnOnPotentialUnquotedUnsignedType(command, result);
- if (m_options.m_is_add_script) {
+ if (m_options.m_is_class_based) {
+#if LLDB_ENABLE_PYTHON
+ Execute_PythonClassSummary(command, result);
+#else
+ result.AppendError("python is disabled");
+#endif
+ } else if (m_options.m_is_add_script) {
#if LLDB_ENABLE_PYTHON
Execute_ScriptSummary(command, result);
#else
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index ab851725979ef..7ed7ed492913a 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -2434,6 +2434,11 @@ let Command = "type summary add" in {
: Option<"input-python", "P">,
Group<3>,
Desc<"Input Python code to use for this type manually.">;
+ def type_summary_add_python_class
+ : Option<"python-class", "l">,
+ Group<3>,
+ Arg<"PythonClass">,
+ Desc<"Use this Python class to produce a summary.">;
def type_summary_add_expand
: Option<"expand", "e">,
Groups<[2, 3]>,
diff --git a/lldb/source/DataFormatters/TypeSummary.cpp b/lldb/source/DataFormatters/TypeSummary.cpp
index 4f01466f85148..73ff39db19a81 100644
--- a/lldb/source/DataFormatters/TypeSummary.cpp
+++ b/lldb/source/DataFormatters/TypeSummary.cpp
@@ -16,6 +16,8 @@
#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/Interfaces/ScriptedStringSummaryInterface.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -60,6 +62,8 @@ std::string TypeSummaryImpl::GetSummaryKindName() {
return "c++";
case Kind::eBytecode:
return "bytecode";
+ case Kind::eScriptedClass:
+ return "python class";
}
llvm_unreachable("Unknown type kind name");
}
@@ -242,6 +246,77 @@ std::string ScriptSummaryFormat::GetDescription() {
std::string ScriptSummaryFormat::GetName() { return m_script_formatter_name; }
+ScriptedSummaryFormat::ScriptedSummaryFormat(
+ const TypeSummaryImpl::Flags &flags, const char *class_name,
+ uint32_t ptr_match_depth)
+ : TypeSummaryImpl(Kind::eScriptedClass, flags, ptr_match_depth),
+ m_class_name(class_name ? class_name : ""), m_interface_sp() {}
+
+bool ScriptedSummaryFormat::FormatObject(ValueObject *valobj,
+ std::string &retval,
+ const TypeSummaryOptions &options) {
+ if (!valobj)
+ return false;
+
+ TargetSP target_sp(valobj->GetTargetSP());
+
+ if (!target_sp) {
+ retval.assign("error: no target");
+ return false;
+ }
+
+ ScriptInterpreter *script_interpreter =
+ target_sp->GetDebugger().GetScriptInterpreter();
+
+ if (!script_interpreter) {
+ retval.assign("error: no ScriptInterpreter");
+ return false;
+ }
+
+ if (!m_interface_sp) {
+ m_interface_sp = script_interpreter->CreateScriptedStringSummaryInterface();
+ if (!m_interface_sp) {
+ retval.assign("error: no ScriptedStringSummaryInterface");
+ return false;
+ }
+
+ llvm::Expected<StructuredData::GenericSP> obj_or_err =
+ m_interface_sp->CreatePluginObject(m_class_name);
+ if (!obj_or_err) {
+ retval.assign(llvm::toString(obj_or_err.takeError()));
+ m_interface_sp.reset();
+ return false;
+ }
+ }
+
+ std::optional<std::string> summary =
+ m_interface_sp->GetSummary(*valobj, options);
+ if (!summary) {
+ retval.assign("error: script did not provide a summary");
+ return false;
+ }
+
+ retval = std::move(*summary);
+ return true;
+}
+
+std::string ScriptedSummaryFormat::GetDescription() {
+ StreamString sstr;
+ sstr.Printf("%s%s%s%s%s%s%s ptr-match-depth=%u\n ",
+ Cascades() ? "" : " (not cascading)",
+ !DoesPrintChildren(nullptr) ? "" : " (show children)",
+ !DoesPrintValue(nullptr) ? " (hide value)" : "",
+ IsOneLiner() ? " (one-line printout)" : "",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ HideNames(nullptr) ? " (hide member names)" : "",
+ GetPtrMatchDepth());
+ sstr.PutCString(m_class_name);
+ return std::string(sstr.GetString());
+}
+
+std::string ScriptedSummaryFormat::GetName() { return m_class_name; }
+
BytecodeSummaryFormat::BytecodeSummaryFormat(
const TypeSummaryImpl::Flags &flags,
std::unique_ptr<llvm::MemoryBuffer> bytecode)
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 4f6095d097d10..33e915951596e 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -221,6 +221,8 @@ ScriptInterpreter::ExtensionToString(lldb::ScriptedExtension extension) {
return "ScriptedFrame";
case eScriptedExtensionScriptedStackFrameRecognizer:
return "ScriptedStackFrameRecognizer";
+ case eScriptedExtensionScriptedStringSummary:
+ return "ScriptedStringSummary";
}
llvm_unreachable("unhandled ScriptedExtension");
}
@@ -241,6 ...
[truncated]
|
74d1c32 to
547ab0b
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
…erface Add `type summary add -L <ClassName>` as a class-based alternative to the existing function-based summary providers, purely additive: nothing about ScriptSummaryFormat/GetScriptedSummary (the existing function-based path) is touched. ScriptedSummaryFormat (TypeSummary.h/.cpp) is a new TypeSummaryImpl backed by a new Kind::eScriptedClass, parallel to ScriptSummaryFormat. Unlike every other scripted extension in this series, its interface object cannot be created eagerly at construction time -- SBTypeSummary::CreateWithClassName can run before any debugger/target context exists -- so CreatePluginObject is deferred to the first FormatObject() call and cached from then on, mirroring how ScriptSummaryFormat already lazily resolves and caches its function object. SBTypeSummary::CreateWithClassName mirrors SBTypeSynthetic::CreateWithClassName's existing shape. The two exhaustive switches over TypeSummaryImpl::Kind (GetSummaryKindName, SBTypeSummary::IsEqualTo) each get a case for eScriptedClass so the new kind does not trip a -Wswitch failure or silently compare unequal. Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
547ab0b to
6156b3e
Compare
Add
type summary add -L <ClassName>as a class-based alternative to the existing function-based summary providers, purely additive: nothing about ScriptSummaryFormat/GetScriptedSummary (the existing function-based path) is touched.ScriptedSummaryFormat is a new
TypeSummaryImplbacked by a newKind::eScriptedClass, parallel toScriptSummaryFormat. Unlike every other scripted extension in this series, its interface object cannot be created eagerly at construction time:SBTypeSummary::CreateWithClassNamecan run before any debugger/target context exists -- soCreatePluginObjectis deferred to the firstFormatObjectcall and cached from then on, mirroring howScriptSummaryFormatalready lazily resolves and caches its function object.