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

Eric Christopher echristo at gmail.com
Wed Oct 8 15:21:41 PDT 2014


It's unlikely to be OS related, but rather build system related.

-eric

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



More information about the lldb-commits mailing list