| //===-- SBType.cpp ----------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <string.h> |
| |
| #include "lldb/API/SBType.h" |
| #include "lldb/API/SBStream.h" |
| #include "lldb/Core/ConstString.h" |
| #include "lldb/Core/Log.h" |
| #include "lldb/Symbol/ClangASTContext.h" |
| #include "lldb/Symbol/ClangASTType.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| |
| bool |
| SBType::IsPointerType (void *opaque_type) |
| { |
| LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); |
| |
| //if (log) |
| // log->Printf ("SBType::IsPointerType (%p)", opaque_type); |
| |
| bool ret_value = ClangASTContext::IsPointerType (opaque_type); |
| |
| if (log) |
| log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); |
| |
| return ret_value; |
| } |
| |
| |
| SBType::SBType (void *ast, void *clang_type) : |
| m_ast (ast), |
| m_type (clang_type) |
| { |
| } |
| |
| SBType::SBType (const SBType &rhs) : |
| m_ast (rhs.m_ast), |
| m_type (rhs.m_type) |
| { |
| } |
| |
| const SBType & |
| SBType::operator =(const SBType &rhs) |
| { |
| m_ast = rhs.m_ast; |
| m_type = rhs.m_type; |
| return *this; |
| } |
| |
| SBType::~SBType () |
| { |
| } |
| |
| bool |
| SBType::IsValid () |
| { |
| return m_ast != NULL && m_type != NULL; |
| } |
| |
| const char * |
| SBType::GetName () |
| { |
| if (IsValid ()) |
| return ClangASTType::GetConstTypeName (m_type).AsCString(NULL); |
| return NULL; |
| } |
| |
| uint64_t |
| SBType::GetByteSize() |
| { |
| if (IsValid ()) |
| return ClangASTType::GetClangTypeBitWidth (static_cast<clang::ASTContext *>(m_ast), m_type); |
| return NULL; |
| } |
| |
| Encoding |
| SBType::GetEncoding (uint32_t &count) |
| { |
| if (IsValid ()) |
| return ClangASTType::GetEncoding (m_type, count); |
| count = 0; |
| return eEncodingInvalid; |
| } |
| |
| uint64_t |
| SBType::GetNumberChildren (bool omit_empty_base_classes) |
| { |
| if (IsValid ()) |
| return ClangASTContext::GetNumChildren (static_cast<clang::ASTContext *>(m_ast), |
| m_type, |
| omit_empty_base_classes); |
| return 0; |
| } |
| |
| |
| bool |
| SBType::GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member) |
| { |
| void *child_clang_type = NULL; |
| std::string child_name; |
| uint32_t child_byte_size = 0; |
| int32_t child_byte_offset = 0; |
| uint32_t child_bitfield_bit_size = 0; |
| uint32_t child_bitfield_bit_offset = 0; |
| bool child_is_base_class = false; |
| bool child_is_deref_of_parent = false; |
| |
| if (IsValid ()) |
| { |
| |
| child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (NULL, |
| static_cast<clang::ASTContext *>(m_ast), |
| NULL, |
| m_type, |
| idx, |
| false, // transparent pointers |
| omit_empty_base_classes, |
| child_name, |
| child_byte_size, |
| child_byte_offset, |
| child_bitfield_bit_size, |
| child_bitfield_bit_offset, |
| child_is_base_class, |
| child_is_deref_of_parent); |
| |
| } |
| |
| if (child_clang_type) |
| { |
| member.m_ast = m_ast; |
| member.m_parent_type = m_type; |
| member.m_member_type = child_clang_type, |
| member.SetName (child_name.c_str()); |
| member.m_offset = child_byte_offset; |
| member.m_bit_size = child_bitfield_bit_size; |
| member.m_bit_offset = child_bitfield_bit_offset; |
| member.m_is_base_class = child_is_base_class; |
| member.m_is_deref_of_paremt = child_is_deref_of_parent; |
| } |
| else |
| { |
| member.Clear(); |
| } |
| |
| return child_clang_type != NULL; |
| } |
| |
| uint32_t |
| SBType::GetChildIndexForName (bool omit_empty_base_classes, const char *name) |
| { |
| return ClangASTContext::GetIndexOfChildWithName (static_cast<clang::ASTContext *>(m_ast), |
| m_type, |
| name, |
| omit_empty_base_classes); |
| } |
| |
| bool |
| SBType::IsAPointerType () |
| { |
| return ClangASTContext::IsPointerType (m_type); |
| } |
| |
| SBType |
| SBType::GetPointeeType () |
| { |
| void *pointee_type = NULL; |
| if (IsAPointerType ()) |
| { |
| pointee_type = ClangASTType::GetPointeeType (m_type); |
| } |
| return SBType (pointee_type ? m_ast : NULL, pointee_type); |
| } |
| |
| bool |
| SBType::GetDescription (SBStream &description) |
| { |
| const char *name = GetName(); |
| uint64_t byte_size = GetByteSize(); |
| uint64_t num_children = GetNumberChildren (true); |
| bool is_ptr = IsAPointerType (); |
| |
| description.Printf ("type_name: %s, size: %d bytes", (name != NULL ? name : "<unknown type name>"), byte_size); |
| if (is_ptr) |
| { |
| SBType pointee_type = GetPointeeType(); |
| const char *pointee_name = pointee_type.GetName(); |
| description.Printf (", (* %s)", (pointee_name != NULL ? pointee_name : "<unknown type name>")); |
| } |
| else if (num_children > 0) |
| { |
| description.Printf (", %d members:\n", num_children); |
| for (uint32_t i = 0; i < num_children; ++i) |
| { |
| SBTypeMember field; |
| GetChildAtIndex (true, i, field); |
| const char *field_name = field.GetName(); |
| SBType field_type = field.GetType(); |
| const char *field_type_name = field_type.GetName(); |
| |
| description.Printf (" %s (type: %s", (field_name != NULL ? field_name : "<unknown member name>"), |
| (field_type_name != NULL ? field_type_name : "<unknown type name>")); |
| |
| if (field.IsBitfield()) |
| { |
| size_t width = field.GetBitfieldWidth (); |
| description.Printf (" , %d bits", (int) width); |
| } |
| description.Printf (")\n"); |
| } |
| } |
| return true; |
| } |
| |
| SBTypeMember::SBTypeMember () : |
| m_ast (NULL), |
| m_parent_type (NULL), |
| m_member_type (NULL), |
| m_member_name (NULL), |
| m_offset (0), |
| m_bit_size (0), |
| m_bit_offset (0), |
| m_is_base_class (false) |
| |
| { |
| } |
| |
| SBTypeMember::SBTypeMember (const SBTypeMember &rhs) : |
| m_ast (rhs.m_ast), |
| m_parent_type (rhs.m_parent_type), |
| m_member_type (rhs.m_member_type), |
| m_member_name (rhs.m_member_name), |
| m_offset (rhs.m_offset), |
| m_bit_size (rhs.m_bit_size), |
| m_bit_offset (rhs.m_bit_offset), |
| m_is_base_class (rhs.m_is_base_class) |
| { |
| } |
| |
| const SBTypeMember& |
| SBTypeMember::operator =(const SBTypeMember &rhs) |
| { |
| if (this != &rhs) |
| { |
| m_ast = rhs.m_ast; |
| m_parent_type = rhs.m_parent_type; |
| m_member_type = rhs.m_member_type; |
| m_member_name = rhs.m_member_name; |
| m_offset = rhs.m_offset; |
| m_bit_size = rhs.m_bit_size; |
| m_bit_offset = rhs.m_bit_offset; |
| m_is_base_class = rhs.m_is_base_class; |
| } |
| return *this; |
| } |
| |
| SBTypeMember::~SBTypeMember () |
| { |
| SetName (NULL); |
| } |
| |
| void |
| SBTypeMember::SetName (const char *name) |
| { |
| if (m_member_name) |
| free (m_member_name); |
| if (name && name[0]) |
| m_member_name = ::strdup (name); |
| else |
| m_member_name = NULL; |
| } |
| |
| void |
| SBTypeMember::Clear() |
| { |
| m_ast = NULL; |
| m_parent_type = NULL; |
| m_member_type = NULL; |
| SetName (NULL); |
| m_offset = 0; |
| m_bit_size = 0; |
| m_bit_offset = 0; |
| m_is_base_class = false; |
| } |
| |
| bool |
| SBTypeMember::IsValid () |
| { |
| return m_member_type != NULL; |
| } |
| |
| bool |
| SBTypeMember::IsBitfield () |
| { |
| return m_bit_size != 0; |
| } |
| |
| size_t |
| SBTypeMember::GetBitfieldWidth () |
| { |
| return m_bit_size; |
| } |
| |
| size_t |
| SBTypeMember::GetBitfieldOffset () |
| { |
| return m_bit_offset; |
| } |
| |
| bool |
| SBTypeMember::IsBaseClass () |
| { |
| return m_is_base_class; |
| } |
| |
| size_t |
| SBTypeMember::GetOffset () |
| { |
| return m_offset; |
| } |
| |
| SBType |
| SBTypeMember::GetType() |
| { |
| return SBType (m_ast, m_member_type); |
| } |
| |
| SBType |
| SBTypeMember::GetParentType() |
| { |
| return SBType (m_ast, m_parent_type); |
| } |
| |
| |
| const char * |
| SBTypeMember::GetName () |
| { |
| return m_member_name; |
| } |
| |