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