24#include "llvm/Support/Error.h"
25#include "llvm/Support/ErrorExtras.h"
32 bool need_add_dot =
true;
33 if (path[0] ==
'.' || (path[0] ==
'-' && path[1] ==
'>') || path[0] ==
'[')
43 const std::string &path) {
46 bool need_add_dot =
true;
47 if (path[0] ==
'.' || (path[0] ==
'-' && path[1] ==
'>') || path[0] ==
'[')
61 for (
size_t i = 0; i <
filter->GetCount(); i++) {
62 const char *expr_cstr =
filter->GetExpressionPathAtIndex(i);
64 if (*expr_cstr ==
'.')
66 else if (*expr_cstr ==
'-' && *(expr_cstr + 1) ==
'>')
70 if (!::strcmp(name_cstr, expr_cstr))
75 return llvm::createStringErrorV(
"type has no child named '{0}'", name);
84 for (
size_t i = 0; i <
GetCount(); i++) {
127 return *value_or_err;
135 llvm::StringRef name, llvm::StringRef expression,
139 name, expression, exe_ctx, options);
141 valobj_sp->SetSyntheticChildrenGenerated(
true);
150 name, address, exe_ctx, type, do_deref);
152 valobj_sp->SetSyntheticChildrenGenerated(
true);
160 m_backend.CreateChildValueObjectFromData(name, data, exe_ctx, type);
162 valobj_sp->SetSyntheticChildrenGenerated(
true);
189 llvm::consumeError(obj_or_err.takeError());
208llvm::Expected<uint32_t>
215llvm::Expected<uint32_t>
236llvm::Expected<size_t>
239 return llvm::createStringErrorV(
"type has no child named '{0}'", name);
265 return obj->GetValue();
270 sstr.
Printf(
"%s%s%s Python class %s",
Cascades() ?
"" :
" (not cascading)",
285 if (
m_impl.version >= 2) {
286 self_sp = std::make_shared<FormatterBytecode::Dictionary>();
294 if (m_impl.version >= 2) {
296 (*self_sp)[
"valobj"] = backend.GetSP();
297 m_init_results.assign({self_sp});
299 m_init_results = std::move(data);
309 "@init failed: {0}");
314 m_init_results.assign({self_sp});
315 else if (data.size() > 0)
316 m_init_results = std::move(data);
328 control, data, FormatterBytecode::sig_update,
m_impl.version);
331 "@update failed: {0}");
337 if (
m_impl.version >= 2) {
340 data.empty() ? nullptr : std::get_if<llvm::APSInt>(&data.back());
341 if (!reply || !(*reply == 0 || *reply == 1)) {
343 "@update did not reply with an Integer of 0 or 1, as required "
344 "of version 2 formatters (type: `{0}`, name: `{1}`)",
351 std::optional<ChildCacheState> can_reuse = std::nullopt;
354 if (
auto *u = std::get_if<uint64_t>(&top))
355 if (*u == 0 || *u == 1)
357 if (
auto *i = std::get_if<int64_t>(&top))
358 if (*i == 0 || *i == 1)
360 if (
auto *ap = std::get_if<llvm::APSInt>(&top))
361 if (*ap == 0 || *ap == 1)
369 "Bytecode formatter can reuse @update: {0} (type: `{1}`, name: `{2}`)",
370 can_reuse ?
"true" :
"false",
m_backend.GetDisplayTypeName(),
374 "Bytecode formatter did not return a valid reuse response from "
375 "@update (type: `{}`, name: `{}`)",
385llvm::Expected<uint32_t>
393 control, data, FormatterBytecode::sig_get_num_children,
m_impl.version);
397 if (data.size() == 0) {
398 char message[] =
"@get_num_children returned empty data stack";
400 return llvm::createStringError(message);
404 if (
auto *u = std::get_if<uint64_t>(&top))
407 if (
auto *i = std::get_if<int64_t>(&top)) {
412 if (
auto *ap = std::get_if<llvm::APSInt>(&top)) {
413 if (ap->isRepresentableByInt64()) {
414 int64_t v = ap->getExtValue();
416 return static_cast<uint32_t
>(v);
421 return llvm::createStringError(
"@get_num_children returned invalid value");
426 if (!
m_impl.get_child_at_index)
430 m_impl.get_child_at_index->getBuffer()};
433 data.
Push(llvm::APSInt::get(idx));
435 data.emplace_back((uint64_t)idx);
437 control, data, FormatterBytecode::sig_get_child_at_index,
m_impl.version);
440 "@get_child_at_index failed: {0}");
444 if (data.size() == 0) {
446 "@get_child_at_index returned empty data stack");
451 if (
auto *child = std::get_if<ValueObjectSP>(&top))
457llvm::Expected<size_t>
459 if (!
m_impl.get_child_index)
460 return llvm::createStringErrorV(
"type has no child named '{0}'", name);
463 m_impl.get_child_index->getBuffer()};
467 control, data, FormatterBytecode::sig_get_child_index,
m_impl.version);
471 if (data.size() == 0) {
472 char message[] =
"@get_child_index returned empty data stack";
474 return llvm::createStringError(message);
478 if (
auto *u = std::get_if<uint64_t>(&top))
481 if (
auto *i = std::get_if<int64_t>(&top)) {
482 if (*i >= 0 &&
static_cast<uint64_t
>(*i) <= SIZE_MAX)
486 if (
auto *ap = std::get_if<llvm::APSInt>(&top)) {
487 if (ap->isRepresentableByInt64()) {
488 int64_t v = ap->getExtValue();
489 if (v >= 0 &&
static_cast<uint64_t
>(v) <= SIZE_MAX)
490 return static_cast<size_t>(v);
495 return llvm::createStringError(
"@get_child_index returned invalid value");
500 sstr.
Printf(
"%s%s%s Bytecode synthetic",
Cascades() ?
"" :
" (not cascading)",
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERRORV(log, error,...)
#define LLDB_LOG_ERROR(log, error,...)
FrontEnd(ValueObject &backend, SyntheticBytecodeImplementation &impl)
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Determine the index of a named child.
llvm::Expected< uint32_t > CalculateNumChildren() override
const SyntheticBytecodeImplementation & m_impl
FormatterBytecode::DataStack m_init_results
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
FormatterBytecode::DataStack m_self
std::string GetDescription() override
SyntheticBytecodeImplementation m_impl
CreateFrontEndCallback m_create_callback
virtual ~CXXSyntheticChildren()
std::string m_description
std::string GetDescription() override
CXXSyntheticChildren(const SyntheticChildren::Flags &flags, const char *description, CreateFrontEndCallback callback)
std::function< SyntheticChildrenFrontEnd *(CXXSyntheticChildren *, lldb::ValueObjectSP)> CreateFrontEndCallback
Generic representation of a type in a programming language.
A uniqued constant string class.
std::string GetString() const
Get the string value as a std::string.
const char * GetCString() const
Get the string value as a C string.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
virtual lldb::ScriptedSyntheticChildrenInterfaceSP CreateScriptedSyntheticChildrenInterface()
Debugger & GetDebugger()
Get the debugger associated with this script interpreter.
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
std::string m_python_class
lldb::ScriptedSyntheticChildrenInterfaceSP m_interface_sp
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Determine the index of a named child.
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
FrontEnd(std::string pclass, ValueObject &backend)
void * GetImplementation() override
lldb::ValueObjectSP GetSyntheticValue() override
llvm::Expected< uint32_t > CalculateNumChildren() override
ConstString GetSyntheticTypeName() override
bool MightHaveChildren() override
std::string GetDescription() override
std::string m_python_class
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
std::shared_ptr< Generic > GenericSP
uint32_t CalculateNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
lldb::ValueObjectSP CreateChildValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
std::unique_ptr< SyntheticChildrenFrontEnd > UniquePointer
lldb::ValueObjectSP CreateChildValueObjectFromExpression(llvm::StringRef name, llvm::StringRef expression, const ExecutionContext &exe_ctx)
virtual llvm::Expected< uint32_t > CalculateNumChildren()=0
SyntheticChildrenFrontEnd(ValueObject &backend)
lldb::ValueObjectSP CreateChildValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
virtual std::string GetDescription()=0
virtual SyntheticChildrenFrontEnd::UniquePointer GetFrontEnd(ValueObject &backend)=0
bool SkipsPointers() const
SyntheticChildren(const Flags &flags)
bool SkipsReferences() const
virtual ~SyntheticChildren()
virtual bool IsScripted()=0
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Determine the index of a named child.
bool SetExpressionPathAtIndex(size_t i, const char *path)
const char * GetExpressionPathAtIndex(size_t i) const
void AddExpressionPath(const char *path)
std::string GetDescription() override
std::vector< std::string > m_expression_paths
lldb::ValueObjectSP GetSP()
lldb::user_id_t GetID() const
Returns a unique id for this ValueObject.
lldb::TargetSP GetTargetSP() const
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
@ eReuse
Children did not change and don't need to be recomputed; re-use what we computed the last time we cal...
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Target > TargetSP
uint32_t version
The version of this record. Specs are found in formatterbytecode.md.