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

Zachary Turner zturner at google.com
Wed Oct 8 14:29:37 PDT 2014


Also seeing this on Windows.

On Wed, 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20141008/3cda119b/attachment.html>


More information about the lldb-commits mailing list