forked from OSchip/llvm-project
Public API changes:
- Completely new implementation of SBType - Various enhancements in several other classes Python synthetic children providers for std::vector<T>, std::list<T> and std::map<K,V>: - these return the actual elements into the container as the children of the container - basic template name parsing that works (hopefully) on both Clang and GCC - find them in examples/synthetic and in the test suite in functionalities/data-formatter/data-formatter-python-synth New summary string token ${svar : - the syntax is just the same as in ${var but this new token lets you read the values coming from the synthetic children provider instead of the actual children - Python providers above provide a synthetic child len that returns the number of elements into the container Full bug fix for the issue in which getting byte size for a non-complete type would crash LLDB Several other fixes, including: - inverted the order of arguments in the ClangASTType constructor - EvaluationPoint now only returns SharedPointer's to Target and Process - the help text for several type subcommands now correctly indicates argument-less options as such llvm-svn: 136504
This commit is contained in:
parent
ce0ceebb1c
commit
6f3533fb1d
|
@ -0,0 +1,61 @@
|
|||
import re
|
||||
class StdListSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def num_children(self):
|
||||
next_val = int(self.Mnext.GetValue(),0)
|
||||
prev_val = int(self.Mprev.GetValue(),0)
|
||||
if next_val == 0:
|
||||
return 0;
|
||||
if next_val == self.Mnode_address:
|
||||
return 0;
|
||||
if next_val == prev_val:
|
||||
return 1;
|
||||
size = 2
|
||||
current = self.Mnext
|
||||
while int(current.GetChildMemberWithName('_M_next').GetValue(),0) != self.Mnode_address:
|
||||
size = size + 1;
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
return (size - 1)
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index
|
||||
current = self.Mnext;
|
||||
while offset > 0:
|
||||
current = current.GetChildMemberWithName('_M_next');
|
||||
offset = offset - 1;
|
||||
return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
|
||||
def extract_type_name(self,name):
|
||||
self.type_name = name[16:]
|
||||
index = 2
|
||||
count_of_template = 1
|
||||
while index < len(self.type_name):
|
||||
if self.type_name[index] == '<':
|
||||
count_of_template = count_of_template + 1;
|
||||
elif self.type_name[index] == '>':
|
||||
count_of_template = count_of_template - 1;
|
||||
elif self.type_name[index] == ',' and count_of_template == 1:
|
||||
self.type_name = self.type_name[:index]
|
||||
break
|
||||
index = index + 1;
|
||||
self.type_name_nospaces = self.type_name.replace(", ", ",")
|
||||
def update(self):
|
||||
self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.Mnode = self.Mimpl.GetChildMemberWithName('_M_node')
|
||||
self.extract_type_name(self.Mimpl.GetType().GetName())
|
||||
self.Mnode_address = int(self.valobj.AddressOf().GetValue(), 0)
|
||||
self.Mnext = self.Mnode.GetChildMemberWithName('_M_next')
|
||||
self.Mprev = self.Mnode.GetChildMemberWithName('_M_prev')
|
||||
self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name)
|
||||
# tries to fight against a difference in formatting type names between gcc and clang
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name_nospaces)
|
||||
self.data_size = self.data_type.GetByteSize()
|
|
@ -0,0 +1,103 @@
|
|||
import re
|
||||
class StdMapSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def update(self):
|
||||
self.Mt = self.valobj.GetChildMemberWithName('_M_t')
|
||||
self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
|
||||
self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
|
||||
# from libstdc++ implementation of _M_root for rbtree
|
||||
self.Mroot = self.Mheader.GetChildMemberWithName('_M_parent')
|
||||
# the stuff into the tree is actually a std::pair<const key, value>
|
||||
# life would be much easier if gcc had a coherent way to print out
|
||||
# template names in debug info
|
||||
self.expand_clang_type_name()
|
||||
self.expand_gcc_type_name()
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.clang_type_name)
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.gcc_type_name)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
self.skip_size = self.Mheader.GetType().GetByteSize()
|
||||
def expand_clang_type_name(self):
|
||||
type_name = self.Mimpl.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
index = index + 1;
|
||||
self.clang_type_name = type_name
|
||||
def expand_gcc_type_name(self):
|
||||
type_name = self.Mt.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
elif type_name[index] == ' ' and template_count == 1 and type_name[index-1] == ',':
|
||||
type_name = type_name[0:index] + type_name[index+1:]
|
||||
index = index - 1
|
||||
index = index + 1;
|
||||
self.gcc_type_name = type_name
|
||||
def num_children(self):
|
||||
root_ptr_val = self.node_ptr_value(self.Mroot)
|
||||
if root_ptr_val == 0:
|
||||
return 0;
|
||||
return int(self.Mimpl.GetChildMemberWithName('_M_node_count').GetValue(), 0);
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index
|
||||
current = self.left(self.Mheader);
|
||||
while offset > 0:
|
||||
current = self.increment_node(current)
|
||||
offset = offset - 1;
|
||||
# skip all the base stuff and get at the data
|
||||
return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
|
||||
# utility functions
|
||||
def node_ptr_value(self,node):
|
||||
return int(node.GetValue(),0);
|
||||
def right(self,node):
|
||||
return node.GetChildMemberWithName("_M_right");
|
||||
def left(self,node):
|
||||
return node.GetChildMemberWithName("_M_left");
|
||||
def parent(self,node):
|
||||
return node.GetChildMemberWithName("_M_parent");
|
||||
# from libstdc++ implementation of iterator for rbtree
|
||||
def increment_node(self,node):
|
||||
if self.node_ptr_value(self.right(node)) != 0:
|
||||
x = self.right(node);
|
||||
while self.node_ptr_value(self.left(x)) != 0:
|
||||
x = self.left(x);
|
||||
return x;
|
||||
else:
|
||||
x = node;
|
||||
y = self.parent(x)
|
||||
while(self.node_ptr_value(x) == self.node_ptr_value(self.right(y))):
|
||||
x = y;
|
||||
y = self.parent(y);
|
||||
if self.node_ptr_value(self.right(x)) != self.node_ptr_value(y):
|
||||
x = y;
|
||||
return x;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
class StdVectorSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def num_children(self):
|
||||
start_val = int(self.Mstart.GetValue(),0)
|
||||
finish_val = int(self.Mfinish.GetValue(),0)
|
||||
return (finish_val-start_val)/self.data_size
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index * self.data_size
|
||||
return self.Mstart.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
|
||||
def update(self):
|
||||
self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.Mstart = self.Mimpl.GetChildMemberWithName('_M_start')
|
||||
self.Mfinish = self.Mimpl.GetChildMemberWithName('_M_finish')
|
||||
self.data_type = self.Mstart.GetType().GetPointeeType()
|
||||
self.data_size = self.data_type.GetByteSize()
|
|
@ -56,6 +56,8 @@ class SBSymbolContext;
|
|||
class SBSymbolContextList;
|
||||
class SBTarget;
|
||||
class SBThread;
|
||||
class SBType;
|
||||
class SBTypeList;
|
||||
class SBValue;
|
||||
class SBValueList;
|
||||
|
||||
|
|
|
@ -153,6 +153,11 @@ public:
|
|||
const char *name,
|
||||
uint32_t max_matches);
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* name);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBType.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
|
@ -342,6 +343,12 @@ public:
|
|||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* type);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
|
@ -367,6 +374,7 @@ protected:
|
|||
friend class SBProcess;
|
||||
friend class SBSymbol;
|
||||
friend class SBModule;
|
||||
friend class SBValue;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors are private, use static Target::Create function to
|
||||
|
|
|
@ -11,129 +11,110 @@
|
|||
#define LLDB_SBType_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/Symbol/ClangASTType.h"
|
||||
#include "lldb/Symbol/Type.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBTypeMember;
|
||||
class SBTypeList;
|
||||
|
||||
class SBType
|
||||
{
|
||||
public:
|
||||
|
||||
SBType (void *ast = NULL, void *clang_type = NULL);
|
||||
|
||||
SBType (const SBType &rhs);
|
||||
|
||||
~SBType ();
|
||||
|
||||
#ifndef SWIG
|
||||
const SBType &
|
||||
operator =(const SBType &rhs);
|
||||
const lldb::SBType &
|
||||
operator = (const lldb::SBType &rhs);
|
||||
|
||||
bool
|
||||
operator == (const lldb::SBType &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBType &rhs) const;
|
||||
|
||||
lldb_private::TypeImpl &
|
||||
ref ();
|
||||
|
||||
const lldb_private::TypeImpl &
|
||||
ref () const;
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
size_t
|
||||
GetByteSize() const;
|
||||
|
||||
bool
|
||||
IsValid();
|
||||
|
||||
const char *
|
||||
GetName();
|
||||
|
||||
uint64_t
|
||||
GetByteSize();
|
||||
|
||||
#ifndef SWIG
|
||||
lldb::Encoding
|
||||
GetEncoding (uint32_t &count);
|
||||
#endif
|
||||
|
||||
uint64_t
|
||||
GetNumberChildren (bool omit_empty_base_classes);
|
||||
|
||||
IsPointerType() const;
|
||||
|
||||
bool
|
||||
GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member);
|
||||
|
||||
uint32_t
|
||||
GetChildIndexForName (bool omit_empty_base_classes, const char *name);
|
||||
|
||||
bool
|
||||
IsAPointerType ();
|
||||
|
||||
IsReferenceType() const;
|
||||
|
||||
SBType
|
||||
GetPointeeType ();
|
||||
|
||||
static bool
|
||||
IsPointerType (void *opaque_type);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
GetPointerType() const;
|
||||
|
||||
SBType
|
||||
GetPointeeType() const;
|
||||
|
||||
SBType
|
||||
GetReferenceType() const;
|
||||
|
||||
SBType
|
||||
GetDereferencedType() const;
|
||||
|
||||
SBType
|
||||
GetBasicType(lldb::BasicType type) const;
|
||||
|
||||
const char*
|
||||
GetName();
|
||||
|
||||
protected:
|
||||
void *m_ast;
|
||||
void *m_type;
|
||||
std::auto_ptr<lldb_private::TypeImpl> m_opaque_ap;
|
||||
|
||||
friend class SBModule;
|
||||
friend class SBTarget;
|
||||
friend class SBValue;
|
||||
friend class SBTypeList;
|
||||
|
||||
SBType (clang::ASTContext*, clang_type_t);
|
||||
SBType (lldb_private::ClangASTType type);
|
||||
SBType (lldb::TypeSP type);
|
||||
SBType (lldb_private::TypeImpl impl);
|
||||
SBType();
|
||||
|
||||
};
|
||||
|
||||
class SBTypeMember
|
||||
|
||||
class SBTypeList
|
||||
{
|
||||
public:
|
||||
|
||||
SBTypeMember ();
|
||||
SBTypeList();
|
||||
|
||||
SBTypeList(const SBTypeList& rhs);
|
||||
|
||||
SBTypeList&
|
||||
operator = (const SBTypeList& rhs);
|
||||
|
||||
SBTypeMember (const SBTypeMember &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBTypeMember&
|
||||
operator =(const SBTypeMember &rhs);
|
||||
#endif
|
||||
|
||||
~SBTypeMember ();
|
||||
|
||||
bool
|
||||
IsBaseClass ();
|
||||
|
||||
bool
|
||||
IsValid ();
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
bool
|
||||
IsBitfield ();
|
||||
AppendType(SBType type);
|
||||
|
||||
size_t
|
||||
GetBitfieldWidth ();
|
||||
SBType
|
||||
GetTypeAtIndex(int index) const;
|
||||
|
||||
size_t
|
||||
GetBitfieldOffset ();
|
||||
|
||||
size_t
|
||||
GetOffset ();
|
||||
|
||||
const char *
|
||||
GetName ();
|
||||
|
||||
SBType
|
||||
GetType();
|
||||
|
||||
SBType
|
||||
GetParentType();
|
||||
|
||||
void
|
||||
SetName (const char *name);
|
||||
|
||||
protected:
|
||||
friend class SBType;
|
||||
|
||||
void *m_ast;
|
||||
void *m_parent_type;
|
||||
void *m_member_type;
|
||||
char *m_member_name;
|
||||
int32_t m_offset;
|
||||
uint32_t m_bit_size;
|
||||
uint32_t m_bit_offset;
|
||||
bool m_is_base_class;
|
||||
bool m_is_deref_of_paremt;
|
||||
int
|
||||
GetSize() const;
|
||||
|
||||
~SBTypeList();
|
||||
|
||||
private:
|
||||
std::auto_ptr<lldb_private::TypeListImpl> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBType_h_
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define LLDB_SBValue_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBType.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -105,6 +106,18 @@ public:
|
|||
|
||||
lldb::SBValue
|
||||
GetChildAtIndex (uint32_t idx);
|
||||
|
||||
lldb::SBValue
|
||||
CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type);
|
||||
|
||||
lldb::SBValue
|
||||
Cast(const SBType& type);
|
||||
|
||||
lldb::SBValue
|
||||
CreateValueFromExpression (const char *name, const char* expression);
|
||||
|
||||
lldb::SBValue
|
||||
CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get a child value by index from a value.
|
||||
|
@ -179,6 +192,9 @@ public:
|
|||
// Expands nested expressions like .a->b[0].c[1]->d
|
||||
lldb::SBValue
|
||||
GetValueForExpressionPath(const char* expr_path);
|
||||
|
||||
lldb::SBValue
|
||||
AddressOf();
|
||||
|
||||
uint32_t
|
||||
GetNumChildren ();
|
||||
|
@ -186,12 +202,26 @@ public:
|
|||
void *
|
||||
GetOpaqueType();
|
||||
|
||||
lldb::SBTarget
|
||||
GetTarget();
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess();
|
||||
|
||||
lldb::SBThread
|
||||
GetThread();
|
||||
|
||||
lldb::SBFrame
|
||||
GetFrame();
|
||||
|
||||
lldb::SBValue
|
||||
Dereference ();
|
||||
|
||||
bool
|
||||
TypeIsPointerType ();
|
||||
|
||||
SBType
|
||||
GetType();
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
|
|
@ -113,6 +113,9 @@ public:
|
|||
virtual uint32_t
|
||||
GetIndexOfChildWithName (const ConstString &name) = 0;
|
||||
|
||||
virtual void
|
||||
Update() = 0;
|
||||
|
||||
typedef lldb::SharedPtr<SyntheticChildrenFrontEnd>::Type SharedPointer;
|
||||
|
||||
};
|
||||
|
@ -238,6 +241,9 @@ public:
|
|||
return m_backend->GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx).c_str(), can_create);
|
||||
}
|
||||
|
||||
virtual void
|
||||
Update() {}
|
||||
|
||||
virtual uint32_t
|
||||
GetIndexOfChildWithName (const ConstString &name)
|
||||
{
|
||||
|
@ -328,6 +334,15 @@ public:
|
|||
|
||||
return sb_ptr->m_opaque_sp;
|
||||
}
|
||||
|
||||
virtual void
|
||||
Update()
|
||||
{
|
||||
if (m_wrapper == NULL || m_interpreter == NULL)
|
||||
return;
|
||||
|
||||
m_interpreter->UpdateSynthProviderInstance(m_wrapper);
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetIndexOfChildWithName (const ConstString &name)
|
||||
|
|
|
@ -225,7 +225,7 @@ public:
|
|||
MapValueType& entry,
|
||||
uint32_t* why = NULL)
|
||||
{
|
||||
uint32_t value = lldb::eFormatterDirectChoice;
|
||||
uint32_t value = lldb::eFormatterChoiceCriterionDirectChoice;
|
||||
clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType());
|
||||
bool ret = Get(vobj, type, entry, value);
|
||||
if (ret)
|
||||
|
@ -315,7 +315,7 @@ private:
|
|||
log->Printf("stripping reference");
|
||||
if (Get(vobj,type.getNonReferenceType(),entry, reason) && !entry->m_skip_references)
|
||||
{
|
||||
reason |= lldb::eFormatterStrippedPointerReference;
|
||||
reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ private:
|
|||
log->Printf("stripping pointer");
|
||||
if (Get(vobj, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
|
||||
{
|
||||
reason |= lldb::eFormatterStrippedPointerReference;
|
||||
reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ private:
|
|||
return false;
|
||||
if (Get(*target, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
|
||||
{
|
||||
reason |= lldb::eFormatterStrippedPointerReference;
|
||||
reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ private:
|
|||
clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
|
||||
if (Get(vobj, ivar_qual_type, entry, reason) && entry->m_cascades)
|
||||
{
|
||||
reason |= lldb::eFormatterNavigatedBaseClasses;
|
||||
reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ private:
|
|||
{
|
||||
if ((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
|
||||
{
|
||||
reason |= lldb::eFormatterNavigatedBaseClasses;
|
||||
reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ private:
|
|||
{
|
||||
if ((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
|
||||
{
|
||||
reason |= lldb::eFormatterNavigatedBaseClasses;
|
||||
reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ private:
|
|||
log->Printf("stripping typedef");
|
||||
if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry, reason)) && entry->m_cascades)
|
||||
{
|
||||
reason |= lldb::eFormatterNavigatedTypedefs;
|
||||
reason |= lldb::eFormatterChoiceCriterionNavigatedTypedefs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ public:
|
|||
return true;
|
||||
bool regex = RegexSummary()->Get(vobj, entry, reason);
|
||||
if (regex && reason)
|
||||
*reason |= lldb::eFormatterRegularExpressionSummary;
|
||||
*reason |= lldb::eFormatterChoiceCriterionRegularExpressionSummary;
|
||||
return regex;
|
||||
}
|
||||
|
||||
|
@ -775,7 +775,7 @@ public:
|
|||
lldb::SummaryFormatSP current_format;
|
||||
if (!category->Get(vobj, current_format, &reason_why))
|
||||
continue;
|
||||
if (reason_why == lldb::eFormatterDirectChoice)
|
||||
if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
|
||||
{
|
||||
entry = current_format;
|
||||
return true;
|
||||
|
@ -806,7 +806,7 @@ public:
|
|||
lldb::SyntheticChildrenSP current_format;
|
||||
if (!category->Get(vobj, current_format, &reason_why))
|
||||
continue;
|
||||
if (reason_why == lldb::eFormatterDirectChoice)
|
||||
if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
|
||||
{
|
||||
entry = current_format;
|
||||
return true;
|
||||
|
|
|
@ -686,6 +686,15 @@ protected:
|
|||
SetArchitecture (const ArchSpec &new_arch);
|
||||
|
||||
private:
|
||||
|
||||
uint32_t
|
||||
FindTypes_Impl (const SymbolContext& sc,
|
||||
const ConstString &name,
|
||||
bool append,
|
||||
uint32_t max_matches,
|
||||
TypeList& types);
|
||||
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (Module);
|
||||
};
|
||||
|
||||
|
|
|
@ -440,6 +440,13 @@ protected:
|
|||
collection m_modules; ///< The collection of modules.
|
||||
mutable Mutex m_modules_mutex;
|
||||
|
||||
private:
|
||||
uint32_t
|
||||
FindTypes_Impl (const SymbolContext& sc,
|
||||
const ConstString &name,
|
||||
bool append,
|
||||
uint32_t max_matches,
|
||||
TypeList& types);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -197,17 +197,17 @@ public:
|
|||
|
||||
ExecutionContextScope *
|
||||
GetExecutionContextScope ();
|
||||
|
||||
Target *
|
||||
GetTarget () const
|
||||
|
||||
lldb::TargetSP
|
||||
GetTargetSP () const
|
||||
{
|
||||
return m_target_sp.get();
|
||||
return m_target_sp;
|
||||
}
|
||||
|
||||
Process *
|
||||
GetProcess () const
|
||||
lldb::ProcessSP
|
||||
GetProcessSP () const
|
||||
{
|
||||
return m_process_sp.get();
|
||||
return m_process_sp;
|
||||
}
|
||||
|
||||
// Set the EvaluationPoint to the values in exe_scope,
|
||||
|
@ -548,6 +548,9 @@ public:
|
|||
lldb::ValueObjectSP
|
||||
GetSyntheticExpressionPathChild(const char* expression, bool can_create);
|
||||
|
||||
virtual lldb::ValueObjectSP
|
||||
GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create);
|
||||
|
||||
lldb::ValueObjectSP
|
||||
GetDynamicValue (lldb::DynamicValueType valueType);
|
||||
|
||||
|
@ -755,7 +758,8 @@ protected:
|
|||
m_is_deref_of_parent:1,
|
||||
m_is_array_item_for_pointer:1,
|
||||
m_is_bitfield_for_scalar:1,
|
||||
m_is_expression_path_child:1;
|
||||
m_is_expression_path_child:1,
|
||||
m_is_child_at_offset:1;
|
||||
|
||||
// used to prevent endless looping into GetpPrintableRepresentation()
|
||||
uint32_t m_dump_printable_counter;
|
||||
|
@ -805,12 +809,6 @@ protected:
|
|||
virtual uint32_t
|
||||
CalculateNumChildren() = 0;
|
||||
|
||||
void
|
||||
SetName (const char *name);
|
||||
|
||||
void
|
||||
SetName (const ConstString &name);
|
||||
|
||||
void
|
||||
SetNumChildren (uint32_t num_children);
|
||||
|
||||
|
@ -824,6 +822,10 @@ protected:
|
|||
ClearUserVisibleData();
|
||||
|
||||
public:
|
||||
|
||||
void
|
||||
SetName (const ConstString &name);
|
||||
|
||||
lldb::addr_t
|
||||
GetPointerValue (AddressType &address_type,
|
||||
bool scalar_is_load_address);
|
||||
|
|
|
@ -38,10 +38,11 @@ public:
|
|||
const char *session_dictionary_name,
|
||||
const lldb::ValueObjectSP& valobj_sp);
|
||||
|
||||
typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor);
|
||||
typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
|
||||
typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
|
||||
typedef lldb::SBValue* (*SWIGPythonCastPyObjectToSBValue) (void* data);
|
||||
typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor);
|
||||
typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
|
||||
typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
|
||||
typedef lldb::SBValue* (*SWIGPythonCastPyObjectToSBValue) (void* data);
|
||||
typedef void (*SWIGPythonUpdateSynthProviderInstance) (void* data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -157,6 +158,11 @@ public:
|
|||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
virtual void
|
||||
UpdateSynthProviderInstance (void* implementor)
|
||||
{
|
||||
}
|
||||
|
||||
virtual lldb::SBValue*
|
||||
CastPyObjectToSBValue (void* data)
|
||||
{
|
||||
|
@ -183,7 +189,8 @@ public:
|
|||
SWIGPythonCalculateNumChildren python_swig_calc_children,
|
||||
SWIGPythonGetChildAtIndex python_swig_get_child_index,
|
||||
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue);
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
|
||||
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider);
|
||||
|
||||
static void
|
||||
TerminateInterpreter ();
|
||||
|
|
|
@ -72,6 +72,9 @@ public:
|
|||
virtual int
|
||||
GetIndexOfChildWithName (void *implementor, const char* child_name);
|
||||
|
||||
virtual void
|
||||
UpdateSynthProviderInstance (void* implementor);
|
||||
|
||||
virtual lldb::SBValue*
|
||||
CastPyObjectToSBValue (void* data);
|
||||
|
||||
|
@ -127,7 +130,8 @@ public:
|
|||
SWIGPythonCalculateNumChildren python_swig_calc_children,
|
||||
SWIGPythonGetChildAtIndex python_swig_get_child_index,
|
||||
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalu);
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
|
||||
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -29,9 +29,10 @@ namespace lldb_private {
|
|||
class ClangASTType
|
||||
{
|
||||
public:
|
||||
ClangASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) :
|
||||
m_type (type),
|
||||
m_ast (ast_context)
|
||||
|
||||
ClangASTType (clang::ASTContext *ast_context, lldb::clang_type_t type) :
|
||||
m_type (type),
|
||||
m_ast (ast_context)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -188,7 +189,7 @@ public:
|
|||
GetFormat (lldb::clang_type_t opaque_clang_qual_type);
|
||||
|
||||
uint32_t
|
||||
GetTypeByteSize();
|
||||
GetTypeByteSize() const;
|
||||
|
||||
static uint32_t
|
||||
GetTypeByteSize(clang::ASTContext *ast_context,
|
||||
|
|
|
@ -21,7 +21,7 @@ template <unsigned int C> class TaggedASTType : public ClangASTType
|
|||
{
|
||||
public:
|
||||
TaggedASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) :
|
||||
ClangASTType(type, ast_context) { }
|
||||
ClangASTType(ast_context, type) { }
|
||||
|
||||
TaggedASTType (const TaggedASTType<C> &tw) :
|
||||
ClangASTType(tw) { }
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <set>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
|
||||
class Type : public UserID
|
||||
{
|
||||
public:
|
||||
|
@ -293,6 +293,99 @@ private:
|
|||
ConstString m_type_name;
|
||||
};
|
||||
|
||||
// the two classes here are used by the public API as a backend to
|
||||
// the SBType and SBTypeList classes
|
||||
|
||||
class TypeImpl
|
||||
{
|
||||
private:
|
||||
std::auto_ptr<ClangASTType> m_clang_ast_type;
|
||||
lldb::TypeSP m_lldb_type;
|
||||
|
||||
public:
|
||||
|
||||
TypeImpl() :
|
||||
m_clang_ast_type(NULL),
|
||||
m_lldb_type(lldb::TypeSP())
|
||||
{}
|
||||
|
||||
TypeImpl(const TypeImpl& rhs) :
|
||||
m_clang_ast_type(rhs.m_clang_ast_type.get()),
|
||||
m_lldb_type(rhs.m_lldb_type)
|
||||
{}
|
||||
|
||||
TypeImpl&
|
||||
operator = (const TypeImpl& rhs);
|
||||
|
||||
bool
|
||||
operator == (const TypeImpl& rhs)
|
||||
{
|
||||
return (m_clang_ast_type.get() == rhs.m_clang_ast_type.get()) &&
|
||||
(m_lldb_type.get() == rhs.m_lldb_type.get());
|
||||
}
|
||||
|
||||
bool
|
||||
operator != (const TypeImpl& rhs)
|
||||
{
|
||||
return (m_clang_ast_type.get() != rhs.m_clang_ast_type.get()) ||
|
||||
(m_lldb_type.get() != rhs.m_lldb_type.get());
|
||||
}
|
||||
|
||||
TypeImpl(const lldb_private::ClangASTType& type);
|
||||
|
||||
TypeImpl(lldb::TypeSP type);
|
||||
|
||||
bool
|
||||
IsValid()
|
||||
{
|
||||
return (m_lldb_type.get() != NULL) || (m_clang_ast_type.get() != NULL);
|
||||
}
|
||||
|
||||
lldb_private::ClangASTType*
|
||||
GetClangASTType()
|
||||
{
|
||||
return m_clang_ast_type.get();
|
||||
}
|
||||
|
||||
clang::ASTContext*
|
||||
GetASTContext();
|
||||
|
||||
lldb::clang_type_t
|
||||
GetOpaqueQualType();
|
||||
};
|
||||
|
||||
class TypeListImpl
|
||||
{
|
||||
public:
|
||||
TypeListImpl() :
|
||||
m_content() {}
|
||||
|
||||
void
|
||||
AppendType(TypeImpl& type)
|
||||
{
|
||||
m_content.push_back(type);
|
||||
}
|
||||
|
||||
TypeImpl
|
||||
GetTypeAtIndex(int index)
|
||||
{
|
||||
if (index < 0 || index >= GetSize())
|
||||
return TypeImpl();
|
||||
|
||||
return m_content[index];
|
||||
}
|
||||
|
||||
int
|
||||
GetSize()
|
||||
{
|
||||
return m_content.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<TypeImpl> m_content;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_Type_h_
|
||||
|
|
|
@ -496,19 +496,52 @@ namespace lldb {
|
|||
eFunctionNameTypeSelector = (1u << 5) // Find function by selector name (ObjC) names
|
||||
} FunctionNameType;
|
||||
|
||||
// this enum determines how a FormatNavigator picked a specific format for a datatype
|
||||
// these values can be used together (e.g. eFormatterStrippedPointerReference | eFormatterNavigatedBaseClasses
|
||||
// if you went from DerivedType& to BaseType to find a valid format)
|
||||
//----------------------------------------------------------------------
|
||||
// Ways that the FormatManager picks a particular format for a type
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum FormatterChoiceCriterion
|
||||
{
|
||||
eFormatterDirectChoice = 0x00000000,
|
||||
eFormatterStrippedPointerReference = 0x00000001,
|
||||
eFormatterNavigatedTypedefs = 0x00000002,
|
||||
eFormatterNavigatedBaseClasses = 0x00000004,
|
||||
eFormatterRegularExpressionSummary = 0x00000008
|
||||
eFormatterChoiceCriterionDirectChoice = 0x00000000,
|
||||
eFormatterChoiceCriterionStrippedPointerReference = 0x00000001,
|
||||
eFormatterChoiceCriterionNavigatedTypedefs = 0x00000002,
|
||||
eFormatterChoiceCriterionNavigatedBaseClasses = 0x00000004,
|
||||
eFormatterChoiceCriterionRegularExpressionSummary = 0x00000008
|
||||
} FormatterChoiceCriterion;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Basic types enumeration for the public API SBType::GetBasicType()
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum BasicType
|
||||
{
|
||||
eBasicTypeInvalid = 0,
|
||||
eBasicTypeVoid = 1,
|
||||
eBasicTypeChar,
|
||||
eBasicTypeSignedChar,
|
||||
eBasicTypeWChar,
|
||||
eBasicTypeChar16,
|
||||
eBasicTypeChar32,
|
||||
eBasicTypeShort,
|
||||
eBasicTypeUnsignedShort,
|
||||
eBasicTypeInt,
|
||||
eBasicTypeUnsignedInt,
|
||||
eBasicTypeLong,
|
||||
eBasicTypeUnsignedLong,
|
||||
eBasicTypeLongLong,
|
||||
eBasicTypeUnsignedLongLong,
|
||||
eBasicTypeInt128,
|
||||
eBasicTypeUnsignedInt128,
|
||||
eBasicTypeBool,
|
||||
eBasicTypeFloat,
|
||||
eBasicTypeDouble,
|
||||
eBasicTypeLongDouble,
|
||||
eBasicTypeFloatComplex,
|
||||
eBasicTypeDoubleComplex,
|
||||
eBasicTypeLongDoubleComplex,
|
||||
eBasicTypeObjCID,
|
||||
eBasicTypeObjCClass,
|
||||
eBasicTypeObjCSel
|
||||
} BasicType;
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
|
||||
|
|
|
@ -137,6 +137,13 @@ public:
|
|||
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
|
||||
bool append,
|
||||
lldb::SBSymbolContextList& sc_list);
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* name);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
|
||||
%feature("docstring", "
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -320,6 +320,12 @@ public:
|
|||
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
|
||||
bool append,
|
||||
lldb::SBSymbolContextList& sc_list);
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* type);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
%feature("docstring", "
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -9,91 +9,63 @@
|
|||
|
||||
namespace lldb {
|
||||
|
||||
class SBTypeMember;
|
||||
|
||||
class SBType
|
||||
{
|
||||
public:
|
||||
|
||||
SBType (void *ast = NULL, void *clang_type = NULL);
|
||||
class SBType
|
||||
{
|
||||
public:
|
||||
|
||||
SBType (const SBType &rhs);
|
||||
|
||||
~SBType ();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
size_t
|
||||
GetByteSize() const;
|
||||
|
||||
bool
|
||||
IsPointerType() const;
|
||||
|
||||
bool
|
||||
IsReferenceType() const;
|
||||
|
||||
SBType
|
||||
GetPointerType() const;
|
||||
|
||||
SBType
|
||||
GetPointeeType() const;
|
||||
|
||||
SBType
|
||||
GetReferenceType() const;
|
||||
|
||||
SBType
|
||||
GetDereferencedType() const;
|
||||
|
||||
SBType
|
||||
GetBasicType(lldb::BasicType type) const;
|
||||
|
||||
const char*
|
||||
GetName();
|
||||
};
|
||||
|
||||
SBType (const SBType &rhs);
|
||||
|
||||
~SBType ();
|
||||
|
||||
bool
|
||||
IsValid();
|
||||
|
||||
const char *
|
||||
GetName();
|
||||
|
||||
uint64_t
|
||||
GetByteSize();
|
||||
|
||||
uint64_t
|
||||
GetNumberChildren (bool omit_empty_base_classes);
|
||||
|
||||
bool
|
||||
GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member);
|
||||
|
||||
uint32_t
|
||||
GetChildIndexForName (bool omit_empty_base_classes, const char *name);
|
||||
|
||||
bool
|
||||
IsAPointerType ();
|
||||
|
||||
SBType
|
||||
GetPointeeType ();
|
||||
|
||||
static bool
|
||||
IsPointerType (void *opaque_type);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
};
|
||||
|
||||
class SBTypeMember
|
||||
{
|
||||
public:
|
||||
|
||||
SBTypeMember ();
|
||||
|
||||
SBTypeMember (const SBTypeMember &rhs);
|
||||
|
||||
~SBTypeMember ();
|
||||
|
||||
bool
|
||||
IsBaseClass ();
|
||||
|
||||
bool
|
||||
IsValid ();
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
bool
|
||||
IsBitfield ();
|
||||
|
||||
size_t
|
||||
GetBitfieldWidth ();
|
||||
|
||||
size_t
|
||||
GetBitfieldOffset ();
|
||||
|
||||
size_t
|
||||
GetOffset ();
|
||||
|
||||
const char *
|
||||
GetName ();
|
||||
|
||||
SBType
|
||||
GetType();
|
||||
|
||||
SBType
|
||||
GetParentType();
|
||||
|
||||
void
|
||||
SetName (const char *name);
|
||||
};
|
||||
class SBTypeList
|
||||
{
|
||||
public:
|
||||
SBTypeList();
|
||||
|
||||
void
|
||||
AppendType(SBType type);
|
||||
|
||||
SBType
|
||||
GetTypeAtIndex(int index);
|
||||
|
||||
int
|
||||
GetSize();
|
||||
|
||||
~SBTypeList();
|
||||
|
||||
private:
|
||||
std::auto_ptr<SBTypeListImpl> m_content;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
|
|
@ -203,7 +203,22 @@ public:
|
|||
GetChildAtIndex (uint32_t idx,
|
||||
lldb::DynamicValueType use_dynamic,
|
||||
bool can_create_synthetic);
|
||||
|
||||
lldb::SBValue
|
||||
CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type);
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::Cast(const SBType& type);
|
||||
|
||||
lldb::SBValue
|
||||
CreateValueFromExpression (const char *name, const char* expression);
|
||||
|
||||
lldb::SBValue
|
||||
CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type);
|
||||
|
||||
lldb::SBType
|
||||
GetType();
|
||||
|
||||
%feature("docstring", "
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the child member index.
|
||||
|
@ -257,13 +272,27 @@ public:
|
|||
void *
|
||||
GetOpaqueType();
|
||||
|
||||
|
||||
lldb::SBValue
|
||||
Dereference ();
|
||||
|
||||
lldb::SBValue
|
||||
AddressOf();
|
||||
|
||||
bool
|
||||
TypeIsPointerType ();
|
||||
|
||||
lldb::SBTarget
|
||||
GetTarget();
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess();
|
||||
|
||||
lldb::SBThread
|
||||
GetThread();
|
||||
|
||||
lldb::SBFrame
|
||||
GetFrame();
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
|
|
|
@ -331,10 +331,11 @@ LLDBSwigPythonCreateSyntheticProvider
|
|||
);
|
||||
|
||||
|
||||
extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
|
||||
extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
|
||||
extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
|
||||
extern "C" lldb::SBValue* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
|
||||
extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
|
||||
extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
|
||||
extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
|
||||
extern "C" lldb::SBValue* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
|
||||
extern "C" void LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
|
||||
|
||||
extern "C" void init_lldb(void);
|
||||
|
||||
|
@ -352,6 +353,7 @@ SBCommandInterpreter::InitializeSWIG ()
|
|||
LLDBSwigPython_CalculateNumChildren,
|
||||
LLDBSwigPython_GetChildAtIndex,
|
||||
LLDBSwigPython_GetIndexOfChildWithName,
|
||||
LLDBSWIGPython_CastPyObjectToSBValue);
|
||||
LLDBSWIGPython_CastPyObjectToSBValue,
|
||||
LLDBSwigPython_UpdateSynthProviderInstance);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/ValueObjectList.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
#include "lldb/Symbol/SymbolVendor.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
@ -342,3 +343,59 @@ SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_
|
|||
|
||||
return sb_value_list;
|
||||
}
|
||||
|
||||
lldb::SBType
|
||||
SBModule::FindFirstType (const char* name_cstr)
|
||||
{
|
||||
if (!IsValid())
|
||||
return lldb::SBType();
|
||||
|
||||
SymbolContext sc;
|
||||
TypeList type_list;
|
||||
uint32_t num_matches = 0;
|
||||
ConstString name(name_cstr);
|
||||
|
||||
num_matches = m_opaque_sp->FindTypes(sc,
|
||||
name,
|
||||
false,
|
||||
1,
|
||||
type_list);
|
||||
|
||||
if (num_matches)
|
||||
{
|
||||
TypeSP type_sp (type_list.GetTypeAtIndex(0));
|
||||
return lldb::SBType(type_sp);
|
||||
}
|
||||
else
|
||||
return lldb::SBType();
|
||||
}
|
||||
|
||||
lldb::SBTypeList
|
||||
SBModule::FindTypes (const char* type)
|
||||
{
|
||||
|
||||
SBTypeList retval;
|
||||
|
||||
if (!IsValid())
|
||||
return retval;
|
||||
|
||||
SymbolContext sc;
|
||||
TypeList type_list;
|
||||
uint32_t num_matches = 0;
|
||||
ConstString name(type);
|
||||
|
||||
num_matches = m_opaque_sp->FindTypes(sc,
|
||||
name,
|
||||
false,
|
||||
UINT32_MAX,
|
||||
type_list);
|
||||
|
||||
for (size_t idx = 0; idx < num_matches; idx++)
|
||||
{
|
||||
TypeSP sp_at_idx = type_list.GetTypeAtIndex(idx);
|
||||
|
||||
retval.AppendType(SBType(sp_at_idx));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Symbol/SymbolVendor.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -879,6 +880,52 @@ SBTarget::FindFunctions (const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
lldb::SBType
|
||||
SBTarget::FindFirstType (const char* type)
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
size_t count = m_opaque_sp->GetImages().GetSize();
|
||||
for (size_t idx = 0; idx < count; idx++)
|
||||
{
|
||||
SBType found_at_idx = GetModuleAtIndex(idx).FindFirstType(type);
|
||||
|
||||
if (found_at_idx.IsValid())
|
||||
return found_at_idx;
|
||||
}
|
||||
}
|
||||
return SBType();
|
||||
}
|
||||
|
||||
lldb::SBTypeList
|
||||
SBTarget::FindTypes (const char* type)
|
||||
{
|
||||
|
||||
SBTypeList retval;
|
||||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
ModuleList& images = m_opaque_sp->GetImages();
|
||||
ConstString name_const(type);
|
||||
SymbolContext sc;
|
||||
TypeList type_list;
|
||||
|
||||
uint32_t num_matches = images.FindTypes(sc,
|
||||
name_const,
|
||||
true,
|
||||
UINT32_MAX,
|
||||
type_list);
|
||||
|
||||
for (size_t idx = 0; idx < num_matches; idx++)
|
||||
{
|
||||
TypeSP sp_at_idx = type_list.GetTypeAtIndex(idx);
|
||||
|
||||
retval.AppendType(SBType(sp_at_idx));
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
SBValueList
|
||||
SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
#include "lldb/API/SBType.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
|
@ -18,334 +24,340 @@
|
|||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace clang;
|
||||
|
||||
SBType::SBType (lldb_private::ClangASTType type) :
|
||||
m_opaque_ap(new TypeImpl(ClangASTType(type.GetASTContext(),
|
||||
type.GetOpaqueQualType())))
|
||||
{
|
||||
}
|
||||
|
||||
SBType::SBType (lldb::TypeSP type) :
|
||||
m_opaque_ap(new TypeImpl(type))
|
||||
{}
|
||||
|
||||
SBType::SBType (const SBType &rhs)
|
||||
{
|
||||
if (rhs.m_opaque_ap.get() != NULL)
|
||||
{
|
||||
m_opaque_ap = std::auto_ptr<TypeImpl>(new TypeImpl(ClangASTType(rhs.m_opaque_ap->GetASTContext(),
|
||||
rhs.m_opaque_ap->GetOpaqueQualType())));
|
||||
}
|
||||
}
|
||||
|
||||
SBType::SBType (clang::ASTContext *ctx, clang_type_t ty) :
|
||||
m_opaque_ap(new TypeImpl(ClangASTType(ctx, ty)))
|
||||
{
|
||||
}
|
||||
|
||||
SBType::SBType() :
|
||||
m_opaque_ap(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
SBType::SBType (TypeImpl impl) :
|
||||
m_opaque_ap(&impl)
|
||||
{}
|
||||
|
||||
bool
|
||||
SBType::IsPointerType (void *opaque_type)
|
||||
SBType::operator == (const lldb::SBType &rhs) const
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
//if (log)
|
||||
// log->Printf ("SBType::IsPointerType (%p)", opaque_type);
|
||||
if (IsValid() == false)
|
||||
return !rhs.IsValid();
|
||||
|
||||
bool ret_value = ClangASTContext::IsPointerType (opaque_type);
|
||||
return (rhs.m_opaque_ap->GetASTContext() == m_opaque_ap->GetASTContext())
|
||||
&&
|
||||
(rhs.m_opaque_ap->GetOpaqueQualType() == m_opaque_ap->GetOpaqueQualType());
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
|
||||
bool
|
||||
SBType::operator != (const lldb::SBType &rhs) const
|
||||
{
|
||||
if (IsValid() == false)
|
||||
return rhs.IsValid();
|
||||
|
||||
return ret_value;
|
||||
return (rhs.m_opaque_ap->GetASTContext() != m_opaque_ap->GetASTContext())
|
||||
||
|
||||
(rhs.m_opaque_ap->GetOpaqueQualType() != m_opaque_ap->GetOpaqueQualType());
|
||||
}
|
||||
|
||||
|
||||
SBType::SBType (void *ast, void *clang_type) :
|
||||
m_ast (ast),
|
||||
m_type (clang_type)
|
||||
const lldb::SBType &
|
||||
SBType::operator = (const lldb::SBType &rhs)
|
||||
{
|
||||
}
|
||||
|
||||
SBType::SBType (const SBType &rhs) :
|
||||
m_ast (rhs.m_ast),
|
||||
m_type (rhs.m_type)
|
||||
{
|
||||
}
|
||||
|
||||
const SBType &
|
||||
SBType::operator =(const SBType &rhs)
|
||||
{
|
||||
m_ast = rhs.m_ast;
|
||||
m_type = rhs.m_type;
|
||||
if (*this != rhs)
|
||||
{
|
||||
if (!rhs.IsValid())
|
||||
m_opaque_ap.reset(NULL);
|
||||
else
|
||||
m_opaque_ap = std::auto_ptr<TypeImpl>(new TypeImpl(ClangASTType(rhs.m_opaque_ap->GetASTContext(),
|
||||
rhs.m_opaque_ap->GetOpaqueQualType())));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBType::~SBType ()
|
||||
{}
|
||||
|
||||
lldb_private::TypeImpl &
|
||||
SBType::ref ()
|
||||
{
|
||||
if (m_opaque_ap.get() == NULL)
|
||||
m_opaque_ap.reset (new lldb_private::TypeImpl());
|
||||
return *m_opaque_ap;
|
||||
}
|
||||
|
||||
const lldb_private::TypeImpl &
|
||||
SBType::ref () const
|
||||
{
|
||||
// "const SBAddress &addr" should already have checked "addr.IsValid()"
|
||||
// prior to calling this function. In case you didn't we will assert
|
||||
// and die to let you know.
|
||||
assert (m_opaque_ap.get());
|
||||
return *m_opaque_ap;
|
||||
}
|
||||
|
||||
bool
|
||||
SBType::IsValid ()
|
||||
SBType::IsValid() const
|
||||
{
|
||||
return m_ast != NULL && m_type != NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
SBType::GetName ()
|
||||
{
|
||||
if (IsValid ())
|
||||
return ClangASTType::GetConstTypeName (m_type).AsCString(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
SBType::GetByteSize()
|
||||
{
|
||||
if (IsValid ())
|
||||
return ClangASTType::GetClangTypeBitWidth (static_cast<clang::ASTContext *>(m_ast), m_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Encoding
|
||||
SBType::GetEncoding (uint32_t &count)
|
||||
{
|
||||
if (IsValid ())
|
||||
return ClangASTType::GetEncoding (m_type, count);
|
||||
count = 0;
|
||||
return eEncodingInvalid;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
SBType::GetNumberChildren (bool omit_empty_base_classes)
|
||||
{
|
||||
if (IsValid ())
|
||||
return ClangASTContext::GetNumChildren (static_cast<clang::ASTContext *>(m_ast),
|
||||
m_type,
|
||||
omit_empty_base_classes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SBType::GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member)
|
||||
{
|
||||
void *child_clang_type = NULL;
|
||||
bool ignore_array_bounds = false;
|
||||
std::string child_name;
|
||||
uint32_t child_byte_size = 0;
|
||||
int32_t child_byte_offset = 0;
|
||||
uint32_t child_bitfield_bit_size = 0;
|
||||
uint32_t child_bitfield_bit_offset = 0;
|
||||
bool child_is_base_class = false;
|
||||
bool child_is_deref_of_parent = false;
|
||||
|
||||
if (IsValid ())
|
||||
{
|
||||
|
||||
child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (NULL,
|
||||
static_cast<clang::ASTContext *>(m_ast),
|
||||
NULL,
|
||||
m_type,
|
||||
idx,
|
||||
false, // transparent pointers
|
||||
omit_empty_base_classes,
|
||||
ignore_array_bounds,
|
||||
child_name,
|
||||
child_byte_size,
|
||||
child_byte_offset,
|
||||
child_bitfield_bit_size,
|
||||
child_bitfield_bit_offset,
|
||||
child_is_base_class,
|
||||
child_is_deref_of_parent);
|
||||
|
||||
}
|
||||
if (m_opaque_ap.get() == NULL)
|
||||
return false;
|
||||
|
||||
if (child_clang_type)
|
||||
{
|
||||
member.m_ast = m_ast;
|
||||
member.m_parent_type = m_type;
|
||||
member.m_member_type = child_clang_type,
|
||||
member.SetName (child_name.c_str());
|
||||
member.m_offset = child_byte_offset;
|
||||
member.m_bit_size = child_bitfield_bit_size;
|
||||
member.m_bit_offset = child_bitfield_bit_offset;
|
||||
member.m_is_base_class = child_is_base_class;
|
||||
member.m_is_deref_of_paremt = child_is_deref_of_parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
member.Clear();
|
||||
}
|
||||
|
||||
return child_clang_type != NULL;
|
||||
return m_opaque_ap->IsValid();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBType::GetChildIndexForName (bool omit_empty_base_classes, const char *name)
|
||||
size_t
|
||||
SBType::GetByteSize() const
|
||||
{
|
||||
return ClangASTContext::GetIndexOfChildWithName (static_cast<clang::ASTContext *>(m_ast),
|
||||
m_type,
|
||||
name,
|
||||
omit_empty_base_classes);
|
||||
if (!IsValid())
|
||||
return 0;
|
||||
|
||||
return ClangASTType::GetTypeByteSize(m_opaque_ap->GetASTContext(), m_opaque_ap->GetOpaqueQualType());
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
SBType::IsAPointerType ()
|
||||
SBType::IsPointerType() const
|
||||
{
|
||||
return ClangASTContext::IsPointerType (m_type);
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
QualType qt = QualType::getFromOpaquePtr(m_opaque_ap->GetOpaqueQualType());
|
||||
const clang::Type* typePtr = qt.getTypePtrOrNull();
|
||||
|
||||
if (typePtr)
|
||||
return typePtr->isAnyPointerType();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SBType::IsReferenceType() const
|
||||
{
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
QualType qt = QualType::getFromOpaquePtr(m_opaque_ap->GetOpaqueQualType());
|
||||
const clang::Type* typePtr = qt.getTypePtrOrNull();
|
||||
|
||||
if (typePtr)
|
||||
return typePtr->isReferenceType();
|
||||
return false;
|
||||
}
|
||||
|
||||
SBType
|
||||
SBType::GetPointeeType ()
|
||||
SBType::GetPointerType() const
|
||||
{
|
||||
void *pointee_type = NULL;
|
||||
if (IsAPointerType ())
|
||||
{
|
||||
pointee_type = ClangASTType::GetPointeeType (m_type);
|
||||
}
|
||||
return SBType (pointee_type ? m_ast : NULL, pointee_type);
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
|
||||
return SBType(m_opaque_ap->GetASTContext(),
|
||||
ClangASTContext::CreatePointerType(m_opaque_ap->GetASTContext(), m_opaque_ap->GetOpaqueQualType()));
|
||||
}
|
||||
|
||||
bool
|
||||
SBType::GetDescription (SBStream &description)
|
||||
SBType
|
||||
SBType::GetPointeeType() const
|
||||
{
|
||||
const char *name = GetName();
|
||||
uint64_t byte_size = GetByteSize();
|
||||
uint64_t num_children = GetNumberChildren (true);
|
||||
bool is_ptr = IsAPointerType ();
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
|
||||
description.Printf ("type_name: %s, size: %d bytes", (name != NULL ? name : "<unknown type name>"), byte_size);
|
||||
if (is_ptr)
|
||||
{
|
||||
SBType pointee_type = GetPointeeType();
|
||||
const char *pointee_name = pointee_type.GetName();
|
||||
description.Printf (", (* %s)", (pointee_name != NULL ? pointee_name : "<unknown type name>"));
|
||||
}
|
||||
else if (num_children > 0)
|
||||
{
|
||||
description.Printf (", %d members:\n", num_children);
|
||||
for (uint32_t i = 0; i < num_children; ++i)
|
||||
{
|
||||
SBTypeMember field;
|
||||
GetChildAtIndex (true, i, field);
|
||||
const char *field_name = field.GetName();
|
||||
SBType field_type = field.GetType();
|
||||
const char *field_type_name = field_type.GetName();
|
||||
|
||||
description.Printf (" %s (type: %s", (field_name != NULL ? field_name : "<unknown member name>"),
|
||||
(field_type_name != NULL ? field_type_name : "<unknown type name>"));
|
||||
|
||||
if (field.IsBitfield())
|
||||
{
|
||||
size_t width = field.GetBitfieldWidth ();
|
||||
description.Printf (" , %d bits", (int) width);
|
||||
}
|
||||
description.Printf (")\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SBTypeMember::SBTypeMember () :
|
||||
m_ast (NULL),
|
||||
m_parent_type (NULL),
|
||||
m_member_type (NULL),
|
||||
m_member_name (NULL),
|
||||
m_offset (0),
|
||||
m_bit_size (0),
|
||||
m_bit_offset (0),
|
||||
m_is_base_class (false)
|
||||
QualType qt = QualType::getFromOpaquePtr(m_opaque_ap->GetOpaqueQualType());
|
||||
const clang::Type* typePtr = qt.getTypePtrOrNull();
|
||||
|
||||
{
|
||||
if (typePtr)
|
||||
return SBType(m_opaque_ap->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr());
|
||||
return SBType();
|
||||
}
|
||||
|
||||
SBTypeMember::SBTypeMember (const SBTypeMember &rhs) :
|
||||
m_ast (rhs.m_ast),
|
||||
m_parent_type (rhs.m_parent_type),
|
||||
m_member_type (rhs.m_member_type),
|
||||
m_member_name (rhs.m_member_name),
|
||||
m_offset (rhs.m_offset),
|
||||
m_bit_size (rhs.m_bit_size),
|
||||
m_bit_offset (rhs.m_bit_offset),
|
||||
m_is_base_class (rhs.m_is_base_class)
|
||||
SBType
|
||||
SBType::GetReferenceType() const
|
||||
{
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
|
||||
return SBType(m_opaque_ap->GetASTContext(),
|
||||
ClangASTContext::CreateLValueReferenceType(m_opaque_ap->GetASTContext(), m_opaque_ap->GetOpaqueQualType()));
|
||||
}
|
||||
|
||||
const SBTypeMember&
|
||||
SBTypeMember::operator =(const SBTypeMember &rhs)
|
||||
SBType
|
||||
SBType::GetDereferencedType() const
|
||||
{
|
||||
if (this != &rhs)
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
|
||||
QualType qt = QualType::getFromOpaquePtr(m_opaque_ap->GetOpaqueQualType());
|
||||
|
||||
return SBType(m_opaque_ap->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr());
|
||||
}
|
||||
|
||||
SBType
|
||||
SBType::GetBasicType(lldb::BasicType type) const
|
||||
{
|
||||
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
|
||||
clang::CanQualType base_type_qual;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
m_ast = rhs.m_ast;
|
||||
m_parent_type = rhs.m_parent_type;
|
||||
m_member_type = rhs.m_member_type;
|
||||
m_member_name = rhs.m_member_name;
|
||||
m_offset = rhs.m_offset;
|
||||
m_bit_size = rhs.m_bit_size;
|
||||
m_bit_offset = rhs.m_bit_offset;
|
||||
m_is_base_class = rhs.m_is_base_class;
|
||||
case eBasicTypeChar:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->CharTy;
|
||||
break;
|
||||
case eBasicTypeSignedChar:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->SignedCharTy;
|
||||
break;
|
||||
case eBasicTypeShort:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->ShortTy;
|
||||
break;
|
||||
case eBasicTypeUnsignedShort:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->UnsignedShortTy;
|
||||
break;
|
||||
case eBasicTypeInt:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->IntTy;
|
||||
break;
|
||||
case eBasicTypeUnsignedInt:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->UnsignedIntTy;
|
||||
break;
|
||||
case eBasicTypeLong:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->LongTy;
|
||||
break;
|
||||
case eBasicTypeUnsignedLong:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->UnsignedLongTy;
|
||||
break;
|
||||
case eBasicTypeBool:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->BoolTy;
|
||||
break;
|
||||
case eBasicTypeFloat:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->FloatTy;
|
||||
break;
|
||||
case eBasicTypeDouble:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->DoubleTy;
|
||||
break;
|
||||
case eBasicTypeObjCID:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->ObjCBuiltinIdTy;
|
||||
break;
|
||||
case eBasicTypeVoid:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->VoidTy;
|
||||
break;
|
||||
case eBasicTypeWChar:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->WCharTy;
|
||||
break;
|
||||
case eBasicTypeChar16:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->Char16Ty;
|
||||
break;
|
||||
case eBasicTypeChar32:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->Char32Ty;
|
||||
break;
|
||||
case eBasicTypeLongLong:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->LongLongTy;
|
||||
break;
|
||||
case eBasicTypeUnsignedLongLong:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->UnsignedLongLongTy;
|
||||
break;
|
||||
case eBasicTypeInt128:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->Int128Ty;
|
||||
break;
|
||||
case eBasicTypeUnsignedInt128:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->UnsignedInt128Ty;
|
||||
break;
|
||||
case eBasicTypeLongDouble:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->LongDoubleTy;
|
||||
break;
|
||||
case eBasicTypeFloatComplex:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->FloatComplexTy;
|
||||
break;
|
||||
case eBasicTypeDoubleComplex:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->DoubleComplexTy;
|
||||
break;
|
||||
case eBasicTypeLongDoubleComplex:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->LongDoubleComplexTy;
|
||||
break;
|
||||
case eBasicTypeObjCClass:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->ObjCBuiltinClassTy;
|
||||
break;
|
||||
case eBasicTypeObjCSel:
|
||||
base_type_qual = m_opaque_ap->GetASTContext()->ObjCBuiltinSelTy;
|
||||
break;
|
||||
default:
|
||||
return SBType();
|
||||
}
|
||||
|
||||
return SBType(m_opaque_ap->GetASTContext(),
|
||||
base_type_qual.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
const char*
|
||||
SBType::GetName()
|
||||
{
|
||||
if (!IsValid())
|
||||
return "";
|
||||
|
||||
return ClangASTType::GetConstTypeName(m_opaque_ap->GetOpaqueQualType()).GetCString();
|
||||
}
|
||||
|
||||
SBTypeList::SBTypeList() :
|
||||
m_opaque_ap(new TypeListImpl())
|
||||
{
|
||||
}
|
||||
|
||||
SBTypeList::SBTypeList(const SBTypeList& rhs) :
|
||||
m_opaque_ap(new TypeListImpl())
|
||||
{
|
||||
for (int j = 0; j < rhs.GetSize(); j++)
|
||||
AppendType(rhs.GetTypeAtIndex(j));
|
||||
}
|
||||
|
||||
SBTypeList&
|
||||
SBTypeList::operator = (const SBTypeList& rhs)
|
||||
{
|
||||
if (m_opaque_ap.get() != rhs.m_opaque_ap.get())
|
||||
{
|
||||
m_opaque_ap.reset(new TypeListImpl());
|
||||
for (int j = 0; j < rhs.GetSize(); j++)
|
||||
AppendType(rhs.GetTypeAtIndex(j));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBTypeMember::~SBTypeMember ()
|
||||
{
|
||||
SetName (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
SBTypeMember::SetName (const char *name)
|
||||
SBTypeList::AppendType(SBType type)
|
||||
{
|
||||
if (m_member_name)
|
||||
free (m_member_name);
|
||||
if (name && name[0])
|
||||
m_member_name = ::strdup (name);
|
||||
else
|
||||
m_member_name = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SBTypeMember::Clear()
|
||||
{
|
||||
m_ast = NULL;
|
||||
m_parent_type = NULL;
|
||||
m_member_type = NULL;
|
||||
SetName (NULL);
|
||||
m_offset = 0;
|
||||
m_bit_size = 0;
|
||||
m_bit_offset = 0;
|
||||
m_is_base_class = false;
|
||||
}
|
||||
|
||||
bool
|
||||
SBTypeMember::IsValid ()
|
||||
{
|
||||
return m_member_type != NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
SBTypeMember::IsBitfield ()
|
||||
{
|
||||
return m_bit_size != 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
SBTypeMember::GetBitfieldWidth ()
|
||||
{
|
||||
return m_bit_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
SBTypeMember::GetBitfieldOffset ()
|
||||
{
|
||||
return m_bit_offset;
|
||||
}
|
||||
|
||||
bool
|
||||
SBTypeMember::IsBaseClass ()
|
||||
{
|
||||
return m_is_base_class;
|
||||
}
|
||||
|
||||
size_t
|
||||
SBTypeMember::GetOffset ()
|
||||
{
|
||||
return m_offset;
|
||||
if (type.IsValid())
|
||||
m_opaque_ap->AppendType(*type.m_opaque_ap.get());
|
||||
}
|
||||
|
||||
SBType
|
||||
SBTypeMember::GetType()
|
||||
SBTypeList::GetTypeAtIndex(int index) const
|
||||
{
|
||||
return SBType (m_ast, m_member_type);
|
||||
return SBType(m_opaque_ap->GetTypeAtIndex(index));
|
||||
}
|
||||
|
||||
SBType
|
||||
SBTypeMember::GetParentType()
|
||||
int
|
||||
SBTypeList::GetSize() const
|
||||
{
|
||||
return SBType (m_ast, m_parent_type);
|
||||
return m_opaque_ap->GetSize();
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
SBTypeMember::GetName ()
|
||||
SBTypeList::~SBTypeList()
|
||||
{
|
||||
return m_member_name;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/Core/ValueObject.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
#include "lldb/Symbol/Block.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Symbol/Variable.h"
|
||||
|
@ -156,9 +157,9 @@ SBValue::IsInScope ()
|
|||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
result = m_opaque_sp->IsInScope ();
|
||||
}
|
||||
}
|
||||
|
@ -182,9 +183,9 @@ SBValue::GetValue ()
|
|||
const char *cstr = NULL;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
cstr = m_opaque_sp->GetValueAsCString ();
|
||||
}
|
||||
}
|
||||
|
@ -237,9 +238,9 @@ SBValue::GetObjectDescription ()
|
|||
const char *cstr = NULL;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
cstr = m_opaque_sp->GetObjectDescription ();
|
||||
}
|
||||
}
|
||||
|
@ -260,15 +261,39 @@ SBValue::GetValueDidChange (const SBFrame &sb_frame)
|
|||
return GetValueDidChange ();
|
||||
}
|
||||
|
||||
SBType
|
||||
SBValue::GetType()
|
||||
{
|
||||
SBType result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
result = SBType(m_opaque_sp->GetClangAST(),
|
||||
m_opaque_sp->GetClangType());
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.IsValid())
|
||||
log->Printf ("SBValue(%p)::GetType => %p", m_opaque_sp.get(), &result);
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetType => NULL", m_opaque_sp.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
SBValue::GetValueDidChange ()
|
||||
{
|
||||
bool result = false;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
result = m_opaque_sp->GetValueDidChange ();
|
||||
}
|
||||
}
|
||||
|
@ -291,9 +316,9 @@ SBValue::GetSummary ()
|
|||
const char *cstr = NULL;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
cstr = m_opaque_sp->GetSummaryAsCString();
|
||||
}
|
||||
}
|
||||
|
@ -320,9 +345,9 @@ SBValue::GetLocation ()
|
|||
const char *cstr = NULL;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
cstr = m_opaque_sp->GetLocationAsCString();
|
||||
}
|
||||
}
|
||||
|
@ -349,22 +374,109 @@ SBValue::SetValueFromCString (const char *value_str)
|
|||
bool success = false;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
success = m_opaque_sp->SetValueFromCString (value_str);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type)
|
||||
{
|
||||
lldb::SBValue result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (type.IsValid())
|
||||
{
|
||||
result = SBValue(m_opaque_sp->GetSyntheticChildAtOffset(offset, *type.m_opaque_ap->GetClangASTType(), true));
|
||||
result.m_opaque_sp->SetName(ConstString(name));
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.IsValid())
|
||||
log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::Cast(const SBType& type)
|
||||
{
|
||||
return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type);
|
||||
}
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::CreateValueFromExpression (const char *name, const char* expression)
|
||||
{
|
||||
lldb::SBValue result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
ValueObjectSP result_valobj_sp;
|
||||
m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression(expression,
|
||||
m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(),
|
||||
true, true, eNoDynamicValues,
|
||||
result_valobj_sp);
|
||||
result_valobj_sp->SetName(ConstString(name));
|
||||
result = SBValue(result_valobj_sp);
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.IsValid())
|
||||
log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type)
|
||||
{
|
||||
lldb::SBValue result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
|
||||
SBType real_type(type.GetPointerType());
|
||||
|
||||
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
|
||||
|
||||
ValueObjectSP result_valobj_sp(ValueObjectConstResult::Create(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(),
|
||||
real_type.m_opaque_ap->GetASTContext(),
|
||||
real_type.m_opaque_ap->GetOpaqueQualType(),
|
||||
ConstString(name),
|
||||
buffer,
|
||||
lldb::endian::InlHostByteOrder(),
|
||||
GetTarget().GetProcess().GetAddressByteSize()));
|
||||
|
||||
result_valobj_sp->SetName(ConstString(name));
|
||||
result = SBValue(result_valobj_sp);
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.IsValid())
|
||||
log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SBValue
|
||||
SBValue::GetChildAtIndex (uint32_t idx)
|
||||
{
|
||||
const bool can_create_synthetic = false;
|
||||
lldb::DynamicValueType use_dynamic = eNoDynamicValues;
|
||||
if (m_opaque_sp)
|
||||
use_dynamic = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
|
||||
use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
|
||||
return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
|
||||
}
|
||||
|
||||
|
@ -375,9 +487,9 @@ SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool
|
|||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
const bool can_create = true;
|
||||
child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
|
||||
if (can_create_synthetic && !child_sp)
|
||||
|
@ -418,9 +530,9 @@ SBValue::GetIndexOfChildWithName (const char *name)
|
|||
uint32_t idx = UINT32_MAX;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
|
||||
}
|
||||
|
@ -441,7 +553,7 @@ SBValue::GetChildMemberWithName (const char *name)
|
|||
{
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
|
||||
lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
|
||||
return GetChildMemberWithName (name, use_dynamic_value);
|
||||
}
|
||||
else
|
||||
|
@ -457,9 +569,9 @@ SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dy
|
|||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
|
||||
if (use_dynamic_value != lldb::eNoDynamicValues)
|
||||
{
|
||||
|
@ -488,9 +600,9 @@ SBValue::GetValueForExpressionPath(const char* expr_path)
|
|||
lldb::ValueObjectSP child_sp;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
// using default values for all the fancy options, just do it if you can
|
||||
child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path);
|
||||
}
|
||||
|
@ -512,9 +624,9 @@ SBValue::GetNumChildren ()
|
|||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
num_children = m_opaque_sp->GetNumChildren();
|
||||
}
|
||||
|
@ -534,9 +646,9 @@ SBValue::Dereference ()
|
|||
SBValue sb_value;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
Error error;
|
||||
sb_value = m_opaque_sp->Dereference (error);
|
||||
|
@ -556,9 +668,9 @@ SBValue::TypeIsPointerType ()
|
|||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
is_ptr_type = m_opaque_sp->IsPointerType();
|
||||
}
|
||||
|
@ -577,9 +689,9 @@ SBValue::GetOpaqueType()
|
|||
{
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
return m_opaque_sp->GetClangType();
|
||||
}
|
||||
|
@ -587,6 +699,95 @@ SBValue::GetOpaqueType()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lldb::SBTarget
|
||||
SBValue::GetTarget()
|
||||
{
|
||||
SBTarget result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()));
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.get() == NULL)
|
||||
log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBProcess
|
||||
SBValue::GetProcess()
|
||||
{
|
||||
SBProcess result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
result = SBProcess(lldb::ProcessSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetProcessSP()));
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.get() == NULL)
|
||||
log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBThread
|
||||
SBValue::GetThread()
|
||||
{
|
||||
SBThread result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
|
||||
{
|
||||
result = SBThread(lldb::ThreadSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()));
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.get() == NULL)
|
||||
log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBFrame
|
||||
SBValue::GetFrame()
|
||||
{
|
||||
SBFrame result;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
|
||||
{
|
||||
result = SBFrame(lldb::StackFrameSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()));
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
{
|
||||
if (result.get() == NULL)
|
||||
log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get());
|
||||
else
|
||||
log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Mimic shared pointer...
|
||||
lldb_private::ValueObject *
|
||||
SBValue::get() const
|
||||
|
@ -685,3 +886,23 @@ SBValue::SetFormat (lldb::Format format)
|
|||
m_opaque_sp->SetFormat(format);
|
||||
}
|
||||
|
||||
lldb::SBValue
|
||||
SBValue::AddressOf()
|
||||
{
|
||||
SBValue sb_value;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
|
||||
|
||||
Error error;
|
||||
sb_value = m_opaque_sp->AddressOf (error);
|
||||
}
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
|
||||
|
||||
return sb_value;
|
||||
}
|
|
@ -1367,11 +1367,11 @@ LookupTypeInModule (CommandInterpreter &interpreter,
|
|||
{
|
||||
if (module && name_cstr && name_cstr[0])
|
||||
{
|
||||
SymbolContextList sc_list;
|
||||
/*SymbolContextList sc_list;
|
||||
|
||||
SymbolVendor *symbol_vendor = module->GetSymbolVendor();
|
||||
if (symbol_vendor)
|
||||
{
|
||||
{*/
|
||||
TypeList type_list;
|
||||
uint32_t num_matches = 0;
|
||||
SymbolContext sc;
|
||||
|
@ -1383,7 +1383,7 @@ LookupTypeInModule (CommandInterpreter &interpreter,
|
|||
// else
|
||||
// {
|
||||
ConstString name(name_cstr);
|
||||
num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
|
||||
num_matches = module->FindTypes(sc, name, true, UINT32_MAX, type_list);
|
||||
// }
|
||||
|
||||
if (num_matches)
|
||||
|
@ -1407,7 +1407,7 @@ LookupTypeInModule (CommandInterpreter &interpreter,
|
|||
}
|
||||
}
|
||||
return num_matches;
|
||||
}
|
||||
//}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -218,8 +218,8 @@ CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
|
|||
{
|
||||
{ LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
|
||||
{ LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format to use to display this type."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
@ -1074,16 +1074,16 @@ CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
|
|||
{
|
||||
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
|
||||
{ LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
|
||||
{ LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean, "Don't show the value, just show the summary, for this type."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean, "Type names are actually regular expressions."},
|
||||
{ LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean, "If true, inline all child values into summary string."},
|
||||
{ LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
|
||||
{ LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."},
|
||||
{ LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString, "Format string used to display text and object contents."},
|
||||
{ LLDB_OPT_SET_3, false, "python-script", 's', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."},
|
||||
{ LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."},
|
||||
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeName, "Input Python code to use for this type manually."},
|
||||
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."},
|
||||
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
|
||||
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
|
||||
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
@ -1249,7 +1249,7 @@ public:
|
|||
OptionDefinition
|
||||
CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Delete from every category."},
|
||||
{ LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."},
|
||||
{ LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
@ -1375,7 +1375,7 @@ public:
|
|||
OptionDefinition
|
||||
CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Clear every category."},
|
||||
{ LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
@ -2236,7 +2236,7 @@ public:
|
|||
OptionDefinition
|
||||
CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Delete from every category."},
|
||||
{ LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."},
|
||||
{ LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
@ -2363,7 +2363,7 @@ public:
|
|||
OptionDefinition
|
||||
CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Clear every category."},
|
||||
{ LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
@ -2377,6 +2377,9 @@ static const char *g_synth_addreader_instructions = "Enter your Python command
|
|||
" def num_children(self):\n"
|
||||
" def get_child_at_index(self, index):\n"
|
||||
" def get_child_index(self, name):\n"
|
||||
"Optionally, you can also define a method:\n"
|
||||
" def update(self):\n"
|
||||
"if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n"
|
||||
"class synthProvider:";
|
||||
|
||||
class TypeSynthAddInputReader : public InputReaderEZ
|
||||
|
@ -2832,12 +2835,12 @@ OptionDefinition
|
|||
CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
|
||||
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
|
||||
{ LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."},
|
||||
{ LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."},
|
||||
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeBoolean, "Type Python code to generate a class that provides synthetic children."},
|
||||
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -1004,16 +1004,28 @@ Debugger::FormatPrompt
|
|||
switch (var_name_begin[0])
|
||||
{
|
||||
case '*':
|
||||
{
|
||||
if (!vobj)
|
||||
break;
|
||||
do_deref_pointer = true;
|
||||
var_name_begin++;
|
||||
}
|
||||
// Fall through...
|
||||
|
||||
case 'v':
|
||||
case 's':
|
||||
{
|
||||
if (!vobj)
|
||||
break;
|
||||
|
||||
// check for *var and *svar
|
||||
if (*var_name_begin == '*')
|
||||
{
|
||||
do_deref_pointer = true;
|
||||
var_name_begin++;
|
||||
}
|
||||
if (*var_name_begin == 's')
|
||||
{
|
||||
vobj = vobj->GetSyntheticValue(lldb::eUseSyntheticFilter).get();
|
||||
var_name_begin++;
|
||||
}
|
||||
|
||||
// should be a 'v' by now
|
||||
if (*var_name_begin != 'v')
|
||||
break;
|
||||
|
||||
ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
|
||||
ValueObject::eDereference : ValueObject::eNothing);
|
||||
ValueObject::GetValueForExpressionPathOptions options;
|
||||
|
|
|
@ -171,7 +171,7 @@ m_python_class(pclass)
|
|||
return;
|
||||
}
|
||||
|
||||
m_interpreter = be->GetUpdatePoint().GetTarget()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
m_interpreter = be->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
|
||||
if (m_interpreter == NULL)
|
||||
m_wrapper = NULL;
|
||||
|
|
|
@ -422,7 +422,7 @@ Module::FindFunctions (const RegularExpression& regex,
|
|||
}
|
||||
|
||||
uint32_t
|
||||
Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
{
|
||||
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
|
||||
if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
|
||||
|
@ -434,6 +434,41 @@ Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append
|
|||
return 0;
|
||||
}
|
||||
|
||||
// depending on implementation details, type lookup might fail because of
|
||||
// embedded spurious namespace:: prefixes. this call strips them, paying
|
||||
// attention to the fact that a type might have namespace'd type names as
|
||||
// arguments to templates, and those must not be stripped off
|
||||
static const char*
|
||||
StripTypeName(const char* name_cstr)
|
||||
{
|
||||
const char* skip_namespace = strstr(name_cstr, "::");
|
||||
const char* template_arg_char = strchr(name_cstr, '<');
|
||||
while (skip_namespace != NULL)
|
||||
{
|
||||
if (template_arg_char != NULL &&
|
||||
skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
|
||||
break;
|
||||
name_cstr = skip_namespace+2;
|
||||
skip_namespace = strstr(name_cstr, "::");
|
||||
}
|
||||
return name_cstr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
{
|
||||
uint32_t retval = FindTypes_Impl(sc, name, append, max_matches, types);
|
||||
|
||||
if (retval == 0)
|
||||
{
|
||||
const char *stripped = StripTypeName(name.GetCString());
|
||||
return FindTypes_Impl(sc, ConstString(stripped), append, max_matches, types);
|
||||
}
|
||||
else
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
//uint32_t
|
||||
//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
|
||||
//{
|
||||
|
|
|
@ -389,7 +389,7 @@ ModuleList::FindModule (const UUID &uuid)
|
|||
|
||||
|
||||
uint32_t
|
||||
ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
ModuleList::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
{
|
||||
Mutex::Locker locker(m_modules_mutex);
|
||||
|
||||
|
@ -409,6 +409,40 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool ap
|
|||
return total_matches;
|
||||
}
|
||||
|
||||
// depending on implementation details, type lookup might fail because of
|
||||
// embedded spurious namespace:: prefixes. this call strips them, paying
|
||||
// attention to the fact that a type might have namespace'd type names as
|
||||
// arguments to templates, and those must not be stripped off
|
||||
static const char*
|
||||
StripTypeName(const char* name_cstr)
|
||||
{
|
||||
const char* skip_namespace = strstr(name_cstr, "::");
|
||||
const char* template_arg_char = strchr(name_cstr, '<');
|
||||
while (skip_namespace != NULL)
|
||||
{
|
||||
if (template_arg_char != NULL &&
|
||||
skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
|
||||
break;
|
||||
name_cstr = skip_namespace+2;
|
||||
skip_namespace = strstr(name_cstr, "::");
|
||||
}
|
||||
return name_cstr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
{
|
||||
uint32_t retval = FindTypes_Impl(sc, name, append, max_matches, types);
|
||||
|
||||
if (retval == 0)
|
||||
{
|
||||
const char *stripped = StripTypeName(name.GetCString());
|
||||
return FindTypes_Impl(sc, ConstString(stripped), append, max_matches, types);
|
||||
}
|
||||
else
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
ModuleSP
|
||||
ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// Project includes
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/ValueObjectChild.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
|
@ -89,6 +90,7 @@ ValueObject::ValueObject (ValueObject &parent) :
|
|||
m_is_array_item_for_pointer(false),
|
||||
m_is_bitfield_for_scalar(false),
|
||||
m_is_expression_path_child(false),
|
||||
m_is_child_at_offset(false),
|
||||
m_dump_printable_counter(0)
|
||||
{
|
||||
m_manager->ManageObject(this);
|
||||
|
@ -132,6 +134,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
|
|||
m_is_array_item_for_pointer(false),
|
||||
m_is_bitfield_for_scalar(false),
|
||||
m_is_expression_path_child(false),
|
||||
m_is_child_at_offset(false),
|
||||
m_dump_printable_counter(0)
|
||||
{
|
||||
m_manager = new ValueObjectManager();
|
||||
|
@ -203,9 +206,12 @@ ValueObject::UpdateValueIfNeeded (bool update_format)
|
|||
void
|
||||
ValueObject::UpdateFormatsIfNeeded()
|
||||
{
|
||||
/*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
if (log)
|
||||
log->Printf("checking for FormatManager revisions. VO named %s is at revision %d, while the format manager is at revision %d",
|
||||
GetName().GetCString(),
|
||||
m_last_format_mgr_revision,
|
||||
Debugger::ValueFormats::GetCurrentRevision());*/
|
||||
Debugger::Formatting::ValueFormats::GetCurrentRevision());
|
||||
if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
|
||||
{
|
||||
ClearCustomSummaryFormat();
|
||||
|
@ -440,12 +446,6 @@ ValueObject::SetNumChildren (uint32_t num_children)
|
|||
m_children.resize(num_children);
|
||||
}
|
||||
|
||||
void
|
||||
ValueObject::SetName (const char *name)
|
||||
{
|
||||
m_name.SetCString(name);
|
||||
}
|
||||
|
||||
void
|
||||
ValueObject::SetName (const ConstString &name)
|
||||
{
|
||||
|
@ -640,7 +640,11 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
if (exe_scope)
|
||||
{
|
||||
Target *target = exe_scope->CalculateTarget();
|
||||
if (target != NULL)
|
||||
if (target == NULL)
|
||||
{
|
||||
s << "<no target to read from>";
|
||||
}
|
||||
else
|
||||
{
|
||||
lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
|
||||
AddressType cstr_address_type = eAddressTypeInvalid;
|
||||
|
@ -663,7 +667,11 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
// We have a pointer
|
||||
cstr_address = GetPointerValue (cstr_address_type, true);
|
||||
}
|
||||
if (cstr_address != LLDB_INVALID_ADDRESS)
|
||||
if (cstr_address == LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
s << "<invalid address for data>";
|
||||
}
|
||||
else
|
||||
{
|
||||
Address cstr_so_addr (NULL, cstr_address);
|
||||
DataExtractor data;
|
||||
|
@ -695,6 +703,8 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
s << "...";
|
||||
s << '"';
|
||||
}
|
||||
else
|
||||
s << "\"<data not available>\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -706,6 +716,8 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
|
||||
s << '"';
|
||||
|
||||
bool any_data = false;
|
||||
|
||||
data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
|
||||
while ((bytes_read = target->ReadMemory (cstr_so_addr,
|
||||
prefer_file_cache,
|
||||
|
@ -713,6 +725,7 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
k_max_buf_size,
|
||||
error)) > 0)
|
||||
{
|
||||
any_data = true;
|
||||
size_t len = strlen(&data_buffer.front());
|
||||
if (len == 0)
|
||||
break;
|
||||
|
@ -741,6 +754,10 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
cstr_len -= len;
|
||||
cstr_so_addr.Slide (k_max_buf_size);
|
||||
}
|
||||
|
||||
if (any_data == false)
|
||||
s << "<data not available>";
|
||||
|
||||
s << '"';
|
||||
}
|
||||
}
|
||||
|
@ -750,6 +767,7 @@ ValueObject::ReadPointedString(Stream& s,
|
|||
else
|
||||
{
|
||||
error.SetErrorString("impossible to read a string from this object");
|
||||
s << "<not a string object>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1350,7 +1368,7 @@ ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
|
|||
{
|
||||
AddSyntheticChild(index_const_str, synthetic_child);
|
||||
synthetic_child_sp = synthetic_child->GetSP();
|
||||
synthetic_child_sp->SetName(index_str);
|
||||
synthetic_child_sp->SetName(ConstString(index_str));
|
||||
synthetic_child_sp->m_is_array_item_for_pointer = true;
|
||||
}
|
||||
}
|
||||
|
@ -1393,7 +1411,7 @@ ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
|
|||
{
|
||||
AddSyntheticChild(index_const_str, synthetic_child);
|
||||
synthetic_child_sp = synthetic_child->GetSP();
|
||||
synthetic_child_sp->SetName(index_str);
|
||||
synthetic_child_sp->SetName(ConstString(index_str));
|
||||
synthetic_child_sp->m_is_array_item_for_pointer = true;
|
||||
}
|
||||
}
|
||||
|
@ -1434,7 +1452,7 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
|
|||
{
|
||||
AddSyntheticChild(index_const_str, synthetic_child);
|
||||
synthetic_child_sp = synthetic_child->GetSP();
|
||||
synthetic_child_sp->SetName(index_str);
|
||||
synthetic_child_sp->SetName(ConstString(index_str));
|
||||
synthetic_child_sp->m_is_bitfield_for_scalar = true;
|
||||
}
|
||||
}
|
||||
|
@ -1442,6 +1460,46 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
|
|||
return synthetic_child_sp;
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
|
||||
{
|
||||
|
||||
ValueObjectSP synthetic_child_sp;
|
||||
|
||||
char name_str[64];
|
||||
snprintf(name_str, sizeof(name_str), "@%i", offset);
|
||||
ConstString name_const_str(name_str);
|
||||
|
||||
// Check if we have already created a synthetic array member in this
|
||||
// valid object. If we have we will re-use it.
|
||||
synthetic_child_sp = GetSyntheticChild (name_const_str);
|
||||
|
||||
if (synthetic_child_sp.get())
|
||||
return synthetic_child_sp;
|
||||
|
||||
if (!can_create)
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
|
||||
type.GetASTContext(),
|
||||
type.GetOpaqueQualType(),
|
||||
name_const_str,
|
||||
type.GetTypeByteSize(),
|
||||
offset,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false);
|
||||
if (synthetic_child)
|
||||
{
|
||||
AddSyntheticChild(name_const_str, synthetic_child);
|
||||
synthetic_child_sp = synthetic_child->GetSP();
|
||||
synthetic_child_sp->SetName(name_const_str);
|
||||
synthetic_child_sp->m_is_child_at_offset = true;
|
||||
}
|
||||
return synthetic_child_sp;
|
||||
}
|
||||
|
||||
// your expression path needs to have a leading . or ->
|
||||
// (unless it somehow "looks like" an array, in which case it has
|
||||
// a leading [ symbol). while the [ is meaningful and should be shown
|
||||
|
@ -1477,7 +1535,7 @@ ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_cr
|
|||
if (synthetic_child_sp.get())
|
||||
{
|
||||
AddSyntheticChild(name_const_string, synthetic_child_sp.get());
|
||||
synthetic_child_sp->SetName(SkipLeadingExpressionPathSeparators(expression));
|
||||
synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
|
||||
synthetic_child_sp->m_is_expression_path_child = true;
|
||||
}
|
||||
}
|
||||
|
@ -1508,7 +1566,7 @@ ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
|
|||
|
||||
if (!m_dynamic_value && !IsDynamic())
|
||||
{
|
||||
Process *process = m_update_point.GetProcess();
|
||||
Process *process = m_update_point.GetProcessSP().get();
|
||||
bool worth_having_dynamic_value = false;
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::Dyn
|
|||
m_type_sp(),
|
||||
m_use_dynamic (use_dynamic)
|
||||
{
|
||||
SetName (parent.GetName().AsCString());
|
||||
SetName (parent.GetName());
|
||||
}
|
||||
|
||||
ValueObjectDynamicValue::~ValueObjectDynamicValue()
|
||||
|
@ -134,7 +134,7 @@ ValueObjectDynamicValue::UpdateValue ()
|
|||
}
|
||||
|
||||
// First make sure our Type and/or Address haven't changed:
|
||||
Process *process = m_update_point.GetProcess();
|
||||
Process *process = m_update_point.GetProcessSP().get();
|
||||
if (!process)
|
||||
return false;
|
||||
|
||||
|
@ -201,7 +201,7 @@ ValueObjectDynamicValue::UpdateValue ()
|
|||
|
||||
// We've moved, so we should be fine...
|
||||
m_address = dynamic_address;
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget());
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get());
|
||||
m_value.GetScalar() = load_address;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
|
|||
{
|
||||
// Do not attempt to construct one of these objects with no variable!
|
||||
assert (m_type_sp.get() != NULL);
|
||||
SetName (name);
|
||||
SetName (ConstString(name));
|
||||
m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget());
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get());
|
||||
if (load_address != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
m_value.SetValueType(Value::eValueTypeLoadAddress);
|
||||
|
@ -99,9 +99,9 @@ ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
|
|||
assert (m_clang_type.GetASTContext());
|
||||
assert (m_clang_type.GetOpaqueQualType());
|
||||
|
||||
SetName (name);
|
||||
SetName (ConstString(name));
|
||||
m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget());
|
||||
lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get());
|
||||
if (load_address != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
m_value.SetValueType(Value::eValueTypeLoadAddress);
|
||||
|
|
|
@ -44,7 +44,7 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic
|
|||
m_children_byindex(),
|
||||
m_name_toindex()
|
||||
{
|
||||
SetName (parent.GetName().AsCString());
|
||||
SetName (parent.GetName());
|
||||
}
|
||||
|
||||
ValueObjectSynthetic::~ValueObjectSynthetic()
|
||||
|
@ -120,6 +120,10 @@ ValueObjectSynthetic::UpdateValue ()
|
|||
m_children_byindex.clear();
|
||||
m_name_toindex.clear();
|
||||
|
||||
// let our backend do its update
|
||||
|
||||
m_synth_filter->Update();
|
||||
|
||||
SetValueIsValid(true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
|
|||
SWIGPythonCalculateNumChildren python_swig_calc_children,
|
||||
SWIGPythonGetChildAtIndex python_swig_get_child_index,
|
||||
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue)
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
|
||||
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider)
|
||||
{
|
||||
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
|
||||
python_swig_breakpoint_callback,
|
||||
|
@ -107,7 +108,8 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
|
|||
python_swig_calc_children,
|
||||
python_swig_get_child_index,
|
||||
python_swig_get_index_child,
|
||||
python_swig_cast_to_sbvalue);
|
||||
python_swig_cast_to_sbvalue,
|
||||
python_swig_update_provider);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -40,6 +40,7 @@ static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children =
|
|||
static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = NULL;
|
||||
static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = NULL;
|
||||
static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = NULL;
|
||||
static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL;
|
||||
|
||||
static int
|
||||
_check_and_flush (FILE *stream)
|
||||
|
@ -1307,7 +1308,7 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name
|
|||
if (!valobj.get())
|
||||
return NULL;
|
||||
|
||||
Target *target = valobj->GetUpdatePoint().GetTarget();
|
||||
Target *target = valobj->GetUpdatePoint().GetTargetSP().get();
|
||||
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
@ -1430,7 +1431,7 @@ ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_n
|
|||
if (!valobj.get())
|
||||
return "<no object>";
|
||||
|
||||
Target *target = valobj->GetUpdatePoint().GetTarget();
|
||||
Target *target = valobj->GetUpdatePoint().GetTargetSP().get();
|
||||
|
||||
if (!target)
|
||||
return "<no target>";
|
||||
|
@ -1768,6 +1769,38 @@ ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char*
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptInterpreterPython::UpdateSynthProviderInstance (void* implementor)
|
||||
{
|
||||
if (!implementor)
|
||||
return;
|
||||
|
||||
if (!g_swig_update_provider)
|
||||
return;
|
||||
|
||||
ScriptInterpreterPython *python_interpreter = this;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
g_swig_update_provider (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
g_swig_update_provider (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lldb::SBValue*
|
||||
ScriptInterpreterPython::CastPyObjectToSBValue (void* data)
|
||||
{
|
||||
|
@ -1811,7 +1844,8 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_ini
|
|||
SWIGPythonCalculateNumChildren python_swig_calc_children,
|
||||
SWIGPythonGetChildAtIndex python_swig_get_child_index,
|
||||
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue)
|
||||
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
|
||||
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider)
|
||||
{
|
||||
g_swig_init_callback = python_swig_init_callback;
|
||||
g_swig_breakpoint_callback = python_swig_breakpoint_callback;
|
||||
|
@ -1821,6 +1855,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_ini
|
|||
g_swig_get_child_index = python_swig_get_child_index;
|
||||
g_swig_get_index_child = python_swig_get_index_child;
|
||||
g_swig_cast_to_sbvalue = python_swig_cast_to_sbvalue;
|
||||
g_swig_update_provider = python_swig_update_provider;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -66,8 +66,8 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
|
|||
if (original_ptr == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
|
||||
Target *target = in_value.GetUpdatePoint().GetTarget();
|
||||
Process *process = in_value.GetUpdatePoint().GetProcess();
|
||||
Target *target = in_value.GetUpdatePoint().GetTargetSP().get();
|
||||
Process *process = in_value.GetUpdatePoint().GetProcessSP().get();
|
||||
|
||||
char memory_buffer[16];
|
||||
DataExtractor data(memory_buffer, sizeof(memory_buffer),
|
||||
|
|
|
@ -235,7 +235,7 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
|
|||
Address &address)
|
||||
{
|
||||
// The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
|
||||
assert (in_value.GetUpdatePoint().GetProcess() == m_process);
|
||||
assert (in_value.GetUpdatePoint().GetProcessSP().get() == m_process);
|
||||
|
||||
// Make sure we can have a dynamic value before starting...
|
||||
if (CouldHaveDynamicValue (in_value))
|
||||
|
|
|
@ -2725,7 +2725,7 @@ ClangASTContext::GetChildClangTypeAtIndex
|
|||
ObjCLanguageRuntime *objc_runtime = exe_ctx->process->GetObjCLanguageRuntime();
|
||||
if (objc_runtime != NULL)
|
||||
{
|
||||
ClangASTType parent_ast_type (parent_qual_type.getAsOpaquePtr(), ast);
|
||||
ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
|
||||
child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ ClangASTType::GetTypeNameForQualType (clang::QualType qual_type)
|
|||
}
|
||||
|
||||
// There is no call to a clang type to get the type name without the
|
||||
// class/struct/union on the front, so lets strip it here
|
||||
// class/struct/union/enum on the front, so lets strip it here
|
||||
const char *type_name_cstr = type_name.c_str();
|
||||
if (type_name_cstr[0] == 'c' &&
|
||||
type_name_cstr[1] == 'l' &&
|
||||
|
@ -93,6 +93,15 @@ ClangASTType::GetTypeNameForQualType (clang::QualType qual_type)
|
|||
{
|
||||
type_name.erase (0, 6);
|
||||
}
|
||||
else if (type_name_cstr[0] == 'e' &&
|
||||
type_name_cstr[1] == 'n' &&
|
||||
type_name_cstr[2] == 'u' &&
|
||||
type_name_cstr[3] == 'm' &&
|
||||
type_name_cstr[4] == ' ')
|
||||
{
|
||||
type_name.erase (0, 5);
|
||||
}
|
||||
|
||||
return type_name;
|
||||
}
|
||||
|
||||
|
@ -943,8 +952,11 @@ ClangASTType::GetClangTypeBitWidth ()
|
|||
uint32_t
|
||||
ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
|
||||
{
|
||||
if (ast_context && clang_type)
|
||||
return ast_context->getTypeSize(clang::QualType::getFromOpaquePtr(clang_type));
|
||||
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
|
||||
{
|
||||
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
|
||||
return ast_context->getTypeSize (qual_type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -957,7 +969,7 @@ ClangASTType::GetTypeBitAlign ()
|
|||
size_t
|
||||
ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type)
|
||||
{
|
||||
if (ast_context && clang_type)
|
||||
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
|
||||
return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type));
|
||||
return 0;
|
||||
}
|
||||
|
@ -1362,7 +1374,7 @@ ClangASTType::ReadFromMemory
|
|||
}
|
||||
|
||||
uint32_t
|
||||
ClangASTType::GetTypeByteSize()
|
||||
ClangASTType::GetTypeByteSize() const
|
||||
{
|
||||
return GetTypeByteSize(m_ast,
|
||||
m_type);
|
||||
|
@ -1379,7 +1391,7 @@ ClangASTType::GetTypeByteSize(
|
|||
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
|
||||
return (ast_context->getTypeSize (qual_type) + 7) / 8;
|
||||
}
|
||||
return UINT32_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -730,3 +730,44 @@ TypeAndOrName::IsEmpty()
|
|||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeImpl::TypeImpl(const lldb_private::ClangASTType& type) :
|
||||
m_clang_ast_type(new ClangASTType(type.GetASTContext(),
|
||||
type.GetOpaqueQualType())),
|
||||
m_lldb_type(lldb::TypeSP())
|
||||
{}
|
||||
|
||||
TypeImpl::TypeImpl(lldb::TypeSP type) :
|
||||
m_clang_ast_type(new ClangASTType(type->GetClangAST(),
|
||||
type->GetClangFullType())),
|
||||
m_lldb_type(type)
|
||||
{}
|
||||
|
||||
TypeImpl&
|
||||
TypeImpl::operator = (const TypeImpl& rhs)
|
||||
{
|
||||
if (*this != rhs)
|
||||
{
|
||||
m_clang_ast_type = std::auto_ptr<ClangASTType>(rhs.m_clang_ast_type.get());
|
||||
m_lldb_type = lldb::TypeSP(rhs.m_lldb_type);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
clang::ASTContext*
|
||||
TypeImpl::GetASTContext()
|
||||
{
|
||||
if (!IsValid())
|
||||
return NULL;
|
||||
|
||||
return m_clang_ast_type->GetASTContext();
|
||||
}
|
||||
|
||||
lldb::clang_type_t
|
||||
TypeImpl::GetOpaqueQualType()
|
||||
{
|
||||
if (!IsValid())
|
||||
return NULL;
|
||||
|
||||
return m_clang_ast_type->GetOpaqueQualType();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import re
|
||||
class StdListSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def num_children(self):
|
||||
next_val = int(self.Mnext.GetValue(),0)
|
||||
prev_val = int(self.Mprev.GetValue(),0)
|
||||
if next_val == 0:
|
||||
return 0;
|
||||
if next_val == self.Mnode_address:
|
||||
return 0;
|
||||
if next_val == prev_val:
|
||||
return 1;
|
||||
size = 2
|
||||
current = self.Mnext
|
||||
while int(current.GetChildMemberWithName('_M_next').GetValue(),0) != self.Mnode_address:
|
||||
size = size + 1;
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
return (size - 1)
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index
|
||||
current = self.Mnext;
|
||||
while offset > 0:
|
||||
current = current.GetChildMemberWithName('_M_next');
|
||||
offset = offset - 1;
|
||||
return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
|
||||
def extract_type_name(self,name):
|
||||
self.type_name = name[16:]
|
||||
index = 2
|
||||
count_of_template = 1
|
||||
while index < len(self.type_name):
|
||||
if self.type_name[index] == '<':
|
||||
count_of_template = count_of_template + 1;
|
||||
elif self.type_name[index] == '>':
|
||||
count_of_template = count_of_template - 1;
|
||||
elif self.type_name[index] == ',' and count_of_template == 1:
|
||||
self.type_name = self.type_name[:index]
|
||||
break
|
||||
index = index + 1;
|
||||
self.type_name_nospaces = self.type_name.replace(", ", ",")
|
||||
def update(self):
|
||||
self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.Mnode = self.Mimpl.GetChildMemberWithName('_M_node')
|
||||
self.extract_type_name(self.Mimpl.GetType().GetName())
|
||||
self.Mnode_address = int(self.valobj.AddressOf().GetValue(), 0)
|
||||
self.Mnext = self.Mnode.GetChildMemberWithName('_M_next')
|
||||
self.Mprev = self.Mnode.GetChildMemberWithName('_M_prev')
|
||||
self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name)
|
||||
# tries to fight against a difference in formatting type names between gcc and clang
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name_nospaces)
|
||||
self.data_size = self.data_type.GetByteSize()
|
|
@ -0,0 +1,103 @@
|
|||
import re
|
||||
class StdMapSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def update(self):
|
||||
self.Mt = self.valobj.GetChildMemberWithName('_M_t')
|
||||
self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
|
||||
self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
|
||||
# from libstdc++ implementation of _M_root for rbtree
|
||||
self.Mroot = self.Mheader.GetChildMemberWithName('_M_parent')
|
||||
# the stuff into the tree is actually a std::pair<const key, value>
|
||||
# life would be much easier if gcc had a coherent way to print out
|
||||
# template names in debug info
|
||||
self.expand_clang_type_name()
|
||||
self.expand_gcc_type_name()
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.clang_type_name)
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.gcc_type_name)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
self.skip_size = self.Mheader.GetType().GetByteSize()
|
||||
def expand_clang_type_name(self):
|
||||
type_name = self.Mimpl.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
index = index + 1;
|
||||
self.clang_type_name = type_name
|
||||
def expand_gcc_type_name(self):
|
||||
type_name = self.Mt.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
elif type_name[index] == ' ' and template_count == 1 and type_name[index-1] == ',':
|
||||
type_name = type_name[0:index] + type_name[index+1:]
|
||||
index = index - 1
|
||||
index = index + 1;
|
||||
self.gcc_type_name = type_name
|
||||
def num_children(self):
|
||||
root_ptr_val = self.node_ptr_value(self.Mroot)
|
||||
if root_ptr_val == 0:
|
||||
return 0;
|
||||
return int(self.Mimpl.GetChildMemberWithName('_M_node_count').GetValue(), 0);
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index
|
||||
current = self.left(self.Mheader);
|
||||
while offset > 0:
|
||||
current = self.increment_node(current)
|
||||
offset = offset - 1;
|
||||
# skip all the base stuff and get at the data
|
||||
return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
|
||||
# utility functions
|
||||
def node_ptr_value(self,node):
|
||||
return int(node.GetValue(),0);
|
||||
def right(self,node):
|
||||
return node.GetChildMemberWithName("_M_right");
|
||||
def left(self,node):
|
||||
return node.GetChildMemberWithName("_M_left");
|
||||
def parent(self,node):
|
||||
return node.GetChildMemberWithName("_M_parent");
|
||||
# from libstdc++ implementation of iterator for rbtree
|
||||
def increment_node(self,node):
|
||||
if self.node_ptr_value(self.right(node)) != 0:
|
||||
x = self.right(node);
|
||||
while self.node_ptr_value(self.left(x)) != 0:
|
||||
x = self.left(x);
|
||||
return x;
|
||||
else:
|
||||
x = node;
|
||||
y = self.parent(x)
|
||||
while(self.node_ptr_value(x) == self.node_ptr_value(self.right(y))):
|
||||
x = y;
|
||||
y = self.parent(y);
|
||||
if self.node_ptr_value(self.right(x)) != self.node_ptr_value(y):
|
||||
x = y;
|
||||
return x;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
class StdVectorSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def num_children(self):
|
||||
start_val = int(self.Mstart.GetValue(),0)
|
||||
finish_val = int(self.Mfinish.GetValue(),0)
|
||||
return (finish_val-start_val)/self.data_size
|
||||
def get_child_index(self,name):
|
||||
if name == "len":
|
||||
return self.num_children();
|
||||
else:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
def get_child_at_index(self,index):
|
||||
if index == self.num_children():
|
||||
return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
|
||||
else:
|
||||
offset = index * self.data_size
|
||||
return self.Mstart.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
|
||||
def update(self):
|
||||
self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.Mstart = self.Mimpl.GetChildMemberWithName('_M_start')
|
||||
self.Mfinish = self.Mimpl.GetChildMemberWithName('_M_finish')
|
||||
self.data_type = self.Mstart.GetType().GetPointeeType()
|
||||
self.data_size = self.data_type.GetByteSize()
|
|
@ -64,9 +64,10 @@ class DataFormatterTestCase(TestBase):
|
|||
self.runCmd("script from fooSynthProvider import *")
|
||||
self.runCmd("type synth add -l fooSynthProvider foo")
|
||||
|
||||
# check that we get only the two variables
|
||||
# check that we get the two real vars and the fake_a variables
|
||||
self.expect("frame variable f00_1",
|
||||
substrs = ['r = 33',
|
||||
'fake_a = 16777216',
|
||||
'a = 0']);
|
||||
|
||||
# check that we do not get the extra vars and that we cache results
|
||||
|
@ -79,15 +80,389 @@ class DataFormatterTestCase(TestBase):
|
|||
|
||||
self.expect("frame variable f00_1",
|
||||
substrs = ['r = 33',
|
||||
'fake_a = 16777216',
|
||||
'a = 1']);
|
||||
|
||||
# check that altering the object also alters fake_a
|
||||
self.runCmd("expr f00_1.a = 280")
|
||||
self.expect("frame variable f00_1",
|
||||
substrs = ['r = 33',
|
||||
'fake_a = 16777217',
|
||||
'a = 280']);
|
||||
|
||||
# check that expanding a pointer does the right thing
|
||||
self.expect("frame variable -P 1 f00_ptr",
|
||||
substrs = ['r = 45',
|
||||
'fake_a = 218103808',
|
||||
'a = 12'])
|
||||
|
||||
# delete the synth and check that we get good output
|
||||
self.runCmd("type synth delete foo")
|
||||
self.expect("frame variable f00_1",
|
||||
substrs = ['a = 1',
|
||||
substrs = ['a = 280',
|
||||
'b = 1',
|
||||
'r = 33']);
|
||||
|
||||
self.expect("frame variable f00_1", matching=False,
|
||||
substrs = ['fake_a = '])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.runCmd("script from ftsp import *")
|
||||
self.runCmd("type synth add -l ftsp wrapint")
|
||||
|
||||
self.expect('frame variable test_cast',
|
||||
substrs = ['A',
|
||||
'B',
|
||||
'C',
|
||||
'D'])
|
||||
|
||||
# now start playing with STL containers
|
||||
# having std::<class_type> here is a workaround for rdar://problem/9835692
|
||||
|
||||
|
||||
# std::vector
|
||||
self.runCmd("script from StdVectorSynthProvider import *")
|
||||
self.runCmd("type synth add -l StdVectorSynthProvider std::int_vect int_vect")
|
||||
self.runCmd("type synth add -l StdVectorSynthProvider std::string_vect string_vect")
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
# empty vectors (and storage pointers SHOULD BOTH BE NULL..)
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {}'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
# first value added
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {',
|
||||
'[0] = 1',
|
||||
'}'])
|
||||
|
||||
# add some more data
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {',
|
||||
'[0] = 1',
|
||||
'[1] = 12',
|
||||
'[2] = 123',
|
||||
'[3] = 1234',
|
||||
'}'])
|
||||
|
||||
# add some more data
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {',
|
||||
'[0] = 1',
|
||||
'[1] = 12',
|
||||
'[2] = 123',
|
||||
'[3] = 1234',
|
||||
'[4] = 12345',
|
||||
'[5] = 123456',
|
||||
'[6] = 1234567',
|
||||
'}'])
|
||||
|
||||
# clear out the vector and see that we do the right thing once again
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {}'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
# first value added
|
||||
self.expect("frame variable numbers",
|
||||
substrs = ['numbers = {',
|
||||
'[0] = 7',
|
||||
'}'])
|
||||
|
||||
# check if we can display strings
|
||||
self.runCmd("n")
|
||||
self.runCmd("n")
|
||||
self.runCmd("n")
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable strings",
|
||||
substrs = ['goofy',
|
||||
'is',
|
||||
'smart'])
|
||||
|
||||
# test summaries based on synthetic children
|
||||
self.runCmd("type summary add std::string_vect string_vect -f \"vector has ${svar.len} items\" -e")
|
||||
self.expect("frame variable strings",
|
||||
substrs = ['vector has 3 items',
|
||||
'goofy',
|
||||
'is',
|
||||
'smart'])
|
||||
|
||||
self.runCmd("n");
|
||||
|
||||
self.expect("frame variable strings",
|
||||
substrs = ['vector has 4 items'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable strings",
|
||||
substrs = ['vector has 0 items'])
|
||||
|
||||
# now test std::list
|
||||
self.runCmd("script from StdListSynthProvider import *")
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.runCmd("frame variable numbers_list -T")
|
||||
self.runCmd("type synth add std::int_list std::string_list int_list string_list -l StdListSynthProvider")
|
||||
self.runCmd("type summary add std::int_list std::string_list int_list string_list -f \"list has ${svar.len} items\" -e")
|
||||
self.runCmd("type format add -f hex int")
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000000 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000001 items',
|
||||
'[0] = ',
|
||||
'0x12345678'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000004 items',
|
||||
'[0] = ',
|
||||
'0x12345678',
|
||||
'[1] =',
|
||||
'0x11223344',
|
||||
'[2] =',
|
||||
'0xbeeffeed',
|
||||
'[3] =',
|
||||
'0x00abba00'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000006 items',
|
||||
'[0] = ',
|
||||
'0x12345678',
|
||||
'0x11223344',
|
||||
'0xbeeffeed',
|
||||
'0x00abba00',
|
||||
'[4] =',
|
||||
'0x0abcdef0',
|
||||
'[5] =',
|
||||
'0x0cab0cab'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000000 items',
|
||||
'{}'])
|
||||
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable numbers_list",
|
||||
substrs = ['list has 0x00000004 items',
|
||||
'[0] = ', '1',
|
||||
'[1] = ', '2',
|
||||
'[2] = ', '3',
|
||||
'[3] = ', '4'])
|
||||
|
||||
self.runCmd("type format delete int")
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect("frame variable text_list",
|
||||
substrs = ['list has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect("frame variable text_list",
|
||||
substrs = ['list has 4 items',
|
||||
'[0]', 'goofy',
|
||||
'[1]', 'is',
|
||||
'[2]', 'smart',
|
||||
'[3]', '!!!'])
|
||||
|
||||
# let's prettify string display
|
||||
self.runCmd("type summary add -f \"${var._M_dataplus._M_p}\" std::string std::basic_string<char> \"std::basic_string<char,std::char_traits<char>,std::allocator<char> >\"")
|
||||
|
||||
self.expect("frame variable text_list",
|
||||
substrs = ['list has 4 items',
|
||||
'[0] = \"goofy\"',
|
||||
'[1] = \"is\"',
|
||||
'[2] = \"smart\"',
|
||||
'[3] = \"!!!\"'])
|
||||
|
||||
# now std::map<K,V>
|
||||
|
||||
self.runCmd("n")
|
||||
self.runCmd("frame variable ii -T")
|
||||
|
||||
self.runCmd("script from StdMapSynthProvider import *")
|
||||
self.runCmd("type summary add std::intint_map intint_map -f \"map has ${svar.len} items\" -e")
|
||||
self.runCmd("type synth add std::intint_map intint_map -l StdMapSynthProvider")
|
||||
|
||||
|
||||
self.expect('frame variable ii',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable ii',
|
||||
substrs = ['map has 2 items',
|
||||
'[0] = {',
|
||||
'first = 0',
|
||||
'second = 0',
|
||||
'[1] = {',
|
||||
'first = 1',
|
||||
'second = 1'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable ii',
|
||||
substrs = ['map has 4 items',
|
||||
'[2] = {',
|
||||
'first = 2',
|
||||
'second = 0',
|
||||
'[3] = {',
|
||||
'first = 3',
|
||||
'second = 1'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable ii',
|
||||
substrs = ['map has 9 items',
|
||||
'[5] = {',
|
||||
'first = 5',
|
||||
'second = 0',
|
||||
'[7] = {',
|
||||
'first = 7',
|
||||
'second = 1'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect('frame variable ii',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n")
|
||||
self.runCmd("frame variable si -T")
|
||||
|
||||
self.runCmd("type summary add std::strint_map strint_map -f \"map has ${svar.len} items\" -e")
|
||||
self.runCmd("type synth add std::strint_map strint_map -l StdMapSynthProvider")
|
||||
|
||||
self.expect('frame variable si',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect('frame variable si',
|
||||
substrs = ['map has 1 items',
|
||||
'[0] = ',
|
||||
'first = \"zero\"',
|
||||
'second = 0'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable si',
|
||||
substrs = ['map has 5 items',
|
||||
'[0] = ',
|
||||
'first = \"zero\"',
|
||||
'second = 0',
|
||||
'[1] = ',
|
||||
'first = \"one\"',
|
||||
'second = 1',
|
||||
'[2] = ',
|
||||
'first = \"two\"',
|
||||
'second = 2',
|
||||
'[3] = ',
|
||||
'first = \"three\"',
|
||||
'second = 3',
|
||||
'[4] = ',
|
||||
'first = \"four\"',
|
||||
'second = 4'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect('frame variable si',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n")
|
||||
self.runCmd("frame variable is -T")
|
||||
|
||||
self.runCmd("type summary add std::intstr_map intstr_map -f \"map has ${svar.len} items\" -e")
|
||||
self.runCmd("type synth add std::intstr_map intstr_map -l StdMapSynthProvider")
|
||||
|
||||
self.expect('frame variable is',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable is',
|
||||
substrs = ['map has 4 items',
|
||||
'[0] = ',
|
||||
'second = \"goofy\"',
|
||||
'first = 0',
|
||||
'[1] = ',
|
||||
'second = \"is\"',
|
||||
'first = 1',
|
||||
'[2] = ',
|
||||
'second = \"smart\"',
|
||||
'first = 2',
|
||||
'[3] = ',
|
||||
'second = \"!!!\"',
|
||||
'first = 3'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect('frame variable is',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n")
|
||||
self.runCmd("frame variable ss -T")
|
||||
|
||||
self.runCmd("type summary add std::strstr_map strstr_map -f \"map has ${svar.len} items\" -e")
|
||||
self.runCmd("type synth add std::strstr_map strstr_map -l StdMapSynthProvider")
|
||||
|
||||
self.expect('frame variable ss',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
||||
|
||||
self.expect('frame variable ss',
|
||||
substrs = ['map has 4 items',
|
||||
'[0] = ',
|
||||
'second = \"hello\"',
|
||||
'first = \"ciao\"',
|
||||
'[1] = ',
|
||||
'second = \"house\"',
|
||||
'first = \"casa\"',
|
||||
'[2] = ',
|
||||
'second = \"cat\"',
|
||||
'first = \"gatto\"',
|
||||
'[3] = ',
|
||||
'second = \"..is always a Mac!\"',
|
||||
'first = \"a Mac..\"'])
|
||||
|
||||
self.runCmd("n")
|
||||
|
||||
self.expect('frame variable ss',
|
||||
substrs = ['map has 0 items',
|
||||
'{}'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import lldb
|
||||
class fooSynthProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
|
||||
def num_children(self):
|
||||
return 2;
|
||||
return 3;
|
||||
def get_child_at_index(self, index):
|
||||
if index == 1:
|
||||
if index == 0:
|
||||
child = self.valobj.GetChildMemberWithName('a');
|
||||
else:
|
||||
if index == 1:
|
||||
child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
|
||||
if index == 2:
|
||||
child = self.valobj.GetChildMemberWithName('r');
|
||||
return child;
|
||||
def get_child_index(self, name):
|
||||
if name == 'a':
|
||||
return 1;
|
||||
else:
|
||||
return 0;
|
||||
if name == 'fake_a':
|
||||
return 1;
|
||||
return 2;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import lldb
|
||||
class ftsp:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
def num_children(self):
|
||||
if self.char.IsValid():
|
||||
return 4;
|
||||
return 0;
|
||||
def get_child_index(self,name):
|
||||
return 0;
|
||||
def get_child_at_index(self,index):
|
||||
if index == 0:
|
||||
return self.x.Cast(self.char)
|
||||
return self.x.CreateChildAtOffset(str(index),
|
||||
index,
|
||||
self.char);
|
||||
def update(self):
|
||||
self.x = self.valobj.GetChildMemberWithName('x');
|
||||
self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)
|
|
@ -1,3 +1,18 @@
|
|||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
typedef std::vector<int> int_vect;
|
||||
typedef std::vector<std::string> string_vect;
|
||||
|
||||
typedef std::list<int> int_list;
|
||||
typedef std::list<std::string> string_list;
|
||||
|
||||
typedef std::map<int, int> intint_map;
|
||||
typedef std::map<std::string, int> strint_map;
|
||||
typedef std::map<int, std::string> intstr_map;
|
||||
typedef std::map<std::string, std::string> strstr_map;
|
||||
|
||||
struct foo
|
||||
{
|
||||
int a;
|
||||
|
@ -40,14 +55,110 @@ struct foo
|
|||
r(X+33) {}
|
||||
};
|
||||
|
||||
struct wrapint
|
||||
{
|
||||
int x;
|
||||
wrapint(int X) : x(X) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
foo f00_1(0);
|
||||
foo f00_2(6);
|
||||
foo *f00_3 = new foo(12);
|
||||
foo& f00_4 = *(new foo(18));
|
||||
foo *f00_ptr = new foo(12);
|
||||
|
||||
f00_1.a++; // Set break point at this line.
|
||||
|
||||
wrapint test_cast('A' +
|
||||
256*'B' +
|
||||
256*256*'C'+
|
||||
256*256*256*'D');
|
||||
|
||||
int_vect numbers;
|
||||
numbers.push_back(1);
|
||||
numbers.push_back(12);
|
||||
numbers.push_back(123);
|
||||
numbers.push_back(1234);
|
||||
numbers.push_back(12345);
|
||||
numbers.push_back(123456);
|
||||
numbers.push_back(1234567);
|
||||
|
||||
numbers.clear();
|
||||
|
||||
numbers.push_back(7);
|
||||
|
||||
string_vect strings;
|
||||
strings.push_back(std::string("goofy"));
|
||||
strings.push_back(std::string("is"));
|
||||
strings.push_back(std::string("smart"));
|
||||
|
||||
strings.push_back(std::string("!!!"));
|
||||
|
||||
strings.clear();
|
||||
|
||||
int_list numbers_list;
|
||||
|
||||
numbers_list.push_back(0x12345678);
|
||||
numbers_list.push_back(0x11223344);
|
||||
numbers_list.push_back(0xBEEFFEED);
|
||||
numbers_list.push_back(0x00ABBA00);
|
||||
numbers_list.push_back(0x0ABCDEF0);
|
||||
numbers_list.push_back(0x0CAB0CAB);
|
||||
|
||||
numbers_list.clear();
|
||||
|
||||
numbers_list.push_back(1);
|
||||
numbers_list.push_back(2);
|
||||
numbers_list.push_back(3);
|
||||
numbers_list.push_back(4);
|
||||
|
||||
string_list text_list;
|
||||
text_list.push_back(std::string("goofy"));
|
||||
text_list.push_back(std::string("is"));
|
||||
text_list.push_back(std::string("smart"));
|
||||
|
||||
text_list.push_back(std::string("!!!"));
|
||||
|
||||
intint_map ii;
|
||||
|
||||
ii[0] = 0;
|
||||
ii[1] = 1;
|
||||
ii[2] = 0;
|
||||
ii[3] = 1;
|
||||
ii[4] = 0;
|
||||
ii[5] = 1;
|
||||
ii[6] = 0;
|
||||
ii[7] = 1;
|
||||
ii[8] = 0;
|
||||
|
||||
ii.clear();
|
||||
|
||||
strint_map si;
|
||||
|
||||
si["zero"] = 0;
|
||||
si["one"] = 1;
|
||||
si["two"] = 2;
|
||||
si["three"] = 3;
|
||||
si["four"] = 4;
|
||||
|
||||
si.clear();
|
||||
|
||||
intstr_map is;
|
||||
|
||||
is[0] = "goofy";
|
||||
is[1] = "is";
|
||||
is[2] = "smart";
|
||||
is[3] = "!!!";
|
||||
|
||||
is.clear();
|
||||
|
||||
strstr_map ss;
|
||||
|
||||
ss["ciao"] = "hello";
|
||||
ss["casa"] = "house";
|
||||
ss["gatto"] = "cat";
|
||||
ss["a Mac.."] = "..is always a Mac!";
|
||||
|
||||
ss.clear();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -294,6 +294,7 @@ class APIDefaultConstructorTestCase(TestBase):
|
|||
sb_thread.fuzz_obj(obj)
|
||||
|
||||
@python_api_test
|
||||
@unittest2.expectedFailure
|
||||
def test_SBType(self):
|
||||
obj = lldb.SBType()
|
||||
if self.TraceOn():
|
||||
|
@ -304,6 +305,7 @@ class APIDefaultConstructorTestCase(TestBase):
|
|||
sb_type.fuzz_obj(obj)
|
||||
|
||||
@python_api_test
|
||||
@unittest2.expectedFailure
|
||||
def test_SBTypeMember(self):
|
||||
obj = lldb.SBTypeMember()
|
||||
if self.TraceOn():
|
||||
|
|
Loading…
Reference in New Issue