[Lldb-commits] [lldb] r219330 - Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
Eric Christopher
echristo at gmail.com
Wed Oct 8 14:06:52 PDT 2014
Seems to have been it. Frustrating.
-eric
On Wed, Oct 8, 2014 at 1:51 PM, Enrico Granata <egranata at apple.com> wrote:
> Not really. It sounds like your LLDBWrapPython.cpp might not be getting regenerated. Try a clean build maybe?
>
> Sent from my iPhone
>
>> On Oct 8, 2014, at 1:31 PM, Eric Christopher <echristo at gmail.com> wrote:
>>
>> Seeing a link error after this:
>>
>> /usr/local/google/home/echristo/sources/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp:534:
>> error: undefined reference to
>> 'LLDBSwigPython_GetValueSynthProviderInstance'
>>
>> Thoughts?
>>
>> -eric
>>
>>> On Wed, Oct 8, 2014 at 11:27 AM, Enrico Granata <egranata at apple.com> wrote:
>>> Author: enrico
>>> Date: Wed Oct 8 13:27:36 2014
>>> New Revision: 219330
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=219330&view=rev
>>> Log:
>>> Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
>>>
>>> The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
>>> If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
>>>
>>> The rationale for doing things this way is twofold:
>>>
>>> - there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
>>> - we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
>>> On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
>>>
>>> Comes with a test case
>>>
>>>
>>> Added:
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/Makefile
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/main.cpp
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py
>>> Modified:
>>> lldb/trunk/include/lldb/Core/ValueObject.h
>>> lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
>>> lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h
>>> lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h
>>> lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
>>> lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
>>> lldb/trunk/scripts/Python/python-wrapper.swig
>>> lldb/trunk/source/API/SBCommandInterpreter.cpp
>>> lldb/trunk/source/Core/ValueObject.cpp
>>> lldb/trunk/source/Core/ValueObjectCast.cpp
>>> lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
>>> lldb/trunk/source/Core/ValueObjectMemory.cpp
>>> lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
>>> lldb/trunk/source/Core/ValueObjectVariable.cpp
>>> lldb/trunk/source/DataFormatters/TypeFormat.cpp
>>> lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp
>>> lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
>>> lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
>>> lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
>>>
>>> Modified: lldb/trunk/include/lldb/Core/ValueObject.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/Core/ValueObject.h (original)
>>> +++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Oct 8 13:27:36 2014
>>> @@ -88,6 +88,7 @@ public:
>>> {
>>> eExpressionPathScanEndReasonEndOfString = 1, // out of data to parse
>>> eExpressionPathScanEndReasonNoSuchChild, // child element not found
>>> + eExpressionPathScanEndReasonNoSuchSyntheticChild, // (synthetic) child element not found
>>> eExpressionPathScanEndReasonEmptyRangeNotAllowed, // [] only allowed for arrays
>>> eExpressionPathScanEndReasonDotInsteadOfArrow, // . used when -> should be used
>>> eExpressionPathScanEndReasonArrowInsteadOfDot, // -> used when . should be used
>>> @@ -379,6 +380,9 @@ public:
>>> // this vends a TypeImpl that is useful at the SB API layer
>>> virtual TypeImpl
>>> GetTypeImpl ();
>>> +
>>> + virtual bool
>>> + CanProvideValue ();
>>>
>>> //------------------------------------------------------------------
>>> // Subclasses must implement the functions below.
>>> @@ -755,6 +759,12 @@ public:
>>> {
>>> return false;
>>> }
>>> +
>>> + virtual bool
>>> + DoesProvideSyntheticValue ()
>>> + {
>>> + return false;
>>> + }
>>>
>>> virtual SymbolContextScope *
>>> GetSymbolContextScope();
>>>
>>> Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
>>> +++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Wed Oct 8 13:27:36 2014
>>> @@ -132,11 +132,12 @@ public:
>>> GetNonSyntheticValue ();
>>>
>>> virtual bool
>>> - ResolveValue (Scalar &scalar)
>>> + CanProvideValue ();
>>> +
>>> + virtual bool
>>> + DoesProvideSyntheticValue ()
>>> {
>>> - if (m_parent)
>>> - return m_parent->ResolveValue(scalar);
>>> - return false;
>>> + return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes);
>>> }
>>>
>>> protected:
>>> @@ -167,12 +168,14 @@ protected:
>>>
>>> LazyBool m_might_have_children;
>>>
>>> + LazyBool m_provides_value;
>>> +
>>> private:
>>> friend class ValueObject;
>>> ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter);
>>>
>>> void
>>> - CopyParentData ();
>>> + CopyValueData (ValueObject *source);
>>>
>>> //------------------------------------------------------------------
>>> // For ValueObject only
>>>
>>> Modified: lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h (original)
>>> +++ lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h Wed Oct 8 13:27:36 2014
>>> @@ -81,6 +81,11 @@ namespace lldb_private {
>>> virtual bool
>>> MightHaveChildren () = 0;
>>>
>>> + // if this function returns a non-null ValueObject, then the returned ValueObject will stand
>>> + // for this ValueObject whenever a "value" request is made to this ValueObject
>>> + virtual lldb::ValueObjectSP
>>> + GetSyntheticValue () { return nullptr; }
>>> +
>>> typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
>>> typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
>>>
>>> @@ -593,6 +598,15 @@ namespace lldb_private {
>>> return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
>>> }
>>>
>>> + virtual lldb::ValueObjectSP
>>> + GetSyntheticValue ()
>>> + {
>>> + if (!m_wrapper_sp || m_interpreter == NULL)
>>> + return nullptr;
>>> +
>>> + return m_interpreter->GetSyntheticValue(m_wrapper_sp);
>>> + }
>>> +
>>> typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
>>>
>>> private:
>>>
>>> Modified: lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h (original)
>>> +++ lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h Wed Oct 8 13:27:36 2014
>>> @@ -295,7 +295,7 @@ protected:
>>> uint32_t curr_depth);
>>>
>>> bool
>>> - GetDynamicValueIfNeeded ();
>>> + GetMostSpecializedValue ();
>>>
>>> const char*
>>> GetDescriptionForDisplay ();
>>>
>>> Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
>>> +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Wed Oct 8 13:27:36 2014
>>> @@ -121,7 +121,7 @@ public:
>>> typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data);
>>> typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data);
>>> typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
>>> -
>>> + typedef void* (*SWIGPythonGetValueSynthProviderInstance) (void *implementor);
>>>
>>> typedef bool (*SWIGPythonCallCommand) (const char *python_function_name,
>>> const char *session_dictionary_name,
>>> @@ -498,6 +498,12 @@ public:
>>> return true;
>>> }
>>>
>>> + virtual lldb::ValueObjectSP
>>> + GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor)
>>> + {
>>> + return nullptr;
>>> + }
>>> +
>>> virtual bool
>>> RunScriptBasedCommand (const char* impl_function,
>>> const char* args,
>>> @@ -607,6 +613,7 @@ public:
>>> SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
>>> SWIGPythonUpdateSynthProviderInstance swig_update_provider,
>>> SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
>>> + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
>>> SWIGPythonCallCommand swig_call_command,
>>> SWIGPythonCallModuleInit swig_call_module_init,
>>> SWIGPythonCreateOSPlugin swig_create_os_plugin,
>>>
>>> Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
>>> +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Wed Oct 8 13:27:36 2014
>>> @@ -141,6 +141,9 @@ public:
>>> virtual bool
>>> MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
>>>
>>> + virtual lldb::ValueObjectSP
>>> + GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor);
>>> +
>>> virtual bool
>>> RunScriptBasedCommand(const char* impl_function,
>>> const char* args,
>>> @@ -285,6 +288,7 @@ public:
>>> SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
>>> SWIGPythonUpdateSynthProviderInstance swig_update_provider,
>>> SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
>>> + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
>>> SWIGPythonCallCommand swig_call_command,
>>> SWIGPythonCallModuleInit swig_call_module_init,
>>> SWIGPythonCreateOSPlugin swig_create_os_plugin,
>>>
>>> Modified: lldb/trunk/scripts/Python/python-wrapper.swig
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/scripts/Python/python-wrapper.swig (original)
>>> +++ lldb/trunk/scripts/Python/python-wrapper.swig Wed Oct 8 13:27:36 2014
>>> @@ -723,6 +723,34 @@ LLDBSwigPython_MightHaveChildrenSynthPro
>>> return ret_val;
>>> }
>>>
>>> +SWIGEXPORT PyObject*
>>> +LLDBSwigPython_GetValueSynthProviderInstance
>>> +(
>>> + PyObject *implementor
>>> +)
>>> +{
>>> + PyObject* ret_val = nullptr;
>>> +
>>> + static char callee_name[] = "get_value";
>>> +
>>> + PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);
>>> +
>>> + if (py_return == Py_None || py_return == nullptr)
>>> + ret_val = nullptr;
>>> +
>>> + lldb::SBValue* sbvalue_ptr = NULL;
>>> +
>>> + if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
>>> + ret_val = nullptr;
>>> + else if (sbvalue_ptr == NULL)
>>> + ret_val = nullptr;
>>> + else
>>> + ret_val = py_return;
>>> +
>>> + Py_XDECREF(py_return);
>>> + return ret_val;
>>> +}
>>> +
>>> SWIGEXPORT void*
>>> LLDBSWIGPython_CastPyObjectToSBValue
>>> (
>>>
>>> Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
>>> +++ lldb/trunk/source/API/SBCommandInterpreter.cpp Wed Oct 8 13:27:36 2014
>>> @@ -474,6 +474,9 @@ LLDBSwigPython_UpdateSynthProviderInstan
>>> extern "C" bool
>>> LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
>>>
>>> +extern "C" void *
>>> +LLDBSwigPython_GetValueSynthProviderInstance (void* implementor);
>>> +
>>> extern "C" bool
>>> LLDBSwigPythonCallCommand (const char *python_function_name,
>>> const char *session_dictionary_name,
>>> @@ -544,6 +547,7 @@ SBCommandInterpreter::InitializeSWIG ()
>>> LLDBSWIGPython_GetValueObjectSPFromSBValue,
>>> LLDBSwigPython_UpdateSynthProviderInstance,
>>> LLDBSwigPython_MightHaveChildrenSynthProviderInstance,
>>> + LLDBSwigPython_GetValueSynthProviderInstance,
>>> LLDBSwigPythonCallCommand,
>>> LLDBSwigPythonCallModuleInit,
>>> LLDBSWIGPythonCreateOSPlugin,
>>>
>>> Modified: lldb/trunk/source/Core/ValueObject.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObject.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObject.cpp Wed Oct 8 13:27:36 2014
>>> @@ -1450,7 +1450,7 @@ ValueObject::GetValueAsCString ()
>>> }
>>> else
>>> {
>>> - my_format = GetClangType().GetFormat();
>>> + my_format = GetValue().GetClangType().GetFormat();
>>> }
>>> }
>>> }
>>> @@ -1482,7 +1482,7 @@ uint64_t
>>> ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
>>> {
>>> // If our byte size is zero this is an aggregate type that has children
>>> - if (!GetClangType().IsAggregateType())
>>> + if (CanProvideValue())
>>> {
>>> Scalar scalar;
>>> if (ResolveValue (scalar))
>>> @@ -1503,7 +1503,7 @@ int64_t
>>> ValueObject::GetValueAsSigned (int64_t fail_value, bool *success)
>>> {
>>> // If our byte size is zero this is an aggregate type that has children
>>> - if (!GetClangType().IsAggregateType())
>>> + if (CanProvideValue())
>>> {
>>> Scalar scalar;
>>> if (ResolveValue (scalar))
>>> @@ -1751,7 +1751,7 @@ ValueObject::DumpPrintableRepresentation
>>> cstr = GetSummaryAsCString();
>>> else if (val_obj_display == eValueObjectRepresentationStyleSummary)
>>> {
>>> - if (GetClangType().IsAggregateType())
>>> + if (!CanProvideValue())
>>> {
>>> strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
>>> cstr = strm.GetString().c_str();
>>> @@ -2805,7 +2805,7 @@ ValueObject::GetValueForExpressionPath_I
>>> if (root->IsSynthetic())
>>> {
>>> *first_unparsed = expression_cstr;
>>> - *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
>>> + *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchSyntheticChild;
>>> *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
>>> return ValueObjectSP();
>>> }
>>> @@ -4080,3 +4080,9 @@ ValueObject::GetFormat () const
>>> }
>>> return m_format;
>>> }
>>> +
>>> +bool
>>> +ValueObject::CanProvideValue ()
>>> +{
>>> + return (false == GetClangType().IsAggregateType());
>>> +}
>>>
>>> Modified: lldb/trunk/source/Core/ValueObjectCast.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectCast.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObjectCast.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObjectCast.cpp Wed Oct 8 13:27:36 2014
>>> @@ -102,7 +102,7 @@ ValueObjectCast::UpdateValue ()
>>> //m_value.SetContext (Value::eContextTypeClangType, clang_type);
>>> m_value.SetClangType (clang_type);
>>> SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
>>> - if (clang_type.IsAggregateType ())
>>> + if (!CanProvideValue())
>>> {
>>> // this value object represents an aggregate type whose
>>> // children have values, but this object does not. So we
>>>
>>> Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Wed Oct 8 13:27:36 2014
>>> @@ -329,7 +329,7 @@ ValueObjectDynamicValue::UpdateValue ()
>>> m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
>>> if (m_error.Success())
>>> {
>>> - if (GetClangType().IsAggregateType ())
>>> + if (!CanProvideValue())
>>> {
>>> // this value object represents an aggregate type whose
>>> // children have values, but this object does not. So we
>>>
>>> Modified: lldb/trunk/source/Core/ValueObjectMemory.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectMemory.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObjectMemory.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObjectMemory.cpp Wed Oct 8 13:27:36 2014
>>> @@ -233,7 +233,7 @@ ValueObjectMemory::UpdateValue ()
>>> }
>>> }
>>>
>>> - if (GetClangType().IsAggregateType())
>>> + if (!CanProvideValue())
>>> {
>>> // this value object represents an aggregate type whose
>>> // children have values, but this object does not. So we
>>>
>>> Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Wed Oct 8 13:27:36 2014
>>> @@ -66,16 +66,17 @@ ValueObjectSynthetic::ValueObjectSynthet
>>> m_name_toindex(),
>>> m_synthetic_children_count(UINT32_MAX),
>>> m_parent_type_name(parent.GetTypeName()),
>>> - m_might_have_children(eLazyBoolCalculate)
>>> + m_might_have_children(eLazyBoolCalculate),
>>> + m_provides_value(eLazyBoolCalculate)
>>> {
>>> -#ifdef LLDB_CONFIGURATION_DEBUG
>>> +#ifdef FOOBAR
>>> std::string new_name(parent.GetName().AsCString());
>>> new_name += "$$__synth__";
>>> SetName (ConstString(new_name.c_str()));
>>> #else
>>> SetName(parent.GetName());
>>> #endif
>>> - CopyParentData();
>>> + CopyValueData(m_parent);
>>> CreateSynthFilter();
>>> }
>>>
>>> @@ -191,7 +192,20 @@ ValueObjectSynthetic::UpdateValue ()
>>> m_might_have_children = eLazyBoolCalculate;
>>> }
>>>
>>> - CopyParentData();
>>> + m_provides_value = eLazyBoolCalculate;
>>> +
>>> + lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
>>> +
>>> + if (synth_val && synth_val->CanProvideValue())
>>> + {
>>> + m_provides_value = eLazyBoolYes;
>>> + CopyValueData(synth_val.get());
>>> + }
>>> + else
>>> + {
>>> + m_provides_value = eLazyBoolNo;
>>> + CopyValueData(m_parent);
>>> + }
>>>
>>> SetValueIsValid(true);
>>> return true;
>>> @@ -268,9 +282,19 @@ ValueObjectSynthetic::GetNonSyntheticVal
>>> }
>>>
>>> void
>>> -ValueObjectSynthetic::CopyParentData ()
>>> +ValueObjectSynthetic::CopyValueData (ValueObject *source)
>>> {
>>> - m_value = m_parent->GetValue();
>>> + m_value = (source->UpdateValueIfNeeded(), source->GetValue());
>>> ExecutionContext exe_ctx (GetExecutionContextRef());
>>> m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
>>> }
>>> +
>>> +bool
>>> +ValueObjectSynthetic::CanProvideValue ()
>>> +{
>>> + if (!UpdateValueIfNeeded())
>>> + return false;
>>> + if (m_provides_value == eLazyBoolYes)
>>> + return true;
>>> + return m_parent->CanProvideValue();
>>> +}
>>>
>>> Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
>>> +++ lldb/trunk/source/Core/ValueObjectVariable.cpp Wed Oct 8 13:27:36 2014
>>> @@ -234,7 +234,7 @@ ValueObjectVariable::UpdateValue ()
>>> }
>>> }
>>>
>>> - if (GetClangType().IsAggregateType())
>>> + if (!CanProvideValue())
>>> {
>>> // this value object represents an aggregate type whose
>>> // children have values, but this object does not. So we
>>>
>>> Modified: lldb/trunk/source/DataFormatters/TypeFormat.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/TypeFormat.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/DataFormatters/TypeFormat.cpp (original)
>>> +++ lldb/trunk/source/DataFormatters/TypeFormat.cpp Wed Oct 8 13:27:36 2014
>>> @@ -59,9 +59,9 @@ TypeFormatImpl_Format::FormatObject (Val
>>> {
>>> if (!valobj)
>>> return false;
>>> - if (valobj->GetClangType().IsAggregateType () == false)
>>> + if (valobj->CanProvideValue())
>>> {
>>> - const Value& value(valobj->GetValue());
>>> + Value& value(valobj->GetValue());
>>> const Value::ContextType context_type = value.GetContextType();
>>> ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
>>> DataExtractor data;
>>> @@ -92,7 +92,7 @@ TypeFormatImpl_Format::FormatObject (Val
>>> }
>>> else
>>> {
>>> - ClangASTType clang_type = valobj->GetClangType ();
>>> + ClangASTType clang_type = value.GetClangType ();
>>> if (clang_type)
>>> {
>>> // put custom bytes to display in the DataExtractor to override the default value logic
>>> @@ -180,7 +180,7 @@ TypeFormatImpl_EnumType::FormatObject (V
>>> dest.clear();
>>> if (!valobj)
>>> return false;
>>> - if (valobj->GetClangType().IsAggregateType ())
>>> + if (!valobj->CanProvideValue())
>>> return false;
>>> ProcessSP process_sp;
>>> TargetSP target_sp;
>>>
>>> Modified: lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp (original)
>>> +++ lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp Wed Oct 8 13:27:36 2014
>>> @@ -66,7 +66,7 @@ ValueObjectPrinter::Init (ValueObject* v
>>> bool
>>> ValueObjectPrinter::PrintValueObject ()
>>> {
>>> - if (!GetDynamicValueIfNeeded () || m_valobj == nullptr)
>>> + if (!GetMostSpecializedValue () || m_valobj == nullptr)
>>> return false;
>>>
>>> if (ShouldPrintValueObject())
>>> @@ -97,7 +97,7 @@ ValueObjectPrinter::PrintValueObject ()
>>> }
>>>
>>> bool
>>> -ValueObjectPrinter::GetDynamicValueIfNeeded ()
>>> +ValueObjectPrinter::GetMostSpecializedValue ()
>>> {
>>> if (m_valobj)
>>> return true;
>>> @@ -134,6 +134,25 @@ ValueObjectPrinter::GetDynamicValueIfNee
>>> else
>>> m_valobj = m_orig_valobj;
>>> }
>>> +
>>> + if (m_valobj->IsSynthetic())
>>> + {
>>> + if (options.m_use_synthetic == false)
>>> + {
>>> + ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
>>> + if (non_synthetic)
>>> + m_valobj = non_synthetic;
>>> + }
>>> + }
>>> + else
>>> + {
>>> + if (options.m_use_synthetic == true)
>>> + {
>>> + ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
>>> + if (synthetic)
>>> + m_valobj = synthetic;
>>> + }
>>> + }
>>> }
>>> m_clang_type = m_valobj->GetClangType();
>>> m_type_flags = m_clang_type.GetTypeInfo ();
>>> @@ -442,8 +461,7 @@ ValueObjectPrinter::ShouldPrintChildren
>>> ValueObject*
>>> ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
>>> {
>>> - ValueObjectSP synth_valobj_sp = m_valobj->GetSyntheticValue (options.m_use_synthetic);
>>> - return (synth_valobj_sp ? synth_valobj_sp.get() : m_valobj);
>>> + return m_valobj;
>>> }
>>>
>>> void
>>> @@ -540,7 +558,13 @@ ValueObjectPrinter::PrintChildren (uint3
>>> {
>>> // Aggregate, no children...
>>> if (ShouldPrintValueObject())
>>> - m_stream->PutCString(" {}\n");
>>> + {
>>> + // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
>>> + if (m_valobj->DoesProvideSyntheticValue())
>>> + m_stream->PutCString( "\n");
>>> + else
>>> + m_stream->PutCString(" {}\n");
>>> + }
>>> }
>>> else
>>> {
>>> @@ -552,7 +576,7 @@ ValueObjectPrinter::PrintChildren (uint3
>>> bool
>>> ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
>>> {
>>> - if (!GetDynamicValueIfNeeded () || m_valobj == nullptr)
>>> + if (!GetMostSpecializedValue () || m_valobj == nullptr)
>>> return false;
>>>
>>> ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
>>>
>>> Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
>>> +++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Wed Oct 8 13:27:36 2014
>>> @@ -124,6 +124,7 @@ ScriptInterpreter::InitializeInterpreter
>>> SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
>>> SWIGPythonUpdateSynthProviderInstance swig_update_provider,
>>> SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
>>> + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
>>> SWIGPythonCallCommand swig_call_command,
>>> SWIGPythonCallModuleInit swig_call_module_init,
>>> SWIGPythonCreateOSPlugin swig_create_os_plugin,
>>> @@ -148,6 +149,7 @@ ScriptInterpreter::InitializeInterpreter
>>> swig_get_valobj_sp_from_sbvalue,
>>> swig_update_provider,
>>> swig_mighthavechildren_provider,
>>> + swig_getvalue_provider,
>>> swig_call_command,
>>> swig_call_module_init,
>>> swig_create_os_plugin,
>>>
>>> Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
>>> +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Wed Oct 8 13:27:36 2014
>>> @@ -55,6 +55,7 @@ static ScriptInterpreter::SWIGPythonCast
>>> static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
>>> static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
>>> static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
>>> +static ScriptInterpreter::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
>>> static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
>>> static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
>>> static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
>>> @@ -2140,6 +2141,42 @@ ScriptInterpreterPython::MightHaveChildr
>>> return ret_val;
>>> }
>>>
>>> +lldb::ValueObjectSP
>>> +ScriptInterpreterPython::GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor_sp)
>>> +{
>>> + lldb::ValueObjectSP ret_val(nullptr);
>>> +
>>> + if (!implementor_sp)
>>> + return ret_val;
>>> +
>>> + void* implementor = implementor_sp->GetObject();
>>> +
>>> + if (!implementor)
>>> + return ret_val;
>>> +
>>> + if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue || !g_swig_get_valobj_sp_from_sbvalue)
>>> + return ret_val;
>>> +
>>> + {
>>> + Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
>>> + void* child_ptr = g_swig_getvalue_provider (implementor);
>>> + if (child_ptr != nullptr && child_ptr != Py_None)
>>> + {
>>> + lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
>>> + if (sb_value_ptr == nullptr)
>>> + Py_XDECREF(child_ptr);
>>> + else
>>> + ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
>>> + }
>>> + else
>>> + {
>>> + Py_XDECREF(child_ptr);
>>> + }
>>> + }
>>> +
>>> + return ret_val;
>>> +}
>>> +
>>> static std::string
>>> ReadPythonBacktrace (PyObject* py_backtrace)
>>> {
>>> @@ -2616,6 +2653,7 @@ ScriptInterpreterPython::InitializeInter
>>> SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
>>> SWIGPythonUpdateSynthProviderInstance swig_update_provider,
>>> SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
>>> + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
>>> SWIGPythonCallCommand swig_call_command,
>>> SWIGPythonCallModuleInit swig_call_module_init,
>>> SWIGPythonCreateOSPlugin swig_create_os_plugin,
>>> @@ -2639,6 +2677,7 @@ ScriptInterpreterPython::InitializeInter
>>> g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
>>> g_swig_update_provider = swig_update_provider;
>>> g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
>>> + g_swig_getvalue_provider = swig_getvalue_provider;
>>> g_swig_call_command = swig_call_command;
>>> g_swig_call_module_init = swig_call_module_init;
>>> g_swig_create_os_plugin = swig_create_os_plugin;
>>>
>>> Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py?rev=219330&r1=219329&r2=219330&view=diff
>>> ==============================================================================
>>> --- lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py (original)
>>> +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py Wed Oct 8 13:27:36 2014
>>> @@ -14,12 +14,14 @@ class SynthDataFormatterTestCase(TestBas
>>>
>>> @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
>>> @dsym_test
>>> + @unittest2.expectedFailure("rdar://15630776 - Summary cannot reference non-synthetic children if synthetic children exist")
>>> def test_with_dsym_and_run_command(self):
>>> """Test data formatter commands."""
>>> self.buildDsym()
>>> self.data_formatter_commands()
>>>
>>> @dwarf_test
>>> + @unittest2.expectedFailure("rdar://15630776 - Summary cannot reference non-synthetic children if synthetic children exist")
>>> def test_with_dwarf_and_run_command(self):
>>> """Test data formatter commands."""
>>> self.buildDwarf()
>>>
>>> Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/Makefile
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/Makefile?rev=219330&view=auto
>>> ==============================================================================
>>> --- lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/Makefile (added)
>>> +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/Makefile Wed Oct 8 13:27:36 2014
>>> @@ -0,0 +1,5 @@
>>> +LEVEL = ../../../make
>>> +
>>> +CXX_SOURCES := main.cpp
>>> +
>>> +include $(LEVEL)/Makefile.rules
>>>
>>> Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py?rev=219330&view=auto
>>> ==============================================================================
>>> --- lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py (added)
>>> +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py Wed Oct 8 13:27:36 2014
>>> @@ -0,0 +1,95 @@
>>> +"""
>>> +Test lldb data formatter subsystem.
>>> +"""
>>> +
>>> +import os, time
>>> +import unittest2
>>> +import lldb
>>> +from lldbtest import *
>>> +import lldbutil
>>> +
>>> +class DataFormatterSynthValueTestCase(TestBase):
>>> +
>>> + mydir = TestBase.compute_mydir(__file__)
>>> +
>>> + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
>>> + @dsym_test
>>> + def test_with_dsym_and_run_command(self):
>>> + """Test using Python synthetic children provider to provide a value."""
>>> + self.buildDsym()
>>> + self.data_formatter_commands()
>>> +
>>> + @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
>>> + @dwarf_test
>>> + def test_with_dwarf_and_run_command(self):
>>> + """Test using Python synthetic children provider to provide a value."""
>>> + 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', 'break here')
>>> +
>>> + def data_formatter_commands(self):
>>> + """Test using Python synthetic children provider to provide a value."""
>>> + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
>>> +
>>> + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
>>> +
>>> + 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 filter clear', check=False)
>>> + self.runCmd('type synth clear', check=False)
>>> +
>>> + # Execute the cleanup function during test case tear down.
>>> + self.addTearDownHook(cleanup)
>>> +
>>> + x = self.frame().FindVariable("x")
>>> + x.SetPreferSyntheticValue(True)
>>> + y = self.frame().FindVariable("y")
>>> + y.SetPreferSyntheticValue(True)
>>> + z = self.frame().FindVariable("z")
>>> + z.SetPreferSyntheticValue(True)
>>> +
>>> + x_val = x.GetValueAsUnsigned
>>> + y_val = y.GetValueAsUnsigned
>>> + z_val = z.GetValueAsUnsigned
>>> +
>>> + if self.TraceOn():
>>> + print "x_val = %s; y_val = %s; z_val = %s" % (x_val(),y_val(),z_val())
>>> +
>>> + self.assertFalse(x_val() == 3, "x == 3 before synthetics")
>>> + self.assertFalse(y_val() == 4, "y == 4 before synthetics")
>>> + self.assertFalse(z_val() == 7, "z == 7 before synthetics")
>>> +
>>> + # now set up the synth
>>> + self.runCmd("script from myIntSynthProvider import *")
>>> + self.runCmd("type synth add -l myIntSynthProvider myInt")
>>> +
>>> + if self.TraceOn():
>>> + print "x_val = %s; y_val = %s; z_val = %s" % (x_val(),y_val(),z_val())
>>> +
>>> + self.assertTrue(x_val() == 3, "x != 3 after synthetics")
>>> + self.assertTrue(y_val() == 4, "y != 4 after synthetics")
>>> + self.assertTrue(z_val() == 7, "z != 7 after synthetics")
>>> +
>>> + self.expect("frame variable x", substrs=['3'])
>>> + self.expect("frame variable x", substrs=['theValue = 3'], matching=False)
>>> +
>>> +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-synthval/main.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/main.cpp?rev=219330&view=auto
>>> ==============================================================================
>>> --- lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/main.cpp (added)
>>> +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/main.cpp Wed Oct 8 13:27:36 2014
>>> @@ -0,0 +1,15 @@
>>> +class myInt {
>>> + private: int theValue;
>>> + public: myInt() : theValue(0) {}
>>> + public: myInt(int _x) : theValue(_x) {}
>>> + int val() { return theValue; }
>>> +};
>>> +
>>> +myInt operator + (myInt x, myInt y) { return myInt(x.val() + y.val()); }
>>> +
>>> +int main() {
>>> + myInt x{3};
>>> + myInt y{4};
>>> + myInt z {x+y};
>>> + return z.val(); // break here
>>> +}
>>>
>>> Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py
>>> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py?rev=219330&view=auto
>>> ==============================================================================
>>> --- lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py (added)
>>> +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py Wed Oct 8 13:27:36 2014
>>> @@ -0,0 +1,17 @@
>>> +class myIntSynthProvider(object):
>>> + def __init__(self, valobj, dict):
>>> + self.valobj = valobj;
>>> + self.val = self.valobj.GetChildMemberWithName("theValue")
>>> + def num_children(self):
>>> + return 0;
>>> + def get_child_at_index(self, index):
>>> + return None
>>> + def get_child_index(self, name):
>>> + return None
>>> + def update(self):
>>> + return False
>>> + def might_have_children(self):
>>> + return False
>>> + def get_value(self):
>>> + return self.val
>>> +
>>>
>>>
>>> _______________________________________________
>>> lldb-commits mailing list
>>> lldb-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list