[Lldb-commits] [lldb] r134943 - in /lldb/trunk: include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Symbol/ include/lldb/Utility/ source/Commands/ source/Core/ source/Interpreter/ source/Symbol/ test/functionalities/data-formatter/data-formatter-cpp/

Enrico Granata granata.enrico at gmail.com
Mon Jul 11 17:18:11 PDT 2011


Author: enrico
Date: Mon Jul 11 19:18:11 2011
New Revision: 134943

URL: http://llvm.org/viewvc/llvm-project?rev=134943&view=rev
Log:
named summaries:
 - a new --name option for "type summary add" lets you give a name to a summary
 - a new --summary option for "frame variable" lets you bind a named summary to one or more variables
${var%s} now works for printing the value of 0-terminated CStrings
type format test case now tests for cascading
 - this is disabled on GCC because GCC may end up stripping typedef chains, basically breaking cascading
new design for the FormatNavigator class
new template class CleanUp2 meant to support cleanup routines with 1 additional parameter beyond resource handle

Modified:
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Core/FormatManager.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Interpreter/OptionGroupVariable.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Utility/CleanUp.h
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/OptionGroupVariable.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/SymbolContext.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Mon Jul 11 19:18:11 2011
@@ -550,6 +550,32 @@
         static uint32_t
         GetCount();
     };
+    
+    class NamedSummaryFormats
+    {
+    public:
+        
+        static bool
+        Get(const ConstString &type, SummaryFormat::SharedPointer &entry);
+        
+        static void
+        Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
+        
+        static bool
+        Delete(const ConstString &type);
+        
+        static void
+        Clear();
+        
+        static void
+        LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
+        
+        static uint32_t
+        GetCurrentRevision();
+        
+        static uint32_t
+        GetCount();
+    };
 
     
 };

Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Mon Jul 11 19:18:11 2011
@@ -142,53 +142,66 @@
     }
     
 };
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator;
     
-template<typename MapType, typename CallbackType>
-class FormatNavigator
+template<typename KeyType, typename ValueType>
+class FormatMap
 {
+private:
+    typedef typename ValueType::SharedPointer ValueSP;
+    Mutex m_map_mutex;
+    IFormatChangeListener* listener;
+    
+    friend class FormatNavigator<KeyType, ValueType>;
+    
+public:
+    typedef std::map<KeyType, ValueSP> MapType;
+
+private:    
+    MapType m_map;
+    
+    MapType& map()
+    {
+        return m_map;
+    }
+    
+    Mutex& mutex()
+    {
+        return m_map_mutex;
+    }
+
 public:
 
     typedef typename MapType::iterator MapIterator;
-    typedef typename MapType::key_type MapKeyType;
-    typedef typename MapType::mapped_type MapValueType;
+    typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
     
-    FormatNavigator(IFormatChangeListener* lst = NULL) :
+    FormatMap(IFormatChangeListener* lst = NULL) :
+    m_map(),
     m_map_mutex(Mutex::eMutexTypeRecursive),
-    m_map(MapType()),
     listener(lst)
     {
     }
-        
-    bool
-    Get(ValueObject& vobj, MapValueType& entry)
-    {
-        Mutex::Locker(m_map_mutex);
-        clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType());
-        bool ret = Get(vobj, type, entry);
-        if(ret)
-            entry = MapValueType(entry);
-        else
-            entry = MapValueType();
-        return ret;
-    }
     
     void
-    Add(const MapKeyType &type, const MapValueType& entry)
+    Add(KeyType name,
+        const ValueSP& entry)
     {
         Mutex::Locker(m_map_mutex);
-        m_map[type] = MapValueType(entry);
-        if(listener)
+        m_map[name] = entry;
+        if (listener)
             listener->Changed();
     }
     
     bool
-    Delete(const char* type)
+    Delete(KeyType name)
     {
         Mutex::Locker(m_map_mutex);
-        MapIterator iter = m_map.find(type);
+        MapIterator iter = m_map.find(name);
         if (iter == m_map.end())
             return false;
-        m_map.erase(type);
+        m_map.erase(name);
         if(listener)
             listener->Changed();
         return true;
@@ -203,6 +216,18 @@
             listener->Changed();
     }
     
+    bool
+    Get(KeyType name,
+        ValueSP& entry)
+    {
+        Mutex::Locker(m_map_mutex);
+        MapIterator iter = m_map.find(name);
+        if (iter == m_map.end())
+            return false;
+        entry = iter->second;
+        return true;
+    }
+    
     void
     LoopThrough(CallbackType callback, void* param)
     {
@@ -212,8 +237,8 @@
             MapIterator pos, end = m_map.end();
             for (pos = m_map.begin(); pos != end; pos++)
             {
-                MapKeyType type = pos->first;
-                if(!callback(param, type, MapValueType(pos->second)))
+                KeyType type = pos->first;
+                if(!callback(param, type, pos->second))
                     break;
             }
         }
@@ -225,36 +250,91 @@
         return m_map.size();
     }
     
-    ~FormatNavigator()
+};
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator
+{
+private:
+    typedef FormatMap<KeyType,ValueType> BackEndType;
+    
+    BackEndType m_format_map;
+        
+public:
+    typedef typename BackEndType::MapType MapType;
+    typedef typename MapType::iterator MapIterator;
+    typedef typename MapType::key_type MapKeyType;
+    typedef typename MapType::mapped_type MapValueType;
+    typedef typename BackEndType::CallbackType CallbackType;
+
+    FormatNavigator(IFormatChangeListener* lst = NULL) :
+    m_format_map(lst)
     {
     }
     
-private:
+    void
+    Add(const MapKeyType &type, const MapValueType& entry)
+    {
+        m_format_map.Add(type,entry);
+    }
     
-    Mutex m_map_mutex;
-    MapType m_map;
-    IFormatChangeListener* listener;
+    // using const char* instead of MapKeyType is necessary here
+    // to make the partial template specializations below work
+    bool
+    Delete(const char *type)
+    {
+        return m_format_map.Delete(type);
+    }
+    
+    bool
+    Get(ValueObject& vobj, MapValueType& entry)
+    {
+        clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType());
+        bool ret = Get(vobj, type, entry);
+        if(ret)
+            entry = MapValueType(entry);
+        else
+            entry = MapValueType();
+        return ret;
+    }
+    
+    void
+    Clear()
+    {
+        m_format_map.Clear();
+    }
+    
+    void
+    LoopThrough(CallbackType callback, void* param)
+    {
+        m_format_map.LoopThrough(callback,param);
+    }
+    
+    uint32_t
+    GetCount()
+    {
+        return m_format_map.GetCount();
+    }
+
+private:
     
     DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
     
+    // using const char* instead of MapKeyType is necessary here
+    // to make the partial template specializations below work
     bool
     Get(const char* type, MapValueType& entry)
     {
-        Mutex::Locker(m_map_mutex);
-        MapIterator iter = m_map.find(type);
-        if (iter == m_map.end())
-            return false;
-        entry = iter->second;
-        return true;
+        return m_format_map.Get(type, entry);
     }
     
     bool Get(ValueObject& vobj,
-             const clang::QualType& q_type,
+             clang::QualType type,
              MapValueType& entry)
     {
-        if (q_type.isNull())
+        if (type.isNull())
             return false;
-        clang::QualType type = q_type.getUnqualifiedType();
+        // clang::QualType type = q_type.getUnqualifiedType();
         type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
         const clang::Type* typePtr = type.getTypePtrOrNull();
         if (!typePtr)
@@ -354,40 +434,41 @@
         // try to strip typedef chains
         const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
         if (type_tdef)
+        {
             if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry)) && entry->m_cascades)
                 return true;
+        }
         return false;
     }
-    
 };
-    
+
 template<>
 bool
-FormatNavigator<std::map<lldb::RegularExpressionSP, SummaryFormat::SharedPointer>, SummaryFormat::RegexSummaryCallback>::Get(const char* key,
-                                                                                                                             SummaryFormat::SharedPointer& value);
+FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Get(const char* key, SummaryFormat::SharedPointer& value);
+
 template<>
 bool
-FormatNavigator<std::map<lldb::RegularExpressionSP, SummaryFormat::SharedPointer>, SummaryFormat::RegexSummaryCallback>::Delete(const char* type);
-    
+FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Delete(const char* type);
+
 class FormatManager : public IFormatChangeListener
 {
-    
-public:
-    
 private:
     
-    typedef std::map<const char*, ValueFormat::SharedPointer> ValueMap;
-    typedef std::map<const char*, SummaryFormat::SharedPointer> SummaryMap;
-    typedef std::map<lldb::RegularExpressionSP, SummaryFormat::SharedPointer> RegexSummaryMap;
-    
-    typedef FormatNavigator<ValueMap, ValueFormat::ValueCallback> ValueNavigator;
-    typedef FormatNavigator<SummaryMap, SummaryFormat::SummaryCallback> SummaryNavigator;
-    typedef FormatNavigator<RegexSummaryMap, SummaryFormat::RegexSummaryCallback> RegexSummaryNavigator;
+    typedef FormatNavigator<const char*, ValueFormat> ValueNavigator;
+    typedef FormatNavigator<const char*, SummaryFormat> SummaryNavigator;
+    typedef FormatNavigator<lldb::RegularExpressionSP, SummaryFormat> RegexSummaryNavigator;
+    
+    typedef ValueNavigator::MapType ValueMap;
+    typedef SummaryNavigator::MapType SummaryMap;
+    typedef RegexSummaryNavigator::MapType RegexSummaryMap;
+    typedef FormatMap<const char*, SummaryFormat> NamedSummariesMap;
     
     ValueNavigator m_value_nav;
     SummaryNavigator m_summary_nav;
     RegexSummaryNavigator m_regex_summary_nav;
-        
+    
+    NamedSummariesMap m_named_summaries_map;
+    
     uint32_t m_last_revision;
     
 public:
@@ -396,6 +477,7 @@
     m_value_nav(this),
     m_summary_nav(this),
     m_regex_summary_nav(this),
+    m_named_summaries_map(this),
     m_last_revision(0)
     {
     }
@@ -404,7 +486,7 @@
     ValueNavigator& Value() { return m_value_nav; }
     SummaryNavigator& Summary() { return m_summary_nav; }
     RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; }
-
+    NamedSummariesMap& NamedSummary() { return m_named_summaries_map; }
     
     static bool
     GetFormatFromCString (const char *format_cstr,

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Mon Jul 11 19:18:11 2011
@@ -93,6 +93,7 @@
         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
     };
     
@@ -102,6 +103,7 @@
         eBitfield,                  // a bitfield
         eBoundedRange,              // a range [low-high]
         eUnboundedRange,            // a range []
+        eValueObjectList,           // several items in a VOList
         eInvalid = 0xFFFF
     };
     
@@ -392,6 +394,15 @@
                               const GetValueForExpressionPathOptions& options = GetValueForExpressionPathOptions::DefaultOptions(),
                               ExpressionPathAftermath* final_task_on_target = NULL);
     
+    int
+    GetValuesForExpressionPath(const char* expression,
+                               lldb::ValueObjectListSP& list,
+                               const char** first_unparsed = NULL,
+                               ExpressionPathScanEndReason* reason_to_stop = NULL,
+                               ExpressionPathEndResultType* final_value_type = NULL,
+                               const GetValueForExpressionPathOptions& options = GetValueForExpressionPathOptions::DefaultOptions(),
+                               ExpressionPathAftermath* final_task_on_target = NULL);
+    
     virtual bool
     IsInScope ()
     {
@@ -581,6 +592,17 @@
                      lldb::DynamicValueType use_dynamic,
                      bool scope_already_checked,
                      bool flat_output);
+    
+    // returns true if this is a char* or a char[]
+    // if it is a char* and check_pointer is true,
+    // it also checks that the pointer is valid
+    bool
+    IsCStringContainer(bool check_pointer = false);
+    
+    void
+    ReadPointedString(Stream& s,
+                      Error& error,
+                      uint32_t max_length = 0);
 
     bool
     GetIsConstant () const
@@ -609,6 +631,42 @@
             m_value_str.clear();
         m_format = format;
     }
+    
+    void
+    SetCustomSummaryFormat(lldb::SummaryFormatSP format)
+    {
+        m_forced_summary_format = format;
+        m_user_id_of_forced_summary = m_update_point.GetUpdateID();
+        m_summary_str.clear();
+    }
+    
+    lldb::SummaryFormatSP
+    GetCustomSummaryFormat()
+    {
+        return m_forced_summary_format;
+    }
+    
+    void
+    ClearCustomSummaryFormat()
+    {
+        m_forced_summary_format.reset();
+        m_summary_str.clear();
+    }
+    
+    bool
+    HasCustomSummaryFormat()
+    {
+        return (m_forced_summary_format.get());
+    }
+    
+    lldb::SummaryFormatSP
+    GetSummaryFormat()
+    {
+        UpdateFormatsIfNeeded();
+        if (HasCustomSummaryFormat())
+            return m_forced_summary_format;
+        return m_last_summary_format;
+    }
 
     // Use GetParent for display purposes, but if you want to tell the parent to update itself
     // then use m_parent.  The ValueObjectDynamicValue's parent is not the correct parent for
@@ -668,10 +726,12 @@
                                              // as an independent ValueObjectConstResult, which isn't managed by us.
     ValueObject *m_deref_valobj;
 
-    lldb::Format        m_format;
-    uint32_t            m_last_format_mgr_revision;
-    lldb::SummaryFormatSP m_last_summary_format;
-    lldb::ValueFormatSP m_last_value_format;
+    lldb::Format            m_format;
+    uint32_t                m_last_format_mgr_revision;
+    lldb::SummaryFormatSP   m_last_summary_format;
+    lldb::ValueFormatSP     m_last_value_format;
+    lldb::SummaryFormatSP   m_forced_summary_format;
+    lldb::user_id_t         m_user_id_of_forced_summary;
     bool                m_value_is_valid:1,
                         m_value_did_change:1,
                         m_children_count_valid:1,
@@ -753,12 +813,27 @@
     //------------------------------------------------------------------
     
     lldb::ValueObjectSP
-    GetValueForExpressionPath_Impl(const char* expression,
+    GetValueForExpressionPath_Impl(const char* expression_cstr,
                                    const char** first_unparsed,
                                    ExpressionPathScanEndReason* reason_to_stop,
                                    ExpressionPathEndResultType* final_value_type,
                                    const GetValueForExpressionPathOptions& options,
                                    ExpressionPathAftermath* final_task_on_target);
+        
+    // this method will ONLY expand [] expressions into a VOList and return
+    // the number of elements it added to the VOList
+    // it will NOT loop through expanding the follow-up of the expression_cstr
+    // for all objects in the list
+    int
+    ExpandArraySliceExpression(const char* expression_cstr,
+                               const char** first_unparsed,
+                               lldb::ValueObjectSP root,
+                               lldb::ValueObjectListSP& list,
+                               ExpressionPathScanEndReason* reason_to_stop,
+                               ExpressionPathEndResultType* final_value_type,
+                               const GetValueForExpressionPathOptions& options,
+                               ExpressionPathAftermath* final_task_on_target);
+                               
     
     DISALLOW_COPY_AND_ASSIGN (ValueObject);
 

Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupVariable.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionGroupVariable.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionGroupVariable.h Mon Jul 11 19:18:11 2011
@@ -53,6 +53,7 @@
              show_scope:1,
              show_decl:1;
         lldb::Format format;
+        std::string summary;
 
     private:
         DISALLOW_COPY_AND_ASSIGN(OptionGroupVariable);

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Mon Jul 11 19:18:11 2011
@@ -49,7 +49,8 @@
         eTypeIsStructUnion      = (1u << 13),
         eTypeIsTemplate         = (1u << 14),
         eTypeIsTypedef          = (1u << 15),
-        eTypeIsVector           = (1u << 16)
+        eTypeIsVector           = (1u << 16),
+        eTypeIsScalar           = (1u << 17),
     };
 
     typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);

Modified: lldb/trunk/include/lldb/Utility/CleanUp.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/CleanUp.h?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/CleanUp.h (original)
+++ lldb/trunk/include/lldb/Utility/CleanUp.h Mon Jul 11 19:18:11 2011
@@ -52,7 +52,7 @@
 //  // malloc/free example
 //  CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
 //----------------------------------------------------------------------
-template <typename T, typename R>
+template <typename T, typename R = void>
 class CleanUp
 {
 public:
@@ -182,6 +182,140 @@
     // Outlaw default constructor, copy constructor and the assignment operator
     DISALLOW_COPY_AND_ASSIGN (CleanUp);                 
 };
+    
+template <typename T, typename R, typename A0>
+class CleanUp2
+{
+public:
+    typedef T value_type;
+    typedef R (*CallbackType)(value_type, A0);
+    
+    //----------------------------------------------------------------------
+    // Constructor that sets the current value only. No values are 
+    // considered to be invalid and the cleanup function will be called
+    // regardless of the value of m_current_value.
+    //----------------------------------------------------------------------
+    CleanUp2 (value_type value, CallbackType callback, A0 arg) : 
+    m_current_value (value),
+    m_invalid_value (),
+    m_callback (callback),
+    m_callback_called (false),
+    m_invalid_value_is_valid (false),
+    m_argument(arg)
+    {
+    }
+    
+    //----------------------------------------------------------------------
+    // Constructor that sets the current value and also the invalid value.
+    // The cleanup function will be called on "m_value" as long as it isn't
+    // equal to "m_invalid_value".
+    //----------------------------------------------------------------------
+    CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) : 
+    m_current_value (value),
+    m_invalid_value (invalid),
+    m_callback (callback),
+    m_callback_called (false),
+    m_invalid_value_is_valid (true),
+    m_argument(arg)
+    {
+    }
+    
+    //----------------------------------------------------------------------
+    // Automatically cleanup when this object goes out of scope.
+    //----------------------------------------------------------------------
+    ~CleanUp2 ()
+    {
+        clean();
+    }
+    
+    //----------------------------------------------------------------------
+    // Access the value stored in this class
+    //----------------------------------------------------------------------
+    value_type get() 
+    {
+        return m_current_value; 
+    }
+    
+    //----------------------------------------------------------------------
+    // Access the value stored in this class
+    //----------------------------------------------------------------------
+    const value_type
+    get() const 
+    {
+        return m_current_value; 
+    }
+    
+    //----------------------------------------------------------------------
+    // Reset the owned value to "value". If a current value is valid and
+    // the cleanup callback hasn't been called, the previous value will
+    // be cleaned up (see void CleanUp::clean()). 
+    //----------------------------------------------------------------------
+    void 
+    set (const value_type value)
+    {
+        // Cleanup the current value if needed
+        clean ();
+        // Now set the new value and mark our callback as not called
+        m_callback_called = false;
+        m_current_value = value;
+    }
+    
+    //----------------------------------------------------------------------
+    // Checks is "m_current_value" is valid. The value is considered valid
+    // no invalid value was supplied during construction of this object or
+    // if an invalid value was supplied and "m_current_value" is not equal
+    // to "m_invalid_value".
+    //
+    // Returns true if "m_current_value" is valid, false otherwise.
+    //----------------------------------------------------------------------
+    bool 
+    is_valid() const 
+    {
+        if (m_invalid_value_is_valid)
+            return m_current_value != m_invalid_value; 
+        return true;
+    }
+    
+    //----------------------------------------------------------------------
+    // This function will call the cleanup callback provided in the 
+    // constructor one time if the value is considered valid (See is_valid()).
+    // This function sets m_callback_called to true so we don't call the
+    // cleanup callback multiple times on the same value.
+    //----------------------------------------------------------------------
+    void 
+    clean()
+    {
+        if (m_callback && !m_callback_called)
+        {
+            m_callback_called = true;
+            if (is_valid())
+                m_callback(m_current_value, m_argument);
+        }
+    }
+    
+    //----------------------------------------------------------------------
+    // Cancels the cleanup that would have been called on "m_current_value" 
+    // if it was valid. This function can be used to release the value 
+    // contained in this object so ownership can be transfered to the caller.
+    //----------------------------------------------------------------------
+    value_type
+    release ()
+    {
+        m_callback_called = true;
+        return m_current_value;
+    }
+    
+private:
+    value_type      m_current_value;
+    const   value_type      m_invalid_value;
+    CallbackType    m_callback;
+    bool            m_callback_called;
+    bool            m_invalid_value_is_valid;
+    A0              m_argument;
+    
+    // Outlaw default constructor, copy constructor and the assignment operator
+    DISALLOW_COPY_AND_ASSIGN (CleanUp2);                 
+};
 
 } // namespace lldb_utility
 

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Mon Jul 11 19:18:11 2011
@@ -439,6 +439,10 @@
 
             const char *name_cstr = NULL;
             size_t idx;
+            
+            SummaryFormatSP summary_format_sp;
+            if (!m_option_variable.summary.empty())
+                Debugger::NamedSummaryFormats::Get(ConstString(m_option_variable.summary.c_str()), summary_format_sp);
 
             if (variable_list)
             {
@@ -484,7 +488,8 @@
                                                     if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
                                                         s.PutCString (": ");
                                                 }
-                                                
+                                                if (summary_format_sp)
+                                                    valobj_sp->SetCustomSummaryFormat(summary_format_sp);
                                                 ValueObject::DumpValueObject (result.GetOutputStream(), 
                                                                               valobj_sp.get(), 
                                                                               var_sp->GetName().AsCString(), 
@@ -534,6 +539,8 @@
                                     var_sp->GetDeclaration ().DumpStopContext (&s, false);
                                     s.PutCString (": ");
                                 }
+                                if (summary_format_sp)
+                                    valobj_sp->SetCustomSummaryFormat(summary_format_sp);
                                 ValueObject::DumpValueObject (result.GetOutputStream(), 
                                                               valobj_sp.get(), 
                                                               valobj_sp->GetParent() ? name_cstr : NULL, 
@@ -622,6 +629,8 @@
                                             var_sp->GetDeclaration ().DumpStopContext (&s, false);
                                             s.PutCString (": ");
                                         }
+                                        if (summary_format_sp)
+                                            valobj_sp->SetCustomSummaryFormat(summary_format_sp);
                                         ValueObject::DumpValueObject (result.GetOutputStream(), 
                                                                       valobj_sp.get(), 
                                                                       name_cstr, 

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Mon Jul 11 19:18:11 2011
@@ -468,6 +468,9 @@
                 case 'x':
                     m_regex = true;
                     break;
+                case 'n':
+                    m_name = new ConstString(option_arg);
+                    break;
                 default:
                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
                     break;
@@ -486,6 +489,7 @@
             m_skip_references = false;
             m_skip_pointers = false;
             m_regex = false;
+            m_name = NULL;
         }
         
         const OptionDefinition*
@@ -508,6 +512,7 @@
         bool m_skip_pointers;
         bool m_regex;
         std::string m_format_string;
+        ConstString* m_name;
     };
     
     CommandOptions m_options;
@@ -601,7 +606,7 @@
     {
         const size_t argc = command.GetArgumentCount();
         
-        if (argc < 1)
+        if (argc < 1 && !m_options.m_name)
         {
             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
             result.SetStatus(eReturnStatusFailed);
@@ -636,14 +641,14 @@
         
         for(int i = 0; i < argc; i++) {
             const char* typeA = command.GetArgumentAtIndex(i);
-            if(!typeA || typeA[0] == '\0')
+            if (!typeA || typeA[0] == '\0')
             {
                 result.AppendError("empty typenames not allowed");
                 result.SetStatus(eReturnStatusFailed);
                 return false;
             }
             ConstString typeCS(typeA);
-            if(!m_options.m_regex)
+            if (!m_options.m_regex)
             {
                 Debugger::SummaryFormats::Add(typeCS, entry);
             }
@@ -660,6 +665,21 @@
                 Debugger::RegexSummaryFormats::Add(typeRX, entry);
             }
         }
+        
+        if (m_options.m_name)
+        {
+            if( (bool)(*(m_options.m_name)) )
+            {
+                Debugger::NamedSummaryFormats::Add(*(m_options.m_name), entry);
+            }
+            else
+            {
+                result.AppendError("added to types, but not given a name");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        
         result.SetStatus(eReturnStatusSuccessFinishNoResult);
         return result.Succeeded();
     }
@@ -676,7 +696,8 @@
     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean,    "Type names are actually regular expressions."},
     { LLDB_OPT_SET_1  , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean,    "If true, inline all child values into summary string."},
     { LLDB_OPT_SET_2  , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString,    "Format string used to display text and object contents."},
-    { LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean,    "Expand aggregate data types to show children on separate lines."},
+    { LLDB_OPT_SET_2,   false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean,    "Expand aggregate data types to show children on separate lines."},
+    { LLDB_OPT_SET_2,   false, "name", 'n', required_argument, NULL, 0, eArgTypeName,    "A name for this summary string."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
@@ -734,7 +755,9 @@
         
         bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
         bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
-        if (delete_summary || delete_regex)
+        bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS);
+        
+        if (delete_summary || delete_regex || delete_named)
         {
             result.SetStatus(eReturnStatusSuccessFinishNoResult);
             return result.Succeeded();
@@ -774,6 +797,7 @@
     {
         Debugger::SummaryFormats::Clear();
         Debugger::RegexSummaryFormats::Clear();
+        Debugger::NamedSummaryFormats::Clear();
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
     }
@@ -847,22 +871,33 @@
         Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
         delete param;
         
-        if(Debugger::RegexSummaryFormats::GetCount() == 0)
+        if(Debugger::RegexSummaryFormats::GetCount() > 0)
         {
-            result.SetStatus(eReturnStatusSuccessFinishResult);
-            return result.Succeeded();
+            result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
+            if (argc == 1) {
+                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
+                regex->Compile(command.GetArgumentAtIndex(0));
+                rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex);
+            }
+            else
+                rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
+            Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
+            delete rxparam;
         }
         
-        result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
-        if (argc == 1) {
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-            regex->Compile(command.GetArgumentAtIndex(0));
-            rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex);
+        if(Debugger::NamedSummaryFormats::GetCount() > 0)
+        {
+            result.GetOutputStream().Printf("Named summaries:\n");
+            if (argc == 1) {
+                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
+                regex->Compile(command.GetArgumentAtIndex(0));
+                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
+            }
+            else
+                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
+            Debugger::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
+            delete param;
         }
-        else
-            rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
-        Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
-        delete rxparam;
         
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Jul 11 19:18:11 2011
@@ -1821,6 +1821,48 @@
     return GetFormatManager().RegexSummary().GetCount();
 }
 
+bool
+Debugger::NamedSummaryFormats::Get(const ConstString &type, SummaryFormat::SharedPointer &entry)
+{
+    return GetFormatManager().NamedSummary().Get(type.AsCString(),entry);
+}
+
+void
+Debugger::NamedSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
+{
+    GetFormatManager().NamedSummary().Add(type.AsCString(),entry);
+}
+
+bool
+Debugger::NamedSummaryFormats::Delete(const ConstString &type)
+{
+    return GetFormatManager().NamedSummary().Delete(type.AsCString());
+}
+
+void
+Debugger::NamedSummaryFormats::Clear()
+{
+    GetFormatManager().NamedSummary().Clear();
+}
+
+void
+Debugger::NamedSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
+{
+    GetFormatManager().NamedSummary().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+Debugger::NamedSummaryFormats::GetCurrentRevision()
+{
+    return GetFormatManager().GetCurrentRevision();
+}
+
+uint32_t
+Debugger::NamedSummaryFormats::GetCount()
+{
+    return GetFormatManager().NamedSummary().GetCount();
+}
+
 #pragma mark Debugger::SettingsController
 
 //--------------------------------------------------

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Mon Jul 11 19:18:11 2011
@@ -154,12 +154,11 @@
 
 template<>
 bool
-FormatNavigator<std::map<lldb::RegularExpressionSP, SummaryFormat::SharedPointer>, SummaryFormat::RegexSummaryCallback>::Get(const char* key,
-                                                                                                                     SummaryFormat::SharedPointer& value)
+FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Get(const char* key, SummaryFormat::SharedPointer& value)
 {
-    Mutex::Locker(m_map_mutex);
-    MapIterator pos, end = m_map.end();
-    for (pos = m_map.begin(); pos != end; pos++)
+    Mutex::Locker(m_format_map.mutex());
+    MapIterator pos, end = m_format_map.map().end();
+    for (pos = m_format_map.map().begin(); pos != end; pos++)
     {
         lldb::RegularExpressionSP regex = pos->first;
         if (regex->Execute(key))
@@ -173,16 +172,16 @@
 
 template<>
 bool
-FormatNavigator<std::map<lldb::RegularExpressionSP, SummaryFormat::SharedPointer>, SummaryFormat::RegexSummaryCallback>::Delete(const char* type)
+FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Delete(const char* type)
 {
-    Mutex::Locker(m_map_mutex);
-    MapIterator pos, end = m_map.end();
-    for (pos = m_map.begin(); pos != end; pos++)
+    Mutex::Locker(m_format_map.mutex());
+    MapIterator pos, end = m_format_map.map().end();
+    for (pos = m_format_map.map().begin(); pos != end; pos++)
     {
         lldb::RegularExpressionSP regex = pos->first;
         if ( ::strcmp(type,regex->GetText()) == 0)
         {
-            m_map.erase(pos);
+            m_format_map.map().erase(pos);
             return true;
         }
     }

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Mon Jul 11 19:18:11 2011
@@ -77,7 +77,8 @@
     m_is_bitfield_for_scalar(false),
     m_last_format_mgr_revision(0),
     m_last_summary_format(),
-    m_last_value_format()
+    m_last_value_format(),
+    m_forced_summary_format()
 {
     m_manager->ManageObject(this);
 }
@@ -114,7 +115,8 @@
     m_is_bitfield_for_scalar(false),
     m_last_format_mgr_revision(0),
     m_last_summary_format(),
-    m_last_value_format()
+    m_last_value_format(),
+    m_forced_summary_format()
 {
     m_manager = new ValueObjectManager();
     m_manager->ManageObject (this);
@@ -189,6 +191,11 @@
     /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
            m_last_format_mgr_revision,
            Debugger::ValueFormats::GetCurrentRevision());*/
+    if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
+    {
+        ClearCustomSummaryFormat();
+        m_summary_str.clear();
+    }
     if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
     {
         if (m_last_summary_format.get())
@@ -495,7 +502,9 @@
     {        
         if (m_summary_str.empty())
         {
-            if (m_last_summary_format.get())
+            SummaryFormat* summary_format = GetSummaryFormat().get();
+
+            if (summary_format)
             {
                 StreamString s;
                 ExecutionContext exe_ctx;
@@ -504,7 +513,7 @@
                 if (exe_ctx.frame)
                     sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
                 
-                if (m_last_summary_format->m_show_members_oneliner)
+                if (summary_format->m_show_members_oneliner)
                 {
                     const uint32_t num_children = GetNumChildren();
                     if (num_children)
@@ -536,7 +545,7 @@
                 }
                 else
                 {
-                    if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
+                    if (Debugger::FormatPrompt(summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
                     {
                         m_summary_str.swap(s.GetString());
                         return m_summary_str.c_str();
@@ -719,6 +728,157 @@
     return m_summary_str.c_str();
 }
 
+bool
+ValueObject::IsCStringContainer(bool check_pointer)
+{
+    clang_type_t elem_or_pointee_clang_type;
+    const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(), 
+                                                          GetClangAST(), 
+                                                          &elem_or_pointee_clang_type));
+    bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
+            ClangASTContext::IsCharType (elem_or_pointee_clang_type));
+    if (!is_char_arr_ptr)
+        return false;
+    if (!check_pointer)
+        return true;
+    if (type_flags.Test(ClangASTContext::eTypeIsArray))
+        return true;
+    lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
+    AddressType cstr_address_type = eAddressTypeInvalid;
+    cstr_address = GetAddressOf (cstr_address_type, true);
+    return (cstr_address != LLDB_INVALID_ADDRESS);
+}
+
+void
+ValueObject::ReadPointedString(Stream& s,
+                               Error& error,
+                               uint32_t max_length)
+{
+    
+    if (max_length == 0)
+        max_length = 128;   // this should be a setting, or a formatting parameter
+    
+    clang_type_t clang_type = GetClangType();
+    clang_type_t elem_or_pointee_clang_type;
+    const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, 
+                                                          GetClangAST(), 
+                                                          &elem_or_pointee_clang_type));
+    if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
+        ClangASTContext::IsCharType (elem_or_pointee_clang_type))
+    {
+        ExecutionContextScope *exe_scope = GetExecutionContextScope();
+            if (exe_scope)
+            {
+                Target *target = exe_scope->CalculateTarget();
+                if (target != NULL)
+                {
+                    lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
+                    AddressType cstr_address_type = eAddressTypeInvalid;
+                    
+                    size_t cstr_len = 0;
+                    bool capped_data = false;
+                    if (type_flags.Test (ClangASTContext::eTypeIsArray))
+                    {
+                        // We have an array
+                        cstr_len = ClangASTContext::GetArraySize (clang_type);
+                        if (cstr_len > max_length) // TODO: make cap a setting
+                        {
+                            cstr_len = ClangASTContext::GetArraySize (clang_type);
+                            if (cstr_len > max_length) // TODO: make cap a setting
+                            {
+                                capped_data = true;
+                                cstr_len = max_length;
+                            }
+                        }
+                        cstr_address = GetAddressOf (cstr_address_type, true);
+                    }
+                    else
+                    {
+                        // We have a pointer
+                        cstr_address = GetPointerValue (cstr_address_type, true);
+                    }
+                    if (cstr_address != LLDB_INVALID_ADDRESS)
+                    {
+                        Address cstr_so_addr (NULL, cstr_address);
+                        DataExtractor data;
+                        size_t bytes_read = 0;
+                        std::vector<char> data_buffer;
+                        Error error;
+                        bool prefer_file_cache = false;
+                        if (cstr_len > 0)
+                        {
+                            data_buffer.resize(cstr_len);
+                            data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
+                            bytes_read = target->ReadMemory (cstr_so_addr, 
+                                                             prefer_file_cache, 
+                                                             &data_buffer.front(), 
+                                                             cstr_len, 
+                                                             error);
+                            if (bytes_read > 0)
+                            {
+                                s << '"';
+                                data.Dump (&s,
+                                           0,                 // Start offset in "data"
+                                           eFormatCharArray,  // Print as characters
+                                           1,                 // Size of item (1 byte for a char!)
+                                           bytes_read,        // How many bytes to print?
+                                           UINT32_MAX,        // num per line
+                                           LLDB_INVALID_ADDRESS,// base address
+                                           0,                 // bitfield bit size
+                                           0);                // bitfield bit offset
+                                if (capped_data)
+                                    s << "...";
+                                s << '"';
+                            }
+                        }
+                        else
+                        {
+                            const size_t k_max_buf_size = 256;
+                            data_buffer.resize (k_max_buf_size + 1);
+                            // NULL terminate in case we don't get the entire C string
+                            data_buffer.back() = '\0';
+                            
+                            s << '"';
+                            
+                            data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
+                            while ((bytes_read = target->ReadMemory (cstr_so_addr, 
+                                                                     prefer_file_cache,
+                                                                     &data_buffer.front(), 
+                                                                     k_max_buf_size, 
+                                                                     error)) > 0)
+                            {
+                                size_t len = strlen(&data_buffer.front());
+                                if (len == 0)
+                                    break;
+                                if (len > bytes_read)
+                                    len = bytes_read;
+                                
+                                data.Dump (&s,
+                                           0,                 // Start offset in "data"
+                                           eFormatCharArray,  // Print as characters
+                                           1,                 // Size of item (1 byte for a char!)
+                                           len,               // How many bytes to print?
+                                           UINT32_MAX,        // num per line
+                                           LLDB_INVALID_ADDRESS,// base address
+                                           0,                 // bitfield bit size
+                                           0);                // bitfield bit offset
+                                
+                                if (len < k_max_buf_size)
+                                    break;
+                                cstr_so_addr.Slide (k_max_buf_size);
+                            }
+                            s << '"';
+                        }
+                    }
+                }
+            }
+    }
+    else
+    {
+        error.SetErrorString("impossible to read a string from this object");
+    }
+}
+
 const char *
 ValueObject::GetObjectDescription ()
 {
@@ -894,13 +1054,25 @@
                                          ValueObjectRepresentationStyle val_obj_display,
                                          lldb::Format custom_format)
 {
-    const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
-    if(targetvalue)
-        s.PutCString(targetvalue);
-    bool var_success = (targetvalue != NULL);
-    if(custom_format != eFormatInvalid)
-        SetFormat(eFormatDefault);
-    return var_success;
+    
+    if (IsCStringContainer(true) &&
+        val_obj_display == ValueObject::eDisplayValue &&
+        custom_format == lldb::eFormatCString)
+    {
+        Error error;
+        ReadPointedString(s, error);
+        return error.Success();
+    }
+    else
+    {
+        const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
+        if(targetvalue)
+            s.PutCString(targetvalue);
+        bool var_success = (targetvalue != NULL);
+        if(custom_format != eFormatInvalid)
+            SetFormat(eFormatDefault);
+        return var_success;
+    }
 }
 
 addr_t
@@ -1503,6 +1675,92 @@
     return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
 }
 
+int
+ValueObject::GetValuesForExpressionPath(const char* expression,
+                                        lldb::ValueObjectListSP& list,
+                                        const char** first_unparsed,
+                                        ExpressionPathScanEndReason* reason_to_stop,
+                                        ExpressionPathEndResultType* final_value_type,
+                                        const GetValueForExpressionPathOptions& options,
+                                        ExpressionPathAftermath* final_task_on_target)
+{
+    const char* dummy_first_unparsed;
+    ExpressionPathScanEndReason dummy_reason_to_stop;
+    ExpressionPathEndResultType dummy_final_value_type;
+    ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
+    
+    ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
+                                                           first_unparsed ? first_unparsed : &dummy_first_unparsed,
+                                                           reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
+                                                           final_value_type ? final_value_type : &dummy_final_value_type,
+                                                           options,
+                                                           final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
+    
+    if (!ret_val.get()) // if there are errors, I add nothing to the list
+        return 0;
+    
+    if (*reason_to_stop != eArrayRangeOperatorMet)
+    {
+        // 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)
+        {
+            list->Append(ret_val);
+            return 1;
+        }
+        if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
+        {
+            if (*final_task_on_target == ValueObject::eDereference)
+            {
+                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;
+                    return 0;
+                }
+                else
+                {
+                    *final_task_on_target = ValueObject::eNothing;
+                    list->Append(final_value);
+                    return 1;
+                }
+            }
+            if (*final_task_on_target == ValueObject::eTakeAddress)
+            {
+                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;
+                    return 0;
+                }
+                else
+                {
+                    *final_task_on_target = ValueObject::eNothing;
+                    list->Append(final_value);
+                    return 1;
+                }
+            }
+        }
+    }
+    else
+    {
+        return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
+                                          first_unparsed ? first_unparsed : &dummy_first_unparsed,
+                                          ret_val,
+                                          list,
+                                          reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
+                                          final_value_type ? final_value_type : &dummy_final_value_type,
+                                          options,
+                                          final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
+    }
+    // in any non-covered case, just do the obviously right thing
+    list->Append(ret_val);
+    return 1;
+}
+
 lldb::ValueObjectSP
 ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
                                             const char** first_unparsed,
@@ -1524,6 +1782,12 @@
         const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
         
         lldb::clang_type_t root_clang_type = root->GetClangType();
+        lldb::clang_type_t pointee_clang_type;
+        Flags root_clang_type_info,pointee_clang_type_info;
+        
+        root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
+        if (pointee_clang_type)
+            pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
         
         if (!expression_cstr || *expression_cstr == '\0')
         {
@@ -1536,16 +1800,15 @@
             case '-':
             {
                 if (options.m_check_dot_vs_arrow_syntax &&
-                    !ClangASTContext::IsPointerType(root_clang_type)) // if you are trying to use -> on a non-pointer and I must catch the error
+                    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;
                     return ValueObjectSP();
                 }
-                const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (root_clang_type, NULL, NULL);
-                if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
-                    (pointer_type_flags & ClangASTContext::eTypeIsPointer) &&
+                if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
+                    root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
                     options.m_no_fragile_ivar)
                 {
                     *first_unparsed = expression_cstr;
@@ -1565,7 +1828,7 @@
             case '.': // or fallthrough from ->
             {
                 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
-                    ClangASTContext::IsPointerType(root_clang_type)) // if you are trying to use . on a pointer and I must catch the error
+                    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;
@@ -1616,9 +1879,9 @@
             }
             case '[':
             {
-                if (!ClangASTContext::IsArrayType(root_clang_type) && !ClangASTContext::IsPointerType(root_clang_type)) // if this is not a T[] nor a T*
+                if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
                 {
-                    if (!ClangASTContext::IsScalarType(root_clang_type)) // if this is not even a scalar, this syntax is just plain wrong!
+                    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;
@@ -1635,7 +1898,7 @@
                 }
                 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
                 {
-                    if (!ClangASTContext::IsArrayType(root_clang_type))
+                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                     {
                         *first_unparsed = expression_cstr;
                         *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
@@ -1672,7 +1935,7 @@
                     }
                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
                     {
-                        if (ClangASTContext::IsArrayType(root_clang_type))
+                        if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                         {
                             *first_unparsed = expression_cstr+2;
                             *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
@@ -1688,7 +1951,7 @@
                         }
                     }
                     // from here on we do have a valid index
-                    if (ClangASTContext::IsArrayType(root_clang_type))
+                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
                     {
                         ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
                         if (!child_valobj_sp)
@@ -1708,10 +1971,10 @@
                             return ValueObjectSP();
                         }
                     }
-                    else if (ClangASTContext::IsPointerType(root_clang_type))
+                    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
-                            ClangASTContext::IsScalarType(clang::QualType::getFromOpaquePtr(root_clang_type).getTypePtr()->getPointeeType().getAsOpaquePtr()))
+                            pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                         {
                             Error error;
                             root = root->Dereference(error);
@@ -1790,7 +2053,7 @@
                         index_lower = index_higher;
                         index_higher = temp;
                     }
-                    if (ClangASTContext::IsScalarType(root_clang_type)) // expansion only works for scalars
+                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
                     {
                         root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
                         if (!root.get())
@@ -1808,9 +2071,9 @@
                             return root;
                         }
                     }
-                    else if (ClangASTContext::IsPointerType(root_clang_type) && // 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
+                    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 &&
-                             ClangASTContext::IsScalarType(clang::QualType::getFromOpaquePtr(root_clang_type).getTypePtr()->getPointeeType().getAsOpaquePtr()))
+                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
                     {
                         Error error;
                         root = root->Dereference(error);
@@ -1849,6 +2112,302 @@
     }
 }
 
+int
+ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
+                                        const char** first_unparsed,
+                                        lldb::ValueObjectSP root,
+                                        lldb::ValueObjectListSP& list,
+                                        ExpressionPathScanEndReason* reason_to_stop,
+                                        ExpressionPathEndResultType* final_result,
+                                        const GetValueForExpressionPathOptions& options,
+                                        ExpressionPathAftermath* what_next)
+{
+    if (!root.get())
+        return 0;
+    
+    *first_unparsed = expression_cstr;
+    
+    while (true)
+    {
+        
+        const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
+        
+        lldb::clang_type_t root_clang_type = root->GetClangType();
+        lldb::clang_type_t pointee_clang_type;
+        Flags root_clang_type_info,pointee_clang_type_info;
+        
+        root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
+        if (pointee_clang_type)
+            pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
+        
+        if (!expression_cstr || *expression_cstr == '\0')
+        {
+            *reason_to_stop = ValueObject::eEndOfString;
+            list->Append(root);
+            return 1;
+        }
+        
+        switch (*expression_cstr)
+        {
+            case '[':
+            {
+                if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
+                {
+                    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;
+                        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;
+                        return 0;
+                    }
+                }
+                if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
+                {
+                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
+                        *final_result = ValueObject::eInvalid;
+                        return 0;
+                    }
+                    else // expand this into list
+                    {
+                        int max_index = root->GetNumChildren() - 1;
+                        for (int index = 0; index < max_index; index++)
+                        {
+                            ValueObjectSP child = 
+                                root->GetChildAtIndex(index, true);
+                            list->Append(child);
+                        }
+                        *first_unparsed = expression_cstr+2;
+                        *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                        *final_result = ValueObject::eValueObjectList;
+                        return max_index; // tell me number of items I added to the VOList
+                    }
+                }
+                const char *separator_position = ::strchr(expression_cstr+1,'-');
+                const char *close_bracket_position = ::strchr(expression_cstr+1,']');
+                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;
+                    return 0;
+                }
+                if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
+                {
+                    char *end = NULL;
+                    unsigned long index = ::strtoul (expression_cstr+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;
+                        return 0;
+                    }
+                    if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
+                    {
+                        if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                        {
+                            int max_index = root->GetNumChildren() - 1;
+                            for (int index = 0; index < max_index; index++)
+                            {
+                                ValueObjectSP child = 
+                                root->GetChildAtIndex(index, true);
+                                list->Append(child);
+                            }
+                            *first_unparsed = expression_cstr+2;
+                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                            *final_result = ValueObject::eValueObjectList;
+                            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;
+                            return 0;
+                        }
+                    }
+                    // from here on we do have a valid index
+                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    {
+                        root = root->GetChildAtIndex(index, true);
+                        if (!root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eNoSuchChild;
+                            *final_result = ValueObject::eInvalid;
+                            return 0;
+                        }
+                        else
+                        {
+                            list->Append(root);
+                            *first_unparsed = end+1; // skip ]
+                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                            *final_result = ValueObject::eValueObjectList;
+                            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
+                            pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                        {
+                            Error error;
+                            root = root->Dereference(error);
+                            if (error.Fail() || !root.get())
+                            {
+                                *first_unparsed = expression_cstr;
+                                *reason_to_stop = ValueObject::eDereferencingFailed;
+                                *final_result = ValueObject::eInvalid;
+                                return 0;
+                            }
+                            else
+                            {
+                                *what_next = eNothing;
+                                continue;
+                            }
+                        }
+                        else
+                        {
+                            root = root->GetSyntheticArrayMemberFromPointer(index, true);
+                            if (!root.get())
+                            {
+                                *first_unparsed = expression_cstr;
+                                *reason_to_stop = ValueObject::eNoSuchChild;
+                                *final_result = ValueObject::eInvalid;
+                                return 0;
+                            }
+                            else
+                            {
+                                list->Append(root);
+                                *first_unparsed = end+1; // skip ]
+                                *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                                *final_result = ValueObject::eValueObjectList;
+                                return 1;
+                            }
+                        }
+                    }
+                    else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
+                    {
+                        root = root->GetSyntheticBitFieldChild(index, index, true);
+                        if (!root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eNoSuchChild;
+                            *final_result = ValueObject::eInvalid;
+                            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;
+                            return 1;
+                        }
+                    }
+                }
+                else // we have a low and a high index
+                {
+                    char *end = NULL;
+                    unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
+                    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;
+                        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;
+                        return 0;
+                    }
+                    if (index_lower > index_higher) // swap indices if required
+                    {
+                        unsigned long temp = index_lower;
+                        index_lower = index_higher;
+                        index_higher = temp;
+                    }
+                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
+                    {
+                        root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
+                        if (!root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eNoSuchChild;
+                            *final_result = ValueObject::eInvalid;
+                            return 0;
+                        }
+                        else
+                        {
+                            list->Append(root);
+                            *first_unparsed = end+1; // skip ]
+                            *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                            *final_result = ValueObject::eValueObjectList;
+                            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 &&
+                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                    {
+                        Error error;
+                        root = root->Dereference(error);
+                        if (error.Fail() || !root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eDereferencingFailed;
+                            *final_result = ValueObject::eInvalid;
+                            return 0;
+                        }
+                        else
+                        {
+                            *what_next = ValueObject::eNothing;
+                            continue;
+                        }
+                    }
+                    else
+                    {
+                        for (int index = index_lower;
+                             index <= index_higher; index++)
+                        {
+                            ValueObjectSP child = 
+                                root->GetChildAtIndex(index, true);
+                            list->Append(child);
+                        }
+                        *first_unparsed = end+1;
+                        *reason_to_stop = ValueObject::eRangeOperatorExpanded;
+                        *final_result = ValueObject::eValueObjectList;
+                        return index_higher-index_lower+1; // tell me number of items I added to the VOList
+                    }
+                }
+                break;
+            }
+            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;
+                return 0;
+                break;
+            }
+        }
+    }
+}
+
 void
 ValueObject::DumpValueObject 
 (
@@ -1921,7 +2480,7 @@
         
         const char *val_cstr = NULL;
         const char *sum_cstr = NULL;
-        SummaryFormat* entry = valobj->m_last_summary_format.get();
+        SummaryFormat* entry = valobj->GetSummaryFormat().get();
         
         if (err_cstr == NULL)
         {

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Mon Jul 11 19:18:11 2011
@@ -935,7 +935,7 @@
     
     // Make a scoped cleanup object that will clear the crash description string 
     // on exit of this function.
-    lldb_utility::CleanUp <const char *, void> crash_description_cleanup(NULL, Host::SetCrashDescription);
+    lldb_utility::CleanUp <const char *> crash_description_cleanup(NULL, Host::SetCrashDescription);
 
     if (log)
         log->Printf ("Processing command: %s", command_line);

Modified: lldb/trunk/source/Interpreter/OptionGroupVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupVariable.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionGroupVariable.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionGroupVariable.cpp Mon Jul 11 19:18:11 2011
@@ -19,6 +19,7 @@
 using namespace lldb;
 using namespace lldb_private;
 
+// if you add any options here, remember to update the counters in OptionGroupVariable::GetNumDefinitions()
 static OptionDefinition
 g_option_table[] =
 {
@@ -28,7 +29,8 @@
     { LLDB_OPT_SET_1, false, "show-declaration",'c', no_argument,       NULL, 0, eArgTypeNone,    "Show variable declaration information (source file and line where the variable was declared)."},
     { LLDB_OPT_SET_1, false, "format",          'f', required_argument, NULL, 0, eArgTypeExprFormat,  "Specify the format that the variable output should use."},
     { LLDB_OPT_SET_1, false, "regex",           'r', no_argument,       NULL, 0, eArgTypeRegularExpression,    "The <variable-name> argument for name lookups are regular expressions."},
-    { LLDB_OPT_SET_1, false, "scope",           's', no_argument,       NULL, 0, eArgTypeNone,    "Show variable scope (argument, local, global, static)."}
+    { LLDB_OPT_SET_1, false, "scope",           's', no_argument,       NULL, 0, eArgTypeNone,    "Show variable scope (argument, local, global, static)."},
+    { LLDB_OPT_SET_1, false, "summary",         'y', required_argument, NULL, 0, eArgTypeName,  "Specify the summary that the variable output should use."},
 };
 
 
@@ -62,7 +64,9 @@
         case 's':
             show_scope = true;
             break;
-            
+        case 'y':
+            summary = std::string(option_arg);
+            break;
         default:
             error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
             break;
@@ -81,6 +85,7 @@
     format        = lldb::eFormatDefault;
     use_regex     = false;
     show_scope    = false;
+    summary       = "";
 }
 
 
@@ -101,9 +106,9 @@
 OptionGroupVariable::GetNumDefinitions ()
 {
     if (include_frame_options)
-        return 7;
+        return 8;
     else
-        return 4;
+        return 5;
 }
 
 

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Jul 11 19:18:11 2011
@@ -2077,7 +2077,30 @@
             if (ast && pointee_or_element_clang_type)
                 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
             return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
-
+                break;
+        case clang::BuiltinType::Bool:
+        case clang::BuiltinType::Char_U:
+        case clang::BuiltinType::UChar:
+        case clang::BuiltinType::WChar_U:
+        case clang::BuiltinType::Char16:
+        case clang::BuiltinType::Char32:
+        case clang::BuiltinType::UShort:
+        case clang::BuiltinType::UInt:
+        case clang::BuiltinType::ULong:
+        case clang::BuiltinType::ULongLong:
+        case clang::BuiltinType::UInt128:
+        case clang::BuiltinType::Char_S:
+        case clang::BuiltinType::SChar:
+        case clang::BuiltinType::WChar_S:
+        case clang::BuiltinType::Short:
+        case clang::BuiltinType::Int:
+        case clang::BuiltinType::Long:
+        case clang::BuiltinType::LongLong:
+        case clang::BuiltinType::Int128:
+        case clang::BuiltinType::Float:
+        case clang::BuiltinType::Double:
+        case clang::BuiltinType::LongDouble:
+                return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
         default: 
             break;
         }
@@ -4645,6 +4668,10 @@
 
         case clang::Type::Typedef:
             return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            break;
+                
+        default:
+            break;
         }
     }
     return 0;

Modified: lldb/trunk/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolContext.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolContext.cpp Mon Jul 11 19:18:11 2011
@@ -164,7 +164,7 @@
                 dumped_something = true;
                 s->PutCString(" at ");
                 if (line_entry.DumpStopContext(s, show_fullpaths))
-                    return;
+                    return dumped_something;
             }
         }
     }

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=134943&r1=134942&r2=134943&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 Jul 11 19:18:11 2011
@@ -73,7 +73,16 @@
         self.expect("frame variable",
             patterns = ['\(Speed\) SPILookHex = 0x[0-9a-f]+' # Speed should look hex-ish now.
                         ]);
-
+        
+        # gcc4.2 on Mac OS X skips typedef chains in the DWARF output
+        if self.getCompiler() in ['clang', 'llvm-gcc']:        
+            self.expect("frame variable",
+                patterns = ['\(SignalMask\) SMILookHex = 0x[0-9a-f]+' # SignalMask should look hex-ish now.
+                            ]);
+            self.expect("frame variable", matching=False,
+                        patterns = ['\(Type4\) T4ILookChar = 0x[0-9a-f]+' # Type4 should NOT look hex-ish now.
+                                    ]);
+        
         # Now let's delete the 'Speed' custom format.
         self.runCmd("type format delete Speed")
 
@@ -85,6 +94,26 @@
         self.expect("type format delete Speed", error=True,
             substrs = ['no custom format for Speed'])
         
+        self.runCmd("type summary add -f \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
+        
+        self.expect("frame variable strarr",
+                    substrs = ['arr = "Hello world!\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0"'])
+        
+        self.runCmd("type summary clear")
+        
+        self.runCmd("type summary add -f \"ptr = ${var%s}\" \"char *\" -v")
+        
+        self.expect("frame variable strptr",
+                    substrs = ['ptr = "Hello world!"'])
+        
+        self.runCmd("type summary add -f \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
+        
+        self.expect("frame variable strarr",
+                    substrs = ['arr = "Hello world!\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0"'])
+        
+        self.expect("frame variable strptr",
+                    substrs = ['ptr = "Hello world!"'])
+
         self.runCmd("type summary add -c Point")
             
         self.expect("frame variable iAmSomewhere",

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp?rev=134943&r1=134942&r2=134943&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp Mon Jul 11 19:18:11 2011
@@ -107,6 +107,9 @@
     int int_array[] = {1,2,3,4,5};
     
     IUseCharStar iEncapsulateCharStar;
+    
+    char  strarr[32] = "Hello world!";
+    char* strptr     = "Hello world!";
         
     return 0; // Set break point at this line.
 }





More information about the lldb-commits mailing list