[Lldb-commits] [lldb] r153061 - in /lldb/trunk: examples/synthetic/ include/lldb/ include/lldb/Core/ include/lldb/Interpreter/ scripts/Python/ source/Commands/ source/Core/ source/Interpreter/ source/Target/ test/functionalities/data-formatter/data-formatter-cpp/ test/functionalities/data-formatter/data-formatter-python-synth/ test/functionalities/data-formatter/data-formatter-stl/libcxx/list/ test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/ test/functionalities/data-formatter/data-formatter-synth/

Enrico Granata egranata at apple.com
Mon Mar 19 15:58:51 PDT 2012


Author: enrico
Date: Mon Mar 19 17:58:49 2012
New Revision: 153061

URL: http://llvm.org/viewvc/llvm-project?rev=153061&view=rev
Log:
Massive enumeration name changes: a number of enums in ValueObject were not following the naming pattern
Changes to synthetic children:
 - the update(self): function can now (optionally) return a value - if it returns boolean value True, ValueObjectSyntheticFilter will not clear its caches across stop-points
   this should allow better performance for Python-based synthetic children when one can be sure that the child ValueObjects have not changed
 - making a difference between a synthetic VO and a VO with a synthetic value: now a ValueObjectSyntheticFilter will not return itself as its own synthetic value, but will (correctly)
   claim to itself be synthetic
 - cleared up the internal synthetic children architecture to make a more consistent use of pointers and references instead of shared pointers when possible
 - major cleanup of unnecessary #include, data and functions in ValueObjectSyntheticFilter itself
 - removed the SyntheticValueType enum and replaced it with a plain boolean (to which it was equivalent in the first place)
Some clean ups to the summary generation code
Centralized the code that clears out user-visible strings and data in ValueObject
More efficient summaries for libc++ containers

Modified:
    lldb/trunk/examples/synthetic/gnu_libstdcpp.py
    lldb/trunk/examples/synthetic/libcxx.py
    lldb/trunk/include/lldb/Core/FormatClasses.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/FormatClasses.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/source/Target/StackFrame.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py

Modified: lldb/trunk/examples/synthetic/gnu_libstdcpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/gnu_libstdcpp.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/gnu_libstdcpp.py (original)
+++ lldb/trunk/examples/synthetic/gnu_libstdcpp.py Mon Mar 19 17:58:49 2012
@@ -10,7 +10,6 @@
 
 	def __init__(self, valobj, dict):
 		self.valobj = valobj
-		self.update()
 
 	def next_node(self,node):
 		return node.GetChildMemberWithName('_M_next')
@@ -109,7 +108,6 @@
 
 	def __init__(self, valobj, dict):
 		self.valobj = valobj;
-		self.update()
 
 	def num_children(self):
 		if self.count == None:
@@ -193,7 +191,6 @@
 
 	def __init__(self, valobj, dict):
 		self.valobj = valobj;
-		self.update()
 		
 	# we need this function as a temporary workaround for rdar://problem/10801549
 	# which prevents us from extracting the std::pair<K,V> SBType out of the template

Modified: lldb/trunk/examples/synthetic/libcxx.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/libcxx.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/libcxx.py (original)
+++ lldb/trunk/examples/synthetic/libcxx.py Mon Mar 19 17:58:49 2012
@@ -56,7 +56,6 @@
 
 	def __init__(self, valobj, dict):
 		self.valobj = valobj;
-		self.update()
 
 	def num_children(self):
 		try:
@@ -114,6 +113,7 @@
 		except:
 			pass
 
+# Just an example: the actual summary is produced by a summary string: size=${svar%#}
 def stdvector_SummaryProvider(valobj,dict):
 	prov = stdvector_SynthProvider(valobj,None)
 	return 'size=' + str(prov.num_children())
@@ -180,7 +180,6 @@
 class stdlist_SynthProvider:
 	def __init__(self, valobj, dict):
 		self.valobj = valobj
-		self.update()
 
 	def next_node(self,node):
 		return node.GetChildMemberWithName('__next_')
@@ -272,6 +271,7 @@
 		except:
 			pass
 
+# Just an example: the actual summary is produced by a summary string: size=${svar%#}
 def stdlist_SummaryProvider(valobj,dict):
 	prov = stdlist_SynthProvider(valobj,None)
 	return 'size=' + str(prov.num_children())
@@ -368,7 +368,6 @@
 	def __init__(self, valobj, dict):
 		self.valobj = valobj;
 		self.pointer_size = self.valobj.GetProcess().GetAddressByteSize()
-		self.update()
 
 	def update(self):
 		try:
@@ -462,6 +461,7 @@
 			print err
 			return None
 
+# Just an example: the actual summary is produced by a summary string: size=${svar%#}
 def stdmap_SummaryProvider(valobj,dict):
 	prov = stdmap_SynthProvider(valobj,None)
 	return 'size=' + str(prov.num_children())

Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Mon Mar 19 17:58:49 2012
@@ -217,16 +217,19 @@
     Flags m_flags;
     lldb::Format m_format;
     uint32_t m_my_revision;
-};
     
+private:
+    DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
+};
+
 class SyntheticChildrenFrontEnd
 {
 protected:
-    lldb::ValueObjectSP m_backend;
+    ValueObject &m_backend;
 public:
     
-    SyntheticChildrenFrontEnd(lldb::ValueObjectSP be) :
-    m_backend(be)
+    SyntheticChildrenFrontEnd(ValueObject &backend) :
+    m_backend(backend)
     {}
     
     virtual
@@ -243,13 +246,21 @@
     virtual uint32_t
     GetIndexOfChildWithName (const ConstString &name) = 0;
     
-    virtual void
+    // this function is assumed to always succeed and it if fails, the front-end should know to deal
+    // with it in the correct way (most probably, by refusing to return any children)
+    // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
+    // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
+    // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
+    virtual bool
     Update() = 0;
     
     typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-
-};
+    typedef std::auto_ptr<SyntheticChildrenFrontEnd> AutoPointer;
     
+private:
+    DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
+};
+
 class SyntheticChildren
 {
 public:
@@ -419,8 +430,8 @@
     virtual std::string
     GetDescription () = 0;
     
-    virtual SyntheticChildrenFrontEnd::SharedPointer
-    GetFrontEnd (lldb::ValueObjectSP backend) = 0;
+    virtual SyntheticChildrenFrontEnd::AutoPointer
+    GetFrontEnd (ValueObject &backend) = 0;
     
     typedef STD_SHARED_PTR(SyntheticChildren) SharedPointer;
     typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
@@ -434,6 +445,9 @@
 protected:
     uint32_t m_my_revision;
     Flags m_flags;
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
 };
 
 class TypeFilterImpl : public SyntheticChildren
@@ -525,8 +539,8 @@
     public:
         
         FrontEnd(TypeFilterImpl* flt,
-                 lldb::ValueObjectSP be) :
-        SyntheticChildrenFrontEnd(be),
+                 ValueObject &backend) :
+        SyntheticChildrenFrontEnd(backend),
         filter(flt)
         {}
         
@@ -546,11 +560,11 @@
         {
             if (idx >= filter->GetCount())
                 return lldb::ValueObjectSP();
-            return m_backend->GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), can_create);
+            return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), can_create);
         }
         
-        virtual void
-        Update() {}
+        virtual bool
+        Update() { return false; }
         
         virtual uint32_t
         GetIndexOfChildWithName (const ConstString &name)
@@ -567,14 +581,18 @@
         
         typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
         
+    private:
+        DISALLOW_COPY_AND_ASSIGN(FrontEnd);
     };
     
-    virtual SyntheticChildrenFrontEnd::SharedPointer
-    GetFrontEnd(lldb::ValueObjectSP backend)
+    virtual SyntheticChildrenFrontEnd::AutoPointer
+    GetFrontEnd(ValueObject &backend)
     {
-        return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(this, backend));
+        return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
     }
     
+private:
+    DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
 };
 
 #ifndef LLDB_DISABLE_PYTHON
@@ -641,7 +659,7 @@
     public:
         
         FrontEnd(std::string pclass,
-                 lldb::ValueObjectSP be);
+                 ValueObject &backend);
         
         virtual
         ~FrontEnd();
@@ -657,13 +675,13 @@
         virtual lldb::ValueObjectSP
         GetChildAtIndex (uint32_t idx, bool can_create);
         
-        virtual void
+        virtual bool
         Update()
         {
             if (!m_wrapper_sp || m_interpreter == NULL)
-                return;
+                return false;
             
-            m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
+            return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
         }
                 
         virtual uint32_t
@@ -675,14 +693,19 @@
         }
         
         typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-        
+
+    private:
+        DISALLOW_COPY_AND_ASSIGN(FrontEnd);
     };
     
-    virtual SyntheticChildrenFrontEnd::SharedPointer
-    GetFrontEnd(lldb::ValueObjectSP backend)
+    virtual SyntheticChildrenFrontEnd::AutoPointer
+    GetFrontEnd(ValueObject &backend)
     {
-        return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(m_python_class, backend));
+        return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
     }    
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(TypeSyntheticImpl);
 };
 
 #endif // #ifndef LLDB_DISABLE_PYTHON
@@ -841,8 +864,8 @@
     public:
         
         FrontEnd(SyntheticArrayView* flt,
-                 lldb::ValueObjectSP be) :
-        SyntheticChildrenFrontEnd(be),
+                 ValueObject &backend) :
+        SyntheticChildrenFrontEnd(backend),
         filter(flt)
         {}
         
@@ -862,28 +885,32 @@
         {
             if (idx >= filter->GetCount())
                 return lldb::ValueObjectSP();
-            return m_backend->GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), can_create);
+            return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), can_create);
         }
         
-        virtual void
-        Update() {}
+        virtual bool
+        Update() { return false; }
         
         virtual uint32_t
         GetIndexOfChildWithName (const ConstString &name_cs);
         
         typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-        
+    
+    private:
+        DISALLOW_COPY_AND_ASSIGN(FrontEnd);
     };
     
-    virtual SyntheticChildrenFrontEnd::SharedPointer
-    GetFrontEnd(lldb::ValueObjectSP backend)
+    virtual SyntheticChildrenFrontEnd::AutoPointer
+    GetFrontEnd(ValueObject &backend)
     {
-        return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(this, backend));
+        return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
     }
 private:
     SyntheticArrayRange m_head;
     SyntheticArrayRange *m_tail;
-    
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(SyntheticArrayView);
 };
 
 
@@ -1158,8 +1185,11 @@
     {
     }
     
+    // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
+    // extended periods of time and we trust the ValueObject to stay around for as long as it is required
+    // for us to generate its summary
     virtual bool
-    FormatObject (lldb::ValueObjectSP object,
+    FormatObject (ValueObject *valobj,
                   std::string& dest) = 0;
     
     virtual std::string
@@ -1181,7 +1211,9 @@
 protected:
     uint32_t m_my_revision;
     Flags m_flags;
-
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
 };
 
 // simple string-based summaries, using ${var to show data
@@ -1213,7 +1245,7 @@
     }
     
     virtual bool
-    FormatObject(lldb::ValueObjectSP object,
+    FormatObject(ValueObject *valobj,
                  std::string& dest);
     
     virtual std::string
@@ -1224,7 +1256,10 @@
     {
         return false;
     }
-        
+
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
 };
     
 #ifndef LLDB_DISABLE_PYTHON
@@ -1277,7 +1312,7 @@
     }
     
     virtual bool
-    FormatObject(lldb::ValueObjectSP object,
+    FormatObject(ValueObject *valobj,
                  std::string& dest);
     
     virtual std::string
@@ -1291,6 +1326,9 @@
     
     typedef STD_SHARED_PTR(ScriptSummaryFormat) SharedPointer;
 
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
 };
 
 #endif // #ifndef LLDB_DISABLE_PYTHON
@@ -1317,7 +1355,7 @@
     }
     
     // if constructing with a given type, is_regex cannot be true since we are
-    // very clearly pap
+    // giving an exact type to match
     TypeNameSpecifierImpl (lldb::TypeSP type) :
     m_is_regex(false),
     m_type()
@@ -1381,6 +1419,10 @@
         lldb::TypeImplSP m_typeimpl_sp;
     };
     TypeOrName m_type;
+    
+    
+private:
+    DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl);
 };
     
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Mon Mar 19 17:58:49 2012
@@ -69,54 +69,67 @@
     
     enum GetExpressionPathFormat
     {
-        eDereferencePointers = 1,
-        eHonorPointers
+        eGetExpressionPathFormatDereferencePointers = 1,
+        eGetExpressionPathFormatHonorPointers
     };
     
     enum ValueObjectRepresentationStyle
     {
-        eDisplayValue = 1,
-        eDisplaySummary,
-        eDisplayLanguageSpecific,
-        eDisplayLocation,
-        eDisplayChildrenCount,
-        eDisplayType
+        eValueObjectRepresentationStyleValue = 1,
+        eValueObjectRepresentationStyleSummary,
+        eValueObjectRepresentationStyleLanguageSpecific,
+        eValueObjectRepresentationStyleLocation,
+        eValueObjectRepresentationStyleChildrenCount,
+        eValueObjectRepresentationStyleType
     };
     
     enum ExpressionPathScanEndReason
     {
-        eEndOfString = 1,           // out of data to parse
-        eNoSuchChild,               // child element not found
-        eEmptyRangeNotAllowed,      // [] only allowed for arrays
-        eDotInsteadOfArrow,         // . used when -> should be used
-        eArrowInsteadOfDot,         // -> used when . should be used
-        eFragileIVarNotAllowed,     // ObjC ivar expansion not allowed
-        eRangeOperatorNotAllowed,   // [] not allowed by options
-        eRangeOperatorInvalid,      // [] not valid on objects other than scalars, pointers or arrays
-        eArrayRangeOperatorMet,     // [] is good for arrays, but I cannot parse it
-        eBitfieldRangeOperatorMet,  // [] is good for bitfields, but I cannot parse after it
-        eUnexpectedSymbol,          // something is malformed in the expression
-        eTakingAddressFailed,       // impossible to apply & operator
-        eDereferencingFailed,       // impossible to apply * operator
-        eRangeOperatorExpanded,     // [] was expanded into a VOList
-        eUnknown = 0xFFFF
+        eExpressionPathScanEndReasonEndOfString = 1,           // out of data to parse
+        eExpressionPathScanEndReasonNoSuchChild,               // child element not found
+        eExpressionPathScanEndReasonEmptyRangeNotAllowed,      // [] only allowed for arrays
+        eExpressionPathScanEndReasonDotInsteadOfArrow,         // . used when -> should be used
+        eExpressionPathScanEndReasonArrowInsteadOfDot,         // -> used when . should be used
+        eExpressionPathScanEndReasonFragileIVarNotAllowed,     // ObjC ivar expansion not allowed
+        eExpressionPathScanEndReasonRangeOperatorNotAllowed,   // [] not allowed by options
+        eExpressionPathScanEndReasonRangeOperatorInvalid,      // [] not valid on objects other than scalars, pointers or arrays
+        eExpressionPathScanEndReasonArrayRangeOperatorMet,     // [] is good for arrays, but I cannot parse it
+        eExpressionPathScanEndReasonBitfieldRangeOperatorMet,  // [] is good for bitfields, but I cannot parse after it
+        eExpressionPathScanEndReasonUnexpectedSymbol,          // something is malformed in the expression
+        eExpressionPathScanEndReasonTakingAddressFailed,       // impossible to apply & operator
+        eExpressionPathScanEndReasonDereferencingFailed,       // impossible to apply * operator
+        eExpressionPathScanEndReasonRangeOperatorExpanded,     // [] was expanded into a VOList
+        eExpressionPathScanEndReasonSyntheticValueMissing,     // getting the synthetic children failed
+        eExpressionPathScanEndReasonUnknown = 0xFFFF
     };
     
     enum ExpressionPathEndResultType
     {
-        ePlain = 1,                 // anything but...
-        eBitfield,                  // a bitfield
-        eBoundedRange,              // a range [low-high]
-        eUnboundedRange,            // a range []
-        eValueObjectList,           // several items in a VOList
-        eInvalid = 0xFFFF
+        eExpressionPathEndResultTypePlain = 1,                 // anything but...
+        eExpressionPathEndResultTypeBitfield,                  // a bitfield
+        eExpressionPathEndResultTypeBoundedRange,              // a range [low-high]
+        eExpressionPathEndResultTypeUnboundedRange,            // a range []
+        eExpressionPathEndResultTypeValueObjectList,           // several items in a VOList
+        eExpressionPathEndResultTypeInvalid = 0xFFFF
     };
     
     enum ExpressionPathAftermath
     {
-        eNothing = 1,               // just return it
-        eDereference,               // dereference the target
-        eTakeAddress                // take target's address
+        eExpressionPathAftermathNothing = 1,               // just return it
+        eExpressionPathAftermathDereference,               // dereference the target
+        eExpressionPathAftermathTakeAddress                // take target's address
+    };
+    
+    enum ClearUserVisibleDataItems
+    {
+        eClearUserVisibleDataItemsNothing = 1u << 0,
+        eClearUserVisibleDataItemsValue = 1u << 1,
+        eClearUserVisibleDataItemsSummary = 1u << 2,
+        eClearUserVisibleDataItemsLocation = 1u << 3,
+        eClearUserVisibleDataItemsDescription = 1u << 4,
+        eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
+        eClearUserVisibleDataItemsAllStrings = eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsLocation | eClearUserVisibleDataItemsDescription,
+        eClearUserVisibleDataItemsAll = 0xFFFF
     };
     
     struct GetValueForExpressionPathOptions
@@ -211,7 +224,7 @@
         bool m_show_location;
         bool m_use_objc;
         lldb::DynamicValueType m_use_dynamic;
-        lldb::SyntheticValueType m_use_synthetic;
+        bool m_use_synthetic;
         bool m_scope_already_checked;
         bool m_flat_output;
         uint32_t m_omit_summary_depth;
@@ -227,7 +240,7 @@
             m_show_location(false),
             m_use_objc(false),
             m_use_dynamic(lldb::eNoDynamicValues),
-            m_use_synthetic(lldb::eUseSyntheticFilter),
+            m_use_synthetic(true),
             m_scope_already_checked(false),
             m_flat_output(false),
             m_omit_summary_depth(0),
@@ -305,9 +318,9 @@
         }
         
         DumpValueObjectOptions&
-        SetUseSyntheticValue(lldb::SyntheticValueType syn = lldb::eUseSyntheticFilter)
+        SetUseSyntheticValue(bool use_synthetic = true)
         {
-            m_use_synthetic = syn;
+            m_use_synthetic = use_synthetic;
             return *this;
         }
 
@@ -344,13 +357,13 @@
         {
             if (raw)
             {
-                SetUseSyntheticValue(lldb::eNoSyntheticFilter);
+                SetUseSyntheticValue(false);
                 SetOmitSummaryDepth(UINT32_MAX);
                 SetIgnoreCap(true);
             }
             else
             {
-                SetUseSyntheticValue(lldb::eUseSyntheticFilter);
+                SetUseSyntheticValue(true);
                 SetOmitSummaryDepth(0);
                 SetIgnoreCap(false);
             }
@@ -599,7 +612,7 @@
     GetBaseClassPath (Stream &s);
 
     virtual void
-    GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat = eDereferencePointers);
+    GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers);
     
     lldb::ValueObjectSP
     GetValueForExpressionPath(const char* expression,
@@ -725,19 +738,21 @@
     GetObjectDescription ();
     
     bool
-    GetPrintableRepresentation(Stream& s,
-                               ValueObjectRepresentationStyle val_obj_display = eDisplaySummary,
-                               lldb::Format custom_format = lldb::eFormatInvalid);
-
-    bool
-    HasSpecialCasesForPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
-                                              lldb::Format custom_format);
+    HasSpecialPrintableRepresentation (ValueObjectRepresentationStyle val_obj_display,
+                                       lldb::Format custom_format);
+    
+    enum PrintableRepresentationSpecialCases
+    {
+        ePrintableRepresentationSpecialCasesDisable = 0,
+        ePrintableRepresentationSpecialCasesAllow = 1,
+        ePrintableRepresentationSpecialCasesOnly = 3
+    };
     
     bool
-    DumpPrintableRepresentation(Stream& s,
-                                ValueObjectRepresentationStyle val_obj_display = eDisplaySummary,
-                                lldb::Format custom_format = lldb::eFormatInvalid,
-                                bool only_special = false);
+    DumpPrintableRepresentation (Stream& s,
+                                 ValueObjectRepresentationStyle val_obj_display = eValueObjectRepresentationStyleSummary,
+                                 lldb::Format custom_format = lldb::eFormatInvalid,
+                                 PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow);
     bool
     GetValueIsValid () const;
 
@@ -800,11 +815,14 @@
     GetStaticValue ();
     
     lldb::ValueObjectSP
-    GetSyntheticValue (lldb::SyntheticValueType use_synthetic);
+    GetSyntheticValue (bool use_synthetic = true);
     
     virtual bool
     HasSyntheticValue();
     
+    virtual bool
+    IsSynthetic() { return false; }
+    
     virtual lldb::ValueObjectSP
     CreateConstantValue (const ConstString &name);
 
@@ -842,9 +860,9 @@
     virtual void
     ValueUpdated ()
     {
-        m_value_str.clear();
-        m_summary_str.clear();
-        m_object_desc_str.clear();
+        ClearUserVisibleData(eClearUserVisibleDataItemsValue |
+                             eClearUserVisibleDataItemsSummary |
+                             eClearUserVisibleDataItemsDescription);
     }
 
     virtual bool
@@ -909,7 +927,7 @@
     SetFormat (lldb::Format format)
     {
         if (format != m_format)
-            m_value_str.clear();
+            ClearUserVisibleData(eClearUserVisibleDataItemsValue);
         m_format = format;
     }
     
@@ -924,7 +942,7 @@
     SetSummaryFormat(lldb::TypeSummaryImplSP format)
     {
         m_type_summary_sp = format;
-        m_summary_str.clear();
+        ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
         m_is_getting_summary = false;
     }
     
@@ -932,7 +950,7 @@
     SetValueFormat(lldb::TypeFormatImplSP format)
     {
         m_type_format_sp = format;
-        m_value_str.clear();
+        ClearUserVisibleData(eClearUserVisibleDataItemsValue);
     }
     
     lldb::TypeFormatImplSP
@@ -943,10 +961,12 @@
     }
     
     void
-    SetSyntheticChildren(lldb::SyntheticChildrenSP synth)
+    SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp)
     {
-        m_synthetic_children_sp = synth;
-        m_synthetic_value = NULL;
+        if (synth_sp.get() == m_synthetic_children_sp.get())
+            return;
+        ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren);
+        m_synthetic_children_sp = synth_sp;
     }
     
     lldb::SyntheticChildrenSP
@@ -1155,7 +1175,7 @@
     CalculateDynamicValue (lldb::DynamicValueType use_dynamic);
     
     virtual void
-    CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic);
+    CalculateSyntheticValue (bool use_synthetic = true);
     
     // Should only be called by ValueObject::GetChildAtIndex()
     // Returns a ValueObject managed by this ValueObject's manager.
@@ -1176,7 +1196,7 @@
     SetValueIsValid (bool valid);
     
     void
-    ClearUserVisibleData();
+    ClearUserVisibleData(uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings);
     
     void
     AddSyntheticChild (const ConstString &key,

Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Mon Mar 19 17:58:49 2012
@@ -13,7 +13,6 @@
 // C Includes
 // C++ Includes
 #include <map>
-#include <ostream>
 #include <vector>
 // Other libraries and framework includes
 // Project includes
@@ -61,13 +60,15 @@
     virtual bool
     HasSyntheticValue()
     {
-        return true;    // we are our own synthetic value
+        return false;
     }
     
+    virtual bool
+    IsSynthetic() { return true; }
+    
     virtual void
-    CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
+    CalculateSyntheticValue (bool use_synthetic)
     {
-        m_synthetic_value = this;
     }
     
     virtual bool
@@ -96,16 +97,6 @@
         else
             return NULL;
     }
-
-    void
-    SetOwningSP (lldb::ValueObjectSP &owning_sp)
-    {
-        if (m_owning_valobj_sp == owning_sp)
-            return;
-            
-        assert (m_owning_valobj_sp.get() == NULL);
-        m_owning_valobj_sp = owning_sp;
-    }
     
 protected:
     virtual bool
@@ -117,21 +108,19 @@
     virtual lldb::clang_type_t
     GetClangTypeImpl ();
 
-    Address  m_address;  ///< The variable that this value object is based upon
-    lldb::TypeSP m_type_sp;
-    lldb::ValueObjectSP m_owning_valobj_sp;
-    lldb::SyntheticValueType m_use_synthetic;
-    lldb::SyntheticChildrenSP m_synth_sp;   // hold on to your synthetic children provider
-    lldb::SyntheticChildrenFrontEndSP m_synth_filter;
+    // we need to hold on to the SyntheticChildren because someone might delete the type binding while we are alive
+    lldb::SyntheticChildrenSP m_synth_sp;
+    std::auto_ptr<SyntheticChildrenFrontEnd> m_synth_filter_ap;
     
-    typedef std::map<uint32_t, lldb::ValueObjectSP> ByIndexMap;
+    typedef std::map<uint32_t, ValueObject*> ByIndexMap;
     typedef std::map<const char*, uint32_t> NameToIndexMap;
     
     typedef ByIndexMap::iterator ByIndexIterator;
     typedef NameToIndexMap::iterator NameToIndexIterator;
-    
-    ByIndexMap m_children_byindex;
-    NameToIndexMap m_name_toindex;
+
+    ByIndexMap      m_children_byindex;
+    NameToIndexMap  m_name_toindex;
+    uint32_t        m_children_count;
 
 private:
     friend class ValueObject;

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Mon Mar 19 17:58:49 2012
@@ -82,7 +82,7 @@
     typedef void*          (*SWIGPythonGetChildAtIndex)             (void *implementor, uint32_t idx);
     typedef int            (*SWIGPythonGetIndexOfChildWithName)     (void *implementor, const char* child_name);
     typedef void*          (*SWIGPythonCastPyObjectToSBValue)       (void* data);
-    typedef void           (*SWIGPythonUpdateSynthProviderInstance) (void* data);    
+    typedef bool           (*SWIGPythonUpdateSynthProviderInstance) (void* data);
     
     typedef bool           (*SWIGPythonCallCommand)                 (const char *python_function_name,
                                                                      const char *session_dictionary_name,
@@ -229,9 +229,10 @@
         return UINT32_MAX;
     }
     
-    virtual void
+    virtual bool
     UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
     {
+        return false;
     }
         
     virtual bool

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Mon Mar 19 17:58:49 2012
@@ -84,7 +84,7 @@
     virtual int
     GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name);
     
-    virtual void
+    virtual bool
     UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
     
     virtual bool

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Mon Mar 19 17:58:49 2012
@@ -336,12 +336,6 @@
         eDynamicDontRunTarget   = 2
     } DynamicValueType;
     
-    typedef enum SyntheticValueType
-    {
-        eNoSyntheticFilter = false,
-        eUseSyntheticFilter = true
-    } SyntheticValueType;
-    
     typedef enum AccessType
     {
         eAccessNone,

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Mon Mar 19 17:58:49 2012
@@ -258,7 +258,7 @@
     // has ownership of it and will manage memory for this object by itself
     lldb::SBValue *valobj_sb = new lldb::SBValue(valobj_sp);
 
-    PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *)valobj_sb, SWIGTYPE_p_lldb__SBValue, SWIG_POINTER_OWN);
+    PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *)valobj_sb, SWIGTYPE_p_lldb__SBValue, 0);
 
     if (ValObj_PyObj == NULL)
         Py_RETURN_NONE;
@@ -456,16 +456,19 @@
     return 0;
 }
 
-SWIGEXPORT void
+SWIGEXPORT bool
 LLDBSwigPython_UpdateSynthProviderInstance
 (
     PyObject *implementor
 )
 {
+
+    bool ret_val = false;
+
     static char callee_name[] = "update";
 
     if (implementor == NULL || implementor == Py_None)
-        return;
+        return ret_val;
 
     // all this code is here because update is optional, so we don't want to bother trying to call it unless it's been def:ined for us
     // other synth provider calls are mandatory, so we want to fail in a very obvious way if they are missing!
@@ -479,7 +482,7 @@
     if (pmeth == NULL || pmeth == Py_None)
     {
         Py_XDECREF(pmeth);
-        return;
+        return ret_val;
     }
 
     if (PyCallable_Check(pmeth) == 0)
@@ -490,7 +493,7 @@
         }
 
         Py_XDECREF(pmeth);
-        return;
+        return ret_val;
     }
 
     if (PyErr_Occurred())
@@ -509,8 +512,13 @@
         PyErr_Print();
         PyErr_Clear();
     }
+    
+    if (py_return == Py_True)
+        ret_val = true;
 
     Py_XDECREF(py_return);
+    
+    return ret_val;
 
 }
 

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Mon Mar 19 17:58:49 2012
@@ -363,7 +363,7 @@
                 .SetUseDynamicType(use_dynamic)
                 .SetScopeChecked(true)
                 .SetFlatOutput(false)
-                .SetUseSyntheticValue(lldb::eUseSyntheticFilter)
+                .SetUseSyntheticValue(true)
                 .SetOmitSummaryDepth(0)
                 .SetIgnoreCap(false)
                 .SetFormat(format)

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Mon Mar 19 17:58:49 2012
@@ -414,7 +414,7 @@
             .SetShowLocation(m_varobj_options.show_location)
             .SetUseObjectiveC(m_varobj_options.use_objc)
             .SetUseDynamicType(m_varobj_options.use_dynamic)
-            .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth)
+            .SetUseSyntheticValue(m_varobj_options.use_synth)
             .SetFlatOutput(m_varobj_options.flat_output)
             .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
             .SetIgnoreCap(m_varobj_options.ignore_cap)

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Mon Mar 19 17:58:49 2012
@@ -701,7 +701,7 @@
                     .SetUseObjectiveC(m_varobj_options.use_objc)
                     .SetScopeChecked(scope_already_checked)
                     .SetFlatOutput(m_varobj_options.flat_output)
-                    .SetUseSyntheticValue(m_varobj_options.be_raw ? lldb::eNoSyntheticFilter : (m_varobj_options.use_synth ? lldb::eUseSyntheticFilter : lldb::eNoSyntheticFilter) )
+                    .SetUseSyntheticValue(m_varobj_options.be_raw ? false : m_varobj_options.use_synth)
                     .SetOmitSummaryDepth(m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth)
                     .SetIgnoreCap(m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap)
                     .SetFormat(format)

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Mon Mar 19 17:58:49 2012
@@ -600,7 +600,7 @@
                .SetShowLocation(m_varobj_options.show_location)
                .SetUseObjectiveC(m_varobj_options.use_objc)
                .SetUseDynamicType(m_varobj_options.use_dynamic)
-               .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth)
+               .SetUseSyntheticValue(m_varobj_options.use_synth)
                .SetFlatOutput(m_varobj_options.flat_output)
                .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
                .SetIgnoreCap(m_varobj_options.ignore_cap);

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Mar 19 17:58:49 2012
@@ -867,20 +867,20 @@
                 log->Printf("%s is an unknown format", format_name);
             // if this is an @ sign, print ObjC description
             if (*format_name == '@')
-                *val_obj_display = ValueObject::eDisplayLanguageSpecific;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
             // if this is a V, print the value using the default format
             else if (*format_name == 'V')
-                *val_obj_display = ValueObject::eDisplayValue;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
             // if this is an L, print the location of the value
             else if (*format_name == 'L')
-                *val_obj_display = ValueObject::eDisplayLocation;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
             // if this is an S, print the summary after all
             else if (*format_name == 'S')
-                *val_obj_display = ValueObject::eDisplaySummary;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
             else if (*format_name == '#')
-                *val_obj_display = ValueObject::eDisplayChildrenCount;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
             else if (*format_name == 'T')
-                *val_obj_display = ValueObject::eDisplayType;
+                *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
             else if (log)
                 log->Printf("%s is an error, leaving the previous value alone", format_name);
         }
@@ -889,7 +889,7 @@
         {
             if (log)
                 log->Printf("will display value for this VO");
-            *val_obj_display = ValueObject::eDisplayValue;
+            *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
         }
         delete format_name;
     }
@@ -989,7 +989,7 @@
         *do_deref_pointer = true;
     }
 
-    valobj->GetExpressionPath(sstring, true, ValueObject::eHonorPointers);
+    valobj->GetExpressionPath(sstring, true, ValueObject::eGetExpressionPathFormatHonorPointers);
     if (log)
         log->Printf("expression path to expand in phase 0: %s",sstring.GetData());
     sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3);
@@ -1020,7 +1020,7 @@
     ValueObject::GetValueForExpressionPathOptions options;
     ValueObject::ExpressionPathEndResultType final_value_type;
     ValueObject::ExpressionPathScanEndReason reason_to_stop;
-    ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eDereference : ValueObject::eNothing);
+    ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
                                                           &first_unparsed,
                                                           &reason_to_stop,
@@ -1135,8 +1135,8 @@
                         const RegisterInfo *reg_info = NULL;
                         RegisterContext *reg_ctx = NULL;
                         bool do_deref_pointer = false;
-                        ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eEndOfString;
-                        ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::ePlain;
+                        ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+                        ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
                         
                         // Each variable must set success to true below...
                         bool var_success = false;
@@ -1164,7 +1164,9 @@
                                 
                                 if (*var_name_begin == 's')
                                 {
-                                    valobj = valobj->GetSyntheticValue(eUseSyntheticFilter).get();
+                                    valobj = valobj->GetSyntheticValue().get();
+                                    if (!valobj)
+                                        break;
                                     var_name_begin++;
                                 }
                                 
@@ -1179,10 +1181,10 @@
                                     log->Printf("initial string: %s",var_name_begin);
                                                                 
                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
-                                                                                  ValueObject::eDereference : ValueObject::eNothing);
+                                                                                  ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
                                 ValueObject::GetValueForExpressionPathOptions options;
                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
-                                ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary;
+                                ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
                                 ValueObject* target = NULL;
                                 Format custom_format = eFormatInvalid;
                                 const char* var_name_final = NULL;
@@ -1201,7 +1203,7 @@
                                 {
                                     was_plain_var = true;
                                     target = valobj;
-                                    val_obj_display = ValueObject::eDisplayValue;
+                                    val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
                                 }
                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
                                 {
@@ -1209,7 +1211,7 @@
                                     // this is a variable with some custom format applied to it
                                     const char* percent_position;
                                     target = valobj;
-                                    val_obj_display = ValueObject::eDisplayValue;
+                                    val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
                                     ScanFormatDescriptor (var_name_begin,
                                                           var_name_end,
                                                           &var_name_final,
@@ -1276,10 +1278,10 @@
                                 else
                                     break;
                                 
-                                is_array_range = (final_value_type == ValueObject::eBoundedRange ||
-                                                  final_value_type == ValueObject::eUnboundedRange);
+                                is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
+                                                  final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
                                 
-                                do_deref_pointer = (what_next == ValueObject::eDereference);
+                                do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
 
                                 if (do_deref_pointer && !is_array_range)
                                 {
@@ -1302,14 +1304,14 @@
                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
                                 
-                                if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eDisplayValue) // this should be wrong, but there are some exceptions
+                                if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
                                 {
                                     StreamString str_temp;
                                     if (log)
                                         log->Printf("I am into array || pointer && !range");
                                     
-                                    if (target->HasSpecialCasesForPrintableRepresentation(val_obj_display,
-                                                                                          custom_format))
+                                    if (target->HasSpecialPrintableRepresentation(val_obj_display,
+                                                                                  custom_format))
                                     {
                                         // try to use the special cases
                                         var_success = target->DumpPrintableRepresentation(str_temp,
@@ -1334,9 +1336,10 @@
                                         }
                                         else if (is_pointer) // if pointer, value is the address stored
                                         {
-                                            var_success = target->GetPrintableRepresentation(s,
+                                            var_success = target->DumpPrintableRepresentation(s,
                                                                                              val_obj_display,
-                                                                                             custom_format);
+                                                                                             custom_format,
+                                                                                             ValueObject::ePrintableRepresentationSpecialCasesDisable);
                                         }
                                         else
                                         {
@@ -1357,7 +1360,7 @@
                                 }
                                 
                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
-                                if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eDisplayValue)))
+                                if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
                                 {
                                     s << "<invalid use of aggregate type>";
                                     var_success = true;

Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Mon Mar 19 17:58:49 2012
@@ -22,7 +22,6 @@
 #include "lldb/Core/FormatClasses.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
-#include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/ClangASTType.h"
 #include "lldb/Target/StackFrame.h"
@@ -66,17 +65,17 @@
 }
 
 bool
-StringSummaryFormat::FormatObject(lldb::ValueObjectSP object,
+StringSummaryFormat::FormatObject(ValueObject *valobj,
                                   std::string& retval)
 {
-    if (!object.get())
+    if (!valobj)
     {
-        retval.assign("NULL sp");
+        retval.assign("NULL ValueObject");
         return false;
     }
     
     StreamString s;
-    ExecutionContext exe_ctx (object->GetExecutionContextRef());
+    ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
     SymbolContext sc;
     StackFrame *frame = exe_ctx.GetFramePtr();
     if (frame)
@@ -84,15 +83,22 @@
     
     if (IsOneliner())
     {
-        ValueObjectSP synth_valobj = object->GetSyntheticValue(lldb::eUseSyntheticFilter);
-        const uint32_t num_children = synth_valobj->GetNumChildren();
+        ValueObject* object;
+        
+        ValueObjectSP synth_valobj = valobj->GetSyntheticValue();
+        if (synth_valobj)
+            object = synth_valobj.get();
+        else
+            object = valobj;
+        
+        const uint32_t num_children = object->GetNumChildren();
         if (num_children)
         {
             s.PutChar('(');
             
             for (uint32_t idx=0; idx<num_children; ++idx)
             {
-                lldb::ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true));
+                lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
                 if (child_sp.get())
                 {
                     if (idx)
@@ -100,9 +106,12 @@
                     if (!HideNames())
                     {
                         s.PutCString(child_sp.get()->GetName().AsCString());
-                        s.PutChar('=');
+                        s.PutCString(" = ");
                     }
-                    child_sp.get()->GetPrintableRepresentation(s);
+                    child_sp.get()->DumpPrintableRepresentation(s,
+                                                                ValueObject::eValueObjectRepresentationStyleSummary,
+                                                                lldb::eFormatInvalid,
+                                                                ValueObject::ePrintableRepresentationSpecialCasesDisable);
                 }
             }
             
@@ -120,7 +129,7 @@
     }
     else
     {
-        if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, object.get()))
+        if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, valobj))
         {
             retval.assign(s.GetString());
             return true;
@@ -167,14 +176,21 @@
 }
 
 bool
-ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object,
+ScriptSummaryFormat::FormatObject(ValueObject *valobj,
                                   std::string& retval)
 {
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
 
-    Debugger& dbg = object->GetTargetSP()->GetDebugger();
-    ScriptInterpreter *script_interpreter = dbg.GetCommandInterpreter().GetScriptInterpreter();
-    
+    TargetSP target_sp(valobj->GetTargetSP());
+
+    if (!target_sp)
+    {
+        retval.assign("error: no target");
+        return false;
+    }
+
+    ScriptInterpreter *script_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+
     if (!script_interpreter)
     {
         retval.assign("error: no ScriptInterpreter");
@@ -182,7 +198,7 @@
     }
         
     return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
-                                                  object,
+                                                  valobj->GetSP(),
                                                   m_script_function_sp,
                                                   retval);
 
@@ -253,19 +269,24 @@
 
 #ifndef LLDB_DISABLE_PYTHON
 
-TypeSyntheticImpl::FrontEnd::FrontEnd(std::string pclass, lldb::ValueObjectSP be) :
-    SyntheticChildrenFrontEnd(be),
+TypeSyntheticImpl::FrontEnd::FrontEnd(std::string pclass, ValueObject &backend) :
+    SyntheticChildrenFrontEnd(backend),
     m_python_class(pclass),
     m_wrapper_sp(),
     m_interpreter(NULL)
 {
-    if (be.get() == NULL)
+    if (backend == NULL)
+        return;
+    
+    TargetSP target_sp = backend.GetTargetSP();
+    
+    if (!target_sp)
         return;
     
-    m_interpreter = m_backend->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+    m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
     
     if (m_interpreter != NULL)
-        m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
+        m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, backend.GetSP());
 }
 
 TypeSyntheticImpl::FrontEnd::~FrontEnd()

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Mon Mar 19 17:58:49 2012
@@ -693,15 +693,12 @@
                                                                                                  "libcxx.stdmap_SynthProvider")));
     
     stl_summary_flags.SetDontShowChildren(false);
-    code.assign("     libcxx.stdvector_SummaryProvider(valobj,dict)");
     libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)vector<.+>$")),
-                                                        TypeSummaryImplSP(new ScriptSummaryFormat(stl_summary_flags, "libcxx.stdvector_SummaryProvider",code.c_str())));
-    code.assign("     libcxx.stdlist_SummaryProvider(valobj,dict)");
+                                                        TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
     libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)list<.+>$")),
-                                                        TypeSummaryImplSP(new ScriptSummaryFormat(stl_summary_flags, "libcxx.stdlist_SummaryProvider",code.c_str())));
-    code.assign("     libcxx.stdmap_SummaryProvider(valobj,dict)");
+                                                        TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
     libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)map<.+> >$")),
-                                                        TypeSummaryImplSP(new ScriptSummaryFormat(stl_summary_flags, "libcxx.stdmap_SummaryProvider",code.c_str())));
+                                                        TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
 #endif
 }
 

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Mon Mar 19 17:58:49 2012
@@ -179,7 +179,7 @@
         // because of the frozen-pointer depth limit)
 		// TODO: decouple summary from value and then remove this code and only force-clear the summary
         if (update_format && !did_change_formats)
-            m_summary_str.clear();
+            ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
         return m_error.Success();
     }
 
@@ -199,7 +199,7 @@
         {
             m_old_value_valid = true;
             m_old_value_str.swap (m_value_str);
-            m_value_str.clear();
+            ClearUserVisibleData(eClearUserVisibleDataItemsValue);
         }
 
         ClearUserVisibleData();
@@ -268,7 +268,7 @@
     m_update_point.SetNeedsUpdate();
     // We have to clear the value string here so ConstResult children will notice if their values are
     // changed by hand (i.e. with SetValueAsCString).
-    m_value_str.clear();
+    ClearUserVisibleData(eClearUserVisibleDataItemsValue);
 }
 
 ClangASTType
@@ -671,7 +671,9 @@
     {
         if (summary_ptr)
         {
-            summary_ptr->FormatObject(GetSP(), destination);
+            if (HasSyntheticValue())
+                m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
+            summary_ptr->FormatObject(this, destination);
         }
         else
         {
@@ -1242,110 +1244,18 @@
     return fail_value;
 }
 
-bool
-ValueObject::GetPrintableRepresentation(Stream& s,
-                                        ValueObjectRepresentationStyle val_obj_display,
-                                        Format custom_format)
-{
-
-    if (custom_format != eFormatInvalid)
-        SetFormat(custom_format);
-    
-    const char * return_value;
-    std::string alloc_mem;
-    
-    switch(val_obj_display)
-    {
-        case eDisplayValue:
-            return_value = GetValueAsCString();
-            break;
-
-        case eDisplaySummary:
-            return_value = GetSummaryAsCString();
-            break;
-
-        case eDisplayLanguageSpecific:
-            return_value = GetObjectDescription();
-            break;
-
-        case eDisplayLocation:
-            return_value = GetLocationAsCString();
-            break;
-
-        case eDisplayChildrenCount:
-            {
-                alloc_mem.resize(512);
-                return_value = &alloc_mem[0];
-                int count = GetNumChildren();
-                snprintf((char*)return_value, 512, "%d", count);
-            }
-            break;
-
-        case eDisplayType:
-            return_value = GetTypeName().AsCString();
-            break;
-
-        default:
-            break;
-    }
-    
-    if (!return_value)
-    {
-        if (val_obj_display == eDisplayValue)
-            return_value = GetSummaryAsCString();        
-        else if (val_obj_display == eDisplaySummary)
-        {
-            if (ClangASTContext::IsAggregateType (GetClangType()) == true)
-            {
-                // this thing has no value, and it seems to have no summary
-                // some combination of unitialized data and other factors can also
-                // raise this condition, so let's print a nice generic description
-                {
-                    alloc_mem.resize(684);
-                    return_value = &alloc_mem[0];
-                    snprintf((char*)return_value, 684, "%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
-                }
-            }
-            else
-                return_value = GetValueAsCString();
-        }
-    }
-    
-    if (return_value)
-        s.PutCString(return_value);
-    else
-    {
-        if (m_error.Fail())
-            s.Printf("<%s>", m_error.AsCString());
-        else if (val_obj_display == eDisplaySummary)
-            s.PutCString("<no summary available>");
-        else if (val_obj_display == eDisplayValue)
-            s.PutCString("<no value available>");
-        else if (val_obj_display == eDisplayLanguageSpecific)
-            s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
-        else
-            s.PutCString("<no printable representation>");
-    }
-    
-    // we should only return false here if we could not do *anything*
-    // even if we have an error message as output, that's a success
-    // from our callers' perspective, so return true
-    return true;
-    
-}
-
 // if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
 // this call up to date by returning true for your new special cases. We will eventually move
 // to checking this call result before trying to display special cases
 bool
-ValueObject::HasSpecialCasesForPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
-                                                       Format custom_format)
+ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
+                                               Format custom_format)
 {
     clang_type_t elem_or_pointee_type;
     Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
     
     if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
-        && val_obj_display == ValueObject::eDisplayValue)
+        && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
     {        
         if (IsCStringContainer(true) && 
             (custom_format == eFormatCString ||
@@ -1382,131 +1292,225 @@
 ValueObject::DumpPrintableRepresentation(Stream& s,
                                          ValueObjectRepresentationStyle val_obj_display,
                                          Format custom_format,
-                                         bool only_special)
+                                         PrintableRepresentationSpecialCases special)
 {
 
     clang_type_t elem_or_pointee_type;
     Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
     
-    if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
-         && val_obj_display == ValueObject::eDisplayValue)
+    bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
+    bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
+    
+    if (allow_special)
     {
-        // when being asked to get a printable display an array or pointer type directly, 
-        // try to "do the right thing"
-        
-        if (IsCStringContainer(true) && 
-            (custom_format == eFormatCString ||
-             custom_format == eFormatCharArray ||
-             custom_format == eFormatChar ||
-             custom_format == eFormatVectorOfChar)) // print char[] & char* directly
-        {
-            Error error;
-            ReadPointedString(s,
-                              error,
-                              0,
-                              (custom_format == eFormatVectorOfChar) ||
-                              (custom_format == eFormatCharArray));
-            return !error.Fail();
-        }
-        
-        if (custom_format == eFormatEnum)
-            return false;
-        
-        // this only works for arrays, because I have no way to know when
-        // the pointed memory ends, and no special \0 end of data marker
-        if (flags.Test(ClangASTContext::eTypeIsArray))
+        if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
+             && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
         {
-            if ((custom_format == eFormatBytes) ||
-                (custom_format == eFormatBytesWithASCII))
+            // when being asked to get a printable display an array or pointer type directly, 
+            // try to "do the right thing"
+            
+            if (IsCStringContainer(true) && 
+                (custom_format == eFormatCString ||
+                 custom_format == eFormatCharArray ||
+                 custom_format == eFormatChar ||
+                 custom_format == eFormatVectorOfChar)) // print char[] & char* directly
             {
-                uint32_t count = GetNumChildren();
-                                
-                s << '[';
-                for (uint32_t low = 0; low < count; low++)
-                {
+                Error error;
+                ReadPointedString(s,
+                                  error,
+                                  0,
+                                  (custom_format == eFormatVectorOfChar) ||
+                                  (custom_format == eFormatCharArray));
+                return !error.Fail();
+            }
+            
+            if (custom_format == eFormatEnum)
+                return false;
+            
+            // this only works for arrays, because I have no way to know when
+            // the pointed memory ends, and no special \0 end of data marker
+            if (flags.Test(ClangASTContext::eTypeIsArray))
+            {
+                if ((custom_format == eFormatBytes) ||
+                    (custom_format == eFormatBytesWithASCII))
+                {
+                    uint32_t count = GetNumChildren();
+                                    
+                    s << '[';
+                    for (uint32_t low = 0; low < count; low++)
+                    {
+                        
+                        if (low)
+                            s << ',';
+                        
+                        ValueObjectSP child = GetChildAtIndex(low,true);
+                        if (!child.get())
+                        {
+                            s << "<invalid child>";
+                            continue;
+                        }
+                        child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, custom_format);
+                    }                
                     
-                    if (low)
-                        s << ',';
+                    s << ']';
                     
-                    ValueObjectSP child = GetChildAtIndex(low,true);
-                    if (!child.get())
-                    {
-                        s << "<invalid child>";
-                        continue;
-                    }
-                    child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
-                }                
-                
-                s << ']';
+                    return true;
+                }
                 
-                return true;
+                if ((custom_format == eFormatVectorOfChar) ||
+                    (custom_format == eFormatVectorOfFloat32) ||
+                    (custom_format == eFormatVectorOfFloat64) ||
+                    (custom_format == eFormatVectorOfSInt16) ||
+                    (custom_format == eFormatVectorOfSInt32) ||
+                    (custom_format == eFormatVectorOfSInt64) ||
+                    (custom_format == eFormatVectorOfSInt8) ||
+                    (custom_format == eFormatVectorOfUInt128) ||
+                    (custom_format == eFormatVectorOfUInt16) ||
+                    (custom_format == eFormatVectorOfUInt32) ||
+                    (custom_format == eFormatVectorOfUInt64) ||
+                    (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
+                {
+                    uint32_t count = GetNumChildren();
+
+                    Format format = FormatManager::GetSingleItemFormat(custom_format);
+                    
+                    s << '[';
+                    for (uint32_t low = 0; low < count; low++)
+                    {
+                        
+                        if (low)
+                            s << ',';
+                        
+                        ValueObjectSP child = GetChildAtIndex(low,true);
+                        if (!child.get())
+                        {
+                            s << "<invalid child>";
+                            continue;
+                        }
+                        child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, format);
+                    }                
+                    
+                    s << ']';
+                    
+                    return true;
+                }
             }
             
-            if ((custom_format == eFormatVectorOfChar) ||
-                (custom_format == eFormatVectorOfFloat32) ||
-                (custom_format == eFormatVectorOfFloat64) ||
-                (custom_format == eFormatVectorOfSInt16) ||
-                (custom_format == eFormatVectorOfSInt32) ||
-                (custom_format == eFormatVectorOfSInt64) ||
-                (custom_format == eFormatVectorOfSInt8) ||
-                (custom_format == eFormatVectorOfUInt128) ||
-                (custom_format == eFormatVectorOfUInt16) ||
-                (custom_format == eFormatVectorOfUInt32) ||
-                (custom_format == eFormatVectorOfUInt64) ||
-                (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
-            {
-                uint32_t count = GetNumChildren();
+            if ((custom_format == eFormatBoolean) ||
+                (custom_format == eFormatBinary) ||
+                (custom_format == eFormatChar) ||
+                (custom_format == eFormatCharPrintable) ||
+                (custom_format == eFormatComplexFloat) ||
+                (custom_format == eFormatDecimal) ||
+                (custom_format == eFormatHex) ||
+                (custom_format == eFormatFloat) ||
+                (custom_format == eFormatOctal) ||
+                (custom_format == eFormatOSType) ||
+                (custom_format == eFormatUnicode16) ||
+                (custom_format == eFormatUnicode32) ||
+                (custom_format == eFormatUnsigned) ||
+                (custom_format == eFormatPointer) ||
+                (custom_format == eFormatComplexInteger) ||
+                (custom_format == eFormatComplex) ||
+                (custom_format == eFormatDefault)) // use the [] operator
+                return false;
+        }
+    }
+    
+    if (only_special)
+        return false;
+    
+    bool var_success = false;
+    
+    {
+        const char * return_value;
+        std::string alloc_mem;
 
-                Format format = FormatManager::GetSingleItemFormat(custom_format);
+        if (custom_format != eFormatInvalid)
+            SetFormat(custom_format);
+        
+        switch(val_obj_display)
+        {
+            case eValueObjectRepresentationStyleValue:
+                return_value = GetValueAsCString();
+                break;
+                
+            case eValueObjectRepresentationStyleSummary:
+                return_value = GetSummaryAsCString();
+                break;
                 
-                s << '[';
-                for (uint32_t low = 0; low < count; low++)
+            case eValueObjectRepresentationStyleLanguageSpecific:
+                return_value = GetObjectDescription();
+                break;
+                
+            case eValueObjectRepresentationStyleLocation:
+                return_value = GetLocationAsCString();
+                break;
+                
+            case eValueObjectRepresentationStyleChildrenCount:
+            {
+                alloc_mem.resize(512);
+                return_value = &alloc_mem[0];
+                int count = GetNumChildren();
+                snprintf((char*)return_value, 512, "%d", count);
+            }
+                break;
+                
+            case eValueObjectRepresentationStyleType:
+                return_value = GetTypeName().AsCString();
+                break;
+                
+            default:
+                break;
+        }
+        
+        if (!return_value)
+        {
+            if (val_obj_display == eValueObjectRepresentationStyleValue)
+                return_value = GetSummaryAsCString();        
+            else if (val_obj_display == eValueObjectRepresentationStyleSummary)
+            {
+                if (ClangASTContext::IsAggregateType (GetClangType()) == true)
                 {
-                    
-                    if (low)
-                        s << ',';
-                    
-                    ValueObjectSP child = GetChildAtIndex(low,true);
-                    if (!child.get())
+                    // this thing has no value, and it seems to have no summary
+                    // some combination of unitialized data and other factors can also
+                    // raise this condition, so let's print a nice generic description
                     {
-                        s << "<invalid child>";
-                        continue;
+                        alloc_mem.resize(684);
+                        return_value = &alloc_mem[0];
+                        snprintf((char*)return_value, 684, "%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
                     }
-                    child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
-                }                
-                
-                s << ']';
-                
-                return true;
+                }
+                else
+                    return_value = GetValueAsCString();
             }
         }
         
-        if ((custom_format == eFormatBoolean) ||
-            (custom_format == eFormatBinary) ||
-            (custom_format == eFormatChar) ||
-            (custom_format == eFormatCharPrintable) ||
-            (custom_format == eFormatComplexFloat) ||
-            (custom_format == eFormatDecimal) ||
-            (custom_format == eFormatHex) ||
-            (custom_format == eFormatFloat) ||
-            (custom_format == eFormatOctal) ||
-            (custom_format == eFormatOSType) ||
-            (custom_format == eFormatUnicode16) ||
-            (custom_format == eFormatUnicode32) ||
-            (custom_format == eFormatUnsigned) ||
-            (custom_format == eFormatPointer) ||
-            (custom_format == eFormatComplexInteger) ||
-            (custom_format == eFormatComplex) ||
-            (custom_format == eFormatDefault)) // use the [] operator
-            return false;
+        if (return_value)
+            s.PutCString(return_value);
+        else
+        {
+            if (m_error.Fail())
+                s.Printf("<%s>", m_error.AsCString());
+            else if (val_obj_display == eValueObjectRepresentationStyleSummary)
+                s.PutCString("<no summary available>");
+            else if (val_obj_display == eValueObjectRepresentationStyleValue)
+                s.PutCString("<no value available>");
+            else if (val_obj_display == eValueObjectRepresentationStyleLanguageSpecific)
+                s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
+            else
+                s.PutCString("<no printable representation>");
+        }
+        
+        // we should only return false here if we could not do *anything*
+        // even if we have an error message as output, that's a success
+        // from our callers' perspective, so return true
+        var_success = true;
+        
+        if (custom_format != eFormatInvalid)
+            SetFormat(eFormatDefault);
     }
     
-    if (only_special)
-        return false;
-    
-    bool var_success = GetPrintableRepresentation(s, val_obj_display, custom_format);
-    if (custom_format != eFormatInvalid)
-        SetFormat(eFormatDefault);
     return var_success;
 }
 
@@ -1987,19 +1991,18 @@
 }
 
 void
-ValueObject::CalculateSyntheticValue (SyntheticValueType use_synthetic)
+ValueObject::CalculateSyntheticValue (bool use_synthetic)
 {
-    if (use_synthetic == eNoSyntheticFilter)
+    if (use_synthetic == false)
         return;
     
-    UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
+    if (!UpdateFormatsIfNeeded(m_last_format_mgr_dynamic) && m_synthetic_value)
+        return;
     
     if (m_synthetic_children_sp.get() == NULL)
         return;
     
-    if (m_synthetic_value == NULL)
-        m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
-    
+    m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
 }
 
 void
@@ -2068,27 +2071,18 @@
     return GetSP();
 }
 
-// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
-// or we do not really want a dynamic VO. this method instead returns this object
-// itself when making it synthetic has no meaning. this makes it much simpler
-// to replace the SyntheticValue for the ValueObject
 ValueObjectSP
-ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
+ValueObject::GetSyntheticValue (bool use_synthetic)
 {
-    if (use_synthetic == eNoSyntheticFilter)
-        return GetSP();
-    
-    UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
-    
-    if (m_synthetic_children_sp.get() == NULL)
-        return GetSP();
-    
+    if (use_synthetic == false)
+        return ValueObjectSP();
+
     CalculateSyntheticValue(use_synthetic);
     
     if (m_synthetic_value)
         return m_synthetic_value->GetSP();
     else
-        return GetSP();
+        return ValueObjectSP();
 }
 
 bool
@@ -2099,7 +2093,7 @@
     if (m_synthetic_children_sp.get() == NULL)
         return false;
     
-    CalculateSyntheticValue(eUseSyntheticFilter);
+    CalculateSyntheticValue(true);
     
     if (m_synthetic_value)
         return true;
@@ -2146,7 +2140,7 @@
 {
     const bool is_deref_of_parent = IsDereferenceOfParent ();
 
-    if (is_deref_of_parent && epformat == eDereferencePointers)
+    if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
     {
         // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
         // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
@@ -2162,7 +2156,7 @@
     // if we are a deref_of_parent just because we are synthetic array
     // members made up to allow ptr[%d] syntax to work in variable
     // printing, then add our name ([%d]) to the expression path
-    if (m_is_array_item_for_pointer && epformat == eHonorPointers)
+    if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers)
         s.PutCString(m_name.AsCString());
             
     if (!IsBaseClass())
@@ -2177,7 +2171,7 @@
                 {
                     const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
                     
-                    if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
+                    if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers)
                     {
                         s.PutCString("->");
                     }
@@ -2209,7 +2203,7 @@
         }
     }
     
-    if (is_deref_of_parent && epformat == eDereferencePointers)
+    if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
     {
         s.PutChar(')');
     }
@@ -2227,7 +2221,7 @@
     const char* dummy_first_unparsed;
     ExpressionPathScanEndReason dummy_reason_to_stop;
     ExpressionPathEndResultType dummy_final_value_type;
-    ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
+    ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
     
     ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
                                                            first_unparsed ? first_unparsed : &dummy_first_unparsed,
@@ -2236,46 +2230,46 @@
                                                            options,
                                                            final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
     
-    if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
+    if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
         return ret_val;
 
-    if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == ePlain)) // I can only deref and takeaddress of plain objects
+    if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress of plain objects
     {
-        if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eDereference)
+        if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eExpressionPathAftermathDereference)
         {
             Error error;
             ValueObjectSP final_value = ret_val->Dereference(error);
             if (error.Fail() || !final_value.get())
             {
                 if (reason_to_stop)
-                    *reason_to_stop = ValueObject::eDereferencingFailed;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
                 if (final_value_type)
-                    *final_value_type = ValueObject::eInvalid;
+                    *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
                 return ValueObjectSP();
             }
             else
             {
                 if (final_task_on_target)
-                    *final_task_on_target = ValueObject::eNothing;
+                    *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
                 return final_value;
             }
         }
-        if (*final_task_on_target == ValueObject::eTakeAddress)
+        if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
         {
             Error error;
             ValueObjectSP final_value = ret_val->AddressOf(error);
             if (error.Fail() || !final_value.get())
             {
                 if (reason_to_stop)
-                    *reason_to_stop = ValueObject::eTakingAddressFailed;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
                 if (final_value_type)
-                    *final_value_type = ValueObject::eInvalid;
+                    *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
                 return ValueObjectSP();
             }
             else
             {
                 if (final_task_on_target)
-                    *final_task_on_target = ValueObject::eNothing;
+                    *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
                 return final_value;
             }
         }
@@ -2295,7 +2289,7 @@
     const char* dummy_first_unparsed;
     ExpressionPathScanEndReason dummy_reason_to_stop;
     ExpressionPathEndResultType dummy_final_value_type;
-    ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
+    ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
     
     ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
                                                            first_unparsed ? first_unparsed : &dummy_first_unparsed,
@@ -2307,46 +2301,46 @@
     if (!ret_val.get()) // if there are errors, I add nothing to the list
         return 0;
     
-    if (*reason_to_stop != eArrayRangeOperatorMet)
+    if (*reason_to_stop != eExpressionPathScanEndReasonArrayRangeOperatorMet)
     {
         // I need not expand a range, just post-process the final value and return
-        if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
+        if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
         {
             list->Append(ret_val);
             return 1;
         }
-        if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
+        if (ret_val.get() && *final_value_type == eExpressionPathEndResultTypePlain) // I can only deref and takeaddress of plain objects
         {
-            if (*final_task_on_target == ValueObject::eDereference)
+            if (*final_task_on_target == ValueObject::eExpressionPathAftermathDereference)
             {
                 Error error;
                 ValueObjectSP final_value = ret_val->Dereference(error);
                 if (error.Fail() || !final_value.get())
                 {
-                    *reason_to_stop = ValueObject::eDereferencingFailed;
-                    *final_value_type = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+                    *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return 0;
                 }
                 else
                 {
-                    *final_task_on_target = ValueObject::eNothing;
+                    *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
                     list->Append(final_value);
                     return 1;
                 }
             }
-            if (*final_task_on_target == ValueObject::eTakeAddress)
+            if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
             {
                 Error error;
                 ValueObjectSP final_value = ret_val->AddressOf(error);
                 if (error.Fail() || !final_value.get())
                 {
-                    *reason_to_stop = ValueObject::eTakingAddressFailed;
-                    *final_value_type = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
+                    *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return 0;
                 }
                 else
                 {
-                    *final_task_on_target = ValueObject::eNothing;
+                    *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
                     list->Append(final_value);
                     return 1;
                 }
@@ -2399,7 +2393,7 @@
         
         if (!expression_cstr || *expression_cstr == '\0')
         {
-            *reason_to_stop = ValueObject::eEndOfString;
+            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
             return root;
         }
         
@@ -2411,8 +2405,8 @@
                     root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eArrowInsteadOfDot;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
                 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
@@ -2420,15 +2414,15 @@
                     options.m_no_fragile_ivar)
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
                 if (expression_cstr[1] != '>')
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
                 expression_cstr++; // skip the -
@@ -2439,8 +2433,8 @@
                     root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eDotInsteadOfArrow;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
                 expression_cstr++; // skip .
@@ -2454,13 +2448,19 @@
                     if (child_valobj_sp.get()) // we know we are done, so just return
                     {
                         *first_unparsed = '\0';
-                        *reason_to_stop = ValueObject::eEndOfString;
-                        *final_result = ValueObject::ePlain;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+                        *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                         return child_valobj_sp;
                     }
                     else if (options.m_no_synthetic_children == false) // let's try with synthetic children
                     {
-                        child_valobj_sp = root->GetSyntheticValue(eNoSyntheticFilter)->GetChildMemberWithName(child_name, true);
+                        if (root->IsSynthetic())
+                            child_valobj_sp = root;
+                        else
+                            child_valobj_sp = root->GetSyntheticValue();
+                        
+                        if (child_valobj_sp.get())
+                            child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
                     }
                     
                     // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
@@ -2468,15 +2468,15 @@
                     if(child_valobj_sp.get()) // if it worked, just return
                     {
                         *first_unparsed = '\0';
-                        *reason_to_stop = ValueObject::eEndOfString;
-                        *final_result = ValueObject::ePlain;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+                        *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                         return child_valobj_sp;
                     }
                     else
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eNoSuchChild;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                 }
@@ -2488,12 +2488,14 @@
                     {
                         root = child_valobj_sp;
                         *first_unparsed = next_separator;
-                        *final_result = ValueObject::ePlain;
+                        *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                         continue;
                     }
                     else if (options.m_no_synthetic_children == false) // let's try with synthetic children
                     {
-                        child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
+                        child_valobj_sp = root->GetSyntheticValue(true);
+                        if (child_valobj_sp)
+                            child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
                     }
                     
                     // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
@@ -2502,14 +2504,14 @@
                     {
                         root = child_valobj_sp;
                         *first_unparsed = next_separator;
-                        *final_result = ValueObject::ePlain;
+                        *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                         continue;
                     }
                     else
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eNoSuchChild;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                 }
@@ -2524,16 +2526,16 @@
                         if (options.m_no_synthetic_children) // ...only chance left is synthetic
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eRangeOperatorInvalid;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                     }
                     else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                 }
@@ -2542,15 +2544,15 @@
                     if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                     else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
                     {
                         *first_unparsed = expression_cstr+2;
-                        *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
-                        *final_result = ValueObject::eUnboundedRange;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
                         return root;
                     }
                 }
@@ -2559,8 +2561,8 @@
                 if (!close_bracket_position) // if there is no ], this is a syntax error
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
                 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
@@ -2570,8 +2572,8 @@
                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
@@ -2579,15 +2581,15 @@
                         if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                         {
                             *first_unparsed = expression_cstr+2;
-                            *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
-                            *final_result = ValueObject::eUnboundedRange;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
                             return root;
                         }
                         else
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                     }
@@ -2598,26 +2600,26 @@
                         if (!child_valobj_sp)
                             child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
                         if (!child_valobj_sp)
-                            if (root->HasSyntheticValue() && root->GetSyntheticValue(eUseSyntheticFilter)->GetNumChildren() > index)
-                                child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true);
+                            if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index)
+                                child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true);
                         if (child_valobj_sp)
                         {
                             root = child_valobj_sp;
                             *first_unparsed = end+1; // skip ]
-                            *final_result = ValueObject::ePlain;
+                            *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                             continue;
                         }
                         else
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                     }
                     else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
                     {
-                        if (*what_next == ValueObject::eDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+                        if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                         {
                             Error error;
@@ -2625,13 +2627,13 @@
                             if (error.Fail() || !root.get())
                             {
                                 *first_unparsed = expression_cstr;
-                                *reason_to_stop = ValueObject::eDereferencingFailed;
-                                *final_result = ValueObject::eInvalid;
+                                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+                                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                                 return ValueObjectSP();
                             }
                             else
                             {
-                                *what_next = eNothing;
+                                *what_next = eExpressionPathAftermathNothing;
                                 continue;
                             }
                         }
@@ -2646,21 +2648,21 @@
                                 &&
                                 options.m_no_synthetic_children == false)
                             {
-                                root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true);
+                                root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
                             }
                             else
                                 root = root->GetSyntheticArrayMemberFromPointer(index, true);
                             if (!root.get())
                             {
                                 *first_unparsed = expression_cstr;
-                                *reason_to_stop = ValueObject::eNoSuchChild;
-                                *final_result = ValueObject::eInvalid;
+                                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                                 return ValueObjectSP();
                             }
                             else
                             {
                                 *first_unparsed = end+1; // skip ]
-                                *final_result = ValueObject::ePlain;
+                                *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                                 continue;
                             }
                         }
@@ -2671,40 +2673,58 @@
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                         else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
                         {
                             *first_unparsed = end+1; // skip ]
-                            *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
-                            *final_result = ValueObject::eBitfield;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
                             return root;
                         }
                     }
-                    else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false)
+                    else if (options.m_no_synthetic_children == false)
                     {
-                        root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true);
+                        if (root->HasSyntheticValue())
+                            root = root->GetSyntheticValue();
+                        else if (!root->IsSynthetic())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+                            return ValueObjectSP();
+                        }
+                        // if we are here, then root itself is a synthetic VO.. should be good to go
+                        
+                        if (!root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+                            return ValueObjectSP();
+                        }
+                        root = root->GetChildAtIndex(index, true);
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                         else
                         {
                             *first_unparsed = end+1; // skip ]
-                            *final_result = ValueObject::ePlain;
+                            *final_result = ValueObject::eExpressionPathEndResultTypePlain;
                             continue;
                         }
                     }
                     else
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eNoSuchChild;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                 }
@@ -2715,16 +2735,16 @@
                     if (!end || end != separator_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                     unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return ValueObjectSP();
                     }
                     if (index_lower > index_higher) // swap indices if required
@@ -2739,20 +2759,20 @@
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                         else
                         {
                             *first_unparsed = end+1; // skip ]
-                            *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
-                            *final_result = ValueObject::eBitfield;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
                             return root;
                         }
                     }
                     else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
-                             *what_next == ValueObject::eDereference &&
+                             *what_next == ValueObject::eExpressionPathAftermathDereference &&
                              pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                     {
                         Error error;
@@ -2760,21 +2780,21 @@
                         if (error.Fail() || !root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eDereferencingFailed;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return ValueObjectSP();
                         }
                         else
                         {
-                            *what_next = ValueObject::eNothing;
+                            *what_next = ValueObject::eExpressionPathAftermathNothing;
                             continue;
                         }
                     }
                     else
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
-                        *final_result = ValueObject::eBoundedRange;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
                         return root;
                     }
                 }
@@ -2783,8 +2803,8 @@
             default: // some non-separator is in the way
             {
                 *first_unparsed = expression_cstr;
-                *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                *final_result = ValueObject::eInvalid;
+                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                 return ValueObjectSP();
                 break;
             }
@@ -2822,7 +2842,7 @@
         
         if (!expression_cstr || *expression_cstr == '\0')
         {
-            *reason_to_stop = ValueObject::eEndOfString;
+            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
             list->Append(root);
             return 1;
         }
@@ -2836,15 +2856,15 @@
                     if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eRangeOperatorInvalid;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                     else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                 }
@@ -2853,8 +2873,8 @@
                     if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                     else // expand this into list
@@ -2867,8 +2887,8 @@
                             list->Append(child);
                         }
                         *first_unparsed = expression_cstr+2;
-                        *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                        *final_result = ValueObject::eValueObjectList;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                         return max_index; // tell me number of items I added to the VOList
                     }
                 }
@@ -2877,8 +2897,8 @@
                 if (!close_bracket_position) // if there is no ], this is a syntax error
                 {
                     *first_unparsed = expression_cstr;
-                    *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                    *final_result = ValueObject::eInvalid;
+                    *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                    *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return 0;
                 }
                 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
@@ -2888,8 +2908,8 @@
                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
@@ -2904,15 +2924,15 @@
                                 list->Append(child);
                             }
                             *first_unparsed = expression_cstr+2;
-                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                            *final_result = ValueObject::eValueObjectList;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                             return max_index; // tell me number of items I added to the VOList
                         }
                         else
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return 0;
                         }
                     }
@@ -2923,22 +2943,22 @@
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return 0;
                         }
                         else
                         {
                             list->Append(root);
                             *first_unparsed = end+1; // skip ]
-                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                            *final_result = ValueObject::eValueObjectList;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                             return 1;
                         }
                     }
                     else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
                     {
-                        if (*what_next == ValueObject::eDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+                        if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                         {
                             Error error;
@@ -2946,13 +2966,13 @@
                             if (error.Fail() || !root.get())
                             {
                                 *first_unparsed = expression_cstr;
-                                *reason_to_stop = ValueObject::eDereferencingFailed;
-                                *final_result = ValueObject::eInvalid;
+                                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+                                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                                 return 0;
                             }
                             else
                             {
-                                *what_next = eNothing;
+                                *what_next = eExpressionPathAftermathNothing;
                                 continue;
                             }
                         }
@@ -2962,16 +2982,16 @@
                             if (!root.get())
                             {
                                 *first_unparsed = expression_cstr;
-                                *reason_to_stop = ValueObject::eNoSuchChild;
-                                *final_result = ValueObject::eInvalid;
+                                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                                 return 0;
                             }
                             else
                             {
                                 list->Append(root);
                                 *first_unparsed = end+1; // skip ]
-                                *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                                *final_result = ValueObject::eValueObjectList;
+                                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                                *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                                 return 1;
                             }
                         }
@@ -2982,16 +3002,16 @@
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return 0;
                         }
                         else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
                         {
                             list->Append(root);
                             *first_unparsed = end+1; // skip ]
-                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                            *final_result = ValueObject::eValueObjectList;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                             return 1;
                         }
                     }
@@ -3003,16 +3023,16 @@
                     if (!end || end != separator_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                     unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
                     {
                         *first_unparsed = expression_cstr;
-                        *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                        *final_result = ValueObject::eInvalid;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                         return 0;
                     }
                     if (index_lower > index_higher) // swap indices if required
@@ -3027,21 +3047,21 @@
                         if (!root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eNoSuchChild;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return 0;
                         }
                         else
                         {
                             list->Append(root);
                             *first_unparsed = end+1; // skip ]
-                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                            *final_result = ValueObject::eValueObjectList;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                             return 1;
                         }
                     }
                     else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
-                             *what_next == ValueObject::eDereference &&
+                             *what_next == ValueObject::eExpressionPathAftermathDereference &&
                              pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                     {
                         Error error;
@@ -3049,13 +3069,13 @@
                         if (error.Fail() || !root.get())
                         {
                             *first_unparsed = expression_cstr;
-                            *reason_to_stop = ValueObject::eDereferencingFailed;
-                            *final_result = ValueObject::eInvalid;
+                            *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+                            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                             return 0;
                         }
                         else
                         {
-                            *what_next = ValueObject::eNothing;
+                            *what_next = ValueObject::eExpressionPathAftermathNothing;
                             continue;
                         }
                     }
@@ -3069,8 +3089,8 @@
                             list->Append(child);
                         }
                         *first_unparsed = end+1;
-                        *reason_to_stop = ValueObject::eRangeOperatorExpanded;
-                        *final_result = ValueObject::eValueObjectList;
+                        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
+                        *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
                         return index_higher-index_lower+1; // tell me number of items I added to the VOList
                     }
                 }
@@ -3079,8 +3099,8 @@
             default: // some non-[ separator, or something entirely wrong, is in the way
             {
                 *first_unparsed = expression_cstr;
-                *reason_to_stop = ValueObject::eUnexpectedSymbol;
-                *final_result = ValueObject::eInvalid;
+                *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+                *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                 return 0;
                 break;
             }
@@ -3283,9 +3303,9 @@
                 
                 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
                 {
-                    ValueObjectSP synth_valobj = valobj->GetSyntheticValue (options.m_use_synthetic ?
-                                                                            eUseSyntheticFilter : 
-                                                                            eNoSyntheticFilter);
+                    ValueObject* synth_valobj;
+                    ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
+                    synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
                     uint32_t num_children = synth_valobj->GetNumChildren();
                     bool print_dotdotdot = false;
                     if (num_children)
@@ -3853,14 +3873,28 @@
 //}
 
 void
-ValueObject::ClearUserVisibleData()
+ValueObject::ClearUserVisibleData(uint32_t clear_mask)
 {
-    m_location_str.clear();
-    m_value_str.clear();
-    m_summary_str.clear();
-    m_object_desc_str.clear();
-    m_synthetic_value = NULL;
-    m_is_getting_summary = false;
+    if ((clear_mask & eClearUserVisibleDataItemsValue) == eClearUserVisibleDataItemsValue)
+        m_value_str.clear();
+    
+    if ((clear_mask & eClearUserVisibleDataItemsLocation) == eClearUserVisibleDataItemsLocation)
+        m_location_str.clear();
+    
+    if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary)
+    {
+        m_is_getting_summary = false;
+        m_summary_str.clear();
+    }
+    
+    if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription)
+        m_object_desc_str.clear();
+    
+    if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) == eClearUserVisibleDataItemsSyntheticChildren)
+    {
+            if (m_synthetic_value)
+                m_synthetic_value = NULL;
+    }
 }
 
 SymbolContextScope *

Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Mon Mar 19 17:58:49 2012
@@ -15,87 +15,62 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/FormatClasses.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Core/Value.h"
 #include "lldb/Core/ValueObject.h"
 
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/Variable.h"
-
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-
-
 using namespace lldb_private;
 
 ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
     ValueObject(parent),
-    m_address (),
-    m_type_sp(),
-    m_use_synthetic (lldb::eUseSyntheticFilter),
     m_synth_sp(filter),
-    m_synth_filter(filter->GetFrontEnd(parent.GetSP())),
+    m_synth_filter_ap(filter->GetFrontEnd(parent)),
     m_children_byindex(),
-    m_name_toindex()
+    m_name_toindex(),
+    m_children_count(UINT32_MAX)
 {
-    SetName (parent.GetName());
+#ifdef LLDB_CONFIGURATION_DEBUG
+    std::string new_name(parent.GetName().AsCString());
+    new_name += "$$__synth__";
+    SetName (ConstString(new_name.c_str()));
+#else
+    SetName(parent.GetName());
+#endif
 }
 
 ValueObjectSynthetic::~ValueObjectSynthetic()
 {
-    m_owning_valobj_sp.reset();
 }
 
 lldb::clang_type_t
 ValueObjectSynthetic::GetClangTypeImpl ()
 {
-    if (m_type_sp)
-        return m_value.GetClangType();
-    else
-        return m_parent->GetClangType();
+    return m_parent->GetClangType();
 }
 
 ConstString
 ValueObjectSynthetic::GetTypeName()
 {
-    const bool success = UpdateValueIfNeeded(false);
-    if (success && m_type_sp)
-        return ClangASTType::GetConstTypeName (GetClangType());
-    else
-        return m_parent->GetTypeName();
+    return m_parent->GetTypeName();
 }
 
 uint32_t
 ValueObjectSynthetic::CalculateNumChildren()
 {
-    return m_synth_filter->CalculateNumChildren();
+    UpdateValueIfNeeded();
+    if (m_children_count < UINT32_MAX)
+        return m_children_count;
+    return (m_children_count = m_synth_filter_ap->CalculateNumChildren());
 }
 
 clang::ASTContext *
 ValueObjectSynthetic::GetClangASTImpl ()
 {
-    const bool success = UpdateValueIfNeeded(false);
-    if (success && m_type_sp)
-        return m_type_sp->GetClangAST();
-    else
-        return m_parent->GetClangAST ();
+    return m_parent->GetClangAST ();
 }
 
 size_t
 ValueObjectSynthetic::GetByteSize()
 {
-    const bool success = UpdateValueIfNeeded(false);
-    if (success && m_type_sp)
-        return m_value.GetValueByteSize(GetClangAST(), NULL);
-    else
-        return m_parent->GetByteSize();
+    return m_parent->GetByteSize();
 }
 
 lldb::ValueType
@@ -113,17 +88,19 @@
     if (!m_parent->UpdateValueIfNeeded(false))
     {
         // our parent could not update.. as we are meaningless without a parent, just stop
-        if (m_error.Success() && m_parent->GetError().Fail())
+        if (m_parent->GetError().Fail())
             m_error = m_parent->GetError();
         return false;
     }
 
-    m_children_byindex.clear();
-    m_name_toindex.clear();
-    
     // let our backend do its update
-    
-    m_synth_filter->Update();
+    if (m_synth_filter_ap->Update() == false)
+    {
+        // filter said that cached values are stale
+        m_children_byindex.clear();
+        m_name_toindex.clear();
+        m_children_count = UINT32_MAX;
+    }
     
     SetValueIsValid(true);
     return true;
@@ -132,27 +109,30 @@
 lldb::ValueObjectSP
 ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create)
 {
+    UpdateValueIfNeeded();
+    
     ByIndexIterator iter = m_children_byindex.find(idx);
     
     if (iter == m_children_byindex.end())
     {
-        if (can_create && m_synth_filter != NULL)
+        if (can_create && m_synth_filter_ap.get() != NULL)
         {
-            lldb::ValueObjectSP synth_guy = m_synth_filter->GetChildAtIndex (idx, can_create);
-            m_children_byindex[idx]= synth_guy;
+            lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx, can_create);
+            m_children_byindex[idx]= synth_guy.get();
             return synth_guy;
         }
         else
             return lldb::ValueObjectSP();
     }
     else
-        return iter->second;
+        return iter->second->GetSP();
 }
 
 lldb::ValueObjectSP
 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
 {
-    
+    UpdateValueIfNeeded();
+
     uint32_t index = GetIndexOfChildWithName(name);
     
     if (index == UINT32_MAX)
@@ -164,15 +144,17 @@
 uint32_t
 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
 {
+    UpdateValueIfNeeded();
+    
     NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
     
-    if (iter == m_name_toindex.end() && m_synth_filter != NULL)
+    if (iter == m_name_toindex.end() && m_synth_filter_ap.get() != NULL)
     {
-        uint32_t index = m_synth_filter->GetIndexOfChildWithName (name);
+        uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
         m_name_toindex[name.GetCString()] = index;
         return index;
     }
-    else if (iter == m_name_toindex.end() && m_synth_filter == NULL)
+    else if (iter == m_name_toindex.end() && m_synth_filter_ap.get() == NULL)
         return UINT32_MAX;
     else /*if (iter != m_name_toindex.end())*/
         return iter->second;

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Mar 19 17:58:49 2012
@@ -91,7 +91,7 @@
 extern "C" void*          LLDBSwigPython_GetChildAtIndex             (void *implementor, uint32_t idx);
 extern "C" int            LLDBSwigPython_GetIndexOfChildWithName     (void *implementor, const char* child_name);
 extern "C" void*          LLDBSWIGPython_CastPyObjectToSBValue       (void* data);
-extern "C" void           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+extern "C" bool           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
 
 extern "C" bool           LLDBSwigPythonCallCommand 
 (
@@ -1654,26 +1654,28 @@
     return ret_val;
 }
 
-void
+bool
 ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
 {
+    bool ret_val = false;
+    
     if (!implementor_sp)
-        return;
+        return ret_val;
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
-        return;
+        return ret_val;
     
     if (!g_swig_update_provider)
-        return;
+        return ret_val;
     
     {
         Locker py_lock(this);
-        g_swig_update_provider       (implementor);
+        ret_val = g_swig_update_provider       (implementor);
     }
     
-    return;
+    return ret_val;
 }
 
 bool

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Mon Mar 19 17:58:49 2012
@@ -642,7 +642,11 @@
                             if (!child_valobj_sp)
                             {
                                 if (no_synth_child == false)
-                                    child_valobj_sp = valobj_sp->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName (child_name, true);
+                                {
+                                    child_valobj_sp = valobj_sp->GetSyntheticValue();
+                                    if (child_valobj_sp)
+                                        child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
+                                }
                                 
                                 if (no_synth_child || !child_valobj_sp)
                                 {
@@ -742,7 +746,7 @@
                                     else if (is_objc_pointer)
                                     {                                            
                                         // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
-                                        ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(eUseSyntheticFilter);
+                                        ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
                                         if (synthetic.get() == NULL /* no synthetic */
                                             || synthetic == valobj_sp) /* synthetic is the same as the original object */
                                         {
@@ -814,7 +818,7 @@
                                 }
                                 else
                                 {
-                                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(eUseSyntheticFilter);
+                                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
                                     if (no_synth_child /* synthetic is forbidden */ ||
                                         synthetic.get() == NULL /* no synthetic */
                                         || synthetic == valobj_sp) /* synthetic is the same as the original object */

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Mon Mar 19 17:58:49 2012
@@ -127,8 +127,8 @@
         self.runCmd("type summary add -c Point")
             
         self.expect("frame variable iAmSomewhere",
-            substrs = ['x=4',
-                       'y=6'])
+            substrs = ['x = 4',
+                       'y = 6'])
         
         self.expect("type summary list",
             substrs = ['Point',

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Mon Mar 19 17:58:49 2012
@@ -22,14 +22,28 @@
         self.buildDwarf()
         self.data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_rdar10960550_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.rdar10960550_formatter_commands()
+
+    def test_rdar10960550_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.rdar10960550_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', '// Set break point at this line.')
+        self.line2 = line_number('main.cpp', '// Set cast break point at this line.')
+        self.line3 = line_number('main.cpp', '// Set second cast break point at this line.')
 
     def data_formatter_commands(self):
-        """Test that that file and class static variables display correctly."""
+        """Test using Python synthetic children provider."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
         self.expect("breakpoint set -f main.cpp -l %d" % self.line,
@@ -184,17 +198,74 @@
 
         self.expect("frame variable f00_1", matching=False,
                 substrs = ['fake_a = '])
-        
-        self.runCmd("n")
-        
-        self.runCmd("script from ftsp import *")
-        self.runCmd("type synth add -l ftsp wrapint")
-        
-        self.expect('frame variable test_cast',
-            substrs = ['A',
-                       'B',
-                       'C',
-                       'D'])
+
+    def rdar10960550_formatter_commands(self):
+        """Test that synthetic children persist stoppoints."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line2,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+                        self.line2)
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line3,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 2: file ='main.cpp', line = %d, locations = 1" %
+                        self.line3)
+
+        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)
+
+        self.runCmd("command script import ./ftsp.py --allow-reload")
+        self.runCmd("type synth add -l ftsp.ftsp wrapint")
+
+        # we need to check that the VO is properly updated so that the same synthetic children are reused
+        # but their values change correctly across stop-points - in order to do this, self.runCmd("next")
+        # does not work because it forces a wipe of the stack frame - this is why we are using this more contrived
+        # mechanism to achieve our goal of preserving test_cast as a VO
+        test_cast = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('test_cast')
+
+        str_cast = str(test_cast)
+
+        if self.TraceOn():
+             print str_cast
+
+        self.assertTrue(str_cast.find('A') != -1, 'could not find A in output')
+        self.assertTrue(str_cast.find('B') != -1, 'could not find B in output')
+        self.assertTrue(str_cast.find('C') != -1, 'could not find C in output')
+        self.assertTrue(str_cast.find('D') != -1, 'could not find D in output')
+        self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
+
+        self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver()
+
+        str_cast = str(test_cast)
+
+        if self.TraceOn():
+             print str_cast
+
+        # we detect that all the values of the child objects have changed - but the counter-generated item
+        # is still fixed at 0 because it is cached - this would fail if update(self): in ftsp returned False
+        # or if synthetic children were not being preserved
+        self.assertTrue(str_cast.find('Q') != -1, 'could not find Q in output')
+        self.assertTrue(str_cast.find('X') != -1, 'could not find X in output')
+        self.assertTrue(str_cast.find('T') != -1, 'could not find T in output')
+        self.assertTrue(str_cast.find('F') != -1, 'could not find F in output')
+        self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py Mon Mar 19 17:58:49 2012
@@ -1,21 +1,23 @@
 import lldb
 class fooSynthProvider:
-     def __init__(self, valobj, dict):
-         self.valobj = valobj;
-         self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
-     def num_children(self):
-         return 3;
-     def get_child_at_index(self, index):
-         if index == 0:
-             child = self.valobj.GetChildMemberWithName('a');
-         if index == 1:
-             child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
-         if index == 2:
-             child = self.valobj.GetChildMemberWithName('r');
-         return child;
-     def get_child_index(self, name):
-         if name == 'a':
-             return 0;
-         if name == 'fake_a':
-             return 1;
-    	 return 2;
+	def __init__(self, valobj, dict):
+		self.valobj = valobj;
+		self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+	def num_children(self):
+		return 3;
+	def get_child_at_index(self, index):
+		if index == 0:
+			child = self.valobj.GetChildMemberWithName('a');
+		if index == 1:
+			child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
+		if index == 2:
+			child = self.valobj.GetChildMemberWithName('r');
+		return child;
+	def get_child_index(self, name):
+		if name == 'a':
+			return 0;
+		if name == 'fake_a':
+			return 1;
+		return 2;
+	def update(self):
+		return True
\ No newline at end of file

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py Mon Mar 19 17:58:49 2012
@@ -1,20 +1,32 @@
 import lldb
+
+counter = 0
+
 class ftsp:
 	def __init__(self, valobj, dict):
 		self.valobj = valobj;
-		self.update()
 	def num_children(self):
 		if self.char.IsValid():
-			return 4;
+			return 5;
 		return 0;
 	def get_child_index(self,name):
 		return 0;
 	def get_child_at_index(self,index):
 		if index == 0:
 			return self.x.Cast(self.char)
+		if index == 4:
+			return self.valobj.CreateValueFromExpression(str(index),'(char)('+str(self.count)+')')
 		return self.x.CreateChildAtOffset(str(index),
 									   index,
 									   self.char);
 	def update(self):
 		self.x = self.valobj.GetChildMemberWithName('x');
 		self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)
+		global counter
+		self.count = counter
+		counter = counter + 1
+		return True # important: if we return False here, or fail to return, the test will fail
+
+def __lldb_init_module(debugger, dict):
+	global counter
+	counter = 0
\ No newline at end of file

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp Mon Mar 19 17:58:49 2012
@@ -57,6 +57,11 @@
                256*'B' +
                256*256*'C'+
                256*256*256*'D');
-    
+    // Set cast break point at this line.
+    test_cast.x = 'Q' +
+	               256*'X' +
+	               256*256*'T'+
+	               256*256*256*'F';
+    // Set second cast break point at this line.
     return 0;
 }
\ No newline at end of file

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp Mon Mar 19 17:58:49 2012
@@ -1,4 +1,7 @@
 #include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
 #define _LIBCPP_INLINE_VISIBILITY
 #include <list>
 

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp?rev=153061&r1=153060&r2=153061&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp Mon Mar 19 17:58:49 2012
@@ -1,4 +1,7 @@
 #include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
 #define _LIBCPP_INLINE_VISIBILITY
 #include <vector>
 typedef std::vector<int> int_vect;

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=153061&r1=153060&r2=153061&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 Mon Mar 19 17:58:49 2012
@@ -149,7 +149,7 @@
         # ...even if we use one-liner summaries
         self.runCmd("type summary add -c BagOfBags")
         self.expect('frame variable bag_bag',
-            substrs = ['(BagOfBags) bag_bag = (x.y=70, y->y[0-0]=true)'])
+            substrs = ['(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)'])
         
         self.runCmd("type summary delete BagOfBags")
 





More information about the lldb-commits mailing list