[Lldb-commits] [lldb] r219330 - Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)

Enrico Granata egranata at apple.com
Wed Oct 8 13:51:37 PDT 2014


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