From 732215f989c37638501c8064762bd93a36b6ec3c Mon Sep 17 00:00:00 2001 From: Todd Fiala Date: Mon, 2 Jun 2014 20:55:29 +0000 Subject: [PATCH] Add support for inspecting enum members. Change by Russell Harmon. Xcode project updates (and all errors therein) by Todd Fiala. llvm-svn: 210046 --- lldb/include/lldb/API/SBDefines.h | 2 + lldb/include/lldb/API/SBStream.h | 1 + lldb/include/lldb/API/SBType.h | 5 + lldb/include/lldb/API/SBTypeEnumMember.h | 98 ++++++++++++ lldb/include/lldb/Core/ClangForward.h | 1 + lldb/include/lldb/Symbol/ClangASTType.h | 3 + lldb/include/lldb/Symbol/Type.h | 102 +++++++++++- lldb/include/lldb/lldb-forward.h | 3 + lldb/lldb.xcodeproj/project.pbxproj | 8 + lldb/scripts/Python/interface/SBType.i | 14 ++ lldb/scripts/Python/interface/SBTypeEnumMember.i | 108 +++++++++++++ lldb/scripts/Python/python-extensions.swig | 14 ++ lldb/scripts/lldb.swig | 2 + lldb/source/API/CMakeLists.txt | 1 + lldb/source/API/SBType.cpp | 24 +++ lldb/source/API/SBTypeEnumMember.cpp | 192 +++++++++++++++++++++++ lldb/source/Symbol/ClangASTType.cpp | 9 ++ lldb/source/Symbol/Type.cpp | 11 ++ lldb/test/python_api/type/TestTypeList.py | 5 + lldb/test/python_api/type/main.cpp | 7 +- 20 files changed, 608 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/API/SBTypeEnumMember.h create mode 100644 lldb/scripts/Python/interface/SBTypeEnumMember.i create mode 100644 lldb/source/API/SBTypeEnumMember.cpp diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index 6171deb..15d8d1f 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -72,6 +72,8 @@ class LLDB_API SBTarget; class LLDB_API SBThread; class LLDB_API SBType; class LLDB_API SBTypeCategory; +class LLDB_API SBTypeEnumMember; +class LLDB_API SBTypeEnumMemberList; class LLDB_API SBTypeFilter; class LLDB_API SBTypeFormat; class LLDB_API SBTypeNameSpecifier; diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index 038adf6..f77b7b7 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/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/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index 40173af..363aa59e 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -143,6 +143,9 @@ public: lldb::SBTypeMember GetVirtualBaseClassAtIndex (uint32_t idx); + lldb::SBTypeEnumMemberList + GetEnumMembers(); + uint32_t GetNumberOfTemplateArguments (); @@ -202,6 +205,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/lldb/include/lldb/API/SBTypeEnumMember.h b/lldb/include/lldb/API/SBTypeEnumMember.h new file mode 100644 index 0000000..75c9917 --- /dev/null +++ b/lldb/include/lldb/API/SBTypeEnumMember.h @@ -0,0 +1,98 @@ + +//===-- 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 m_opaque_ap; +}; + +} // namespace lldb + +#endif // LLDB_SBTypeEnumMember_h_ diff --git a/lldb/include/lldb/Core/ClangForward.h b/lldb/include/lldb/Core/ClangForward.h index 0b3f13a..ef7308d2 100644 --- a/lldb/include/lldb/Core/ClangForward.h +++ b/lldb/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/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index 7f136bd..c072903 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -647,6 +647,9 @@ public: AddressType address_type, StreamString &new_value); + clang::EnumDecl * + GetAsEnumDecl () const; + clang::RecordDecl * GetAsRecordDecl () const; diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index a103404..a315c1e 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -17,6 +17,8 @@ #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/Declaration.h" +#include "llvm/ADT/APSInt.h" + #include namespace lldb_private { @@ -785,7 +787,105 @@ private: TypePair m_type_pair; ConstString m_type_name; }; - + +class TypeEnumMemberImpl +{ +public: + TypeEnumMemberImpl () : + m_integer_type(), + m_name(""), + 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 m_content; +}; + } // namespace lldb_private #endif // liblldb_Type_h_ diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index f5539bc..9cd6adb 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -244,6 +244,8 @@ class TypeImpl; class TypeList; class TypeListImpl; class TypeMemberImpl; +class TypeEnumMemberImpl; +class TypeEnumMemberListImpl; class TypeNameSpecifierImpl; class TypePair; class UUID; @@ -382,6 +384,7 @@ namespace lldb { typedef std::weak_ptr TypeWP; typedef std::shared_ptr TypeCategoryImplSP; typedef std::shared_ptr TypeImplSP; + typedef std::shared_ptr TypeEnumMemberImplSP; typedef std::shared_ptr TypeFilterImplSP; typedef std::shared_ptr TypeFormatImplSP; typedef std::shared_ptr TypeNameSpecifierImplSP; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index be382e0..0663161 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -51,6 +51,8 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 23EFE389193D1ABC00E54E54 /* SBTypeEnumMember.h in Headers */ = {isa = PBXBuildFile; fileRef = 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 23EFE38B193D1AEC00E54E54 /* SBTypeEnumMember.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */; }; 260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; }; 260157C71885F52500F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; }; 260157C81885F53100F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; }; @@ -869,6 +871,8 @@ /* Begin PBXFileReference section */ 23EDE3371926AAD500F6A132 /* RegisterInfoInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterInfoInterface.h; path = Utility/RegisterInfoInterface.h; sourceTree = ""; }; + 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeEnumMember.h; path = include/lldb/API/SBTypeEnumMember.h; sourceTree = ""; }; + 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SBTypeEnumMember.cpp; path = source/API/SBTypeEnumMember.cpp; sourceTree = ""; }; 260157C41885F4FF00F875CF /* libpanel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpanel.dylib; path = /usr/lib/libpanel.dylib; sourceTree = ""; }; 260223E7115F06D500A601A2 /* SBCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBCommunication.h; path = include/lldb/API/SBCommunication.h; sourceTree = ""; }; 260223E8115F06E500A601A2 /* SBCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBCommunication.cpp; path = source/API/SBCommunication.cpp; sourceTree = ""; }; @@ -2087,6 +2091,8 @@ 08FB7794FE84155DC02AAC07 /* lldb */ = { isa = PBXGroup; children = ( + 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */, + 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */, 26F5C32810F3DF7D009D5894 /* Libraries */, 264E8576159BE51A00E9D7A2 /* Resources */, 08FB7795FE84155DC02AAC07 /* Source */, @@ -3994,6 +4000,7 @@ 26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */, 26D265BC136B4269002EEE45 /* lldb-public.h in Headers */, 4CE4F673162C971A00F75CB3 /* SBExpressionOptions.h in Headers */, + 23EFE389193D1ABC00E54E54 /* SBTypeEnumMember.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4422,6 +4429,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 23EFE38B193D1AEC00E54E54 /* SBTypeEnumMember.cpp in Sources */, 9461569A14E358A6003A195C /* SBTypeFilter.cpp in Sources */, 9461569B14E358A6003A195C /* SBTypeFormat.cpp in Sources */, 262F12B51835468600AEB384 /* SBPlatform.cpp in Sources */, diff --git a/lldb/scripts/Python/interface/SBType.i b/lldb/scripts/Python/interface/SBType.i index 8a0ad6e..6fb4801 100644 --- a/lldb/scripts/Python/interface/SBType.i +++ b/lldb/scripts/Python/interface/SBType.i @@ -213,6 +213,9 @@ public: lldb::SBTypeMember GetVirtualBaseClassAtIndex (uint32_t idx); + lldb::SBTypeEnumMemberList + GetEnumMembers(); + const char* GetName(); @@ -345,6 +348,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.''') @@ -357,6 +368,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/lldb/scripts/Python/interface/SBTypeEnumMember.i b/lldb/scripts/Python/interface/SBTypeEnumMember.i new file mode 100644 index 0000000..02d89f1 --- /dev/null +++ b/lldb/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 m_opaque_ap; +}; + +} // namespace lldb diff --git a/lldb/scripts/Python/python-extensions.swig b/lldb/scripts/Python/python-extensions.swig index 3dbcb88..9e9feb8 100644 --- a/lldb/scripts/Python/python-extensions.swig +++ b/lldb/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/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index 8633f15..1a230d1 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -93,6 +93,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" @@ -159,6 +160,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/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index a626f61..63adb68 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -42,6 +42,7 @@ add_lldb_library(lldbAPI SBThread.cpp SBType.cpp SBTypeCategory.cpp + SBTypeEnumMember.cpp SBTypeFilter.cpp SBTypeFormat.cpp SBTypeNameSpecifier.cpp diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index 1e04841b..064fb32 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/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; @@ -364,6 +367,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(true).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->GetClangASTContext(true), enum_decl->getIntegerType()))); + sb_enum_member_list.Append(enum_member); + } + } + } + return sb_enum_member_list; +} + SBTypeMember SBType::GetFieldAtIndex (uint32_t idx) { diff --git a/lldb/source/API/SBTypeEnumMember.cpp b/lldb/source/API/SBTypeEnumMember.cpp new file mode 100644 index 0000000..47c57dd --- /dev/null +++ b/lldb/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(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(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(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(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/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index b864844..b94da55 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -4452,6 +4452,15 @@ IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind) return true; } +clang::EnumDecl * +ClangASTType::GetAsEnumDecl () const +{ + const clang::EnumType *enum_type = llvm::dyn_cast(GetCanonicalQualType()); + if (enum_type) + return enum_type->getDecl(); + return NULL; +} + clang::RecordDecl * ClangASTType::GetAsRecordDecl () const { diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index e58cbc1..e79ff60 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/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; @@ -1166,3 +1168,12 @@ TypeImpl::GetDescription (lldb_private::Stream &strm, m_static_type.GetClangASTType().DumpTypeDescription(&strm); return true; } + +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/lldb/test/python_api/type/TestTypeList.py b/lldb/test/python_api/type/TestTypeList.py index 39f4a29..71d1f45 100644 --- a/lldb/test/python_api/type/TestTypeList.py +++ b/lldb/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/lldb/test/python_api/type/main.cpp b/lldb/test/python_api/type/main.cpp index db0e249..67b57ac 100644 --- a/lldb/test/python_api/type/main.cpp +++ b/lldb/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) {} }; -- 2.7.4