<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Would be worth figuring out why the code that figures out to regenerate that file doesn't work on non-mac platforms. <br><br>Sent from my iPhone</div><div><br>On Oct 8, 2014, at 2:45 PM, Zachary Turner <<a href="mailto:zturner@google.com">zturner@google.com</a>> wrote:<br><br></div><blockquote type="cite"><div><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("<a href="rdar://15630776">rdar://15630776</a> - 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("<a href="rdar://15630776">rdar://15630776</a> - 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>
</div></blockquote></body></html>