[lldb-dev] Enumerating the members of an enum

Greg Clayton gclayton at apple.com
Thu Nov 7 13:01:21 PST 2013


Yeah, in clang at least the main enumeration has a type that is signed or unsigned, but each enumerator also has a type. 

Actually scratch my suggestion, because SBTypeEnumMember already has GetType():

SBType
SBTypeEnumMember::GetType()

Which we can then figure out if it is signed or not.

So your patch looks good as is.

Greg

On Nov 7, 2013, at 12:56 PM, Russell Harmon <russ at eatnumber1.com> wrote:

> I had figured that a client could figure that out by looking at the enum member's type. I'll add it though
> 
> --
> Russell Harmon
> 
> 
> On Thu, Nov 7, 2013 at 12:53 PM, Greg Clayton <gclayton at apple.com> wrote:
> Looks good. The only thing I can think of is we might want to expose the following function:
> 
> bool
> SBTypeEnumMember::IsSigned();
> 
> That way clients know if each member is signed or not. I know that each enum member in clang code knows if it is signed or not.
> 
> Greg
> 
> On Nov 7, 2013, at 11:16 AM, Russell Harmon <russ at eatnumber1.com> wrote:
> 
> > bump
> >
> > --
> > Russell Harmon
> >
> >
> > On Sat, Oct 26, 2013 at 7:32 AM, Russell Harmon <russ at eatnumber1.com> wrote:
> > Here ya' go. Let me know if it needs some changes.
> >
> > --
> > Russell Harmon
> >
> > From 72332118f0c23360633f4ab4df8590e0451dd39b Mon Sep 17 00:00:00 2001
> > From: Russell Harmon <russ at eatnumber1.com>
> > Date: Sat, 26 Oct 2013 07:26:17 -0700
> > Subject: [PATCH] Add support for inspecting enum members.
> >
> > ---
> >  include/lldb/API/SBDefines.h                |    2 +
> >  include/lldb/API/SBStream.h                 |    1 +
> >  include/lldb/API/SBType.h                   |    5 +
> >  include/lldb/API/SBTypeEnumMember.h         |   97 ++++++++++++++
> >  include/lldb/Core/ClangForward.h            |    1 +
> >  include/lldb/Symbol/ClangASTType.h          |    3 +
> >  include/lldb/Symbol/Type.h                  |   99 +++++++++++++-
> >  include/lldb/lldb-forward.h                 |    3 +
> >  scripts/Python/interface/SBType.i           |   14 ++
> >  scripts/Python/interface/SBTypeEnumMember.i |  108 +++++++++++++++
> >  scripts/Python/python-extensions.swig       |   14 ++
> >  scripts/lldb.swig                           |    2 +
> >  source/API/CMakeLists.txt                   |    1 +
> >  source/API/SBType.cpp                       |   24 ++++
> >  source/API/SBTypeEnumMember.cpp             |  192 +++++++++++++++++++++++++++
> >  source/Symbol/ClangASTType.cpp              |    9 ++
> >  source/Symbol/Type.cpp                      |   11 ++
> >  test/python_api/type/TestTypeList.py        |    5 +
> >  test/python_api/type/main.cpp               |    7 +-
> >  19 files changed, 596 insertions(+), 2 deletions(-)
> >  create mode 100644 include/lldb/API/SBTypeEnumMember.h
> >  create mode 100644 scripts/Python/interface/SBTypeEnumMember.i
> >  create mode 100644 source/API/SBTypeEnumMember.cpp
> >
> > diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h
> > index 2cdf921..971e449 100644
> > --- a/include/lldb/API/SBDefines.h
> > +++ b/include/lldb/API/SBDefines.h
> > @@ -67,6 +67,8 @@ class SBTarget;
> >  class SBThread;
> >  class SBType;
> >  class SBTypeCategory;
> > +class SBTypeEnumMember;
> > +class SBTypeEnumMemberList;
> >  class SBTypeFilter;
> >  class SBTypeFormat;
> >  class SBTypeNameSpecifier;
> > diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h
> > index 038adf6..f77b7b7 100644
> > --- a/include/lldb/API/SBStream.h
> > +++ b/include/lldb/API/SBStream.h
> > @@ -86,6 +86,7 @@ protected:
> >      friend class SBTarget;
> >      friend class SBThread;
> >      friend class SBType;
> > +    friend class SBTypeEnumMember;
> >      friend class SBTypeMember;
> >      friend class SBValue;
> >      friend class SBWatchpoint;
> > diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h
> > index 3729b2f..1f9ec63 100644
> > --- a/include/lldb/API/SBType.h
> > +++ b/include/lldb/API/SBType.h
> > @@ -140,6 +140,9 @@ public:
> >      lldb::SBTypeMember
> >      GetVirtualBaseClassAtIndex (uint32_t idx);
> >
> > +    lldb::SBTypeEnumMemberList
> > +    GetEnumMembers();
> > +
> >      uint32_t
> >      GetNumberOfTemplateArguments ();
> >
> > @@ -196,6 +199,8 @@ protected:
> >      friend class SBFunction;
> >      friend class SBModule;
> >      friend class SBTarget;
> > +    friend class SBTypeEnumMember;
> > +    friend class SBTypeEnumMemberList;
> >      friend class SBTypeNameSpecifier;
> >      friend class SBTypeMember;
> >      friend class SBTypeList;
> > diff --git a/include/lldb/API/SBTypeEnumMember.h b/include/lldb/API/SBTypeEnumMember.h
> > new file mode 100644
> > index 0000000..9c447f1
> > --- /dev/null
> > +++ b/include/lldb/API/SBTypeEnumMember.h
> > @@ -0,0 +1,97 @@
> > +//===-- SBTypeEnumMember.h --------------------------------------*- C++ -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLDB_SBTypeEnumMember_h_
> > +#define LLDB_SBTypeEnumMember_h_
> > +
> > +#include "lldb/API/SBDefines.h"
> > +
> > +namespace lldb {
> > +
> > +class SBTypeEnumMember
> > +{
> > +public:
> > +    SBTypeEnumMember ();
> > +
> > +    SBTypeEnumMember (const SBTypeEnumMember& rhs);
> > +
> > +    ~SBTypeEnumMember();
> > +
> > +    SBTypeEnumMember&
> > +    operator = (const SBTypeEnumMember& rhs);
> > +
> > +    bool
> > +    IsValid() const;
> > +
> > +    int64_t
> > +    GetValueAsSigned();
> > +
> > +    uint64_t
> > +    GetValueAsUnsigned();
> > +
> > +    const char *
> > +    GetName ();
> > +
> > +    lldb::SBType
> > +    GetType ();
> > +
> > +    bool
> > +    GetDescription (lldb::SBStream &description,
> > +                    lldb::DescriptionLevel description_level);
> > +
> > +protected:
> > +    friend class SBType;
> > +    friend class SBTypeEnumMemberList;
> > +
> > +    void
> > +    reset (lldb_private::TypeEnumMemberImpl *);
> > +
> > +    lldb_private::TypeEnumMemberImpl &
> > +    ref ();
> > +
> > +    const lldb_private::TypeEnumMemberImpl &
> > +    ref () const;
> > +
> > +    lldb::TypeEnumMemberImplSP m_opaque_sp;
> > +
> > +    SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &);
> > +};
> > +
> > +class SBTypeEnumMemberList
> > +{
> > +public:
> > +    SBTypeEnumMemberList();
> > +
> > +    SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs);
> > +
> > +    ~SBTypeEnumMemberList();
> > +
> > +    SBTypeEnumMemberList&
> > +    operator = (const SBTypeEnumMemberList& rhs);
> > +
> > +    bool
> > +    IsValid();
> > +
> > +    void
> > +    Append (SBTypeEnumMember entry);
> > +
> > +    SBTypeEnumMember
> > +    GetTypeEnumMemberAtIndex (uint32_t index);
> > +
> > +    uint32_t
> > +    GetSize();
> > +
> > +
> > +private:
> > +    std::unique_ptr<lldb_private::TypeEnumMemberListImpl> m_opaque_ap;
> > +};
> > +
> > +} // namespace lldb
> > +
> > +#endif // LLDB_SBTypeEnumMember_h_
> > diff --git a/include/lldb/Core/ClangForward.h b/include/lldb/Core/ClangForward.h
> > index 0b3f13a..ef7308d 100644
> > --- a/include/lldb/Core/ClangForward.h
> > +++ b/include/lldb/Core/ClangForward.h
> > @@ -58,6 +58,7 @@ namespace clang
> >      class DiagnosticsEngine;
> >      class DiagnosticOptions;
> >      class EnumDecl;
> > +    class EnumConstantDecl;
> >      class Expr;
> >      class ExternalASTSource;
> >      class ExtVectorElementExpr;
> > diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h
> > index f0dffe3..c8a039a 100644
> > --- a/include/lldb/Symbol/ClangASTType.h
> > +++ b/include/lldb/Symbol/ClangASTType.h
> > @@ -642,6 +642,9 @@ public:
> >      clang::ObjCInterfaceDecl *
> >      GetAsObjCInterfaceDecl () const;
> >
> > +    clang::EnumDecl *
> > +    GetAsEnumDecl () const;
> > +
> >      void
> >      Clear()
> >      {
> > diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
> > index 50b22fe..0e8e5c7 100644
> > --- a/include/lldb/Symbol/Type.h
> > +++ b/include/lldb/Symbol/Type.h
> > @@ -589,7 +589,104 @@ protected:
> >      bool m_is_bitfield;
> >  };
> >
> > -
> > +class TypeEnumMemberImpl
> > +{
> > +public:
> > +    TypeEnumMemberImpl () :
> > +        m_integer_type(),
> > +        m_name("<invalid>"),
> > +        m_value(),
> > +        m_valid(false)
> > +    {
> > +    }
> > +
> > +    TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl,
> > +                        const lldb_private::ClangASTType& integer_type);
> > +
> > +    TypeEnumMemberImpl (const TypeEnumMemberImpl& rhs) :
> > +        m_integer_type(rhs.m_integer_type),
> > +        m_name(rhs.m_name),
> > +        m_value(rhs.m_value),
> > +        m_valid(rhs.m_valid)
> > +    {
> > +    }
> > +
> > +    TypeEnumMemberImpl&
> > +    operator = (const TypeEnumMemberImpl& rhs);
> > +
> > +    bool
> > +    IsValid ()
> > +    {
> > +        return m_valid;
> > +    }
> > +
> > +    const ConstString &
> > +    GetName () const
> > +    {
> > +        return m_name;
> > +    }
> > +
> > +    const lldb::TypeImplSP &
> > +    GetIntegerType () const
> > +    {
> > +        return m_integer_type;
> > +    }
> > +
> > +    uint64_t
> > +    GetValueAsUnsigned () const
> > +    {
> > +        return *m_value.getRawData();
> > +    }
> > +
> > +    int64_t
> > +    GetValueAsSigned () const
> > +    {
> > +        return (int64_t) *m_value.getRawData();
> > +    }
> > +
> > +protected:
> > +    lldb::TypeImplSP m_integer_type;
> > +    ConstString m_name;
> > +    llvm::APSInt m_value;
> > +    bool m_valid;
> > +};
> > +
> > +class TypeEnumMemberListImpl
> > +{
> > +public:
> > +    TypeEnumMemberListImpl() :
> > +        m_content()
> > +    {
> > +    }
> > +
> > +    void
> > +    Append (const lldb::TypeEnumMemberImplSP& type)
> > +    {
> > +        m_content.push_back(type);
> > +    }
> > +
> > +    void
> > +    Append (const lldb_private::TypeEnumMemberListImpl& type_list);
> > +
> > +    lldb::TypeEnumMemberImplSP
> > +    GetTypeEnumMemberAtIndex(size_t idx)
> > +    {
> > +        lldb::TypeEnumMemberImplSP enum_member;
> > +        if (idx < GetSize())
> > +            enum_member = m_content[idx];
> > +        return enum_member;
> > +    }
> > +
> > +    size_t
> > +    GetSize()
> > +    {
> > +        return m_content.size();
> > +    }
> > +
> > +private:
> > +    std::vector<lldb::TypeEnumMemberImplSP> m_content;
> > +};
> > +
> >  } // namespace lldb_private
> >
> >  #endif  // liblldb_Type_h_
> > diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
> > index e06044b..754a2d8 100644
> > --- a/include/lldb/lldb-forward.h
> > +++ b/include/lldb/lldb-forward.h
> > @@ -233,6 +233,8 @@ class   TypeAndOrName;
> >  class   TypeList;
> >  class   TypeListImpl;
> >  class   TypeMemberImpl;
> > +class   TypeEnumMemberImpl;
> > +class   TypeEnumMemberListImpl;
> >  class   TypeNameSpecifierImpl;
> >  class   UUID;
> >  class   Unwind;
> > @@ -360,6 +362,7 @@ namespace lldb {
> >      typedef std::weak_ptr<lldb_private::Type> TypeWP;
> >      typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP;
> >      typedef std::shared_ptr<lldb_private::TypeImpl> TypeImplSP;
> > +    typedef std::shared_ptr<lldb_private::TypeEnumMemberImpl> TypeEnumMemberImplSP;
> >      typedef std::shared_ptr<lldb_private::TypeFilterImpl> TypeFilterImplSP;
> >      typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP;
> >      typedef std::shared_ptr<lldb_private::TypeNameSpecifierImpl> TypeNameSpecifierImplSP;
> > diff --git a/scripts/Python/interface/SBType.i b/scripts/Python/interface/SBType.i
> > index fbeed3e..95fe50a 100644
> > --- a/scripts/Python/interface/SBType.i
> > +++ b/scripts/Python/interface/SBType.i
> > @@ -210,6 +210,9 @@ public:
> >      lldb::SBTypeMember
> >      GetVirtualBaseClassAtIndex (uint32_t idx);
> >
> > +    lldb::SBTypeEnumMemberList
> > +    GetEnumMembers();
> > +
> >      const char*
> >      GetName();
> >
> > @@ -339,6 +342,14 @@ public:
> >                      members.append(field)
> >              return members
> >
> > +        def get_enum_members_array(self):
> > +            '''An accessor function that returns a list() that contains all enum members in an lldb.SBType object.'''
> > +            enum_members_list = []
> > +            sb_enum_members = self.GetEnumMembers()
> > +            for idx in range(sb_enum_members.GetSize()):
> > +                enum_members_list.append(sb_enum_members.GetTypeEnumMemberAtIndex(idx))
> > +            return enum_members_list
> > +
> >          __swig_getmethods__["bases"] = get_bases_array
> >          if _newclass: bases = property(get_bases_array, None, doc='''A read only property that returns a list() of lldb.SBTypeMember objects that represent all of the direct base classes for this type.''')
> >
> > @@ -351,6 +362,9 @@ public:
> >          __swig_getmethods__["members"] = get_members_array
> >          if _newclass: members = property(get_members_array, None, doc='''A read only property that returns a list() of all lldb.SBTypeMember objects that represent all of the base classes, virtual base classes and fields for this type in ascending bit offset order.''')
> >
> > +        __swig_getmethods__["enum_members"] = get_enum_members_array
> > +        if _newclass: enum_members = property(get_enum_members_array, None, doc='''A read only property that returns a list() of all lldb.SBTypeEnumMember objects that represent the enum members for this type.''')
> > +
> >          %}
> >
> >  };
> > diff --git a/scripts/Python/interface/SBTypeEnumMember.i b/scripts/Python/interface/SBTypeEnumMember.i
> > new file mode 100644
> > index 0000000..02d89f1
> > --- /dev/null
> > +++ b/scripts/Python/interface/SBTypeEnumMember.i
> > @@ -0,0 +1,108 @@
> > +//===-- SWIG Interface for SBTypeEnumMember ---------------------*- C++ -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +namespace lldb {
> > +
> > +%feature(
> > +    "docstring",
> > +    "Represents a member of an enum in lldb."
> > +) SBTypeEnumMember;
> > +
> > +class SBTypeEnumMember
> > +{
> > +public:
> > +    SBTypeEnumMember ();
> > +
> > +    SBTypeEnumMember (const SBTypeEnumMember& rhs);
> > +
> > +    ~SBTypeEnumMember();
> > +
> > +    bool
> > +    IsValid() const;
> > +
> > +    int64_t
> > +    GetValueAsSigned();
> > +
> > +    uint64_t
> > +    GetValueAsUnsigned();
> > +
> > +    const char *
> > +    GetName ();
> > +
> > +    lldb::SBType
> > +    GetType ();
> > +
> > +    bool
> > +    GetDescription (lldb::SBStream &description,
> > +                    lldb::DescriptionLevel description_level);
> > +
> > +    %pythoncode %{
> > +        __swig_getmethods__["name"] = GetName
> > +        if _newclass: name = property(GetName, None, doc='''A read only property that returns the name for this enum member as a string.''')
> > +
> > +        __swig_getmethods__["type"] = GetType
> > +        if _newclass: type = property(GetType, None, doc='''A read only property that returns an lldb object that represents the type (lldb.SBType) for this enum member.''')
> > +
> > +        __swig_getmethods__["signed"] = GetValueAsSigned
> > +        if _newclass: signed = property(GetValueAsSigned, None, doc='''A read only property that returns the value of this enum member as a signed integer.''')
> > +
> > +        __swig_getmethods__["unsigned"] = GetValueAsUnsigned
> > +        if _newclass: unsigned = property(GetValueAsUnsigned, None, doc='''A read only property that returns the value of this enum member as a unsigned integer.''')
> > +    %}
> > +
> > +protected:
> > +    friend class SBType;
> > +    friend class SBTypeEnumMemberList;
> > +
> > +    void
> > +    reset (lldb_private::TypeEnumMemberImpl *);
> > +
> > +    lldb_private::TypeEnumMemberImpl &
> > +    ref ();
> > +
> > +    const lldb_private::TypeEnumMemberImpl &
> > +    ref () const;
> > +
> > +    lldb::TypeEnumMemberImplSP m_opaque_sp;
> > +
> > +    SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &);
> > +};
> > +
> > +%feature(
> > +    "docstring",
> > +    "Represents a list of SBTypeEnumMembers."
> > +) SBTypeEnumMemberList;
> > +
> > +class SBTypeEnumMemberList
> > +{
> > +public:
> > +    SBTypeEnumMemberList();
> > +
> > +    SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs);
> > +
> > +    ~SBTypeEnumMemberList();
> > +
> > +    bool
> > +    IsValid();
> > +
> > +    void
> > +    Append (SBTypeEnumMember entry);
> > +
> > +    SBTypeEnumMember
> > +    GetTypeEnumMemberAtIndex (uint32_t index);
> > +
> > +    uint32_t
> > +    GetSize();
> > +
> > +
> > +private:
> > +    std::unique_ptr<lldb_private::TypeEnumMemberListImpl> m_opaque_ap;
> > +};
> > +
> > +} // namespace lldb
> > diff --git a/scripts/Python/python-extensions.swig b/scripts/Python/python-extensions.swig
> > index c4bc8b9..752dffb 100644
> > --- a/scripts/Python/python-extensions.swig
> > +++ b/scripts/Python/python-extensions.swig
> > @@ -608,6 +608,20 @@
> >                      return PyString_FromString("");
> >          }
> >  }
> > +%extend lldb::SBTypeEnumMember {
> > +        PyObject *lldb::SBTypeEnumMember::__str__ (){
> > +                lldb::SBStream description;
> > +                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
> > +                const char *desc = description.GetData();
> > +                size_t desc_len = description.GetSize();
> > +                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
> > +                    --desc_len;
> > +                if (desc_len > 0)
> > +                    return PyString_FromStringAndSize (desc, desc_len);
> > +                else
> > +                    return PyString_FromString("");
> > +        }
> > +}
> >  %extend lldb::SBTypeNameSpecifier {
> >          PyObject *lldb::SBTypeNameSpecifier::__str__ (){
> >                  lldb::SBStream description;
> > diff --git a/scripts/lldb.swig b/scripts/lldb.swig
> > index 6be699f..3d74996 100644
> > --- a/scripts/lldb.swig
> > +++ b/scripts/lldb.swig
> > @@ -91,6 +91,7 @@ import os
> >  #include "lldb/API/SBThread.h"
> >  #include "lldb/API/SBType.h"
> >  #include "lldb/API/SBTypeCategory.h"
> > +#include "lldb/API/SBTypeEnumMember.h"
> >  #include "lldb/API/SBTypeFilter.h"
> >  #include "lldb/API/SBTypeFormat.h"
> >  #include "lldb/API/SBTypeNameSpecifier.h"
> > @@ -155,6 +156,7 @@ import os
> >  %include "./Python/interface/SBThread.i"
> >  %include "./Python/interface/SBType.i"
> >  %include "./Python/interface/SBTypeCategory.i"
> > +%include "./Python/interface/SBTypeEnumMember.i"
> >  %include "./Python/interface/SBTypeFilter.i"
> >  %include "./Python/interface/SBTypeFormat.i"
> >  %include "./Python/interface/SBTypeNameSpecifier.i"
> > diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
> > index ef70ad5..a5b26fe 100644
> > --- a/source/API/CMakeLists.txt
> > +++ b/source/API/CMakeLists.txt
> > @@ -40,6 +40,7 @@ add_lldb_library(lldbAPI
> >    SBThread.cpp
> >    SBType.cpp
> >    SBTypeCategory.cpp
> > +  SBTypeEnumMember.cpp
> >    SBTypeFilter.cpp
> >    SBTypeFormat.cpp
> >    SBTypeNameSpecifier.cpp
> > diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
> > index 9e25477..d9ee7eb 100644
> > --- a/source/API/SBType.cpp
> > +++ b/source/API/SBType.cpp
> > @@ -9,6 +9,7 @@
> >
> >  #include "lldb/API/SBDefines.h"
> >  #include "lldb/API/SBType.h"
> > +#include "lldb/API/SBTypeEnumMember.h"
> >  #include "lldb/API/SBStream.h"
> >  #include "lldb/Core/ConstString.h"
> >  #include "lldb/Core/Log.h"
> > @@ -17,6 +18,8 @@
> >  #include "lldb/Symbol/ClangASTType.h"
> >  #include "lldb/Symbol/Type.h"
> >
> > +#include "clang/AST/Decl.h"
> > +
> >  using namespace lldb;
> >  using namespace lldb_private;
> >  using namespace clang;
> > @@ -352,6 +355,27 @@ SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
> >      return sb_type_member;
> >  }
> >
> > +SBTypeEnumMemberList
> > +SBType::GetEnumMembers ()
> > +{
> > +    SBTypeEnumMemberList sb_enum_member_list;
> > +    if (IsValid())
> > +    {
> > +        const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType().GetAsEnumDecl();
> > +        if (enum_decl)
> > +        {
> > +            clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
> > +            for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
> > +            {
> > +                SBTypeEnumMember enum_member;
> > +                enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetASTContext(), enum_decl->getIntegerType())));
> > +                sb_enum_member_list.Append(enum_member);
> > +            }
> > +        }
> > +    }
> > +    return sb_enum_member_list;
> > +}
> > +
> >  SBTypeMember
> >  SBType::GetFieldAtIndex (uint32_t idx)
> >  {
> > diff --git a/source/API/SBTypeEnumMember.cpp b/source/API/SBTypeEnumMember.cpp
> > new file mode 100644
> > index 0000000..47c57dd
> > --- /dev/null
> > +++ b/source/API/SBTypeEnumMember.cpp
> > @@ -0,0 +1,192 @@
> > +//===-- SBTypeEnumMember.cpp ---------------------------------- -*- C++ -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +#include "lldb/API/SBDefines.h"
> > +#include "lldb/API/SBType.h"
> > +#include "lldb/API/SBTypeEnumMember.h"
> > +#include "lldb/API/SBStream.h"
> > +#include "lldb/Core/Stream.h"
> > +#include "lldb/Symbol/ClangASTType.h"
> > +#include "lldb/Symbol/Type.h"
> > +
> > +using namespace lldb;
> > +using namespace lldb_private;
> > +using namespace clang;
> > +
> > +SBTypeEnumMember::SBTypeEnumMember() :
> > +    m_opaque_sp()
> > +{
> > +}
> > +
> > +SBTypeEnumMember::~SBTypeEnumMember()
> > +{
> > +}
> > +SBTypeEnumMember::SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &enum_member_sp) :
> > +    m_opaque_sp(enum_member_sp)
> > +{
> > +}
> > +
> > +SBTypeEnumMember::SBTypeEnumMember (const SBTypeEnumMember& rhs) :
> > +    m_opaque_sp()
> > +{
> > +    if (this != &rhs)
> > +    {
> > +        if (rhs.IsValid())
> > +            m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref()));
> > +    }
> > +}
> > +
> > +SBTypeEnumMember&
> > +SBTypeEnumMember::operator = (const SBTypeEnumMember& rhs)
> > +{
> > +    if (this != &rhs)
> > +    {
> > +        if (rhs.IsValid())
> > +            m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref()));
> > +    }
> > +    return *this;
> > +}
> > +
> > +bool
> > +SBTypeEnumMember::IsValid() const
> > +{
> > +    return m_opaque_sp.get();
> > +}
> > +
> > +const char *
> > +SBTypeEnumMember::GetName ()
> > +{
> > +    if (m_opaque_sp.get())
> > +        return m_opaque_sp->GetName().GetCString();
> > +    return NULL;
> > +}
> > +
> > +int64_t
> > +SBTypeEnumMember::GetValueAsSigned()
> > +{
> > +    if (m_opaque_sp.get())
> > +        return m_opaque_sp->GetValueAsSigned();
> > +    return 0;
> > +}
> > +
> > +uint64_t
> > +SBTypeEnumMember::GetValueAsUnsigned()
> > +{
> > +    if (m_opaque_sp.get())
> > +        return m_opaque_sp->GetValueAsUnsigned();
> > +    return 0;
> > +}
> > +
> > +SBType
> > +SBTypeEnumMember::GetType ()
> > +{
> > +    SBType sb_type;
> > +    if (m_opaque_sp.get())
> > +    {
> > +        sb_type.SetSP(m_opaque_sp->GetIntegerType());
> > +    }
> > +    return sb_type;
> > +
> > +}
> > +
> > +void
> > +SBTypeEnumMember::reset(TypeEnumMemberImpl *type_member_impl)
> > +{
> > +    m_opaque_sp.reset(type_member_impl);
> > +}
> > +
> > +TypeEnumMemberImpl &
> > +SBTypeEnumMember::ref ()
> > +{
> > +    if (m_opaque_sp.get() == NULL)
> > +        m_opaque_sp.reset (new TypeEnumMemberImpl());
> > +    return *m_opaque_sp.get();
> > +}
> > +
> > +const TypeEnumMemberImpl &
> > +SBTypeEnumMember::ref () const
> > +{
> > +    return *m_opaque_sp.get();
> > +}
> > +
> > +
> > +SBTypeEnumMemberList::SBTypeEnumMemberList() :
> > +    m_opaque_ap(new TypeEnumMemberListImpl())
> > +{
> > +}
> > +
> > +SBTypeEnumMemberList::SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs) :
> > +    m_opaque_ap(new TypeEnumMemberListImpl())
> > +{
> > +    for (uint32_t i = 0, rhs_size = const_cast<SBTypeEnumMemberList&>(rhs).GetSize(); i < rhs_size; i++)
> > +        Append(const_cast<SBTypeEnumMemberList&>(rhs).GetTypeEnumMemberAtIndex(i));
> > +}
> > +
> > +bool
> > +SBTypeEnumMemberList::IsValid ()
> > +{
> > +    return (m_opaque_ap.get() != NULL);
> > +}
> > +
> > +SBTypeEnumMemberList&
> > +SBTypeEnumMemberList::operator = (const SBTypeEnumMemberList& rhs)
> > +{
> > +    if (this != &rhs)
> > +    {
> > +        m_opaque_ap.reset (new TypeEnumMemberListImpl());
> > +        for (uint32_t i = 0, rhs_size = const_cast<SBTypeEnumMemberList&>(rhs).GetSize(); i < rhs_size; i++)
> > +            Append(const_cast<SBTypeEnumMemberList&>(rhs).GetTypeEnumMemberAtIndex(i));
> > +    }
> > +    return *this;
> > +}
> > +
> > +void
> > +SBTypeEnumMemberList::Append (SBTypeEnumMember enum_member)
> > +{
> > +    if (enum_member.IsValid())
> > +        m_opaque_ap->Append (enum_member.m_opaque_sp);
> > +}
> > +
> > +SBTypeEnumMember
> > +SBTypeEnumMemberList::GetTypeEnumMemberAtIndex(uint32_t index)
> > +{
> > +    if (m_opaque_ap.get())
> > +        return SBTypeEnumMember(m_opaque_ap->GetTypeEnumMemberAtIndex(index));
> > +    return SBTypeEnumMember();
> > +}
> > +
> > +uint32_t
> > +SBTypeEnumMemberList::GetSize()
> > +{
> > +    return m_opaque_ap->GetSize();
> > +}
> > +
> > +SBTypeEnumMemberList::~SBTypeEnumMemberList()
> > +{
> > +}
> > +
> > +bool
> > +SBTypeEnumMember::GetDescription (lldb::SBStream &description,
> > +                                  lldb::DescriptionLevel description_level)
> > +{
> > +    Stream &strm = description.ref();
> > +
> > +    if (m_opaque_sp.get())
> > +    {
> > +        if( m_opaque_sp->GetIntegerType()->GetDescription(strm, description_level) )
> > +        {
> > +            strm.Printf(" %s", m_opaque_sp->GetName().GetCString());
> > +        }
> > +    }
> > +    else
> > +    {
> > +        strm.PutCString ("No value");
> > +    }
> > +    return true;
> > +}
> > diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp
> > index da445d8..ee55f18 100644
> > --- a/source/Symbol/ClangASTType.cpp
> > +++ b/source/Symbol/ClangASTType.cpp
> > @@ -4307,6 +4307,15 @@ check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
> >          return false;
> >  }
> >
> > +clang::EnumDecl *
> > +ClangASTType::GetAsEnumDecl () const
> > +{
> > +    const EnumType *enum_type = dyn_cast<EnumType>(GetCanonicalQualType());
> > +    if (enum_type)
> > +        return enum_type->getDecl();
> > +    return NULL;
> > +}
> > +
> >  clang::RecordDecl *
> >  ClangASTType::GetAsRecordDecl () const
> >  {
> > diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
> > index 0af2359..20dc583 100644
> > --- a/source/Symbol/Type.cpp
> > +++ b/source/Symbol/Type.cpp
> > @@ -30,6 +30,8 @@
> >
> >  #include "llvm/ADT/StringRef.h"
> >
> > +#include "clang/AST/Decl.h"
> > +
> >  using namespace lldb;
> >  using namespace lldb_private;
> >
> > @@ -988,3 +990,12 @@ TypeImpl::GetName ()
> >          return m_clang_ast_type.GetConstTypeName();
> >      return ConstString();
> >  }
> > +
> > +TypeEnumMemberImpl::TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl,
> > +                                        const lldb_private::ClangASTType& integer_type) :
> > +    m_value(enum_member_decl->getInitVal()),
> > +    m_integer_type(new TypeImpl(integer_type))
> > +{
> > +    m_name = ConstString(enum_member_decl->getNameAsString().c_str());
> > +    m_valid = true;
> > +}
> > diff --git a/test/python_api/type/TestTypeList.py b/test/python_api/type/TestTypeList.py
> > index a06259d..36b60f5 100644
> > --- a/test/python_api/type/TestTypeList.py
> > +++ b/test/python_api/type/TestTypeList.py
> > @@ -70,6 +70,11 @@ class TypeAndTypeListTestCase(TestBase):
> >          for type in type_list:
> >              self.assertTrue(type)
> >              self.DebugSBType(type)
> > +            for field in type.fields:
> > +                if field.name == "type":
> > +                    for enum_member in field.type.enum_members:
> > +                        self.assertTrue(enum_member)
> > +                        self.DebugSBType(enum_member.type)
> >
> >          # Pass an empty string.  LLDB should not crash. :-)
> >          fuzz_types = target.FindTypes(None)
> > diff --git a/test/python_api/type/main.cpp b/test/python_api/type/main.cpp
> > index db0e249..67b57ac 100644
> > --- a/test/python_api/type/main.cpp
> > +++ b/test/python_api/type/main.cpp
> > @@ -12,9 +12,14 @@ class Task {
> >  public:
> >      int id;
> >      Task *next;
> > +    enum {
> > +        TASK_TYPE_1,
> > +        TASK_TYPE_2
> > +    } type;
> >      Task(int i, Task *n):
> >          id(i),
> > -        next(n)
> > +        next(n),
> > +        type(TASK_TYPE_1)
> >      {}
> >  };
> >
> > --
> > 1.7.10.4
> >
> >
> 
> 




More information about the lldb-dev mailing list