forked from OSchip/llvm-project
599 lines
21 KiB
OpenEdge ABL
599 lines
21 KiB
OpenEdge ABL
|
//===-- SWIG Interface for SBValue ------------------------------*- C++ -*-===//
|
||
|
//
|
||
|
// 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
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
namespace lldb {
|
||
|
|
||
|
%feature("docstring",
|
||
|
"Represents the value of a variable, a register, or an expression.
|
||
|
|
||
|
SBValue supports iteration through its child, which in turn is represented
|
||
|
as an SBValue. For example, we can get the general purpose registers of a
|
||
|
frame as an SBValue, and iterate through all the registers,
|
||
|
|
||
|
registerSet = frame.registers # Returns an SBValueList.
|
||
|
for regs in registerSet:
|
||
|
if 'general purpose registers' in regs.name.lower():
|
||
|
GPRs = regs
|
||
|
break
|
||
|
|
||
|
print('%s (number of children = %d):' % (GPRs.name, GPRs.num_children))
|
||
|
for reg in GPRs:
|
||
|
print('Name: ', reg.name, ' Value: ', reg.value)
|
||
|
|
||
|
produces the output:
|
||
|
|
||
|
General Purpose Registers (number of children = 21):
|
||
|
Name: rax Value: 0x0000000100000c5c
|
||
|
Name: rbx Value: 0x0000000000000000
|
||
|
Name: rcx Value: 0x00007fff5fbffec0
|
||
|
Name: rdx Value: 0x00007fff5fbffeb8
|
||
|
Name: rdi Value: 0x0000000000000001
|
||
|
Name: rsi Value: 0x00007fff5fbffea8
|
||
|
Name: rbp Value: 0x00007fff5fbffe80
|
||
|
Name: rsp Value: 0x00007fff5fbffe60
|
||
|
Name: r8 Value: 0x0000000008668682
|
||
|
Name: r9 Value: 0x0000000000000000
|
||
|
Name: r10 Value: 0x0000000000001200
|
||
|
Name: r11 Value: 0x0000000000000206
|
||
|
Name: r12 Value: 0x0000000000000000
|
||
|
Name: r13 Value: 0x0000000000000000
|
||
|
Name: r14 Value: 0x0000000000000000
|
||
|
Name: r15 Value: 0x0000000000000000
|
||
|
Name: rip Value: 0x0000000100000dae
|
||
|
Name: rflags Value: 0x0000000000000206
|
||
|
Name: cs Value: 0x0000000000000027
|
||
|
Name: fs Value: 0x0000000000000010
|
||
|
Name: gs Value: 0x0000000000000048
|
||
|
|
||
|
See also linked_list_iter() for another perspective on how to iterate through an
|
||
|
SBValue instance which interprets the value object as representing the head of a
|
||
|
linked list."
|
||
|
) SBValue;
|
||
|
class SBValue
|
||
|
{
|
||
|
public:
|
||
|
SBValue ();
|
||
|
|
||
|
SBValue (const SBValue &rhs);
|
||
|
|
||
|
~SBValue ();
|
||
|
|
||
|
bool
|
||
|
IsValid();
|
||
|
|
||
|
explicit operator bool() const;
|
||
|
|
||
|
void
|
||
|
Clear();
|
||
|
|
||
|
SBError
|
||
|
GetError();
|
||
|
|
||
|
lldb::user_id_t
|
||
|
GetID ();
|
||
|
|
||
|
const char *
|
||
|
GetName();
|
||
|
|
||
|
const char *
|
||
|
GetTypeName ();
|
||
|
|
||
|
const char *
|
||
|
GetDisplayTypeName ();
|
||
|
|
||
|
size_t
|
||
|
GetByteSize ();
|
||
|
|
||
|
bool
|
||
|
IsInScope ();
|
||
|
|
||
|
lldb::Format
|
||
|
GetFormat ();
|
||
|
|
||
|
void
|
||
|
SetFormat (lldb::Format format);
|
||
|
|
||
|
const char *
|
||
|
GetValue ();
|
||
|
|
||
|
int64_t
|
||
|
GetValueAsSigned(SBError& error, int64_t fail_value=0);
|
||
|
|
||
|
uint64_t
|
||
|
GetValueAsUnsigned(SBError& error, uint64_t fail_value=0);
|
||
|
|
||
|
int64_t
|
||
|
GetValueAsSigned(int64_t fail_value=0);
|
||
|
|
||
|
uint64_t
|
||
|
GetValueAsUnsigned(uint64_t fail_value=0);
|
||
|
|
||
|
ValueType
|
||
|
GetValueType ();
|
||
|
|
||
|
bool
|
||
|
GetValueDidChange ();
|
||
|
|
||
|
const char *
|
||
|
GetSummary ();
|
||
|
|
||
|
const char *
|
||
|
GetSummary (lldb::SBStream& stream,
|
||
|
lldb::SBTypeSummaryOptions& options);
|
||
|
|
||
|
const char *
|
||
|
GetObjectDescription ();
|
||
|
|
||
|
lldb::SBValue
|
||
|
GetDynamicValue (lldb::DynamicValueType use_dynamic);
|
||
|
|
||
|
lldb::SBValue
|
||
|
GetStaticValue ();
|
||
|
|
||
|
lldb::SBValue
|
||
|
GetNonSyntheticValue ();
|
||
|
|
||
|
lldb::DynamicValueType
|
||
|
GetPreferDynamicValue ();
|
||
|
|
||
|
void
|
||
|
SetPreferDynamicValue (lldb::DynamicValueType use_dynamic);
|
||
|
|
||
|
bool
|
||
|
GetPreferSyntheticValue ();
|
||
|
|
||
|
void
|
||
|
SetPreferSyntheticValue (bool use_synthetic);
|
||
|
|
||
|
bool
|
||
|
IsDynamic();
|
||
|
|
||
|
bool
|
||
|
IsSynthetic ();
|
||
|
|
||
|
bool
|
||
|
IsSyntheticChildrenGenerated ();
|
||
|
|
||
|
void
|
||
|
SetSyntheticChildrenGenerated (bool);
|
||
|
|
||
|
const char *
|
||
|
GetLocation ();
|
||
|
|
||
|
bool
|
||
|
SetValueFromCString (const char *value_str);
|
||
|
|
||
|
bool
|
||
|
SetValueFromCString (const char *value_str, lldb::SBError& error);
|
||
|
|
||
|
lldb::SBTypeFormat
|
||
|
GetTypeFormat ();
|
||
|
|
||
|
lldb::SBTypeSummary
|
||
|
GetTypeSummary ();
|
||
|
|
||
|
lldb::SBTypeFilter
|
||
|
GetTypeFilter ();
|
||
|
|
||
|
lldb::SBTypeSynthetic
|
||
|
GetTypeSynthetic ();
|
||
|
|
||
|
lldb::SBValue
|
||
|
GetChildAtIndex (uint32_t idx);
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Get a child value by index from a value.
|
||
|
|
||
|
Structs, unions, classes, arrays and pointers have child
|
||
|
values that can be access by index.
|
||
|
|
||
|
Structs and unions access child members using a zero based index
|
||
|
for each child member. For
|
||
|
|
||
|
Classes reserve the first indexes for base classes that have
|
||
|
members (empty base classes are omitted), and all members of the
|
||
|
current class will then follow the base classes.
|
||
|
|
||
|
Pointers differ depending on what they point to. If the pointer
|
||
|
points to a simple type, the child at index zero
|
||
|
is the only child value available, unless synthetic_allowed
|
||
|
is true, in which case the pointer will be used as an array
|
||
|
and can create 'synthetic' child values using positive or
|
||
|
negative indexes. If the pointer points to an aggregate type
|
||
|
(an array, class, union, struct), then the pointee is
|
||
|
transparently skipped and any children are going to be the indexes
|
||
|
of the child values within the aggregate type. For example if
|
||
|
we have a 'Point' type and we have a SBValue that contains a
|
||
|
pointer to a 'Point' type, then the child at index zero will be
|
||
|
the 'x' member, and the child at index 1 will be the 'y' member
|
||
|
(the child at index zero won't be a 'Point' instance).
|
||
|
|
||
|
If you actually need an SBValue that represents the type pointed
|
||
|
to by a SBValue for which GetType().IsPointeeType() returns true,
|
||
|
regardless of the pointee type, you can do that with the SBValue.Dereference
|
||
|
method (or the equivalent deref property).
|
||
|
|
||
|
Arrays have a preset number of children that can be accessed by
|
||
|
index and will returns invalid child values for indexes that are
|
||
|
out of bounds unless the synthetic_allowed is true. In this
|
||
|
case the array can create 'synthetic' child values for indexes
|
||
|
that aren't in the array bounds using positive or negative
|
||
|
indexes.
|
||
|
|
||
|
@param[in] idx
|
||
|
The index of the child value to get
|
||
|
|
||
|
@param[in] use_dynamic
|
||
|
An enumeration that specifies whether to get dynamic values,
|
||
|
and also if the target can be run to figure out the dynamic
|
||
|
type of the child value.
|
||
|
|
||
|
@param[in] synthetic_allowed
|
||
|
If true, then allow child values to be created by index
|
||
|
for pointers and arrays for indexes that normally wouldn't
|
||
|
be allowed.
|
||
|
|
||
|
@return
|
||
|
A new SBValue object that represents the child member value.") GetChildAtIndex;
|
||
|
lldb::SBValue
|
||
|
GetChildAtIndex (uint32_t idx,
|
||
|
lldb::DynamicValueType use_dynamic,
|
||
|
bool can_create_synthetic);
|
||
|
|
||
|
lldb::SBValue
|
||
|
CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type);
|
||
|
|
||
|
lldb::SBValue
|
||
|
SBValue::Cast (lldb::SBType type);
|
||
|
|
||
|
lldb::SBValue
|
||
|
CreateValueFromExpression (const char *name, const char* expression);
|
||
|
|
||
|
lldb::SBValue
|
||
|
CreateValueFromExpression (const char *name, const char* expression, SBExpressionOptions &options);
|
||
|
|
||
|
lldb::SBValue
|
||
|
CreateValueFromAddress(const char* name, lldb::addr_t address, lldb::SBType type);
|
||
|
|
||
|
lldb::SBValue
|
||
|
CreateValueFromData (const char* name,
|
||
|
lldb::SBData data,
|
||
|
lldb::SBType type);
|
||
|
|
||
|
lldb::SBType
|
||
|
GetType();
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Returns the child member index.
|
||
|
|
||
|
Matches children of this object only and will match base classes and
|
||
|
member names if this is a clang typed object.
|
||
|
|
||
|
@param[in] name
|
||
|
The name of the child value to get
|
||
|
|
||
|
@return
|
||
|
An index to the child member value.") GetIndexOfChildWithName;
|
||
|
uint32_t
|
||
|
GetIndexOfChildWithName (const char *name);
|
||
|
|
||
|
lldb::SBValue
|
||
|
GetChildMemberWithName (const char *name);
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Returns the child member value.
|
||
|
|
||
|
Matches child members of this object and child members of any base
|
||
|
classes.
|
||
|
|
||
|
@param[in] name
|
||
|
The name of the child value to get
|
||
|
|
||
|
@param[in] use_dynamic
|
||
|
An enumeration that specifies whether to get dynamic values,
|
||
|
and also if the target can be run to figure out the dynamic
|
||
|
type of the child value.
|
||
|
|
||
|
@return
|
||
|
A new SBValue object that represents the child member value.") GetChildMemberWithName;
|
||
|
lldb::SBValue
|
||
|
GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic);
|
||
|
|
||
|
%feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d."
|
||
|
) GetValueForExpressionPath;
|
||
|
lldb::SBValue
|
||
|
GetValueForExpressionPath(const char* expr_path);
|
||
|
|
||
|
lldb::SBDeclaration
|
||
|
GetDeclaration ();
|
||
|
|
||
|
bool
|
||
|
MightHaveChildren ();
|
||
|
|
||
|
bool
|
||
|
IsRuntimeSupportValue ();
|
||
|
|
||
|
uint32_t
|
||
|
GetNumChildren ();
|
||
|
|
||
|
%feature("doctstring", "
|
||
|
Returns the number for children.
|
||
|
|
||
|
@param[in] max
|
||
|
If max is less the lldb.UINT32_MAX, then the returned value is
|
||
|
capped to max.
|
||
|
|
||
|
@return
|
||
|
An integer value capped to the argument max.") GetNumChildren;
|
||
|
uint32_t
|
||
|
GetNumChildren (uint32_t max);
|
||
|
|
||
|
void *
|
||
|
GetOpaqueType();
|
||
|
|
||
|
lldb::SBValue
|
||
|
Dereference ();
|
||
|
|
||
|
lldb::SBValue
|
||
|
AddressOf();
|
||
|
|
||
|
bool
|
||
|
TypeIsPointerType ();
|
||
|
|
||
|
lldb::SBTarget
|
||
|
GetTarget();
|
||
|
|
||
|
lldb::SBProcess
|
||
|
GetProcess();
|
||
|
|
||
|
lldb::SBThread
|
||
|
GetThread();
|
||
|
|
||
|
lldb::SBFrame
|
||
|
GetFrame();
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Find and watch a variable.
|
||
|
It returns an SBWatchpoint, which may be invalid.") Watch;
|
||
|
lldb::SBWatchpoint
|
||
|
Watch (bool resolve_location, bool read, bool write, SBError &error);
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Find and watch the location pointed to by a variable.
|
||
|
It returns an SBWatchpoint, which may be invalid.") WatchPointee;
|
||
|
lldb::SBWatchpoint
|
||
|
WatchPointee (bool resolve_location, bool read, bool write, SBError &error);
|
||
|
|
||
|
bool
|
||
|
GetDescription (lldb::SBStream &description);
|
||
|
|
||
|
bool
|
||
|
GetExpressionPath (lldb::SBStream &description);
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Get an SBData wrapping what this SBValue points to.
|
||
|
|
||
|
This method will dereference the current SBValue, if its
|
||
|
data type is a T* or T[], and extract item_count elements
|
||
|
of type T from it, copying their contents in an SBData.
|
||
|
|
||
|
@param[in] item_idx
|
||
|
The index of the first item to retrieve. For an array
|
||
|
this is equivalent to array[item_idx], for a pointer
|
||
|
to *(pointer + item_idx). In either case, the measurement
|
||
|
unit for item_idx is the sizeof(T) rather than the byte
|
||
|
|
||
|
@param[in] item_count
|
||
|
How many items should be copied into the output. By default
|
||
|
only one item is copied, but more can be asked for.
|
||
|
|
||
|
@return
|
||
|
An SBData with the contents of the copied items, on success.
|
||
|
An empty SBData otherwise.") GetPointeeData;
|
||
|
lldb::SBData
|
||
|
GetPointeeData (uint32_t item_idx = 0,
|
||
|
uint32_t item_count = 1);
|
||
|
|
||
|
%feature("docstring", "
|
||
|
Get an SBData wrapping the contents of this SBValue.
|
||
|
|
||
|
This method will read the contents of this object in memory
|
||
|
and copy them into an SBData for future use.
|
||
|
|
||
|
@return
|
||
|
An SBData with the contents of this SBValue, on success.
|
||
|
An empty SBData otherwise.") GetData;
|
||
|
lldb::SBData
|
||
|
GetData ();
|
||
|
|
||
|
bool
|
||
|
SetData (lldb::SBData &data, lldb::SBError& error);
|
||
|
|
||
|
lldb::addr_t
|
||
|
GetLoadAddress();
|
||
|
|
||
|
lldb::SBAddress
|
||
|
GetAddress();
|
||
|
|
||
|
lldb::SBValue
|
||
|
Persist ();
|
||
|
|
||
|
%feature("docstring", "Returns an expression path for this value."
|
||
|
) GetExpressionPath;
|
||
|
bool
|
||
|
GetExpressionPath (lldb::SBStream &description, bool qualify_cxx_base_classes);
|
||
|
|
||
|
lldb::SBValue
|
||
|
EvaluateExpression(const char *expr) const;
|
||
|
|
||
|
lldb::SBValue
|
||
|
EvaluateExpression(const char *expr,
|
||
|
const SBExpressionOptions &options) const;
|
||
|
|
||
|
lldb::SBValue
|
||
|
EvaluateExpression(const char *expr,
|
||
|
const SBExpressionOptions &options,
|
||
|
const char *name) const;
|
||
|
|
||
|
STRING_EXTENSION(SBValue)
|
||
|
|
||
|
#ifdef SWIGPYTHON
|
||
|
%pythoncode %{
|
||
|
def __get_dynamic__ (self):
|
||
|
'''Helper function for the "SBValue.dynamic" property.'''
|
||
|
return self.GetDynamicValue (eDynamicCanRunTarget)
|
||
|
|
||
|
class children_access(object):
|
||
|
'''A helper object that will lazily hand out thread for a process when supplied an index.'''
|
||
|
|
||
|
def __init__(self, sbvalue):
|
||
|
self.sbvalue = sbvalue
|
||
|
|
||
|
def __len__(self):
|
||
|
if self.sbvalue:
|
||
|
return int(self.sbvalue.GetNumChildren())
|
||
|
return 0
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
if type(key) is int and key < len(self):
|
||
|
return self.sbvalue.GetChildAtIndex(key)
|
||
|
return None
|
||
|
|
||
|
def get_child_access_object(self):
|
||
|
'''An accessor function that returns a children_access() object which allows lazy member variable access from a lldb.SBValue object.'''
|
||
|
return self.children_access (self)
|
||
|
|
||
|
def get_value_child_list(self):
|
||
|
'''An accessor function that returns a list() that contains all children in a lldb.SBValue object.'''
|
||
|
children = []
|
||
|
accessor = self.get_child_access_object()
|
||
|
for idx in range(len(accessor)):
|
||
|
children.append(accessor[idx])
|
||
|
return children
|
||
|
|
||
|
def __iter__(self):
|
||
|
'''Iterate over all child values of a lldb.SBValue object.'''
|
||
|
return lldb_iter(self, 'GetNumChildren', 'GetChildAtIndex')
|
||
|
|
||
|
def __len__(self):
|
||
|
'''Return the number of child values of a lldb.SBValue object.'''
|
||
|
return self.GetNumChildren()
|
||
|
|
||
|
children = property(get_value_child_list, None, doc='''A read only property that returns a list() of lldb.SBValue objects for the children of the value.''')
|
||
|
child = property(get_child_access_object, None, doc='''A read only property that returns an object that can access children of a variable by index (child_value = value.children[12]).''')
|
||
|
name = property(GetName, None, doc='''A read only property that returns the name of this value as a string.''')
|
||
|
type = property(GetType, None, doc='''A read only property that returns a lldb.SBType object that represents the type for this value.''')
|
||
|
size = property(GetByteSize, None, doc='''A read only property that returns the size in bytes of this value.''')
|
||
|
is_in_scope = property(IsInScope, None, doc='''A read only property that returns a boolean value that indicates whether this value is currently lexically in scope.''')
|
||
|
format = property(GetName, SetFormat, doc='''A read/write property that gets/sets the format used for lldb.SBValue().GetValue() for this value. See enumerations that start with "lldb.eFormat".''')
|
||
|
value = property(GetValue, SetValueFromCString, doc='''A read/write property that gets/sets value from a string.''')
|
||
|
value_type = property(GetValueType, None, doc='''A read only property that returns an lldb enumeration value (see enumerations that start with "lldb.eValueType") that represents the type of this value (local, argument, global, register, etc.).''')
|
||
|
changed = property(GetValueDidChange, None, doc='''A read only property that returns a boolean value that indicates if this value has changed since it was last updated.''')
|
||
|
data = property(GetData, None, doc='''A read only property that returns an lldb object (lldb.SBData) that represents the bytes that make up the value for this object.''')
|
||
|
load_addr = property(GetLoadAddress, None, doc='''A read only property that returns the load address of this value as an integer.''')
|
||
|
addr = property(GetAddress, None, doc='''A read only property that returns an lldb.SBAddress that represents the address of this value if it is in memory.''')
|
||
|
deref = property(Dereference, None, doc='''A read only property that returns an lldb.SBValue that is created by dereferencing this value.''')
|
||
|
address_of = property(AddressOf, None, doc='''A read only property that returns an lldb.SBValue that represents the address-of this value.''')
|
||
|
error = property(GetError, None, doc='''A read only property that returns the lldb.SBError that represents the error from the last time the variable value was calculated.''')
|
||
|
summary = property(GetSummary, None, doc='''A read only property that returns the summary for this value as a string''')
|
||
|
description = property(GetObjectDescription, None, doc='''A read only property that returns the language-specific description of this value as a string''')
|
||
|
dynamic = property(__get_dynamic__, None, doc='''A read only property that returns an lldb.SBValue that is created by finding the dynamic type of this value.''')
|
||
|
location = property(GetLocation, None, doc='''A read only property that returns the location of this value as a string.''')
|
||
|
target = property(GetTarget, None, doc='''A read only property that returns the lldb.SBTarget that this value is associated with.''')
|
||
|
process = property(GetProcess, None, doc='''A read only property that returns the lldb.SBProcess that this value is associated with, the returned value might be invalid and should be tested.''')
|
||
|
thread = property(GetThread, None, doc='''A read only property that returns the lldb.SBThread that this value is associated with, the returned value might be invalid and should be tested.''')
|
||
|
frame = property(GetFrame, None, doc='''A read only property that returns the lldb.SBFrame that this value is associated with, the returned value might be invalid and should be tested.''')
|
||
|
num_children = property(GetNumChildren, None, doc='''A read only property that returns the number of child lldb.SBValues that this value has.''')
|
||
|
unsigned = property(GetValueAsUnsigned, None, doc='''A read only property that returns the value of this SBValue as an usigned integer.''')
|
||
|
signed = property(GetValueAsSigned, None, doc='''A read only property that returns the value of this SBValue as a signed integer.''')
|
||
|
|
||
|
def get_expr_path(self):
|
||
|
s = SBStream()
|
||
|
self.GetExpressionPath (s)
|
||
|
return s.GetData()
|
||
|
|
||
|
path = property(get_expr_path, None, doc='''A read only property that returns the expression path that one can use to reach this value in an expression.''')
|
||
|
|
||
|
def synthetic_child_from_expression(self, name, expr, options=None):
|
||
|
if options is None: options = lldb.SBExpressionOptions()
|
||
|
child = self.CreateValueFromExpression(name, expr, options)
|
||
|
child.SetSyntheticChildrenGenerated(True)
|
||
|
return child
|
||
|
|
||
|
def synthetic_child_from_data(self, name, data, type):
|
||
|
child = self.CreateValueFromData(name, data, type)
|
||
|
child.SetSyntheticChildrenGenerated(True)
|
||
|
return child
|
||
|
|
||
|
def synthetic_child_from_address(self, name, addr, type):
|
||
|
child = self.CreateValueFromAddress(name, addr, type)
|
||
|
child.SetSyntheticChildrenGenerated(True)
|
||
|
return child
|
||
|
|
||
|
def __eol_test(val):
|
||
|
"""Default function for end of list test takes an SBValue object.
|
||
|
|
||
|
Return True if val is invalid or it corresponds to a null pointer.
|
||
|
Otherwise, return False.
|
||
|
"""
|
||
|
if not val or val.GetValueAsUnsigned() == 0:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
# ==================================================
|
||
|
# Iterator for lldb.SBValue treated as a linked list
|
||
|
# ==================================================
|
||
|
def linked_list_iter(self, next_item_name, end_of_list_test=__eol_test):
|
||
|
"""Generator adaptor to support iteration for SBValue as a linked list.
|
||
|
|
||
|
linked_list_iter() is a special purpose iterator to treat the SBValue as
|
||
|
the head of a list data structure, where you specify the child member
|
||
|
name which points to the next item on the list and you specify the
|
||
|
end-of-list test function which takes an SBValue for an item and returns
|
||
|
True if EOL is reached and False if not.
|
||
|
|
||
|
linked_list_iter() also detects infinite loop and bails out early.
|
||
|
|
||
|
The end_of_list_test arg, if omitted, defaults to the __eol_test
|
||
|
function above.
|
||
|
|
||
|
For example,
|
||
|
|
||
|
# Get Frame #0.
|
||
|
...
|
||
|
|
||
|
# Get variable 'task_head'.
|
||
|
task_head = frame0.FindVariable('task_head')
|
||
|
...
|
||
|
|
||
|
for t in task_head.linked_list_iter('next'):
|
||
|
print t
|
||
|
"""
|
||
|
if end_of_list_test(self):
|
||
|
return
|
||
|
item = self
|
||
|
visited = set()
|
||
|
try:
|
||
|
while not end_of_list_test(item) and not item.GetValueAsUnsigned() in visited:
|
||
|
visited.add(item.GetValueAsUnsigned())
|
||
|
yield item
|
||
|
# Prepare for the next iteration.
|
||
|
item = item.GetChildMemberWithName(next_item_name)
|
||
|
except:
|
||
|
# Exception occurred. Stop the generator.
|
||
|
pass
|
||
|
|
||
|
return
|
||
|
%}
|
||
|
#endif
|
||
|
|
||
|
};
|
||
|
|
||
|
} // namespace lldb
|