[Lldb-commits] [lldb] r198105 - Add a new way to bind a format to a type: by enum type

Enrico Granata egranata at apple.com
Sat Dec 28 00:44:03 PST 2013


Author: enrico
Date: Sat Dec 28 02:44:02 2013
New Revision: 198105

URL: http://llvm.org/viewvc/llvm-project?rev=198105&view=rev
Log:
Add a new way to bind a format to a type: by enum type
The "type format add" command gets a new flag --type (-t). If you pass -t <sometype>, upon fetching the value for an object of your type,
LLDB will display it as-if it was of enumeration type <sometype>
This is useful in cases of non-contiguous enums where there are empty gaps of unspecified values, and as such one cannot type their variables as the enum type,
but users would still like to see them as-if they were of the enum type (e.g. DWARF field types with their user-reserved ranges)

The SB API has also been improved to handle both types of formats, and a test case is added


Added:
    lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/
    lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
    lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
Modified:
    lldb/trunk/include/lldb/API/SBTypeFormat.h
    lldb/trunk/include/lldb/DataFormatters/TypeFormat.h
    lldb/trunk/scripts/Python/interface/SBTypeFormat.i
    lldb/trunk/source/API/SBTypeFormat.cpp
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/DataFormatters/FormatManager.cpp
    lldb/trunk/source/DataFormatters/TypeFormat.cpp

Modified: lldb/trunk/include/lldb/API/SBTypeFormat.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTypeFormat.h?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTypeFormat.h (original)
+++ lldb/trunk/include/lldb/API/SBTypeFormat.h Sat Dec 28 02:44:02 2013
@@ -22,6 +22,9 @@ public:
     
     SBTypeFormat (lldb::Format format,
                   uint32_t options = 0); // see lldb::eTypeOption values
+
+    SBTypeFormat (const char* type,
+                  uint32_t options = 0); // see lldb::eTypeOption values
     
     SBTypeFormat (const lldb::SBTypeFormat &rhs);
     
@@ -33,6 +36,9 @@ public:
     lldb::Format
     GetFormat ();
     
+    const char*
+    GetTypeName ();
+    
     uint32_t
     GetOptions();
     
@@ -40,6 +46,9 @@ public:
     SetFormat (lldb::Format);
     
     void
+    SetTypeName (const char*);
+    
+    void
     SetOptions (uint32_t);
     
     bool
@@ -73,8 +82,15 @@ protected:
     
     SBTypeFormat (const lldb::TypeFormatImplSP &);
     
+    enum class Type
+    {
+        eTypeKeepSame,
+        eTypeFormat,
+        eTypeEnum
+    };
+    
     bool
-    CopyOnWrite_Impl();
+    CopyOnWrite_Impl(Type);
     
 };
 

Modified: lldb/trunk/include/lldb/DataFormatters/TypeFormat.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeFormat.h?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeFormat.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeFormat.h Sat Dec 28 02:44:02 2013
@@ -130,15 +130,12 @@ namespace lldb_private {
             uint32_t m_flags;
         };
         
-        TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
-                        const Flags& flags = Flags());
+        TypeFormatImpl (const Flags& flags = Flags());
         
         typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
         typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
         
-        ~TypeFormatImpl ()
-        {
-        }
+        virtual ~TypeFormatImpl () = default;
         
         bool
         Cascades () const
@@ -173,6 +170,66 @@ namespace lldb_private {
         {
             m_flags.SetSkipReferences(value);
         }
+
+        uint32_t
+        GetOptions ()
+        {
+            return m_flags.GetValue();
+        }
+        
+        void
+        SetOptions (uint32_t value)
+        {
+            m_flags.SetValue(value);
+        }
+        
+        uint32_t&
+        GetRevision ()
+        {
+            return m_my_revision;
+        }
+        
+        enum class Type
+        {
+            eTypeUnknown,
+            eTypeFormat,
+            eTypeEnum
+        };
+        
+        virtual Type
+        GetType ()
+        {
+            return Type::eTypeUnknown;
+        }
+        
+        // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
+        // extended periods of time and we trust the ValueObject to stay around for as long as it is required
+        // for us to generate its value
+        virtual bool
+        FormatObject (ValueObject *valobj,
+                      std::string& dest) const = 0;
+        
+        virtual std::string
+        GetDescription() = 0;
+        
+    protected:
+        Flags m_flags;
+        uint32_t m_my_revision;
+        
+    private:
+        DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
+    };
+    
+    class TypeFormatImpl_Format : public TypeFormatImpl
+    {
+    public:
+        TypeFormatImpl_Format (lldb::Format f = lldb::eFormatInvalid,
+                               const TypeFormatImpl::Flags& flags = Flags());
+        
+        typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer;
+        typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_Format::SharedPointer&);
+        
+        virtual ~TypeFormatImpl_Format () = default;
         
         lldb::Format
         GetFormat () const
@@ -186,42 +243,69 @@ namespace lldb_private {
             m_format = fmt;
         }
         
-        uint32_t
-        GetOptions ()
+        virtual TypeFormatImpl::Type
+        GetType ()
         {
-            return m_flags.GetValue();
+            return TypeFormatImpl::Type::eTypeFormat;
+        }
+        
+        virtual bool
+        FormatObject (ValueObject *valobj,
+                      std::string& dest) const;
+        
+        virtual std::string
+        GetDescription();
+        
+    protected:
+        lldb::Format m_format;
+        
+    private:
+        DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_Format);
+    };
+    
+    class TypeFormatImpl_EnumType : public TypeFormatImpl
+    {
+    public:
+        TypeFormatImpl_EnumType (ConstString type_name = ConstString(""),
+                                 const TypeFormatImpl::Flags& flags = Flags());
+        
+        typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer;
+        typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_EnumType::SharedPointer&);
+        
+        ~TypeFormatImpl_EnumType () = default;
+        
+        ConstString
+        GetTypeName ()
+        {
+            return m_enum_type;
         }
         
         void
-        SetOptions (uint32_t value)
+        SetTypeName (ConstString enum_type)
         {
-            m_flags.SetValue(value);
+            m_enum_type = enum_type;
         }
         
-        uint32_t&
-        GetRevision ()
+        virtual TypeFormatImpl::Type
+        GetType ()
         {
-            return m_my_revision;
+            return TypeFormatImpl::Type::eTypeEnum;
         }
         
-        // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
-        // extended periods of time and we trust the ValueObject to stay around for as long as it is required
-        // for us to generate its value
-        bool
+        virtual bool
         FormatObject (ValueObject *valobj,
                       std::string& dest) const;
         
-        std::string
+        virtual std::string
         GetDescription();
         
     protected:
-        Flags m_flags;
-        lldb::Format m_format;
-        uint32_t m_my_revision;
+        ConstString m_enum_type;
+        mutable std::map<void*,ClangASTType> m_types;
         
     private:
-        DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
-    };    
+        DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType);
+    };
 } // namespace lldb_private
 
 #endif	// lldb_TypeFormat_h_

Modified: lldb/trunk/scripts/Python/interface/SBTypeFormat.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTypeFormat.i?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTypeFormat.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTypeFormat.i Sat Dec 28 02:44:02 2013
@@ -21,6 +21,8 @@ namespace lldb {
         
         SBTypeFormat (lldb::Format format, uint32_t options = 0);
         
+        SBTypeFormat (const char* type, uint32_t options = 0);
+        
         SBTypeFormat (const lldb::SBTypeFormat &rhs);
         
         ~SBTypeFormat ();
@@ -34,6 +36,9 @@ namespace lldb {
         lldb::Format
         GetFormat ();
         
+        const char*
+        GetTypeName ();
+        
         uint32_t
         GetOptions();
         
@@ -41,6 +46,9 @@ namespace lldb {
         SetFormat (lldb::Format);
         
         void
+        SetTypeName (const char*);
+        
+        void
         SetOptions (uint32_t);        
         
         bool

Modified: lldb/trunk/source/API/SBTypeFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeFormat.cpp?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTypeFormat.cpp (original)
+++ lldb/trunk/source/API/SBTypeFormat.cpp Sat Dec 28 02:44:02 2013
@@ -25,7 +25,13 @@ m_opaque_sp()
 
 SBTypeFormat::SBTypeFormat (lldb::Format format,
                             uint32_t options)
-: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl(format,options)))
+: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_Format(format,options)))
+{
+}
+
+SBTypeFormat::SBTypeFormat (const char* type,
+                            uint32_t options)
+: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(type ? type : ""),options)))
 {
 }
 
@@ -47,11 +53,19 @@ SBTypeFormat::IsValid() const
 lldb::Format
 SBTypeFormat::GetFormat ()
 {
-    if (IsValid())
-        return m_opaque_sp->GetFormat();
+    if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
+        return ((TypeFormatImpl_Format*)m_opaque_sp.get())->GetFormat();
     return lldb::eFormatInvalid;
 }
 
+const char*
+SBTypeFormat::GetTypeName ()
+{
+    if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum)
+        return ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->GetTypeName().AsCString("");
+    return "";
+}
+
 uint32_t
 SBTypeFormat::GetOptions()
 {
@@ -63,14 +77,21 @@ SBTypeFormat::GetOptions()
 void
 SBTypeFormat::SetFormat (lldb::Format fmt)
 {
-    if (CopyOnWrite_Impl())
-        m_opaque_sp->SetFormat(fmt);
+    if (CopyOnWrite_Impl(Type::eTypeFormat))
+        ((TypeFormatImpl_Format*)m_opaque_sp.get())->SetFormat(fmt);
+}
+
+void
+SBTypeFormat::SetTypeName (const char* type)
+{
+    if (CopyOnWrite_Impl(Type::eTypeEnum))
+        ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->SetTypeName(ConstString(type ? type : ""));
 }
 
 void
 SBTypeFormat::SetOptions (uint32_t value)
 {
-    if (CopyOnWrite_Impl())
+    if (CopyOnWrite_Impl(Type::eTypeKeepSame))
         m_opaque_sp->SetOptions(value);
 }
 
@@ -143,13 +164,30 @@ SBTypeFormat::SBTypeFormat (const lldb::
 }
 
 bool
-SBTypeFormat::CopyOnWrite_Impl()
+SBTypeFormat::CopyOnWrite_Impl(Type type)
 {
     if (!IsValid())
         return false;
-    if (m_opaque_sp.unique())
+    
+    if (m_opaque_sp.unique() &&
+        ((type == Type::eTypeKeepSame) ||
+         (type == Type::eTypeFormat && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) ||
+         (type == Type::eTypeEnum && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum))
+        )
         return true;
 
-    SetSP(TypeFormatImplSP(new TypeFormatImpl(GetFormat(),GetOptions())));
+    if (type == Type::eTypeKeepSame)
+    {
+        if (m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
+            type = Type::eTypeFormat;
+        else
+            type = Type::eTypeEnum;
+    }
+    
+    if (type == Type::eTypeFormat)
+        SetSP(TypeFormatImplSP(new TypeFormatImpl_Format(GetFormat(),GetOptions())));
+    else
+        SetSP(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(GetTypeName()),GetOptions())));
+    
     return true;
 }

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Sat Dec 28 02:44:02 2013
@@ -371,6 +371,7 @@ private:
             m_skip_references = false;
             m_regex = false;
             m_category.assign("default");
+            m_custom_type_name.clear();
         }
         virtual Error
         SetOptionValue (CommandInterpreter &interpreter,
@@ -400,6 +401,9 @@ private:
                 case 'x':
                     m_regex = true;
                     break;
+                case 't':
+                    m_custom_type_name.assign(option_value);
+                    break;
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
                     break;
@@ -419,6 +423,7 @@ private:
         bool m_skip_pointers;
         bool m_regex;
         std::string m_category;
+        std::string m_custom_type_name;
     };
     
     OptionGroupOptions m_option_group;
@@ -480,7 +485,7 @@ public:
                     );
     
         // Add the "--format" to all options groups
-        m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL);
+        m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
         m_option_group.Append (&m_command_options);
         m_option_group.Finalize();
 
@@ -504,7 +509,7 @@ protected:
         }
         
         const Format format = m_format_options.GetFormat();
-        if (format == eFormatInvalid)
+        if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
         {
             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
             result.SetStatus(eReturnStatusFailed);
@@ -513,10 +518,16 @@ protected:
         
         TypeFormatImplSP entry;
         
-        entry.reset(new TypeFormatImpl(format,
-                                    TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
-                                    SetSkipPointers(m_command_options.m_skip_pointers).
-                                    SetSkipReferences(m_command_options.m_skip_references)));
+        if (m_command_options.m_custom_type_name.empty())
+            entry.reset(new TypeFormatImpl_Format(format,
+                                                  TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+                                                  SetSkipPointers(m_command_options.m_skip_pointers).
+                                                  SetSkipReferences(m_command_options.m_skip_references)));
+        else
+            entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
+                                                    TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+                                                    SetSkipPointers(m_command_options.m_skip_pointers).
+                                                    SetSkipReferences(m_command_options.m_skip_references)));
 
         // now I have a valid format, let's add it to every type
         
@@ -562,11 +573,12 @@ protected:
 OptionDefinition
 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
-    { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
-    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
-    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
+    { LLDB_OPT_SET_ALL, false,  "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
+    { LLDB_OPT_SET_ALL, false,  "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
+    { LLDB_OPT_SET_ALL, false,  "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
+    { LLDB_OPT_SET_ALL, false,  "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
+    { LLDB_OPT_SET_2,   false,  "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Format variables as if they were of this type."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Sat Dec 28 02:44:02 2013
@@ -1402,7 +1402,7 @@ bool
 ValueObject::GetValueAsCString (lldb::Format format,
                                 std::string& destination)
 {
-    return GetValueAsCString(TypeFormatImpl(format),destination);
+    return GetValueAsCString(TypeFormatImpl_Format(format),destination);
 }
 
 const char *
@@ -1439,7 +1439,7 @@ ValueObject::GetValueAsCString ()
         {
             m_last_format = my_format;
             if (!format_sp)
-                format_sp.reset(new TypeFormatImpl(my_format));
+                format_sp.reset(new TypeFormatImpl_Format(my_format));
             if (GetValueAsCString(*format_sp.get(), m_value_str))
             {
                 if (!m_value_did_change && m_old_value_valid)

Modified: lldb/trunk/source/DataFormatters/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/FormatManager.cpp?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/FormatManager.cpp (original)
+++ lldb/trunk/source/DataFormatters/FormatManager.cpp Sat Dec 28 02:44:02 2013
@@ -741,7 +741,7 @@ AddFormat (TypeCategoryImpl::SharedPoint
            TypeFormatImpl::Flags flags,
            bool regex = false)
 {
-    lldb::TypeFormatImplSP format_sp(new TypeFormatImpl(format, flags));
+    lldb::TypeFormatImplSP format_sp(new TypeFormatImpl_Format(format, flags));
     
     if (regex)
         category_sp->GetRegexTypeFormatsContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),format_sp);

Modified: lldb/trunk/source/DataFormatters/TypeFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/TypeFormat.cpp?rev=198105&r1=198104&r2=198105&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/TypeFormat.cpp (original)
+++ lldb/trunk/source/DataFormatters/TypeFormat.cpp Sat Dec 28 02:44:02 2013
@@ -25,22 +25,30 @@
 #include "lldb/DataFormatters/TypeFormat.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-TypeFormatImpl::TypeFormatImpl (lldb::Format f,
-                                const Flags& flags) :
+TypeFormatImpl::TypeFormatImpl (const Flags& flags) :
 m_flags(flags),
+m_my_revision(0)
+{
+}
+
+
+TypeFormatImpl_Format::TypeFormatImpl_Format (lldb::Format f,
+                                              const TypeFormatImpl::Flags& flags) :
+TypeFormatImpl(flags),
 m_format (f)
 {
 }
 
 bool
-TypeFormatImpl::FormatObject (ValueObject *valobj,
-                              std::string& dest) const
+TypeFormatImpl_Format::FormatObject (ValueObject *valobj,
+                                     std::string& dest) const
 {
     if (!valobj)
         return false;
@@ -127,7 +135,7 @@ TypeFormatImpl::FormatObject (ValueObjec
 }
 
 std::string
-TypeFormatImpl::GetDescription()
+TypeFormatImpl_Format::GetDescription()
 {
     StreamString sstr;
     sstr.Printf ("%s%s%s%s",
@@ -138,3 +146,87 @@ TypeFormatImpl::GetDescription()
     return sstr.GetString();
 }
 
+TypeFormatImpl_EnumType::TypeFormatImpl_EnumType (ConstString type_name,
+                                                  const TypeFormatImpl::Flags& flags) :
+TypeFormatImpl(flags),
+m_enum_type(type_name),
+m_types()
+{
+}
+
+bool
+TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj,
+                                       std::string& dest) const
+{
+    dest.clear();
+    if (!valobj)
+        return false;
+    if (valobj->GetClangType().IsAggregateType ())
+        return false;
+    ProcessSP process_sp;
+    TargetSP target_sp;
+    void* valobj_key = (process_sp = valobj->GetProcessSP()).get();
+    if (!valobj_key)
+        valobj_key = (target_sp = valobj->GetTargetSP()).get();
+    else
+        target_sp = process_sp->GetTarget().shared_from_this();
+    if (!valobj_key)
+        return false;
+    auto iter = m_types.find(valobj_key),
+    end = m_types.end();
+    ClangASTType valobj_enum_type;
+    if (iter == end)
+    {
+        // probably a redundant check
+        if (!target_sp)
+            return false;
+        const ModuleList& images(target_sp->GetImages());
+        SymbolContext sc;
+        TypeList types;
+        images.FindTypes(sc, m_enum_type, false, UINT32_MAX, types);
+        if (types.GetSize() == 0)
+            return false;
+        for (lldb::TypeSP type_sp : types.Types())
+        {
+            if (!type_sp)
+                continue;
+            if ( (type_sp->GetClangForwardType().GetTypeInfo() & ClangASTType::eTypeIsEnumeration) == ClangASTType::eTypeIsEnumeration)
+            {
+                valobj_enum_type = type_sp->GetClangFullType();
+                m_types.emplace(valobj_key,valobj_enum_type);
+                break;
+            }
+        }
+    }
+    else
+        valobj_enum_type = iter->second;
+    if (valobj_enum_type.IsValid() == false)
+        return false;
+    DataExtractor data;
+    valobj->GetData(data);
+    ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
+    StreamString sstr;
+    valobj_enum_type.DumpTypeValue(&sstr,
+                                   lldb::eFormatEnum,
+                                   data,
+                                   0,
+                                   data.GetByteSize(),
+                                   0,
+                                   0,
+                                   exe_ctx.GetBestExecutionContextScope());
+    if (!sstr.GetString().empty())
+        dest.swap(sstr.GetString());
+    return !dest.empty();
+}
+
+std::string
+TypeFormatImpl_EnumType::GetDescription()
+{
+    StreamString sstr;
+    sstr.Printf ("as type %s%s%s%s",
+                 m_enum_type.AsCString("<invalid type>"),
+                 Cascades() ? "" : " (not cascading)",
+                 SkipsPointers() ? " (skip pointers)" : "",
+                 SkipsReferences() ? " (skip references)" : "");
+    return sstr.GetString();
+}

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/Makefile?rev=198105&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/Makefile Sat Dec 28 02:44:02 2013
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py?rev=198105&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py Sat Dec 28 02:44:02 2013
@@ -0,0 +1,80 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class EnumFormatTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands()
+
+    @dwarf_test
+    def test_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.data_formatter_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.cpp', '// Set break point at this line.')
+
+    def data_formatter_commands(self):
+        """Test that that file and class static variables display correctly."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        self.expect("frame variable",
+            substrs = ['(Foo) f = Case45',
+            '(int) x = 1',
+            '(int) y = 45',
+            '(int) z = 43'
+                        ]);
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        self.runCmd("type format add --type Foo int")
+
+        # The type format list should show our custom formats.
+        self.expect("type format list -w default",
+            substrs = ['int: as type Foo'])
+
+        self.expect("frame variable",
+            substrs = ['(Foo) f = Case45',
+            '(int) x = Case1',
+            '(int) y = Case45',
+            '(int) z = 43'
+	                        ]);
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp?rev=198105&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp Sat Dec 28 02:44:02 2013
@@ -0,0 +1,13 @@
+enum Foo {
+	Case1 = 1,
+	Case2 = 2,
+	Case45 = 45
+};
+
+int main() {
+	Foo f = Case45;
+	int x = 1;
+	int y = 45;
+	int z = 43;
+	return 1; // Set break point at this line.
+}





More information about the lldb-commits mailing list