[Lldb-commits] [lldb] r134679 - in /lldb/trunk: include/lldb/Core/ValueObject.h include/lldb/Interpreter/CommandObject.h lldb.xcodeproj/project.pbxproj source/Core/Debugger.cpp source/Core/ValueObject.cpp source/Interpreter/CommandObject.cpp test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py test/functionalities/data-formatter/data-formatter-advanced/main.cpp test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py www/varformats.html

Enrico Granata granata.enrico at gmail.com
Thu Jul 7 19:51:02 PDT 2011


Author: enrico
Date: Thu Jul  7 21:51:01 2011
New Revision: 134679

URL: http://llvm.org/viewvc/llvm-project?rev=134679&view=rev
Log:
final fix for the global constructors issue
new GetValueForExpressionPath() method in ValueObject to navigate expression paths in a more bitfield vs slices aware way
changes to the varformats.html document (WIP)

Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Interpreter/CommandObject.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Interpreter/CommandObject.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
    lldb/trunk/www/varformats.html

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Jul  7 21:51:01 2011
@@ -73,10 +73,111 @@
     
     enum ValueObjectRepresentationStyle
     {
-        eDisplayValue,
+        eDisplayValue = 1,
         eDisplaySummary,
         eDisplayLanguageSpecific
     };
+    
+    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
+        eUnknown = 0xFFFF
+    };
+    
+    enum ExpressionPathEndResultType
+    {
+        ePlain = 1,                 // anything but...
+        eBitfield,                  // a bitfield
+        eBoundedRange,              // a range [low-high]
+        eUnboundedRange,            // a range []
+        eInvalid = 0xFFFF
+    };
+    
+    enum ExpressionPathAftermath
+    {
+        eNothing = 1,               // just return it
+        eDereference,               // dereference the target
+        eTakeAddress                // take target's address
+    };
+    
+    struct GetValueForExpressionPathOptions
+    {
+        bool m_check_dot_vs_arrow_syntax;
+        bool m_no_fragile_ivar;
+        bool m_allow_bitfields_syntax;
+        
+        GetValueForExpressionPathOptions(bool dot = false,
+                                         bool no_ivar = false,
+                                         bool bitfield = true) :
+        m_check_dot_vs_arrow_syntax(dot),
+        m_no_fragile_ivar(no_ivar),
+        m_allow_bitfields_syntax(bitfield)
+        {
+        }
+        
+        GetValueForExpressionPathOptions&
+        DoCheckDotVsArrowSyntax()
+        {
+            m_check_dot_vs_arrow_syntax = true;
+            return *this;
+        }
+        
+        GetValueForExpressionPathOptions&
+        DontCheckDotVsArrowSyntax()
+        {
+            m_check_dot_vs_arrow_syntax = false;
+            return *this;
+        }
+        
+        GetValueForExpressionPathOptions&
+        DoAllowFragileIVar()
+        {
+            m_no_fragile_ivar = false;
+            return *this;
+        }
+        
+        GetValueForExpressionPathOptions&
+        DontAllowFragileIVar()
+        {
+            m_no_fragile_ivar = true;
+            return *this;
+        }
+
+        GetValueForExpressionPathOptions&
+        DoAllowBitfieldSyntax()
+        {
+            m_allow_bitfields_syntax = true;
+            return *this;
+        }
+        
+        GetValueForExpressionPathOptions&
+        DontAllowBitfieldSyntax()
+        {
+            m_allow_bitfields_syntax = false;
+            return *this;
+        }
+        
+        static const GetValueForExpressionPathOptions
+        DefaultOptions()
+        {
+            static GetValueForExpressionPathOptions g_default_options;
+            
+            return g_default_options;
+        }
+
+    };
 
     class EvaluationPoint 
     {
@@ -280,6 +381,14 @@
     virtual void
     GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat = eDereferencePointers);
     
+    lldb::ValueObjectSP
+    GetValueForExpressionPath(const char* expression,
+                              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 ()
     {
@@ -636,6 +745,15 @@
     //------------------------------------------------------------------
     // For ValueObject only
     //------------------------------------------------------------------
+    
+    lldb::ValueObjectSP
+    GetValueForExpressionPath_Impl(const char* expression,
+                                   const char** first_unparsed,
+                                   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/CommandObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObject.h?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObject.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObject.h Thu Jul  7 21:51:01 2011
@@ -33,6 +33,18 @@
     {
         ArgumentHelpCallbackFunction  *help_callback;
         bool                           self_formatting;
+        
+        const char*
+        operator () () const
+        {
+            return (*help_callback)();
+        }
+        
+        operator bool() const
+        {
+            return (help_callback != NULL);
+        }
+
     };
     
     struct ArgumentTableEntry  // Entries in the main argument information table

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Jul  7 21:51:01 2011
@@ -1786,12 +1786,12 @@
 				26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */,
 				26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.cpp */,
 				26F996A8119B79C300412154 /* ARM_GCC_Registers.h */,
-				2660D9F611922A1300958FBD /* StringExtractor.cpp */,
 				2660D9F711922A1300958FBD /* StringExtractor.h */,
-				2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */,
+				2660D9F611922A1300958FBD /* StringExtractor.cpp */,
 				2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */,
-				2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
+				2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */,
 				2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */,
+				2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
 			);
 			name = Utility;
 			sourceTree = "<group>";

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Thu Jul  7 21:51:01 2011
@@ -694,7 +694,7 @@
     }
 }
 
-// #define VERBOSE_FORMATPROMPT_OUTPUT
+//#define VERBOSE_FORMATPROMPT_OUTPUT
 #ifdef VERBOSE_FORMATPROMPT_OUTPUT
 #define IFERROR_PRINT_IT if (error.Fail()) \
 { \
@@ -832,35 +832,41 @@
 ExpandIndexedExpression(ValueObject* vobj,
                         uint32_t index,
                         StackFrame* frame,
-                        Error error)
+                        bool deref_pointer)
 {
-    ValueObjectSP item;
-    bool is_array = ClangASTContext::IsArrayType(vobj->GetClangType());
-
-    if (is_array)
-        return vobj->GetChildAtIndex(index, true);
-    else
-    {
-        const char* ptr_deref_format = "%s[%d]";
-        char* ptr_deref_buffer = new char[1024];
-        StreamString expr_path_string;
-        vobj->GetExpressionPath(expr_path_string, true, ValueObject::eHonorPointers);
-        const char* expr_path = expr_path_string.GetData();
+    const char* ptr_deref_format = "[%d]";
+    std::auto_ptr<char> ptr_deref_buffer(new char[10]);
+    ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
 #ifdef VERBOSE_FORMATPROMPT_OUTPUT
-        printf("name to deref in phase 0: %s\n",expr_path);
+    printf("name to deref: %s\n",ptr_deref_buffer.get());
 #endif //VERBOSE_FORMATPROMPT_OUTPUT
-        ::sprintf(ptr_deref_buffer, ptr_deref_format, expr_path, index);
-#ifdef VERBOSE_FORMATPROMPT_OUTPUT
-        printf("name to deref in phase 1: %s\n",ptr_deref_buffer);
+    const char* first_unparsed;
+    ValueObject::GetValueForExpressionPathOptions options;
+    ValueObject::ExpressionPathEndResultType final_value_type;
+    ValueObject::ExpressionPathScanEndReason reason_to_stop;
+    ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eDereference : ValueObject::eNothing);
+    ValueObjectSP item = vobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
+                                                          &first_unparsed,
+                                                          &reason_to_stop,
+                                                          &final_value_type,
+                                                          options,
+                                                          &what_next);
+    if (!item)
+    {
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+        printf("ERROR: unparsed portion = %s, why stopping = %d,"
+               " final_value_type %d\n",
+               first_unparsed, reason_to_stop, final_value_type);
 #endif //VERBOSE_FORMATPROMPT_OUTPUT
-        lldb::VariableSP var_sp;
-        item = frame->GetValueForVariableExpressionPath (ptr_deref_buffer,
-                                                         eNoDynamicValues, 
-                                                         0,
-                                                         var_sp,
-                                                         error);
-        delete ptr_deref_buffer;
     }
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+    else
+    {
+        printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
+               " final_value_type %d\n",
+               first_unparsed, reason_to_stop, final_value_type);
+    }
+#endif //VERBOSE_FORMATPROMPT_OUTPUT
     return item;
 }
 
@@ -954,8 +960,9 @@
                         const RegisterInfo *reg_info = NULL;
                         RegisterContext *reg_ctx = NULL;
                         bool do_deref_pointer = false;
-                        bool did_deref_pointer = true;
-
+                        ValueObject::ExpressionPathScanEndReason reason_to_stop;
+                        ValueObject::ExpressionPathEndResultType final_value_type;
+                        
                         // Each variable must set success to true below...
                         bool var_success = false;
                         switch (var_name_begin[0])
@@ -971,6 +978,10 @@
 
                         case 'v':
                             {
+                                ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
+                                                                                  ValueObject::eDereference : ValueObject::eNothing);
+                                ValueObject::GetValueForExpressionPathOptions options;
+                                options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar();
                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary;
                                 ValueObject* target = NULL;
                                 lldb::Format custom_format = eFormatInvalid;
@@ -980,6 +991,8 @@
                                 int64_t index_lower = -1;
                                 int64_t index_higher = -1;
                                 bool is_array_range = false;
+                                const char* first_unparsed;
+
                                 if (!vobj) break;
                                 // simplest case ${var}, just print vobj's value
                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
@@ -1025,57 +1038,47 @@
                                                         &index_higher);
                                                                     
                                     Error error;
-                                    target = ExpandExpressionPath (vobj,
-                                                                   exe_ctx->frame,
-                                                                   &do_deref_pointer,
-                                                                   var_name_begin,
-                                                                   var_name_final,
-                                                                   error).get();
-
-                                    if (error.Fail() || !target)
+                                                                        
+                                    std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
+                                    ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
+                                    memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
+                                                                        
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+                                    printf("symbol to expand: %s\n",expr_path.get());
+#endif //VERBOSE_FORMATPROMPT_OUTPUT
+                                    
+                                    target = vobj->GetValueForExpressionPath(expr_path.get(),
+                                                                             &first_unparsed,
+                                                                             &reason_to_stop,
+                                                                             &final_value_type,
+                                                                             options,
+                                                                             &what_next).get();
+                                    
+                                    if (!target)
                                     {
 #ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
-                                        printf("ERROR: %s\n",error.AsCString("unknown"));
+                                        printf("ERROR: unparsed portion = %s, why stopping = %d,"
+                                               " final_value_type %d\n",
+                                               first_unparsed, reason_to_stop, final_value_type);
 #endif //VERBOSE_FORMATPROMPT_OUTPUT
-                                        if (var_name_final_if_array_range)
-                                        {
-                                            target = ExpandExpressionPath(vobj,
-                                                                          exe_ctx->frame,
-                                                                          &do_deref_pointer,
-                                                                          var_name_begin,
-                                                                          var_name_final_if_array_range,
-                                                                          error).get();
-                                        }
-                                        
-                                        if (var_name_final_if_array_range && (error.Fail() || !target))
-                                        {
-                                            bool fake_do_deref = false;
-                                            target = ExpandExpressionPath(vobj,
-                                                                          exe_ctx->frame,
-                                                                          &fake_do_deref,
-                                                                          var_name_begin,
-                                                                          var_name_final_if_array_range,
-                                                                          error).get();
-                                            
-                                            did_deref_pointer = false;
-                                            
-                                            if (target && ClangASTContext::IsArrayType(target->GetClangType()))
-                                                error.Clear();
-                                            else
-                                                error.SetErrorString("error in expression");
-                                        }
-                                        
-                                        IFERROR_PRINT_IT
-                                        else
-                                            is_array_range = true;
+                                        break;
                                     }
-                                    
-                                    if (did_deref_pointer)
-                                        do_deref_pointer = false; // I have honored the request to deref                               
-
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+                                    else
+                                    {
+                                        printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
+                                               " final_value_type %d\n",
+                                               first_unparsed, reason_to_stop, final_value_type);
+                                    }
+#endif //VERBOSE_FORMATPROMPT_OUTPUT
                                 }
                                 else
                                     break;
+                                
+                                is_array_range = (final_value_type == ValueObject::eBoundedRange ||
+                                                  final_value_type == ValueObject::eUnboundedRange);
+                                
+                                do_deref_pointer = (what_next == ValueObject::eDereference);
 
                                 if (do_deref_pointer && !is_array_range)
                                 {
@@ -1092,30 +1095,22 @@
                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
                                 else
                                 {
-                                    bool is_array = ClangASTContext::IsArrayType(vobj->GetClangType());
-                                    bool is_pointer = ClangASTContext::IsPointerType(vobj->GetClangType());
+                                    bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
+                                    bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
                                     
                                     if (!is_array && !is_pointer)
                                         break;
                                     
-                                    char* special_directions = NULL;
+                                    const char* special_directions = NULL;
+                                    StreamString special_directions_writer;
                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
                                     {
-                                        int base_len = var_name_end-close_bracket_position;
-                                        special_directions = new char[7+base_len];
-                                        int star_offset = (do_deref_pointer ? 1 : 0);
-                                        special_directions[0] = '$';
-                                        special_directions[1] = '{';
-                                        if (do_deref_pointer)
-                                            special_directions[2] = '*';
-                                        special_directions[2+star_offset] = 'v';
-                                        special_directions[3+star_offset] = 'a';
-                                        special_directions[4+star_offset] = 'r';
-                                        memcpy(special_directions+5+star_offset, close_bracket_position+1, base_len);
-                                        special_directions[base_len+5+star_offset] = '\0';
-#ifdef VERBOSE_FORMATPROMPT_OUTPUT
-                                        printf("%s\n",special_directions);
-#endif //VERBOSE_FORMATPROMPT_OUTPUT
+                                        ConstString additional_data;
+                                        additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
+                                        special_directions_writer.Printf("${%svar%s}",
+                                                                         do_deref_pointer ? "*" : "",
+                                                                         additional_data.GetCString());
+                                        special_directions = special_directions_writer.GetData();
                                     }
                                     
                                     // let us display items index_lower thru index_higher of this array
@@ -1127,13 +1122,24 @@
                                     
                                     for (;index_lower<=index_higher;index_lower++)
                                     {
-                                        Error error;
-                                        ValueObject* item = ExpandIndexedExpression(vobj,
+                                        ValueObject* item = ExpandIndexedExpression(target,
                                                                                     index_lower,
                                                                                     exe_ctx->frame,
-                                                                                    error).get();
+                                                                                    false).get();
                                         
-                                        IFERROR_PRINT_IT
+                                        if (!item)
+                                        {
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+                                            printf("ERROR\n");
+#endif //VERBOSE_FORMATPROMPT_OUTPUT
+                                        }
+#ifdef VERBOSE_FORMATPROMPT_OUTPUT                                
+                                        else
+                                        {
+                                            printf("special_directions: %s\n",special_directions);
+                                        }
+#endif //VERBOSE_FORMATPROMPT_OUTPUT
+
                                         if (!special_directions)
                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
                                         else

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Thu Jul  7 21:51:01 2011
@@ -1366,6 +1366,412 @@
     }
 }
 
+lldb::ValueObjectSP
+ValueObject::GetValueForExpressionPath(const char* expression,
+                                       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 (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
+    {
+        return ret_val;
+    }
+    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 ValueObjectSP();
+            }
+            else
+            {
+                *final_task_on_target = ValueObject::eNothing;
+                return final_value;
+            }
+        }
+        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 ValueObjectSP();
+            }
+            else
+            {
+                *final_task_on_target = ValueObject::eNothing;
+                return final_value;
+            }
+        }
+    }
+    return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
+}
+
+lldb::ValueObjectSP
+ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
+                                            const char** first_unparsed,
+                                            ExpressionPathScanEndReason* reason_to_stop,
+                                            ExpressionPathEndResultType* final_result,
+                                            const GetValueForExpressionPathOptions& options,
+                                            ExpressionPathAftermath* what_next)
+{
+    ValueObjectSP root = GetSP();
+    
+    if (!root.get())
+        return ValueObjectSP();
+    
+    *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();
+        
+        if (!expression_cstr || *expression_cstr == '\0')
+        {
+            *reason_to_stop = ValueObject::eEndOfString;
+            return root;
+        }
+        
+        switch (*expression_cstr)
+        {
+            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
+                {
+                    *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) &&
+                    options.m_no_fragile_ivar)
+                {
+                    *first_unparsed = expression_cstr;
+                    *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
+                    *final_result = ValueObject::eInvalid;
+                    return ValueObjectSP();
+                }
+                if (expression_cstr[1] != '>')
+                {
+                    *first_unparsed = expression_cstr;
+                    *reason_to_stop = ValueObject::eUnexpectedSymbol;
+                    *final_result = ValueObject::eInvalid;
+                    return ValueObjectSP();
+                }
+                expression_cstr++; // skip the -
+            }
+            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
+                {
+                    *first_unparsed = expression_cstr;
+                    *reason_to_stop = ValueObject::eDotInsteadOfArrow;
+                    *final_result = ValueObject::eInvalid;
+                    return ValueObjectSP();
+                }
+                expression_cstr++; // skip .
+                const char *next_separator = strpbrk(expression_cstr+1,"-.[");
+                ConstString child_name;
+                if (!next_separator) // if no other separator just expand this last layer
+                {
+                    child_name.SetCString (expression_cstr);
+                    root = root->GetChildMemberWithName(child_name, true);
+                    if (root.get()) // we know we are done, so just return
+                    {
+                        *first_unparsed = '\0';
+                        *reason_to_stop = ValueObject::eEndOfString;
+                        *final_result = ValueObject::ePlain;
+                        return root;
+                    }
+                    else
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eNoSuchChild;
+                        *final_result = ValueObject::eInvalid;
+                        return ValueObjectSP();
+                    }
+                }
+                else // other layers do expand
+                {
+                    child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
+                    root = root->GetChildMemberWithName(child_name, true);
+                    if (root.get()) // store the new root and move on
+                    {
+                        *first_unparsed = next_separator;
+                        *final_result = ValueObject::ePlain;
+                        continue;
+                    }
+                    else
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eNoSuchChild;
+                        *final_result = ValueObject::eInvalid;
+                        return ValueObjectSP();
+                    }
+                }
+                break;
+            }
+            case '[':
+            {
+                if (!ClangASTContext::IsArrayType(root_clang_type) && !ClangASTContext::IsPointerType(root_clang_type)) // 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!
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eRangeOperatorInvalid;
+                        *final_result = ValueObject::eInvalid;
+                        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;
+                        return ValueObjectSP();
+                    }
+                }
+                if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
+                {
+                    if (!ClangASTContext::IsArrayType(root_clang_type))
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
+                        *final_result = ValueObject::eInvalid;
+                        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;
+                        return root;
+                    }
+                }
+                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 ValueObjectSP();
+                }
+                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 ValueObjectSP();
+                    }
+                    if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
+                    {
+                        if (ClangASTContext::IsArrayType(root_clang_type))
+                        {
+                            *first_unparsed = expression_cstr+2;
+                            *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
+                            *final_result = ValueObject::eUnboundedRange;
+                            return root;
+                        }
+                        else
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
+                            *final_result = ValueObject::eInvalid;
+                            return ValueObjectSP();
+                        }
+                    }
+                    // from here on we do have a valid index
+                    if (ClangASTContext::IsArrayType(root_clang_type))
+                    {
+                        root = root->GetChildAtIndex(index, true);
+                        if (!root.get())
+                        {
+                            *first_unparsed = expression_cstr;
+                            *reason_to_stop = ValueObject::eNoSuchChild;
+                            *final_result = ValueObject::eInvalid;
+                            return ValueObjectSP();
+                        }
+                        else
+                        {
+                            *first_unparsed = end+1; // skip ]
+                            *final_result = ValueObject::ePlain;
+                            continue;
+                        }
+                    }
+                    else if (ClangASTContext::IsPointerType(root_clang_type))
+                    {
+                        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()))
+                        {
+                            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 ValueObjectSP();
+                            }
+                            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 ValueObjectSP();
+                            }
+                            else
+                            {
+                                *first_unparsed = end+1; // skip ]
+                                *final_result = ValueObject::ePlain;
+                                continue;
+                            }
+                        }
+                    }
+                    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 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;
+                            return root;
+                        }
+                    }
+                }
+                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 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;
+                        return ValueObjectSP();
+                    }
+                    if (index_lower > index_higher) // swap indices if required
+                    {
+                        unsigned long temp = index_lower;
+                        index_lower = index_higher;
+                        index_higher = temp;
+                    }
+                    if (ClangASTContext::IsScalarType(root_clang_type)) // 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 ValueObjectSP();
+                        }
+                        else
+                        {
+                            *first_unparsed = end+1; // skip ]
+                            *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
+                            *final_result = ValueObject::eBitfield;
+                            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
+                             *what_next == ValueObject::eDereference &&
+                             ClangASTContext::IsScalarType(clang::QualType::getFromOpaquePtr(root_clang_type).getTypePtr()->getPointeeType().getAsOpaquePtr()))
+                    {
+                        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 ValueObjectSP();
+                        }
+                        else
+                        {
+                            *what_next = ValueObject::eNothing;
+                            continue;
+                        }
+                    }
+                    else
+                    {
+                        *first_unparsed = expression_cstr;
+                        *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
+                        *final_result = ValueObject::eBoundedRange;
+                        return root;
+                    }
+                }
+                break;
+            }
+            default: // some non-separator is in the way
+            {
+                *first_unparsed = expression_cstr;
+                *reason_to_stop = ValueObject::eUnexpectedSymbol;
+                *final_result = ValueObject::eInvalid;
+                return ValueObjectSP();
+                break;
+            }
+        }
+    }
+}
+
 void
 ValueObject::DumpValueObject 
 (

Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Thu Jul  7 21:51:01 2011
@@ -469,9 +469,9 @@
     StreamString name_str;
     name_str.Printf ("<%s>", entry->arg_name);
 
-    if (entry->help_function.help_callback)
+    if (entry->help_function)
     {
-        const char* help_text = (*entry->help_function.help_callback)();
+        const char* help_text = entry->help_function();
         if (!entry->help_function.self_formatting)
         {
             interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py Thu Jul  7 21:51:01 2011
@@ -159,6 +159,19 @@
             substrs = ['0x',
                        '7'])
 
+        self.runCmd("type summary clear")
+
+        self.runCmd("type summary add -f \"${*var[].x[0-3]%hex} is a bitfield on a set of integers\" -x \"SimpleWithPointers \[[0-9]\]\"")
+        self.runCmd("type summary add -f \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\" Couple")
+
+        self.expect("frame variable couple",
+            substrs = ['1 are low bits of integer 9.',
+                       'If I pretend it is an array I get [9,'])
+
+        self.expect("frame variable sparray",
+            substrs = ['[0x0000000f,0x0000000c,0x00000009]'])
+        
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp Thu Jul  7 21:51:01 2011
@@ -41,6 +41,38 @@
 	IWrapPointers() : int_pointer(new int(4)), float_pointer(new float(1.111)) {}
 };
 
+struct Simple
+{
+	int x;
+	float y;
+	char z;
+	Simple(int X, float Y, char Z) :
+	x(X),
+	y(Y),
+	z(Z)
+	{}
+};
+
+struct SimpleWithPointers
+{
+	int *x;
+	float *y;
+	char *z;
+	SimpleWithPointers(int X, float Y, char Z) :
+	x(new int (X)),
+	y(new float (Y)),
+	z(new char (Z))
+	{}
+};
+
+struct Couple
+{
+	SimpleWithPointers sp;
+	Simple* s;
+	Couple(int X, float Y, char Z) : sp(X,Y,Z),
+	s(new Simple(X,Y,Z)) {}
+};
+
 int main (int argc, const char * argv[])
 {
     
@@ -66,6 +98,13 @@
     int* pointer = &cool_array[4].integer;
     
     IWrapPointers *wrap_pointer = &wrapper;
-        
+    
+    Couple couple(9,9.99,'X');
+	
+	SimpleWithPointers sparray[] = 
+        {SimpleWithPointers(-1,-2,'3'),
+        SimpleWithPointers(-4,-5,'6'),
+        SimpleWithPointers(-7,-8,'9')};
+    
     return 0; // Set break point at this line.
 }
\ No newline at end of file

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=134679&r1=134678&r2=134679&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 Thu Jul  7 21:51:01 2011
@@ -99,6 +99,12 @@
 
         self.expect("frame variable iAmSomewhere",
             substrs = ['y=0x'])
+        
+        self.runCmd("type summary add -f \"y=${var.y},x=${var.x}\" Point")
+        
+        self.expect("frame variable iAmSomewhere",
+                    substrs = ['y=6',
+                               'x=4'])
 
         self.runCmd("type summary add -f \"hello\" Point -e")
 

Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=134679&r1=134678&r2=134679&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Thu Jul  7 21:51:01 2011
@@ -1,576 +1,717 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-<link href="style.css" rel="stylesheet" type="text/css" />
-<title>LLDB Homepage</title>
-</head>
-
-<body>
-    <div class="www_title">
-      The <strong>LLDB</strong> Debugger
-    </div>
-    
-<div id="container">
-	<div id="content">
-       <!--#include virtual="sidebar.incl"-->
-
-		<div id="middle">
-			<div class="post">
-				<h1 class ="postheader">Variable display</h1>
-				<div class="postcontent">
-				   <p>LLDB was recently modified to allow users to define the 
-				       format of the variables display on a per-type basis.</p>
-				       
-					<p>Usually, when you type <code>frame
-					variable</code> or run some <code>expression</code>
-					LLDB will automatically choose the <i>best</i> way
-					to display your results according to its own
-					logic:</p> <p> <code> (SimpleWithPointers [3])
-					sparray = {<br/> (SimpleWithPointers) [0] = {<br/>
-					(int *) x = 0x00000001001000f0<br/> (float *) y =
-					0x0000000100100100<br/> (char *) z =
-					0x0000000100100110 "3"<br/>
-					  }<br/>
-					  (SimpleWithPointers) [1] = {<br/> (int *) x =
-					  0x0000000100100120<br/> (float *) y =
-					  0x0000000100100130<br/> (char *) z =
-					  0x0000000100100140 "6"<br/>
-					  }<br/>
-					  (SimpleWithPointers) [2] = {<br/> (int *) x =
-					  0x0000000100100150<br/> (float *) y =
-					  0x0000000100100160<br/> (char *) z =
-					  0x0000000100100170 "9"<br/>
-					  }<br/>
-					}<br/>
-					</code> </p>
-
-				   <p>However, there are cases in which your idea of
-				   <i>best</i> is different from LLDB's. Now there are two
-				   new commands that enable you to give hints to the debugger
-				   as to how datatypes should be displayed.</p>
-				   
-				   <p>Using them you can obtain a format like this one for
-				   <code>sparray</code>, instead of the default shown above:
-				   </p>
-				   
-				   <p>
-				   <code>
-				   (SimpleWithPointers [3]) sparray = {<br/>
-  [0] = (x=0x00000001001000f0 -> -1, y=0x0000000100100100 -> -2, z="3")<br/>
-  [1] = (x=0x0000000100100120 -> -4, y=0x0000000100100130 -> -5, z="6")<br/>
-  [2] = (x=0x0000000100100150 -> -7, y=0x0000000100100160 -> -8, z="9")<br/>
-}<br/>
-</code>
-</p>
-				   <p>Variable formatting can be set using the <b>type</b> commands:</p>
-				   <p><code>type format</code></p>
-				   <p><code>type summary</code></p>
-				   <p>Each of these commands has four subcommands:</p>
-				   <p><code>add</code>: adds a new entry</p>
-				   <p><code>delete</code>: deletes an existing entry</p>
-				   <p><code>list</code>: provides a listing of all entries</p>
-				   <p><code>clear</code>: deletes all entries</p>
-
-                   </div>
-       			<div class="postfooter"></div>
-   			</div>
-
-   			<div class="post">
-   				<h1 class ="postheader">type format</h1>
-   				<div class="postcontent">
-
-				   <p>Type formats enable you to quickly override the default format for displaying primitive types (the usual basic C/C++/ObjC types: int, float, char, ...).</p>
-				   <p>LLDB has a list of formatting options available out of which you can pick:</p>
-				   
-				   <table border="1">
-                   <tr valign=top><td width=23%><b>Format name</b></td><td><b>Abbreviation</b></td><td><b>Description</b></td></tr>
-                   <tr valign=top><td><b>default</b></td><td></td><td>the default LLDB algorithm is used to pick a format</td></tr>
-                   <tr valign=top><td><b>boolean</b></td><td>B</td><td>show this as a true/false boolean, using the customary rule that 0 is false and everything else is true</td></tr>
-                   <tr valign=top><td><b>binary</b></td><td>b</td><td>show this as a sequence of bits</td></tr>
-                   <tr valign=top><td><b>bytes</b></td><td>y</td><td>show the bytes one after the other<br/>e.g. <code>(int) s.x = 07 00 00 00</code></td></tr>
-                   <tr valign=top><td><b>bytes with ASCII</b></td><td>Y</td><td>show the bytes, but try to print them as ASCII characters<br/>e.g. <code>(int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00                         P.._....</code></td></tr>
-                   <tr valign=top><td><b>character</b></td><td>c</td><td>show the bytes printed as ASCII characters<br/>e.g. <code>(int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0</code></td></tr>
-                   <tr valign=top><td><b>printable character</b></td><td>C</td><td>show the bytes printed as printable ASCII characters<br/> e.g. <code>(int *) c.sp.x = P.._....</code></td></tr>
-                   <tr valign=top><td><b>complex float</b></td><td>F</td><td>interpret this value as the real and imaginary part of a complex floating-point number<br/>e.g. <code>(int *) c.sp.x = 2.76658e+19 + 4.59163e-41i</code></td></tr>
-                   <tr valign=top><td><b>c-string</b></td><td>s</td><td>show this as a 0-terminated C string</td></tr>
-                   <tr valign=top><td><b>signed decimal</b></td><td>i</td><td>show this as a signed integer number (this does not perform a cast, it simply shows the bytes as signed integer)</td></tr>
-                   <tr valign=top><td><b>enumeration</b></td><td>E</td><td>show this as an enumeration, printing the value's name if available or the integer value otherwise<br/>e.g. <code>(enum enumType) val_type = eValue2</code></td></tr>
-                   <tr valign=top><td><b>hex</b></td><td>x</td><td>show this as in hexadecimal notation (this does not perform a cast, it simply shows the bytes as hex)</td></tr>
-                   <tr valign=top><td><b>float</b></td><td>f</td><td>show this as a floating-point number (this does not perform a cast, it simply interprets the bytes as an IEEE754 floating-point value)</td></tr>
-                   <tr valign=top><td><b>octal</b></td><td>o</td><td>show this in octal notation</td></tr>
-                   <tr valign=top><td><b>OSType</b></td><td>O</td><td>show this as a MacOS OSType<br/>e.g. <code>(float) *c.sp.y = '\n\x1f\xd7\n'</code></td></tr>
-                   <tr valign=top><td><b>unicode16</b></td><td>U</td><td>show this as UTF-16 characters<br/> e.g. <code>(float) *c.sp.y = 0xd70a 0x411f</code></td></tr>
-                   <tr valign=top><td><b>unicode32</b></td><td></td><td>show this as UTF-32 characters<br/> e.g. <code>(float) *c.sp.y = 0x411fd70a</code></td></tr>
-                   <tr valign=top><td><b>unsigned decimal</b></td><td>u</td><td>show this as an unsigned integer number (this does not perform a cast, it simply shows the bytes as unsigned integer)</td></tr>
-                   <tr valign=top><td><b>pointer</b></td><td>p</td><td>show this as a native pointer (unless this is really a pointer, the resulting address will probably be invalid)</td></tr>
-                   <tr valign=top><td><b>char[]</b></td><td></td><td>show this as an array of characters<br/>e.g. <code>(char) *c.sp.z = {X}</code></td></tr>
-                   <tr valign=top><td><b>int8_t[], uint8_t[]<br/>int16_t[], uint16_t[]<br/>int32_t[], uint32_t[]<br/>int64_t[], uint64_t[]<br>uint128_t[]</b></td><td></td><td>show this as an array of the corresponding integer type<br/>e.g.<br/><code>(int) sarray[0].x = {1 0 0 0}</code><br/><code>(int) sarray[0].x = {0x00000001}</code></td></tr>
-                   <tr valign=top><td><b>float32[], float64[]</b></td><td></td><td>show this as an array of the corresponding floating-point type<br/>e.g. <code>(int *) pointer = {1.46991e-39 1.4013e-45}</code></td></tr>
-                   <tr valign=top><td><b>complex integer</b></td><td>I</td><td>interpret this value as the real and imaginary part of a complex integer number<br/> e.g. <code>(int *) pointer = 1048960 + 1i</code></td></tr>
-                   <tr valign=top><td><b>character array</b></td><td>a</td><td>show this as a character array<br/>e.g. <code>(int *) pointer = \x80\x01\x10\0\x01\0\0\0</code></td></tr>
-                   </table>
-				   
-				   <p>Some of the examples shown are willingfully
-				   unnatural ways to print some values, and meant to
-				   show that there is no casting or data-loss occurring
-				   when you change the format of a type. All that lldb
-				   does when you ask it to change format is reinterpret
-				   the bytes for display, leaving the original value
-				   unaltered.</p>
-
-				   <p>There are two ways to modify the format, one is
-				   temporary and per-variable, the other is permanent
-				   and per-type.</p> <p>In the first case you can simply
-				   use the <code>-f</code> option to <b><code>frame
-				   variable</code></b>, passing it one of the format
-				   names or abbreviations in the previous table:</p>
-				   <p><code>frame variable counter -f hex</code></p>
-				   <p>This has the effect of displaying the value of
-				   <code>counter</code> as an hexadecimal number, and
-				   will keep showing it this way until you either pick a
-				   different format or a subsequent stoppoint is
-				   hit.</p> <p>Obviously, if you have two
-				   <code>int</code> variables, and you format one as
-				   hex, the other will be left untouched. If for some
-				   reason, you want all <code>int</code> variables to
-				   print out as hex, you must add a format to the
-				   <code>int</code> type.</p> <p>This is done by typing
-				   <code>type format add -f hex int</code> at the LLDB
-				   command line.</p> <p>The <code>-f</code> option
-				   accepts one of the format names or abbreviations, and
-				   after that you can give out a list of names to which
-				   you want the new format applied.</p> <p>A frequent
-				   scenario is that your program has a
-				   <code>typedef</code> for a numeric type that you know
-				   represents something that must be printed in a
-				   certain way. Again, you can add a format just to that
-				   typedef by using <code>type format add</code> with
-				   the name alias.</p> <p>But things can quickly get
-				   hierarchical. Let's say you have a situation like the
-				   following:</p> <p><code>typedef int A;<br/>typedef A
-				   B;<br/>typedef B C;<br/>typedef C D;</code></p>
-				   <p>and you want to show all <code>A</code>s as hex,
-				   all <code>C</code>s as pointers and leave the
-				   defaults untouched for other types.</p> <p>If you
-				   simply type <br/><code>type format add -f hex
-				   A<br/>type format add -f pointer C</code><br/> values
-				   of type <code>B</code> will be shown as hex and
-				   values of type <code>D</code> as pointers.</p>
-				   <p>This is because by default LLDB <i>cascades</i>
-				   formats through typedef chains. In order to avoid
-				   that you can use the option <code>-C no</code> to
-				   prevent cascading, thus making the two commands
-				   required to achieve your goal:<br/> <code> type
-				   format add -f hex -C no A<br/> type format add -f
-				   pointer -C no C </code></p> <p>Two additional options
-				   that you will want to look at are <code>-p</code> and
-				   <code>-r</code>. These two options prevent LLDB from
-				   applying a format for type <code>T</code> to values
-				   of type <code>T*</code> and <code>T&</code>
-				   respectively.</p>
-				   <p>
-				   <code>
-				    <b>(lldb)</b> type format add -f float32[] int<br/>
-					<b>(lldb)</b> fr var pointer *pointer -T<br/>
-					(int *) pointer = {1.46991e-39 1.4013e-45}<br/>
-					(int) *pointer = {1.53302e-42}<br/>
-					<b>(lldb)</b> type format add -f float32[] int -p<br/>
-					<b>(lldb)</b> fr var pointer *pointer -T<br/>
-					(int *) pointer = 0x0000000100100180<br/>
-					(int) *pointer = {1.53302e-42}<br/>
-				   </code>
-				   </p>
-				   <p>As the previous example highlights, you will most
-				   probably want to use <code>-p</code> for your
-				   formats.</p> <p>If you need to delete a custom format
-				   simply type <code>type format delete</code> followed
-				   by the name of the type to which the format applies.
-				   To delete ALL formats, use <code>type format
-				   clear</code>. To see all the formats defined, type
-				   <code>type format list</code>.</p>
-
-				    </div> <div class="postfooter"></div> </div>
-
-   			<div class="post"> <h1 class ="postheader">type
-   			summary</h1> <div class="postcontent">
-
-				   <p>Type summaries enable you to add more information
-				   to the default viewing format for a type, or to
-				   completely replace it with your own display option.
-				   Unlike formats which only apply to basic types,
-				   summaries can be used on every type (basic types,
-				   classes (C++ and Objective-C), arrays, ...).</p>
-				   <p>The basic idea beneath type summaries is
-				   extracting information from variables and arranging
-				   it in a format that is suitable for display:</p> <p>
-				   <i>before adding a summary...</i><br/> <code> <b>(lldb)</b>
-				   fr var -T one<br/> (i_am_cool) one = {<br/> (int)
-				   integer = 3<br/> (float) floating = 3.14159<br/>
-				   (char) character = 'E'<br/>
-					}<br/>
-					</code> <br/> <i>after adding a summary...</i><br/>
-					<code> <b>(lldb)</b> fr var one<br/> (i_am_cool) one = int
-					= 3, float = 3.14159, char = 69<br/> </code> </p>
-
-				   <p>Evidently, somehow we managed to tell LLDB to grab
-				   the three member variables of the
-				   <code>i_am_cool</code> datatype, mix their values
-				   with some text, and even ask it to display the
-				   <code>character</code> member using a custom
-				   format.</p> <p>The way to do this is add a <i>summary
-				   string</i> to the datatype using the <code>type
-				   summary add</code> command.</p> <p>Its syntax is
-				   similar to <code>type format add</code>, but some
-				   more options are supported that will be described in
-				   the follow-up.</p> <p>The main option to <code>type
-				   summary add</code> is <code>-f</code> which accepts
-				   as parameter a summary string. After that, you can
-				   type as many type names as you want to associate the
-				   given summary string to them.</p>
-
-                   </div>
-       			<div class="postfooter"></div>
-   			</div>
-
-   			<div class="post">
-   				<h1 class ="postheader">Summary Strings</h1>
-   				<div class="postcontent">
-
-                   <p>So what is the format of the summary strings?
-                   Summary strings can contain plain text, control
-                   characters and special symbols that have access to
-                   information about the current object and the overall
-                   program state.</p>
-
-                   <p>Normal characters are any text that doesn't
-                   contain a <code><b>'{'</b></code>,
-                   <code><b>'}'</b></code>, <code><b>'$'</b></code>, or
-                   <code><b>'\'</b></code> character.</p>
-
-                   <p>Variable names are found in between a
-                   <code><b>"${"</b></code> prefix, and end with a
-                   <code><b>"}"</b></code> suffix. In other words, a
-                   variable looks like
-                   <code>"<b>${frame.pc}</b>"</code>.</p>
-
-                   <p>Basically, all the variables described in <a
-                   href="formats.html">Frame and Thread Formatting</a>
-                   are accepted. Also acceptable are the control
-                   characters and scoping features described in that
-                   page. Additionally, <code>${var</code> and
-                   <code>${*var</code> become acceptable symbols in this
-                   scenario.</p> <p>The simplest thing you can do is
-                   grab a member variable of a class or structure by
-                   typing its <i>expression path</i>. In the previous
-                   example, the expression path for the floating member
-                   is simply <code>.floating</code>, because all you
-                   have to do to get at it given an object of type
-                   <code>i_am_cool</code> is access it straight away.
-                   Thus, to ask the summary string to display
-                   <code>floating</code> you would type
-                   <code>${var.floating}</code> (<code>${var</code> is a
-                   placeholder token replaced with whatever variable is
-                   being displayed).</p> <p>If you have code like the
-                   following: <br/> <code> struct A {<br/> int x;<br/>
-                   int y;<br/>
-				   };<br/>
-				   struct B {<br/> A x;<br/> A y;<br/> int z;<br/>
-			 	   };<br/>
-			 	   </code> the expression path for the <code>y</code>
-			 	   member of the <code>x</code> member of an object of
-			 	   type <code>B</code> would be <code>.x.y</code> and
-			 	   you would type <code>${var.x.y}</code> to display it
-			 	   in a summary string for type <code>B</code>. </p>
-			 	   <p>As you could be using a summary string for both
-			 	   displaying objects of type <code>T</code> or
-			 	   <code>T*</code> (unless <code>-p</code> is used to
-			 	   prevent this), the expression paths do not
-			 	   differentiate between <code>.</code> and
-			 	   <code>-></code>, and the above expression path
-			 	   <code>.x.y</code> would be just as good if you were
-			 	   displaying a <code>B*</code>, or even if the actual
-			 	   definition of <code>B</code> were:
-				   	<code><br/>
-				   struct B {<br/>
-				    A *x;<br/>
-				    A y;<br/>
-				    int z;<br/>
-			 	   };<br/>
-			 	   </code>
-				   </p>
-				   <p>This is unlike the behaviour of <code>frame
-				   variable</code> which, on the contrary, will enforce
-				   the distinction. As hinted above, the rationale for
-				   this choice is that waiving this distinction enables
-				   one to write a summary string once for type
-				   <code>T</code> and use it for both <code>T</code> and
-				   <code>T*</code> instances. As a summary string is
-				   mostly about extracting nested members' information,
-				   a pointer to an object is just as good as the object
-				   itself for the purpose.</p>
-
-				   <p>Of course, you can have multiple entries in one
-				   summary string. For instance, the command used to
-				   produce the above summary string for i_am_cool was:
-				   <br/><code>type summary add -f "int = ${var.integer},
-				   float = ${var.floating}, char = ${var.character%u}"
-				   i_am_cool </code> </p> <p>As you can see, the last
-				   expression path also contains a <code>%u</code>
-				   symbol which is nowhere to be found in the actual
-				   member variable name. The symbol is reminding of a
-				   <code>printf()</code> format symbol, and in fact it
-				   has a similar effect. If you add a % sign followed by
-				   any one format name or abbreviation from the above
-				   table after an expression path, the resulting object
-				   will be displyed using exactly that format instead of
-				   the LLDB default one.
-				   </p>
-				   <p>There are two more special format symbols that you
-				   can use only as part of a summary string:
-				   <code>%V</code> and <code>%@</code>. The first one
-				   tells LLDB to ignore summary strings for the type of
-				   the object referred by the expression path and
-				   instead print the object's value. The second is only
-				   applicable to Objective-C classes, and tells LLDB to
-				   get the object's description from the Objective-C
-				   runtime. By default, if no format is provided, LLDB
-				   will try to get the object's summary, and if empty
-				   the object's value. If neither can be obtained,
-				   nothing will be displayed.</p>
-				   <p>As previously said, pointers and values are
-				   treated the same way when getting to their members in
-				   an expression path. However, if your expression path
-				   leads to a pointer, LLDB will not automatically
-				   dereference it. In order to obtain The deferenced
-				   value for a pointer, your expression path must start
-				   with <code>${*var</code> instead of
-				   <code>${var</code>. Because there is no need to
-				   dereference pointers along your way, the
-				   dereferencing symbol only applies to the result of
-				   the whole expression path traversing.
-				   <br/>
-				   e.g.
-				   <code>
-				   <br/>
-				   <b>(lldb)</b> fr var -T c<br/>
-(Couple) c = {<br/>
-  (SimpleWithPointers) sp = {<br/>
-    (int *) x = 0x00000001001000b0<br/>
-    (float *) y = 0x00000001001000c0<br/>
-    (char *) z = 0x00000001001000d0 "X"<br/>
-  }<br/>
-  (Simple *) s = 0x00000001001000e0<br/>
-}<br/>
-<b>(lldb)</b> type summary add -f "int = ${*var.sp.x}, float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple = ${*var.s}" Couple<br/>
-<b>(lldb)</b> type summary add -c -p Simple<br/>
-<b>(lldb)</b> fr var c<br/>
-(Couple) c = int = 9, float = 9.99, char = 88, Simple = (x=9, y=9.99, z='X')<br/>
-				   </code>
-				   </p>
-				   <p>Option <code>-c</code> to <code>type summary
-				   add</code> tells LLDB not to look for a summary
-				   string, but instead to just print a listing of all
-				   the object's children on one line, lay out as in the
-				   previous example. The <code>-p</code> flag is used as
-				   a trick to show that aggregate types can be
-				   dereferenced as well as primitive ones. The above
-				   output would be shown even by typing <code>type
-				   summary add -f "int = ${*var.sp.x}, float =
-				   ${*var.sp.y}, char = ${*var.sp.z%u}, Simple =
-				   ${var.s}" Couple</code> if one took away the
-				   <code>-p</code> flag from the summary for type
-				   <code>Simple</code>. </p>
-				   
-				    </div>
-       			<div class="postfooter"></div>
-   			</div>
-
-   			<div class="post">
-   				<h1 class ="postheader">More on summary strings</h1>
-   				<div class="postcontent">
-
-				   <p>What was described above are the main features
-				   that you can use in summary strings. However, there
-				   are three more features to them.</p> <p>Sometimes, a
-				   basic type's value actually represents several
-				   different values packed together in a bitfield. With
-				   the classical view, there is no way to look at them.
-				   Hexadecimal display can help, but if the bits
-				   actually span byte boundaries, the help is limited.
-				   Binary view would show it all without ambiguity, but
-				   is often too detailed and hard to read for real-life
-				   scenarios. To cope with the issue, LLDB supports
-				   native bitfield formatting in summary strings. If
-				   your expression paths leads to a so-called <i>scalar
-				   type</i> (the usual int, float, char, double, short,
-				   long, long long, double, long double and unsigned
-				   variants), you can ask LLDB to only grab some bits
-				   out of the value and display them in any format you
-				   like. The syntax is similar to that used for arrays,
-				   just you can also give a pair of indices separated by
-				   a <code>-</code>. <br/>
-				   e.g.
-				   <br/>
-				   <code>
-				   <b>(lldb)</b> fr var float_point<br/>
-(float) float_point = -3.14159<br/>
-<b>(lldb)</b> type summary add -f "Sign: ${var[31]%B} Exponent: ${var[30-23]%x} Mantissa: ${var[0-22]%u}" float<br/>
-<b>(lldb)</b> fr var float_point<br/>
-(float) float_point = -3.14159 Sign: true Exponent: 0x00000080 Mantissa: 4788184<br/>
-				   </code>
-				   In this example, LLDB shows the internal
-				   representation of a <code>float</code> variable by
-				   extracting bitfields out of a float object. If you
-				   give a single index, only that one bit will be
-				   extracted. If you give a pair of indices, all the
-				   bits in the range (extremes included) will be
-				   extracted. Ranges can be specified either by giving
-				   the lower index first, or higher index first (as is
-				   often customary in describing packed data-type
-				   formats). </p>
-				   <p>The second additional feature allows you to
-				   display array members inside a summary string. For
-				   instance, you may want to display all arrays of a
-				   given type using a more compact notation than the
-				   default, and then just delve into individual array
-				   members that prove interesting to your debugging
-				   task. You can use a similar syntax to the one used
-				   for bitfields to tell LLDB to format arrays in
-				   special ways.
-				    <br/>
-				   e.g.
-				   <br/>
-				   <code>
-				   <b>(lldb)</b> fr var sarray<br/>
-(Simple [3]) sarray = {<br/>
-  [0] = {<br/>
-    x = 1<br/>
-    y = 2<br/>
-    z = '\x03'<br/>
-  }<br/>
-  [1] = {<br/>
-    x = 4<br/>
-    y = 5<br/>
-    z = '\x06'<br/>
-  }<br/>
-  [2] = {<br/>
-    x = 7<br/>
-    y = 8<br/>
-    z = '\t'<br/>
-  }<br/>
-}<br/>
-<b>(lldb)</b> type summary add -f "${var[].x}" "Simple [3]"<br/>
-<b>(lldb)</b> fr var sarray<br/>
-(Simple [3]) sarray = [1,4,7]<br/>
-				   </code>
-				   The <code>[]</code> symbol amounts to: <i>if
-				   <code>var</code> is an array and I knows its size,
-				   apply this summary string to every element of the
-				   array</i>. Here, we are asking LLDB to display
-				   <code>.x</code> for every element of the array, and
-				   in fact this is what happens. If you find some of
-				   those integers anomalous, you can then inspect that
-				   one item in greater detail, without the array format
-				   getting in the way:
-				   <br/>
-				   	<code>
-				   	<b>(lldb)</b> fr var sarray[1]<br/>
-(Simple) sarray[1] = {<br/>
-  x = 4<br/>
-  y = 5<br/>
-  z = '\x06'<br/>
-}<br/>
-				   	</code>
-				   </p>
-				   <p>You can also ask LLDB to only print a subset of
-				   the array range by using the same syntax used to
-				   extract bit for bitfields.</p> <p>The same logic
-				   works if you are printing a pointer instead of an
-				   array, however in this latter case, <code>[]</code>
-				   cannot be used and you need to give exact range
-				   limits.</p> <p>The third, and last, additional
-				   feature does not directly apply to the summary
-				   strings themselves, but is an additional option to
-				   the <code>type summary add</code> command:
-				   <code>-x</code></p> <p>As you noticed, in order to
-				   associate the custom summary string to the array
-				   types, one must give the array size as part of the
-				   typename. This can long become tiresome when using
-				   arrays of different sizes, <code>Simple [3]</code>,
-				   <code>Simple [9]</code>, <code>Simple [12]</code>,
-				   ...</p> <p>If you use the <code>-x</code> option,
-				   type names are treated as regular expressions instead
-				   of type names. This would let you rephrase the above
-				   example as:
-				   	<br/>
-				   <code>
-<b>(lldb)</b> type summary add -f "${var[].x}" -x "Simple \[[0-9]+\]"<br/>
-<b>(lldb)</b> fr var sarray<br/>
-(Simple [3]) sarray = [1,4,7]<br/>
-					</code>
-					The above scenario works for <code>Simple [3]</code>
-					as well as for any other array of
-					<code>Simple</code> objects. </p> <p>While this
-					feature is mostly useful for arrays, you could also
-					use regular expressions to catch other type sets
-					grouped by name. However, as regular expression
-					matching is slower than normal name matching, LLDB
-					will first try to match by name in any way it can,
-					and only when this fails, will it resort to regular
-					expression matching. Thus, if your type has a base
-					class with a cascading summary, this will be
-					preferred over any regular expression match for your
-					type itself.</p>
-
-   				    </div> <div class="postfooter"></div> </div>
-
-   			 <div class="post"> <h1 class ="postheader">Finding
-   			 summaries 101</h1> <div class="postcontent">
-
-   				   <p>While the rules for finding an appropriate
-   				   format for a type are relatively simple (just go
-   				   through typedef hierarchies), summaries follow a
-   				   more complicated process in finding the right
-   				   summary string for a variable. Namely, what
-   				   happens is:</p> <ul> <li>If there is a summary for
-   				   the type of the variable, use it</li> <li>If this
-   				   object is a pointer, and there is a summary for
-   				   the pointee type that does not skip pointers, use
-   				   it</li> <li>If this object is a reference, and
-   				   there is a summary for the pointee type that does
-   				   not skip references, use it</li> <li>If this
-   				   object is an Objective-C class with a parent
-   				   class, look at the parent class (and parent of
-   				   parent, ...)</li> <li>If this object is a C++
-   				   class with base classes, look at base classes (and
-   				   bases of bases, ...)</li> <li>If this object is a
-   				   C++ class with virtual base classes, look at the
-   				   virtual base classes (and bases of bases,
-   				   ...)</li> <li>If this object's type is a typedef,
-   				   go through typedef hierarchy</li> <li>If
-   				   everything has failed, repeat the above search,
-   				   looking for regular expressions instead of exact
-   				   matches</li> </ul> </div> <div
-   				   class="postfooter"></div> </div>
-
-   			<div class="post"> <h1 class ="postheader">TODOs</h1>
-   			<div class="postcontent">
-
-				<ul> <li>There's no way to do multiple dereferencing,
-				and you need to be careful what the dereferencing
-				operation is binding to in complicated scenarios</li>
-				<li>There is no way to call functions inside summary
-				strings, not even <code>const</code> ones</li>
-				<li><code>type format add</code> does not support the
-				<code>-x</code> option</li> <li>Object location cannot
-				be printed in the summary string</li> </ul>
-                </div>
-          		<div class="postfooter"></div>
-      			</div>
-
-		</div>
-	</div>
-</div>
-</body>
-</html>
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;
+      charset=ISO-8859-1">
+    <link href="style.css" rel="stylesheet" type="text/css">
+    <title>LLDB Homepage</title>
+  </head>
+  <body>
+    <div class="www_title"> The <strong>LLDB</strong> Debugger </div>
+    <div id="container">
+      <div id="content">
+        <!--#include virtual="sidebar.incl"-->
+        <div id="middle">
+          <div class="post">
+            <h1 class="postheader">Variable display</h1>
+            <div class="postcontent">
+            
+              <p>LLDB was recently modified to allow users to define custom
+                formatting options for the variables display.</p>
+            
+            <p>Usually, when you type <code>frame variable</code> or
+                run some <code>expression</code> LLDB will
+                automatically choose a format to display your results on
+                a per-type basis, as in the following example:</p>
+            
+            <p> <code> <b>(lldb)</b> frame variable -T sp<br>
+                  (SimpleWithPointers) sp = {<br>
+                      (int *) x = 0x0000000100100120<br>
+                      (float *) y =
+                  0x0000000100100130<br>
+                      (char *) z =
+                  0x0000000100100140 "6"<br>
+                  }<br>
+                </code> </p>
+            
+            <p>However, in certain cases, you may want to associate a
+                different format to the display for certain datatypes.
+                To do so, you need to give hints to the debugger as to
+                how datatypes should be displayed.<br>
+                A new <b>type</b> command has been introduced in LLDB
+                which allows to do just that.<br>
+              </p>
+            
+            <p>Using it you can obtain a format like this one for <code>sp</code>,
+                instead of the default shown above: </p>
+            
+            <p> <code> <b>(lldb)</b> frame variable sp<br>
+                  (SimpleWithPointers) sp =
+                  (x=0x0000000100100120 -> -1, y=0x0000000100100130
+                  -> -2, z="3")<br>
+                </code> </p>
+            
+            <p>There are two kinds of printing options: <span
+                  style="font-style: italic;">summary</span> and <span
+                  style="font-style: italic;">format</span>. While a
+                detailed description of both will be given below, one
+                can briefly say that a summary is mainly used for
+                aggregate types, while a format is attached to primitive
+                types.</p>
+            
+            <p>To reflect this, the the <b>type</b> command has two
+                subcommands:<br>
+              </p>
+            
+            <p><code>type format</code></p>
+            <p><code>type summary</code></p>
+            
+            <p>These commands are meant to bind printing options to
+                types. When variables are printed, LLDB will first check
+                if custom printing options have been associated to a
+                variable's type and, if so, use them instead of picking
+                the default choices.<br>
+              </p>
+              
+              <p>The two commands <code>type format</code> and <code>type
+                  summary</code> each have four subcommands:<br>
+              </p>
+              <p><code>add</code>: associates a new printing option to one
+              or more types</p>
+              <p><code>delete</code>: deletes an existing association</p>
+              <p><code>list</code>: provides a listing of all
+                associations</p>
+              <p><code>clear</code>: deletes all associations</p>
+            </div>
+          </div>
+          
+          <div class="post">
+            <h1 class="postheader">type format</h1>
+            <div class="postcontent">
+          
+          <p>Type formats enable you to quickly override the default
+                format for displaying primitive types (the usual basic
+                C/C++/ObjC types: int, float, char, ...).</p>
+              
+            <p>If for some reason you want all <code>int</code>
+              variables in your program to print out as hex, you can add
+              a format to the <code>int</code> type.<br></p>
+          
+          <p>This is done by typing <code>type format add -f hex
+                  int</code> at the LLDB command line.</p>
+                  
+              <p>The <code>-f</code> option accepts a <a
+                  href="#formatstable">format name</a>, and a list of
+                types to which you want the new format applied.</p>
+                
+              <p>A frequent scenario is that your program has a <code>typedef</code>
+                for a numeric type that you know represents something
+                that must be printed in a certain way. Again, you can
+                add a format just to that typedef by using <code>type
+                  format add</code> with the name alias.</p>
+                  
+              <p>But things can quickly get hierarchical. Let's say you
+                have a situation like the following:</p>
+                
+              <p><code>typedef int A;<br>
+                  typedef A B;<br>
+                  typedef B C;<br>
+                  typedef C D;<br>
+                </code></p>
+                
+              <p>and you want to show all <code>A</code>'s as hex, all
+                <code>C'</code>s as pointers and leave the defaults
+                untouched for other types.</p>
+                
+              <p>If you simply type <br>
+              <code>type format add -f hex A<br>
+                  type format add -f pointer C</code><br>
+              <br>           
+              values of type <code>B</code> will be shown as hex
+                and values of type <code>D</code> as pointers.</p>
+                
+              <p>This is because by default LLDB <i>cascades</i>
+                formats through typedef chains. In order to avoid that
+                you can use the option <code>-C no</code> to prevent
+                cascading, thus making the two commands required to
+                achieve your goal:<br>
+                <code> type format add -f hex -C no A<br>
+                  type format add -f pointer -C no C </code></p>
+                  
+              <p>Two additional options that you will want to look at
+                are <code>-p</code> and <code>-r</code>. These two
+                options prevent LLDB from applying a format for type <code>T</code>
+                to values of type <code>T*</code> and <code>T&</code>
+                respectively.</p>
+                
+              <p> <code> <b>(lldb)</b> type format add -f float32[]
+                  int<br>
+                  <b>(lldb)</b> fr var pointer *pointer -T<br>
+                  (int *) pointer = {1.46991e-39 1.4013e-45}<br>
+                  (int) *pointer = {1.53302e-42}<br>
+                  <b>(lldb)</b> type format add -f float32[] int -p<br>
+                  <b>(lldb)</b> fr var pointer *pointer -T<br>
+                  (int *) pointer = 0x0000000100100180<br>
+                  (int) *pointer = {1.53302e-42}<br>
+                </code> </p>
+                
+              <p>As the previous example highlights, you will most
+                probably want to use <code>-p</code> for your formats.</p>
+
+              <p>If you need to delete a custom format simply type <code>type
+                  format delete</code> followed by the name of the type
+                to which the format applies. To delete ALL formats, use
+                <code>type format clear</code>. To see all the formats
+                defined, type <code>type format list</code>.<br>
+              </p>
+              
+              <p>If all you need to do, however, is display one variable
+                in a custom format, while leaving the others of the same
+                type untouched, you can simply type:<br>
+              <br>
+              <code>frame variable counter -f hex</code></p>
+              
+              <p>This has the effect of displaying the value of <code>counter</code>
+                as an hexadecimal number, and will keep showing it this
+                way until you either pick a different format or till you
+                let your program run again.</p>
+                
+              <p>Finally, this is a list of formatting options available
+                out of
+                which you can pick:</p><a name="formatstable"></a>
+              <table border="1">
+                <tbody>
+                  <tr valign="top">
+                    <td width="23%"><b>Format name</b></td>
+                    <td><b>Abbreviation</b></td>
+                    <td><b>Description</b></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>default</b></td>
+                    <td><br>
+                    </td>
+                    <td>the default LLDB algorithm is used to pick a
+                      format</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>boolean</b></td>
+                    <td>B</td>
+                    <td>show this as a true/false boolean, using the
+                      customary rule that 0 is false and everything else
+                      is true</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>binary</b></td>
+                    <td>b</td>
+                    <td>show this as a sequence of bits</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>bytes</b></td>
+                    <td>y</td>
+                    <td>show the bytes one after the other<br>
+                      e.g. <code>(int) s.x = 07 00 00 00</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>bytes with ASCII</b></td>
+                    <td>Y</td>
+                    <td>show the bytes, but try to print them as ASCII
+                      characters<br>
+                      e.g. <code>(int *) c.sp.x = 50 f8 bf 5f ff 7f 00
+                        00 P.._....</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>character</b></td>
+                    <td>c</td>
+                    <td>show the bytes printed as ASCII characters<br>
+                      e.g. <code>(int *) c.sp.x =
+                        P\xf8\xbf_\xff\x7f\0\0</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>printable character</b></td>
+                    <td>C</td>
+                    <td>show the bytes printed as printable ASCII
+                      characters<br>
+                      e.g. <code>(int *) c.sp.x = P.._....</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>complex float</b></td>
+                    <td>F</td>
+                    <td>interpret this value as the real and imaginary
+                      part of a complex floating-point number<br>
+                      e.g. <code>(int *) c.sp.x = 2.76658e+19 +
+                        4.59163e-41i</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>c-string</b></td>
+                    <td>s</td>
+                    <td>show this as a 0-terminated C string</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>signed decimal</b></td>
+                    <td>i</td>
+                    <td>show this as a signed integer number (this does
+                      not perform a cast, it simply shows the bytes as
+                      signed integer)</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>enumeration</b></td>
+                    <td>E</td>
+                    <td>show this as an enumeration, printing the
+                      value's name if available or the integer value
+                      otherwise<br>
+                      e.g. <code>(enum enumType) val_type = eValue2</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>hex</b></td>
+                    <td>x</td>
+                    <td>show this as in hexadecimal notation (this does
+                      not perform a cast, it simply shows the bytes as
+                      hex)</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>float</b></td>
+                    <td>f</td>
+                    <td>show this as a floating-point number (this does
+                      not perform a cast, it simply interprets the bytes
+                      as an IEEE754 floating-point value)</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>octal</b></td>
+                    <td>o</td>
+                    <td>show this in octal notation</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>OSType</b></td>
+                    <td>O</td>
+                    <td>show this as a MacOS OSType<br>
+                      e.g. <code>(float) *c.sp.y = '\n\x1f\xd7\n'</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>unicode16</b></td>
+                    <td>U</td>
+                    <td>show this as UTF-16 characters<br>
+                      e.g. <code>(float) *c.sp.y = 0xd70a 0x411f</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>unicode32</b></td>
+                    <td><br>
+                    </td>
+                    <td>show this as UTF-32 characters<br>
+                      e.g. <code>(float) *c.sp.y = 0x411fd70a</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>unsigned decimal</b></td>
+                    <td>u</td>
+                    <td>show this as an unsigned integer number (this
+                      does not perform a cast, it simply shows the bytes
+                      as unsigned integer)</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>pointer</b></td>
+                    <td>p</td>
+                    <td>show this as a native pointer (unless this is
+                      really a pointer, the resulting address will
+                      probably be invalid)</td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>char[]</b></td>
+                    <td><br>
+                    </td>
+                    <td>show this as an array of characters<br>
+                      e.g. <code>(char) *c.sp.z = {X}</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>int8_t[], uint8_t[]<br>
+                        int16_t[], uint16_t[]<br>
+                        int32_t[], uint32_t[]<br>
+                        int64_t[], uint64_t[]<br>
+                        uint128_t[]</b></td>
+                    <td><br>
+                    </td>
+                    <td>show this as an array of the corresponding
+                      integer type<br>
+                      e.g.<br>
+                      <code>(int) sarray[0].x = {1 0 0 0}</code><br>
+                      <code>(int) sarray[0].x = {0x00000001}</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>float32[], float64[]</b></td>
+                    <td><br>
+                    </td>
+                    <td>show this as an array of the corresponding
+                      floating-point type<br>
+                      e.g. <code>(int *) pointer = {1.46991e-39
+                        1.4013e-45}</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>complex integer</b></td>
+                    <td>I</td>
+                    <td>interpret this value as the real and imaginary
+                      part of a complex integer number<br>
+                      e.g. <code>(int *) pointer = 1048960 + 1i</code></td>
+                  </tr>
+                  <tr valign="top">
+                    <td><b>character array</b></td>
+                    <td>a</td>
+                    <td>show this as a character array<br>
+                      e.g. <code>(int *) pointer =
+                        \x80\x01\x10\0\x01\0\0\0</code></td>
+                  </tr>
+                </tbody>
+              </table>
+            </div>
+          </div>
+          
+          <div class="post">
+            <h1 class="postheader">type summary</h1>
+            <div class="postcontent">
+              <p>Type summaries enable you to add more information to
+                the default viewing format for a type, or to completely
+                replace it with your own display option. Unlike formats
+                which only apply to basic types, summaries can be used
+                on every type (basic types, classes (C++ and
+                Objective-C), arrays, ...).</p>
+              <p>The basic idea beneath type summaries is extracting
+                information from variables and arranging it in a format
+                that is suitable for display:</p>
+              <p> <i>before adding a summary...</i><br>
+                <code> <b>(lldb)</b> fr var -T one<br>
+                  (i_am_cool) one = {<br>
+                  (int) integer = 3<br>
+                  (float) floating = 3.14159<br>
+                  (char) character = 'E'<br>
+                  }<br>
+                </code> <br>
+                <i>after adding a summary...</i><br>
+                <code> <b>(lldb)</b> fr var one<br>
+                  (i_am_cool) one = int = 3, float = 3.14159, char = 69<br>
+                </code> </p>
+              <p>Evidently, somehow we managed to tell LLDB to grab the
+                three member variables of the <code>i_am_cool</code>
+                datatype, mix their values with some text, and even ask
+                it to display the <code>character</code> member using a
+                custom format.</p>
+              <p>The way to do this is add a <i>summary string</i> to
+                the datatype using the <code>type summary add</code>
+                command.</p>
+              <p>Its syntax is similar to <code>type format add</code>,
+                but some more options are supported that will be
+                described in the follow-up.</p>
+              <p>The main option to <code>type summary add</code> is <code>-f</code>
+                which accepts as parameter a summary string. After that,
+                you can type as many type names as you want to associate
+                the given summary string to them.</p>
+            </div>
+          </div>
+          <div class="post">
+            <h1 class="postheader">Summary Strings</h1>
+            <div class="postcontent">
+              <p>So what is the format of the summary strings? Summary
+                strings can contain plain text, control characters and
+                special symbols that have access to information about
+                the current object and the overall program state.</p>
+              <p>Normal characters are any text that doesn't contain a <code><b>'{'</b></code>,
+                <code><b>'}'</b></code>, <code><b>'$'</b></code>, or <code><b>'\'</b></code>
+                character.</p>
+              <p>Variable names are found in between a <code><b>"${"</b></code>
+                prefix, and end with a <code><b>"}"</b></code> suffix.
+                In other words, a variable looks like <code>"<b>${frame.pc}</b>"</code>.</p>
+              <p>Basically, all the variables described in <a
+                  href="formats.html">Frame and Thread Formatting</a>
+                are accepted. Also acceptable are the control characters
+                and scoping features described in that page.
+                Additionally, <code>${var</code> and <code>${*var</code>
+                become acceptable symbols in this scenario.</p>
+              <p>The simplest thing you can do is grab a member variable
+                of a class or structure by typing its <i>expression
+                  path</i>. In the previous example, the expression path
+                for the floating member is simply <code>.floating</code>,
+                because all you have to do to get at it given an object
+                of type <code>i_am_cool</code> is access it straight
+                away. Thus, to ask the summary string to display <code>floating</code>
+                you would type <code>${var.floating}</code> (<code>${var</code>
+                is a placeholder token replaced with whatever variable
+                is being displayed).</p>
+              <p>If you have code like the following: <br>
+                <code> struct A {<br>
+                  int x;<br>
+                  int y;<br>
+                  };<br>
+                  struct B {<br>
+                  A x;<br>
+                  A y;<br>
+                  int z;<br>
+                  };<br>
+                </code> the expression path for the <code>y</code>
+                member of the <code>x</code> member of an object of
+                type <code>B</code> would be <code>.x.y</code> and you
+                would type <code>${var.x.y}</code> to display it in a
+                summary string for type <code>B</code>. </p>
+              <p>As you could be using a summary string for both
+                displaying objects of type <code>T</code> or <code>T*</code>
+                (unless <code>-p</code> is used to prevent this), the
+                expression paths do not differentiate between <code>.</code>
+                and <code>-></code>, and the above expression path <code>.x.y</code>
+                would be just as good if you were displaying a <code>B*</code>,
+                or even if the actual definition of <code>B</code>
+                were: <code><br>
+                  struct B {<br>
+                  A *x;<br>
+                  A y;<br>
+                  int z;<br>
+                  };<br>
+                </code> </p>
+              <p>This is unlike the behaviour of <code>frame variable</code>
+                which, on the contrary, will enforce the distinction. As
+                hinted above, the rationale for this choice is that
+                waiving this distinction enables one to write a summary
+                string once for type <code>T</code> and use it for both
+                <code>T</code> and <code>T*</code> instances. As a
+                summary string is mostly about extracting nested
+                members' information, a pointer to an object is just as
+                good as the object itself for the purpose.</p>
+              <p>Of course, you can have multiple entries in one summary
+                string. For instance, the command used to produce the
+                above summary string for i_am_cool was: <br>
+                <code>type summary add -f "int = ${var.integer}, float =
+                  ${var.floating}, char = ${var.character%u}" i_am_cool
+                </code> </p>
+              <p>As you can see, the last expression path also contains
+                a <code>%u</code> symbol which is nowhere to be found
+                in the actual member variable name. The symbol is
+                reminding of a <code>printf()</code> format symbol, and
+                in fact it has a similar effect. If you add a % sign
+                followed by any one format name or abbreviation from the
+                above table after an expression path, the resulting
+                object will be displyed using exactly that format
+                instead of the LLDB default one. </p>
+              <p>There are two more special format symbols that you can
+                use only as part of a summary string: <code>%V</code>
+                and <code>%@</code>. The first one tells LLDB to ignore
+                summary strings for the type of the object referred by
+                the expression path and instead print the object's
+                value. The second is only applicable to Objective-C
+                classes, and tells LLDB to get the object's description
+                from the Objective-C runtime. By default, if no format
+                is provided, LLDB will try to get the object's summary,
+                and if empty the object's value. If neither can be
+                obtained, nothing will be displayed.</p>
+              <p>As previously said, pointers and values are treated the
+                same way when getting to their members in an expression
+                path. However, if your expression path leads to a
+                pointer, LLDB will not automatically dereference it. In
+                order to obtain The deferenced value for a pointer, your
+                expression path must start with <code>${*var</code>
+                instead of <code>${var</code>. Because there is no need
+                to dereference pointers along your way, the
+                dereferencing symbol only applies to the result of the
+                whole expression path traversing. <br>
+                e.g. <code> <br>
+                  <b>(lldb)</b> fr var -T c<br>
+                  (Couple) c = {<br>
+                  (SimpleWithPointers) sp = {<br>
+                  (int *) x = 0x00000001001000b0<br>
+                  (float *) y = 0x00000001001000c0<br>
+                  (char *) z = 0x00000001001000d0 "X"<br>
+                  }<br>
+                  (Simple *) s = 0x00000001001000e0<br>
+                  }<br>
+                  <b>(lldb)</b> type summary add -f "int = ${*var.sp.x},
+                  float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple =
+                  ${*var.s}" Couple<br>
+                  <b>(lldb)</b> type summary add -c -p Simple<br>
+                  <b>(lldb)</b> fr var c<br>
+                  (Couple) c = int = 9, float = 9.99, char = 88, Simple
+                  = (x=9, y=9.99, z='X')<br>
+                </code> </p>
+              <p>Option <code>-c</code> to <code>type summary add</code>
+                tells LLDB not to look for a summary string, but instead
+                to just print a listing of all the object's children on
+                one line, lay out as in the previous example. The <code>-p</code>
+                flag is used as a trick to show that aggregate types can
+                be dereferenced as well as primitive ones. The above
+                output would be shown even by typing <code>type summary
+                  add -f "int = ${*var.sp.x}, float = ${*var.sp.y}, char
+                  = ${*var.sp.z%u}, Simple = ${var.s}" Couple</code> if
+                one took away the <code>-p</code> flag from the summary
+                for type <code>Simple</code>. </p>
+            </div>
+          </div>
+          <div class="post">
+            <h1 class="postheader">More on summary strings</h1>
+            <div class="postcontent">
+              <p>What was described above are the main features that you
+                can use in summary strings. However, there are three
+                more features to them.</p>
+              <p>Sometimes, a basic type's value actually represents
+                several different values packed together in a bitfield.
+                With the classical view, there is no way to look at
+                them. Hexadecimal display can help, but if the bits
+                actually span byte boundaries, the help is limited.
+                Binary view would show it all without ambiguity, but is
+                often too detailed and hard to read for real-life
+                scenarios. To cope with the issue, LLDB supports native
+                bitfield formatting in summary strings. If your
+                expression paths leads to a so-called <i>scalar type</i>
+                (the usual int, float, char, double, short, long, long
+                long, double, long double and unsigned variants), you
+                can ask LLDB to only grab some bits out of the value and
+                display them in any format you like. The syntax is
+                similar to that used for arrays, just you can also give
+                a pair of indices separated by a <code>-</code>. <br>
+                e.g. <br>
+                <code> <b>(lldb)</b> fr var float_point<br>
+                  (float) float_point = -3.14159<br>
+                  <b>(lldb)</b> type summary add -f "Sign: ${var[31]%B}
+                  Exponent: ${var[30-23]%x} Mantissa: ${var[0-22]%u}"
+                  float<br>
+                  <b>(lldb)</b> fr var float_point<br>
+                  (float) float_point = -3.14159 Sign: true Exponent:
+                  0x00000080 Mantissa: 4788184<br>
+                </code> In this example, LLDB shows the internal
+                representation of a <code>float</code> variable by
+                extracting bitfields out of a float object. If you give
+                a single index, only that one bit will be extracted. If
+                you give a pair of indices, all the bits in the range
+                (extremes included) will be extracted. Ranges can be
+                specified either by giving the lower index first, or
+                higher index first (as is often customary in describing
+                packed data-type formats). </p>
+              <p>The second additional feature allows you to display
+                array members inside a summary string. For instance, you
+                may want to display all arrays of a given type using a
+                more compact notation than the default, and then just
+                delve into individual array members that prove
+                interesting to your debugging task. You can use a
+                similar syntax to the one used for bitfields to tell
+                LLDB to format arrays in special ways. <br>
+                e.g. <br>
+                <code> <b>(lldb)</b> fr var sarray<br>
+                  (Simple [3]) sarray = {<br>
+                  [0] = {<br>
+                  x = 1<br>
+                  y = 2<br>
+                  z = '\x03'<br>
+                  }<br>
+                  [1] = {<br>
+                  x = 4<br>
+                  y = 5<br>
+                  z = '\x06'<br>
+                  }<br>
+                  [2] = {<br>
+                  x = 7<br>
+                  y = 8<br>
+                  z = '\t'<br>
+                  }<br>
+                  }<br>
+                  <b>(lldb)</b> type summary add -f "${var[].x}" "Simple
+                  [3]"<br>
+                  <b>(lldb)</b> fr var sarray<br>
+                  (Simple [3]) sarray = [1,4,7]<br>
+                </code> The <code>[]</code> symbol amounts to: <i>if <code>var</code>
+                  is an array and I knows its size, apply this summary
+                  string to every element of the array</i>. Here, we are
+                asking LLDB to display <code>.x</code> for every
+                element of the array, and in fact this is what happens.
+                If you find some of those integers anomalous, you can
+                then inspect that one item in greater detail, without
+                the array format getting in the way: <br>
+                <code> <b>(lldb)</b> fr var sarray[1]<br>
+                  (Simple) sarray[1] = {<br>
+                  x = 4<br>
+                  y = 5<br>
+                  z = '\x06'<br>
+                  }<br>
+                </code> </p>
+              <p>You can also ask LLDB to only print a subset of the
+                array range by using the same syntax used to extract bit
+                for bitfields.</p>
+              <p>The same logic works if you are printing a pointer
+                instead of an array, however in this latter case, <code>[]</code>
+                cannot be used and you need to give exact range limits.</p>
+              <p>The third, and last, additional feature does not
+                directly apply to the summary strings themselves, but is
+                an additional option to the <code>type summary add</code>
+                command: <code>-x</code></p>
+              <p>As you noticed, in order to associate the custom
+                summary string to the array types, one must give the
+                array size as part of the typename. This can long become
+                tiresome when using arrays of different sizes, <code>Simple
+
+                  [3]</code>, <code>Simple [9]</code>, <code>Simple
+                  [12]</code>, ...</p>
+              <p>If you use the <code>-x</code> option, type names are
+                treated as regular expressions instead of type names.
+                This would let you rephrase the above example as: <br>
+                <code> <b>(lldb)</b> type summary add -f "${var[].x}"
+                  -x "Simple \[[0-9]+\]"<br>
+                  <b>(lldb)</b> fr var sarray<br>
+                  (Simple [3]) sarray = [1,4,7]<br>
+                </code> The above scenario works for <code>Simple [3]</code>
+                as well as for any other array of <code>Simple</code>
+                objects. </p>
+              <p>While this feature is mostly useful for arrays, you
+                could also use regular expressions to catch other type
+                sets grouped by name. However, as regular expression
+                matching is slower than normal name matching, LLDB will
+                first try to match by name in any way it can, and only
+                when this fails, will it resort to regular expression
+                matching. Thus, if your type has a base class with a
+                cascading summary, this will be preferred over any
+                regular expression match for your type itself.</p>
+            </div>
+          </div>
+          <div class="post">
+            <h1 class="postheader">Finding summaries 101</h1>
+            <div class="postcontent">
+              <p>While the rules for finding an appropriate format for a
+                type are relatively simple (just go through typedef
+                hierarchies), summaries follow a more complicated
+                process in finding the right summary string for a
+                variable. Namely, what happens is:</p>
+              <ul>
+                <li>If there is a summary for the type of the variable,
+                  use it</li>
+                <li>If this object is a pointer, and there is a summary
+                  for the pointee type that does not skip pointers, use
+                  it</li>
+                <li>If this object is a reference, and there is a
+                  summary for the pointee type that does not skip
+                  references, use it</li>
+                <li>If this object is an Objective-C class with a parent
+                  class, look at the parent class (and parent of parent,
+                  ...)</li>
+                <li>If this object is a C++ class with base classes,
+                  look at base classes (and bases of bases, ...)</li>
+                <li>If this object is a C++ class with virtual base
+                  classes, look at the virtual base classes (and bases
+                  of bases, ...)</li>
+                <li>If this object's type is a typedef, go through
+                  typedef hierarchy</li>
+                <li>If everything has failed, repeat the above search,
+                  looking for regular expressions instead of exact
+                  matches</li>
+              </ul>
+            </div>
+          </div>
+          <div class="post">
+            <h1 class="postheader">TODOs</h1>
+            <div class="postcontent">
+              <ul>
+                <li>There's no way to do multiple dereferencing, and you
+                  need to be careful what the dereferencing operation is
+                  binding to in complicated scenarios</li>
+                <li>There is no way to call functions inside summary
+                  strings, not even <code>const</code> ones</li>
+                <li><code>type format add</code> does not support the <code>-x</code>
+                  option</li>
+                <li>Object location cannot be printed in the summary
+                  string</li>
+              </ul>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>





More information about the lldb-commits mailing list