108 changes: 108 additions & 0 deletions lldb/scripts/Python/interface/SBTypeEnumMember.i
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions lldb/scripts/Python/python-extensions.swig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions lldb/scripts/lldb.swig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions lldb/source/API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ add_lldb_library(lldbAPI
SBThread.cpp
SBType.cpp
SBTypeCategory.cpp
SBTypeEnumMember.cpp
SBTypeFilter.cpp
SBTypeFormat.cpp
SBTypeNameSpecifier.cpp
Expand Down
24 changes: 24 additions & 0 deletions lldb/source/API/SBType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
192 changes: 192 additions & 0 deletions lldb/source/API/SBTypeEnumMember.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
9 changes: 9 additions & 0 deletions lldb/source/Symbol/ClangASTType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<clang::EnumType>(GetCanonicalQualType());
if (enum_type)
return enum_type->getDecl();
return NULL;
}

clang::RecordDecl *
ClangASTType::GetAsRecordDecl () const
{
Expand Down
11 changes: 11 additions & 0 deletions lldb/source/Symbol/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "llvm/ADT/StringRef.h"

#include "clang/AST/Decl.h"

using namespace lldb;
using namespace lldb_private;

Expand Down Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions lldb/test/python_api/type/TestTypeList.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ def type_and_typelist_api(self, exe_name):
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)
Expand Down
7 changes: 6 additions & 1 deletion lldb/test/python_api/type/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{}
};

Expand Down