[Lldb-commits] [lldb] r135865 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Utility/ lldb.xcodeproj/ scripts/ source/API/ source/Commands/ source/Core/ source/Interpreter/ test/functionalities/data-formatter/data-formatter-python-synth/
Enrico Granata
granata.enrico at gmail.com
Sat Jul 23 17:14:56 PDT 2011
Author: enrico
Date: Sat Jul 23 19:14:56 2011
New Revision: 135865
URL: http://llvm.org/viewvc/llvm-project?rev=135865&view=rev
Log:
Python synthetic children:
- you can now define a Python class as a synthetic children producer for a type
the class must adhere to this "interface":
def __init__(self, valobj, dict):
def get_child_at_index(self, index):
def get_child_index(self, name):
then using type synth add -l className typeName
(e.g. type synth add -l fooSynthProvider foo)
(This is still WIP with lots to be added)
A small test case is available also as reference
Added:
lldb/trunk/include/lldb/Utility/PythonPointer.h
lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/
lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/Makefile
lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
Modified:
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/include/lldb/Core/Debugger.h
lldb/trunk/include/lldb/Core/FormatClasses.h
lldb/trunk/include/lldb/Core/FormatManager.h
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/include/lldb/lldb-forward-rtti.h
lldb/trunk/include/lldb/lldb-forward.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/scripts/lldb.swig
lldb/trunk/source/API/SBCommandInterpreter.cpp
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/FormatClasses.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
lldb/trunk/source/Interpreter/CommandObjectScript.cpp
lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Sat Jul 23 19:14:56 2011
@@ -14,6 +14,10 @@
#include <stdio.h>
+#ifndef SWIG
+class lldb_private::SyntheticScriptProvider;
+#endif
+
namespace lldb {
class SBValue
@@ -205,7 +209,9 @@
friend class SBFrame;
#ifndef SWIG
-
+ // need this to decapsulate the SP from here
+ friend class lldb_private::SyntheticScriptProvider;
+
// Mimic shared pointer...
lldb_private::ValueObject *
get() const;
Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Sat Jul 23 19:14:56 2011
@@ -477,6 +477,11 @@
class Formatting
{
public:
+
+ // use this call to force the FM to consider itself updated even when there is no apparent reason for that
+ static void
+ ForceUpdate();
+
class ValueFormats
{
public:
@@ -507,7 +512,7 @@
lldb::SummaryFormatSP& entry);
static bool
GetSyntheticFilter(ValueObject& vobj,
- lldb::SyntheticFilterSP& entry);
+ lldb::SyntheticChildrenSP& entry);
class NamedSummaryFormats
{
Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Sat Jul 23 19:14:56 2011
@@ -12,6 +12,12 @@
// C Includes
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
#include <stdint.h>
#include <unistd.h>
@@ -25,6 +31,7 @@
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/API/SBValue.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -82,19 +89,90 @@
};
-struct SyntheticFilter
+class SyntheticChildrenFrontEnd
{
+protected:
+ lldb::ValueObjectSP m_backend;
+public:
+
+ SyntheticChildrenFrontEnd(lldb::ValueObjectSP be) :
+ m_backend(be)
+ {}
+
+ virtual
+ ~SyntheticChildrenFrontEnd()
+ {
+ }
+
+ virtual uint32_t
+ CalculateNumChildren() = 0;
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (uint32_t idx, bool can_create) = 0;
+
+ virtual uint32_t
+ GetIndexOfChildWithName (const ConstString &name) = 0;
+
+ typedef lldb::SharedPtr<SyntheticChildrenFrontEnd>::Type SharedPointer;
+
+};
+
+class SyntheticChildren
+{
+public:
bool m_cascades;
bool m_skip_pointers;
bool m_skip_references;
- std::vector<std::string> m_expression_paths;
+public:
+ SyntheticChildren(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false) :
+ m_cascades(casc),
+ m_skip_pointers(skipptr),
+ m_skip_references(skipref)
+ {
+ }
+ virtual
+ ~SyntheticChildren()
+ {
+ }
+
+ bool
+ Cascades() const
+ {
+ return m_cascades;
+ }
+ bool
+ SkipsPointers() const
+ {
+ return m_skip_pointers;
+ }
+ bool
+ SkipsReferences() const
+ {
+ return m_skip_references;
+ }
+
+ virtual std::string
+ GetDescription() = 0;
+
+ virtual SyntheticChildrenFrontEnd::SharedPointer
+ GetFrontEnd(lldb::ValueObjectSP backend) = 0;
+
+ typedef lldb::SharedPtr<SyntheticChildren>::Type SharedPointer;
+ typedef bool(*SyntheticChildrenCallback)(void*, const char*, const SyntheticChildren::SharedPointer&);
+
+};
+
+class SyntheticFilter : public SyntheticChildren
+{
+ std::vector<std::string> m_expression_paths;
+public:
SyntheticFilter(bool casc = false,
bool skipptr = false,
bool skipref = false) :
- m_cascades(casc),
- m_skip_pointers(skipptr),
- m_skip_references(skipref),
+ SyntheticChildren(casc, skipptr, skipref),
m_expression_paths()
{
}
@@ -129,10 +207,149 @@
std::string
GetDescription();
- typedef lldb::SharedPtr<SyntheticFilter>::Type SharedPointer;
- typedef bool(*SyntheticFilterCallback)(void*, const char*, const SyntheticFilter::SharedPointer&);
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ SyntheticFilter* filter;
+ public:
+
+ FrontEnd(SyntheticFilter* flt,
+ lldb::ValueObjectSP be) :
+ SyntheticChildrenFrontEnd(be),
+ filter(flt)
+ {}
+
+ virtual
+ ~FrontEnd()
+ {
+ }
+
+ virtual uint32_t
+ CalculateNumChildren()
+ {
+ return filter->GetCount();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (uint32_t idx, bool can_create)
+ {
+ if (idx >= filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_backend->GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx).c_str(), can_create);
+ }
+
+ virtual uint32_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ const char* name_cstr = name.GetCString();
+ for (int i = 0; i < filter->GetCount(); i++)
+ {
+ const char* expr_cstr = filter->GetExpressionPathAtIndex(i).c_str();
+ if (::strcmp(name_cstr, expr_cstr))
+ return i;
+ }
+ return UINT32_MAX;
+ }
+
+ typedef lldb::SharedPtr<SyntheticChildrenFrontEnd>::Type SharedPointer;
+
+ };
+
+ virtual SyntheticChildrenFrontEnd::SharedPointer
+ GetFrontEnd(lldb::ValueObjectSP backend)
+ {
+ return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(this, backend));
+ }
+
};
+class SyntheticScriptProvider : public SyntheticChildren
+{
+ std::string m_python_class;
+public:
+ SyntheticScriptProvider(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false,
+ std::string pclass = "") :
+ SyntheticChildren(casc, skipptr, skipref),
+ m_python_class(pclass)
+ {
+ }
+
+
+ std::string
+ GetPythonClassName() { return m_python_class; }
+
+ std::string
+ GetDescription();
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ std::string m_python_class;
+ PyObject* m_wrapper;
+ ScriptInterpreter *m_interpreter;
+ public:
+
+ FrontEnd(std::string pclass,
+ lldb::ValueObjectSP be);
+
+ virtual
+ ~FrontEnd()
+ {
+ Py_XDECREF(m_wrapper);
+ }
+
+ virtual uint32_t
+ CalculateNumChildren()
+ {
+ if (m_wrapper == NULL)
+ return 0;
+ return m_interpreter->CalculateNumChildren(m_wrapper);
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (uint32_t idx, bool can_create)
+ {
+ if (m_wrapper == NULL)
+ return lldb::ValueObjectSP();
+
+ PyObject* py_return = (PyObject*)m_interpreter->GetChildAtIndex(m_wrapper, idx);
+ if (py_return == NULL || py_return == Py_None)
+ {
+ Py_XDECREF(py_return);
+ return lldb::ValueObjectSP();
+ }
+
+ lldb::SBValue *sb_ptr = m_interpreter->CastPyObjectToSBValue(py_return);
+
+ if (py_return == NULL)
+ return lldb::ValueObjectSP();
+
+ return sb_ptr->m_opaque_sp;
+ }
+
+ virtual uint32_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ if (m_wrapper == NULL)
+ return UINT32_MAX;
+ return m_interpreter->GetIndexOfChildWithName(m_wrapper, name.GetCString());
+ }
+
+ typedef lldb::SharedPtr<SyntheticChildrenFrontEnd>::Type SharedPointer;
+
+ };
+
+ virtual SyntheticChildrenFrontEnd::SharedPointer
+ GetFrontEnd(lldb::ValueObjectSP backend)
+ {
+ return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(m_python_class, backend));
+ }
+
+};
+
+
struct SummaryFormat
{
bool m_cascades;
Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Sat Jul 23 19:14:56 2011
@@ -545,7 +545,7 @@
bool
Get(ValueObject& vobj,
- lldb::SyntheticFilterSP& entry,
+ lldb::SyntheticChildrenSP& entry,
uint32_t* reason = NULL)
{
if (!IsEnabled())
@@ -791,7 +791,7 @@
bool
Get(ValueObject& vobj,
- lldb::SyntheticFilterSP& entry)
+ lldb::SyntheticChildrenSP& entry)
{
Mutex::Locker(m_map_mutex);
@@ -803,7 +803,7 @@
for (begin = m_active_categories.begin(); begin != end; begin++)
{
FormatCategory::SharedPointer category = *begin;
- lldb::SyntheticFilterSP current_format;
+ lldb::SyntheticChildrenSP current_format;
if (!category->Get(vobj, current_format, &reason_why))
continue;
if (reason_why == lldb::eFormatterDirectChoice)
@@ -947,7 +947,7 @@
}
bool
Get(ValueObject& vobj,
- lldb::SyntheticFilterSP& entry)
+ lldb::SyntheticChildrenSP& entry)
{
return m_categories_map.Get(vobj, entry);
}
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Sat Jul 23 19:14:56 2011
@@ -739,13 +739,14 @@
// as an independent ValueObjectConstResult, which isn't managed by us.
ValueObject *m_deref_valobj;
- lldb::Format m_format;
- uint32_t m_last_format_mgr_revision;
- lldb::SummaryFormatSP m_last_summary_format;
- lldb::SummaryFormatSP m_forced_summary_format;
- lldb::ValueFormatSP m_last_value_format;
- lldb::SyntheticFilterSP m_last_synthetic_filter;
- lldb::user_id_t m_user_id_of_forced_summary;
+ lldb::Format m_format;
+ uint32_t m_last_format_mgr_revision;
+ lldb::SummaryFormatSP m_last_summary_format;
+ lldb::SummaryFormatSP m_forced_summary_format;
+ lldb::ValueFormatSP m_last_value_format;
+ lldb::SyntheticChildrenSP m_last_synthetic_filter;
+ lldb::user_id_t m_user_id_of_forced_summary;
+
bool m_value_is_valid:1,
m_value_did_change:1,
m_children_count_valid:1,
Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Sat Jul 23 19:14:56 2011
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <map>
#include <ostream>
#include <vector>
// Other libraries and framework includes
@@ -21,14 +22,17 @@
namespace lldb_private {
//----------------------------------------------------------------------
-// A ValueObject that represents memory at a given address, viewed as some
-// set lldb type.
+// A ValueObject that obtains its children from some source other than
+// real information
+// This is currently used to implement children filtering, where only
+// a subset of the real children are shown, but it can be used for any
+// source of made-up children information
//----------------------------------------------------------------------
-class ValueObjectSyntheticFilter : public ValueObject
+class ValueObjectSynthetic : public ValueObject
{
public:
virtual
- ~ValueObjectSyntheticFilter();
+ ~ValueObjectSynthetic();
virtual size_t
GetByteSize();
@@ -105,16 +109,25 @@
lldb::TypeSP m_type_sp;
lldb::ValueObjectSP m_owning_valobj_sp;
lldb::SyntheticValueType m_use_synthetic;
- lldb::SyntheticFilterSP m_synth_filter;
+ lldb::SyntheticChildrenFrontEndSP m_synth_filter;
+
+ typedef std::map<uint32_t, lldb::ValueObjectSP> ByIndexMap;
+ typedef std::map<const char*, uint32_t> NameToIndexMap;
+
+ typedef ByIndexMap::iterator ByIndexIterator;
+ typedef NameToIndexMap::iterator NameToIndexIterator;
+
+ ByIndexMap m_children_byindex;
+ NameToIndexMap m_name_toindex;
private:
friend class ValueObject;
- ValueObjectSyntheticFilter (ValueObject &parent, lldb::SyntheticFilterSP filter);
+ ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter);
//------------------------------------------------------------------
// For ValueObject only
//------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (ValueObjectSyntheticFilter);
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectSynthetic);
};
} // namespace lldb_private
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Sat Jul 23 19:14:56 2011
@@ -10,10 +10,13 @@
#ifndef liblldb_ScriptInterpreter_h_
#define liblldb_ScriptInterpreter_h_
+#include "lldb/API/SBValue.h"
+
#include "lldb/lldb-private.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Utility/PseudoTerminal.h"
+
namespace lldb_private {
class ScriptInterpreter
@@ -30,6 +33,15 @@
typedef std::string (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
const char *session_dictionary_name,
const lldb::ValueObjectSP& valobj_sp);
+
+ typedef void* (*SWIGPythonCreateSyntheticProvider) (const std::string python_class_name,
+ 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 enum
{
@@ -89,6 +101,13 @@
return false;
}
+ virtual void*
+ CreateSyntheticScriptedProvider (std::string class_name,
+ lldb::ValueObjectSP valobj)
+ {
+ return NULL;
+ }
+
// use this if the function code is just a one-liner script
virtual bool
GenerateTypeScriptFunction (const char* oneliner, StringList &output)
@@ -113,6 +132,30 @@
{
return;
}
+
+ virtual uint32_t
+ CalculateNumChildren (void *implementor)
+ {
+ return 0;
+ }
+
+ virtual void*
+ GetChildAtIndex (void *implementor, uint32_t idx)
+ {
+ return NULL;
+ }
+
+ virtual int
+ GetIndexOfChildWithName (void *implementor, const char* child_name)
+ {
+ return UINT32_MAX;
+ }
+
+ virtual lldb::SBValue*
+ CastPyObjectToSBValue (void* data)
+ {
+ return NULL;
+ }
const char *
GetScriptInterpreterPtyName ();
@@ -129,7 +172,12 @@
static void
InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback);
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
+ SWIGPythonCalculateNumChildren python_swig_calc_children,
+ SWIGPythonGetChildAtIndex python_swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue);
static void
TerminateInterpreter ();
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Sat Jul 23 19:14:56 2011
@@ -56,6 +56,22 @@
bool
GenerateTypeScriptFunction (const char* oneliner, StringList &output);
+ void*
+ CreateSyntheticScriptedProvider (std::string class_name,
+ lldb::ValueObjectSP valobj);
+
+ virtual uint32_t
+ CalculateNumChildren (void *implementor);
+
+ virtual void*
+ GetChildAtIndex (void *implementor, uint32_t idx);
+
+ virtual int
+ GetIndexOfChildWithName (void *implementor, const char* child_name);
+
+ virtual lldb::SBValue*
+ CastPyObjectToSBValue (void* data);
+
bool
GenerateFunction(std::string& signature, StringList &input, StringList &output);
@@ -103,7 +119,12 @@
static void
InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback);
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
+ SWIGPythonCalculateNumChildren python_swig_calc_children,
+ SWIGPythonGetChildAtIndex python_swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalu);
protected:
Added: lldb/trunk/include/lldb/Utility/PythonPointer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/PythonPointer.h?rev=135865&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Utility/PythonPointer.h (added)
+++ lldb/trunk/include/lldb/Utility/PythonPointer.h Sat Jul 23 19:14:56 2011
@@ -0,0 +1,78 @@
+//===---------------------PythonPointer.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_PythonPointer_h_
+#define utility_PythonPointer_h_
+
+#include <algorithm>
+#include <memory>
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+namespace lldb_private {
+
+template<class T>
+class PythonPointer
+{
+public:
+ typedef PyObject* element_type;
+private:
+ element_type* ptr_;
+ bool my_ref;
+public:
+
+ PythonPointer(element_type p, bool steal_ref = false) :
+ ptr_(p),
+ my_ref(!steal_ref)
+ {
+ if (my_ref)
+ Py_INCREF(ptr_);
+ }
+
+ PythonPointer(const PythonPointer& r, bool steal_ref = false) :
+ ptr_(r.ptr_),
+ my_ref(!steal_ref)
+ {
+ if (my_ref)
+ Py_INCREF(ptr_);
+ }
+
+ ~PythonPointer()
+ {
+ if (my_ref)
+ Py_XDECREF(ptr_);
+ }
+
+ PythonPointer
+ StealReference()
+ {
+ return PythonPointer(ptr_,true);
+ }
+
+ PythonPointer
+ DuplicateReference()
+ {
+ return PythonPointer(ptr_, false);
+ }
+
+ element_type get() const {return ptr_;}
+
+ bool IsNull() { return ptr_ == NULL; }
+ bool IsNone() { return ptr_ == Py_None; }
+
+ operator PyObject* () { return ptr_; }
+};
+
+} // namespace lldb
+
+#endif // utility_PythonPointer_h_
Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward-rtti.h (original)
+++ lldb/trunk/include/lldb/lldb-forward-rtti.h Sat Jul 23 19:14:56 2011
@@ -67,7 +67,8 @@
typedef SharedPtr<lldb_private::SummaryFormat>::Type SummaryFormatSP;
typedef SharedPtr<lldb_private::SymbolFile>::Type SymbolFileSP;
typedef SharedPtr<lldb_private::SymbolContextSpecifier>::Type SymbolContextSpecifierSP;
- typedef SharedPtr<lldb_private::SyntheticFilter>::Type SyntheticFilterSP;
+ typedef SharedPtr<lldb_private::SyntheticChildren>::Type SyntheticChildrenSP;
+ typedef SharedPtr<lldb_private::SyntheticChildrenFrontEnd>::Type SyntheticChildrenFrontEndSP;
typedef SharedPtr<lldb_private::Target>::Type TargetSP;
typedef SharedPtr<lldb_private::Thread>::Type ThreadSP;
typedef SharedPtr<lldb_private::ThreadPlan>::Type ThreadPlanSP;
Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Sat Jul 23 19:14:56 2011
@@ -144,7 +144,9 @@
class SymbolFile;
class SymbolVendor;
class Symtab;
-class SyntheticFilter;
+class SyntheticChildren;
+class SyntheticChildrenFrontEnd;
+class SyntheticScriptProvider;
class Target;
class TargetList;
class Thread;
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sat Jul 23 19:14:56 2011
@@ -1221,6 +1221,7 @@
94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/Core/FormatClasses.cpp; sourceTree = "<group>"; };
94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = "<group>"; };
94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = "<group>"; };
+ 94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = "<group>"; };
961FABB81235DE1600F93A47 /* FuncUnwinders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FuncUnwinders.cpp; path = source/Symbol/FuncUnwinders.cpp; sourceTree = "<group>"; };
961FABB91235DE1600F93A47 /* UnwindPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindPlan.cpp; path = source/Symbol/UnwindPlan.cpp; sourceTree = "<group>"; };
961FABBA1235DE1600F93A47 /* UnwindTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindTable.cpp; path = source/Symbol/UnwindTable.cpp; sourceTree = "<group>"; };
@@ -1864,6 +1865,7 @@
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */,
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */,
+ 94EBAC8313D9EE26009BA64E /* PythonPointer.h */,
);
name = Utility;
sourceTree = "<group>";
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Sat Jul 23 19:14:56 2011
@@ -281,7 +281,6 @@
// Find the current session's dictionary in the main module's dictionary.
if (PyDict_Check (main_dict))
-
{
session_dict = NULL;
while (PyDict_Next (main_dict, &pos, &key, &value))
@@ -401,7 +400,6 @@
// Find the current session's dictionary in the main module's dictionary.
if (PyDict_Check (main_dict))
-
{
session_dict = NULL;
while (PyDict_Next (main_dict, &pos, &key, &value))
@@ -493,5 +491,278 @@
return retval;
}
+SWIGEXPORT void*
+LLDBSwigPythonCreateSyntheticProvider
+(
+ const std::string python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+)
+{
+ PyObject* retval = NULL;
+
+ if (python_class_name.empty() || !session_dictionary_name)
+ Py_RETURN_NONE;
+
+ lldb::ValueObjectSP* valobj_sp_ptr = new lldb::ValueObjectSP(valobj_sp);
+
+ PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) valobj_sp_ptr, SWIGTYPE_p_lldb__SBValue, SWIG_POINTER_OWN);
+
+ if (ValObj_PyObj == NULL)
+ Py_RETURN_NONE;
+
+ const char* python_function_name = python_class_name.c_str();
+
+ PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+ PyObject *pvalue;
+
+ pmodule = PyImport_AddModule ("__main__");
+ if (pmodule != NULL)
+ {
+ main_dict = PyModule_GetDict (pmodule);
+ if (main_dict != NULL)
+ {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ // Find the current session's dictionary in the main module's dictionary.
+
+ if (PyDict_Check (main_dict))
+ {
+ session_dict = NULL;
+ while (PyDict_Next (main_dict, &pos, &key, &value))
+ {
+ // We have stolen references to the key and value objects in the dictionary; we need to increment
+ // them now so that Python's garbage collector doesn't collect them out from under us.
+ Py_INCREF (key);
+ Py_INCREF (value);
+ if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
+ {
+ session_dict = value;
+ break;
+ }
+ }
+ }
+
+ if (!session_dict || !PyDict_Check (session_dict))
+ return retval;
+
+ // Find the function we need to call in the current session's dictionary.
+
+ pos = 0;
+ pfunc = NULL;
+ while (PyDict_Next (session_dict, &pos, &key, &value))
+ {
+ if (PyString_Check (key))
+ {
+ // We have stolen references to the key and value objects in the dictionary; we need to increment
+ // them now so that Python's garbage collector doesn't collect them out from under us.
+ Py_INCREF (key);
+ Py_INCREF (value);
+ if (strcmp (PyString_AsString (key), python_function_name) == 0)
+ {
+ pfunc = value;
+ break;
+ }
+ }
+ }
+
+ // Set up the arguments and call the function.
+
+ if (pfunc && PyCallable_Check (pfunc))
+ {
+ PyObject *argList = Py_BuildValue("SS", ValObj_PyObj, session_dict);
+
+ if (PyErr_Occurred ())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ return retval;
+ }
+
+ if (argList == NULL)
+ {
+ return retval;
+ }
+
+ Py_INCREF(ValObj_PyObj);
+
+ pvalue = PyObject_CallObject(pfunc, argList);
+
+ Py_DECREF(argList);
+
+ if (pvalue != NULL)
+ {
+ if (pvalue != Py_None)
+ retval = pvalue;
+ else
+ {
+ retval = Py_None;
+ Py_INCREF(retval);
+ }
+ }
+ else if (PyErr_Occurred ())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ Py_INCREF (session_dict);
+ }
+ else if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ else if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ else if (PyErr_Occurred ())
+ {
+ PyErr_Print();
+ PyErr_Clear ();
+ }
+ if (retval)
+ return retval;
+ else
+ Py_RETURN_NONE;
+}
+
+/*
+these four calls below are meant to support
+Python-based synthetic children providers
+they essentially mimic the four pure virtual
+method calls provided by the frontend class
+*/
+
+SWIGEXPORT uint32_t
+LLDBSwigPython_CalculateNumChildren
+(
+ PyObject *implementor
+)
+{
+
+ static char callee_name[] = "num_children";
+
+ if (implementor == NULL || implementor == Py_None)
+ return 0;
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return == NULL || py_return == Py_None)
+ {
+ Py_XDECREF(py_return);
+ return UINT32_MAX;
+ }
+ long retval = PyInt_AsLong(py_return);
+ Py_DECREF(py_return);
+ if (retval >= 0)
+ return (uint32_t)retval;
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ return 0;
+}
+
+SWIGEXPORT PyObject*
+LLDBSwigPython_GetChildAtIndex
+(
+ PyObject *implementor,
+ uint32_t idx
+)
+{
+
+ static char callee_name[] = "get_child_at_index";
+ static char param_format[] = "i";
+
+ if (implementor == NULL || implementor == Py_None)
+ return NULL;
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, idx);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return == NULL || py_return == Py_None)
+ {
+ Py_XDECREF(py_return);
+ return NULL;
+ }
+
+ lldb::SBValue* sbvalue_ptr = NULL;
+
+ if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
+ {
+ Py_DECREF(py_return);
+ return NULL;
+ }
+
+ if (sbvalue_ptr == NULL)
+ return NULL;
+
+ return py_return;
+}
+
+SWIGEXPORT int
+LLDBSwigPython_GetIndexOfChildWithName
+(
+ PyObject *implementor,
+ const char* child_name
+)
+{
+ static char callee_name[] = "get_child_index";
+ static char param_format[] = "s";
+
+ if (implementor == NULL || implementor == Py_None)
+ return 0;
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, child_name);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return == NULL || py_return == Py_None)
+ {
+ Py_XDECREF(py_return);
+ return UINT32_MAX;
+ }
+ long retval = PyInt_AsLong(py_return);
+ Py_DECREF(py_return);
+ if (retval >= 0)
+ return (uint32_t)retval;
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ return 0;
+}
+
+SWIGEXPORT lldb::SBValue*
+LLDBSWIGPython_CastPyObjectToSBValue
+(
+ PyObject* data
+)
+{
+ lldb::SBValue* sb_ptr = NULL;
+
+ int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
%}
Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Sat Jul 23 19:14:56 2011
@@ -322,6 +322,19 @@
const lldb::ValueObjectSP& valobj_sp
);
+extern "C" void*
+LLDBSwigPythonCreateSyntheticProvider
+(
+ const std::string python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+);
+
+
+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 init_lldb(void);
@@ -334,6 +347,11 @@
g_initialized = true;
ScriptInterpreter::InitializeInterpreter (init_lldb,
LLDBSwigPythonBreakpointCallbackFunction,
- LLDBSwigPythonCallTypeScript);
+ LLDBSwigPythonCallTypeScript,
+ LLDBSwigPythonCreateSyntheticProvider,
+ LLDBSwigPython_CalculateNumChildren,
+ LLDBSwigPython_GetChildAtIndex,
+ LLDBSwigPython_GetIndexOfChildWithName,
+ LLDBSWIGPython_CastPyObjectToSBValue);
}
}
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Sat Jul 23 19:14:56 2011
@@ -10,6 +10,9 @@
#include "CommandObjectType.h"
// C Includes
+
+#include <ctype.h>
+
// C++ Includes
#include "lldb/Core/ConstString.h"
@@ -418,8 +421,8 @@
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
-static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
- "def function (valobj,dict):";
+static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+ "def function (valobj,dict):";
class TypeScriptAddInputReader : public InputReaderEZ
{
@@ -441,7 +444,7 @@
bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
if (!batch_mode)
{
- out_stream->Printf ("%s\n", g_reader_instructions);
+ out_stream->Printf ("%s\n", g_summary_addreader_instructions);
if (data.reader.GetPrompt())
out_stream->Printf ("%s", data.reader.GetPrompt());
out_stream->Flush();
@@ -1016,7 +1019,7 @@
" value = valobj.GetChildMemberWithName('value');\n"
" return 'My value is ' + value.GetValue();\n"
"DONE\n"
- "(lldb)"
+ "(lldb) <-- type further LLDB commands here\n"
);
}
@@ -2404,6 +2407,10 @@
case 'c':
m_expr_paths.push_back(option_arg);
break;
+ case 'l':
+ m_class_name = std::string(option_arg);
+ is_class_based = true;
+ break;
case 'p':
m_skip_pointers = true;
break;
@@ -2425,10 +2432,12 @@
OptionParsingStarting ()
{
m_cascade = true;
- m_expr_paths.clear();
+ m_class_name = "";
m_skip_pointers = false;
m_skip_references = false;
m_category = NULL;
+ m_expr_paths.clear();
+ is_class_based = false;
}
const OptionDefinition*
@@ -2446,9 +2455,13 @@
bool m_cascade;
bool m_skip_references;
bool m_skip_pointers;
+ std::string m_class_name;
+ bool m_input_python;
option_vector m_expr_paths;
const char* m_category;
+ bool is_class_based;
+
typedef option_vector::iterator ExpressionPathsIterator;
};
@@ -2460,31 +2473,8 @@
return &m_options;
}
-public:
- CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
- CommandObject (interpreter,
- "type synth add",
- "Add a new synthetic provider for a type.",
- NULL), m_options (interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- }
-
- ~CommandObjectTypeSynthAdd ()
- {
- }
-
bool
- Execute (Args& command, CommandReturnObject &result)
+ Execute_ChildrenList (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
@@ -2502,17 +2492,19 @@
return false;
}
- SyntheticFilterSP entry;
+ SyntheticChildrenSP entry;
- entry.reset(new SyntheticFilter(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references));
+ SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references);
+
+ entry.reset(impl);
// go through the expression paths
CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
- entry->AddExpressionPath(*begin);
+ impl->AddExpressionPath(*begin);
// now I have a valid provider, let's add it to every type
@@ -2536,16 +2528,100 @@
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
+
+ bool
+ Execute_PythonClass (Args& command, CommandReturnObject &result)
+ {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1)
+ {
+ result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.m_class_name.empty() && !m_options.m_input_python)
+ {
+ result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ SyntheticChildrenSP entry;
+
+ SyntheticScriptProvider* impl = new SyntheticScriptProvider(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_class_name);
+
+ entry.reset(impl);
+
+ // now I have a valid provider, let's add it to every type
+
+ lldb::FormatCategorySP category;
+ Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+
+ for (size_t i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ ConstString typeCS(typeA);
+ if (typeCS)
+ category->Filter()->Add(typeCS.GetCString(), entry);
+ else
+ {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+
+public:
+
+ CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "type synth add",
+ "Add a new synthetic provider for a type.",
+ NULL), m_options (interpreter)
+ {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back (type_style_arg);
+
+ m_arguments.push_back (type_arg);
+
+ }
+
+ ~CommandObjectTypeSynthAdd ()
+ {
+ }
+
+ bool
+ Execute (Args& command, CommandReturnObject &result)
+ {
+ if (m_options.is_class_based)
+ return Execute_PythonClass(command, result);
+ else
+ return Execute_ChildrenList(command, result);
+ }
};
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, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."},
{ 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, "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."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Sat Jul 23 19:14:56 2011
@@ -1746,6 +1746,12 @@
return g_format_manager;
}
+void
+Debugger::Formatting::ForceUpdate()
+{
+ GetFormatManager().Changed();
+}
+
bool
Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry)
{
@@ -1796,7 +1802,7 @@
}
bool
Debugger::Formatting::GetSyntheticFilter(ValueObject& vobj,
- lldb::SyntheticFilterSP& entry)
+ lldb::SyntheticChildrenSP& entry)
{
return GetFormatManager().Get(vobj, entry);
}
Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Sat Jul 23 19:14:56 2011
@@ -21,8 +21,10 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatClasses.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -156,3 +158,25 @@
sstr.Printf("}");
return sstr.GetString();
}
+
+SyntheticScriptProvider::FrontEnd::FrontEnd(std::string pclass,
+ lldb::ValueObjectSP be) :
+SyntheticChildrenFrontEnd(be),
+m_python_class(pclass)
+{
+ m_interpreter = be->GetUpdatePoint().GetTarget()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ m_wrapper = (PyObject*)m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
+}
+
+std::string
+SyntheticScriptProvider::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s Python class: %s",
+ m_cascades ? "" : " (not cascading)",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "",
+ m_python_class.c_str());
+
+ return sstr.GetString();
+}
\ No newline at end of file
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Sat Jul 23 19:14:56 2011
@@ -219,6 +219,8 @@
m_last_value_format.reset(/*(ValueFormat*)NULL*/);
if (m_last_synthetic_filter.get())
m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/);
+
+ m_synthetic_value = NULL;
Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
@@ -1493,7 +1495,8 @@
if (m_last_synthetic_filter.get() == NULL)
return;
- m_synthetic_value = new ValueObjectSyntheticFilter(*this, m_last_synthetic_filter);
+ if (m_synthetic_value == NULL)
+ m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
}
Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Sat Jul 23 19:14:56 2011
@@ -35,23 +35,25 @@
using namespace lldb_private;
-ValueObjectSyntheticFilter::ValueObjectSyntheticFilter (ValueObject &parent, lldb::SyntheticFilterSP filter) :
+ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
ValueObject(parent),
m_address (),
m_type_sp(),
-m_use_synthetic (lldb::eUseSyntheticFilter),
- m_synth_filter(filter)
+ m_use_synthetic (lldb::eUseSyntheticFilter),
+ m_synth_filter(filter->GetFrontEnd(parent.GetSP())),
+ m_children_byindex(),
+ m_name_toindex()
{
SetName (parent.GetName().AsCString());
}
-ValueObjectSyntheticFilter::~ValueObjectSyntheticFilter()
+ValueObjectSynthetic::~ValueObjectSynthetic()
{
m_owning_valobj_sp.reset();
}
lldb::clang_type_t
-ValueObjectSyntheticFilter::GetClangType ()
+ValueObjectSynthetic::GetClangType ()
{
if (m_type_sp)
return m_value.GetClangType();
@@ -60,7 +62,7 @@
}
ConstString
-ValueObjectSyntheticFilter::GetTypeName()
+ValueObjectSynthetic::GetTypeName()
{
const bool success = UpdateValueIfNeeded();
if (success && m_type_sp)
@@ -70,22 +72,13 @@
}
uint32_t
-ValueObjectSyntheticFilter::CalculateNumChildren()
+ValueObjectSynthetic::CalculateNumChildren()
{
- const bool success = UpdateValueIfNeeded();
- if (!success)
- return 0;
- if (m_synth_filter.get())
- return m_synth_filter->GetCount();
- return 0;
- if (success && m_type_sp)
- return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
- else
- return m_parent->GetNumChildren();
+ return m_synth_filter->CalculateNumChildren();
}
clang::ASTContext *
-ValueObjectSyntheticFilter::GetClangAST ()
+ValueObjectSynthetic::GetClangAST ()
{
const bool success = UpdateValueIfNeeded(false);
if (success && m_type_sp)
@@ -95,7 +88,7 @@
}
size_t
-ValueObjectSyntheticFilter::GetByteSize()
+ValueObjectSynthetic::GetByteSize()
{
const bool success = UpdateValueIfNeeded();
if (success && m_type_sp)
@@ -105,13 +98,13 @@
}
lldb::ValueType
-ValueObjectSyntheticFilter::GetValueType() const
+ValueObjectSynthetic::GetValueType() const
{
return m_parent->GetValueType();
}
bool
-ValueObjectSyntheticFilter::UpdateValue ()
+ValueObjectSynthetic::UpdateValue ()
{
SetValueIsValid (false);
m_error.Clear();
@@ -124,46 +117,61 @@
return false;
}
+ m_children_byindex.clear();
+ m_name_toindex.clear();
+
SetValueIsValid(true);
return true;
}
lldb::ValueObjectSP
-ValueObjectSyntheticFilter::GetChildAtIndex (uint32_t idx, bool can_create)
+ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create)
{
- if (!m_synth_filter.get())
- return lldb::ValueObjectSP();
- if (idx >= m_synth_filter->GetCount())
- return lldb::ValueObjectSP();
- return m_parent->GetSyntheticExpressionPathChild(m_synth_filter->GetExpressionPathAtIndex(idx).c_str(), can_create);
+ ByIndexIterator iter = m_children_byindex.find(idx);
+
+ if (iter == m_children_byindex.end())
+ {
+ if (can_create)
+ {
+ lldb::ValueObjectSP synth_guy = m_synth_filter->GetChildAtIndex (idx, can_create);
+ m_children_byindex[idx]= synth_guy;
+ return synth_guy;
+ }
+ else
+ return lldb::ValueObjectSP();
+ }
+ else
+ return iter->second;
}
lldb::ValueObjectSP
-ValueObjectSyntheticFilter::GetChildMemberWithName (const ConstString &name, bool can_create)
+ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
{
- if (!m_synth_filter.get())
- return lldb::ValueObjectSP();
- uint32_t idx = GetIndexOfChildWithName(name);
- if (idx >= m_synth_filter->GetCount())
+
+ uint32_t index = GetIndexOfChildWithName(name);
+
+ if (index == UINT32_MAX)
return lldb::ValueObjectSP();
- return m_parent->GetSyntheticExpressionPathChild(name.GetCString(), can_create);
+
+ return GetChildAtIndex(index, can_create);
}
uint32_t
-ValueObjectSyntheticFilter::GetIndexOfChildWithName (const ConstString &name)
+ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
{
- const char* name_cstr = name.GetCString();
- for (int i = 0; i < m_synth_filter->GetCount(); i++)
+ NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
+
+ if (iter == m_name_toindex.end())
{
- const char* expr_cstr = m_synth_filter->GetExpressionPathAtIndex(i).c_str();
- if (::strcmp(name_cstr, expr_cstr))
- return i;
+ uint32_t index = m_synth_filter->GetIndexOfChildWithName (name);
+ m_name_toindex[name.GetCString()] = index;
+ return index;
}
- return UINT32_MAX;
+ return iter->second;
}
bool
-ValueObjectSyntheticFilter::IsInScope ()
+ValueObjectSynthetic::IsInScope ()
{
return m_parent->IsInScope();
}
Modified: lldb/trunk/source/Interpreter/CommandObjectScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObjectScript.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObjectScript.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObjectScript.cpp Sat Jul 23 19:14:56 2011
@@ -13,6 +13,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+
+#include "lldb/Core/Debugger.h"
+
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -54,6 +57,8 @@
result.SetStatus (eReturnStatusFailed);
}
+ Debugger::Formatting::ForceUpdate(); // script might change Python code we use for formatting.. make sure we keep up to date with it
+
if (command == NULL || command[0] == '\0') {
script_interpreter->ExecuteInterpreterLoop ();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Sat Jul 23 19:14:56 2011
@@ -93,11 +93,21 @@
void
ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback)
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
+ SWIGPythonCalculateNumChildren python_swig_calc_children,
+ SWIGPythonGetChildAtIndex python_swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue)
{
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
python_swig_breakpoint_callback,
- python_swig_typescript_callback);
+ python_swig_typescript_callback,
+ python_swig_synthetic_script,
+ python_swig_calc_children,
+ python_swig_get_child_index,
+ python_swig_get_index_child,
+ python_swig_cast_to_sbvalue);
}
void
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=135865&r1=135864&r2=135865&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Sat Jul 23 19:14:56 2011
@@ -35,7 +35,11 @@
static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = NULL;
static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = NULL;
static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = NULL;
-
+static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = NULL;
+static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = NULL;
+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 int
_check_and_flush (FILE *stream)
@@ -1245,6 +1249,55 @@
return true;
}
+void*
+ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
+ lldb::ValueObjectSP valobj)
+{
+ if (class_name.empty())
+ return NULL;
+
+ if (!valobj.get())
+ return NULL;
+
+ Target *target = valobj->GetUpdatePoint().GetTarget();
+
+ if (!target)
+ return NULL;
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
+
+ if (!script_interpreter)
+ return NULL;
+
+ void* ret_val;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_synthetic_script (class_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_synthetic_script (class_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
bool
ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, StringList &output)
{
@@ -1565,15 +1618,161 @@
return NULL;
}
+uint32_t
+ScriptInterpreterPython::CalculateNumChildren (void *implementor)
+{
+ if (!implementor)
+ return 0;
+
+ if (!g_swig_calc_children)
+ return 0;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ uint32_t ret_val = 0;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_calc_children (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 ();
+ ret_val = g_swig_calc_children (implementor);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+void*
+ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx)
+{
+ if (!implementor)
+ return 0;
+
+ if (!g_swig_get_child_index)
+ return 0;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ void* ret_val = NULL;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_child_index (implementor,idx);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_child_index (implementor,idx);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+int
+ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char* child_name)
+{
+ if (!implementor)
+ return UINT32_MAX;
+
+ if (!g_swig_get_index_child)
+ return UINT32_MAX;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ int ret_val = UINT32_MAX;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_index_child (implementor, child_name);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_index_child (implementor, child_name);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+lldb::SBValue*
+ScriptInterpreterPython::CastPyObjectToSBValue (void* data)
+{
+ if (!data)
+ return NULL;
+
+ if (!g_swig_cast_to_sbvalue)
+ return NULL;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ lldb::SBValue* ret_val = NULL;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_cast_to_sbvalue (data);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_cast_to_sbvalue (data);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback)
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
+ SWIGPythonCalculateNumChildren python_swig_calc_children,
+ SWIGPythonGetChildAtIndex python_swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue)
{
g_swig_init_callback = python_swig_init_callback;
g_swig_breakpoint_callback = python_swig_breakpoint_callback;
g_swig_typescript_callback = python_swig_typescript_callback;
+ g_swig_synthetic_script = python_swig_synthetic_script;
+ g_swig_calc_children = python_swig_calc_children;
+ 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;
}
void
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/Makefile?rev=135865&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/Makefile Sat Jul 23 19:14:56 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=135865&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Sat Jul 23 19:14:56 2011
@@ -0,0 +1,95 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-python-synth")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+ BREAKPOINT_CREATED,
+ startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+ self.line)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # print the f00_1 variable without a synth
+ self.expect("frame variable f00_1",
+ substrs = ['a = 0',
+ 'b = 1',
+ 'r = 33']);
+
+ # now set up the synth
+ self.runCmd("script from fooSynthProvider import *")
+ self.runCmd("type synth add -l fooSynthProvider foo")
+
+ # check that we get only the two variables
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'a = 0']);
+
+ # check that we do not get the extra vars and that we cache results
+ self.expect("frame variable f00_1", matching=False,
+ substrs = ['looking for',
+ 'b = 1']);
+
+ # check that the caching does not span beyond the stopoint
+ self.runCmd("n")
+
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'a = 1']);
+
+ # 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',
+ 'b = 1',
+ 'r = 33']);
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py?rev=135865&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py Sat Jul 23 19:14:56 2011
@@ -0,0 +1,16 @@
+class fooSynthProvider:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ def num_children(self):
+ return 2;
+ def get_child_at_index(self, index):
+ if index == 1:
+ child = self.valobj.GetChildMemberWithName('a');
+ else:
+ child = self.valobj.GetChildMemberWithName('r');
+ return child;
+ def get_child_index(self, name):
+ if name == 'a':
+ return 1;
+ else:
+ return 0;
\ No newline at end of file
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp?rev=135865&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp Sat Jul 23 19:14:56 2011
@@ -0,0 +1,53 @@
+struct foo
+{
+ int a;
+ int b;
+ int c;
+ int d;
+ int e;
+ int f;
+ int g;
+ int h;
+ int i;
+ int j;
+ int k;
+ int l;
+ int m;
+ int n;
+ int o;
+ int p;
+ int q;
+ int r;
+
+ foo(int X) :
+ a(X),
+ b(X+1),
+ c(X+3),
+ d(X+5),
+ e(X+7),
+ f(X+9),
+ g(X+11),
+ h(X+13),
+ i(X+15),
+ j(X+17),
+ k(X+19),
+ l(X+21),
+ m(X+23),
+ n(X+25),
+ o(X+27),
+ p(X+29),
+ q(X+31),
+ r(X+33) {}
+};
+
+int main()
+{
+ foo f00_1(0);
+ foo f00_2(6);
+ foo *f00_3 = new foo(12);
+ foo& f00_4 = *(new foo(18));
+
+ f00_1.a++; // Set break point at this line.
+
+ return 0;
+}
\ No newline at end of file
More information about the lldb-commits
mailing list