[Lldb-commits] [lldb] r161091 - in /lldb/trunk: include/lldb/API/SBType.h include/lldb/Symbol/ClangASTContext.h include/lldb/Symbol/Type.h scripts/Python/interface/SBType.i source/API/SBType.cpp source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp source/Symbol/ClangASTContext.cpp
Greg Clayton
gclayton at apple.com
Tue Jul 31 16:39:10 PDT 2012
Author: gclayton
Date: Tue Jul 31 18:39:10 2012
New Revision: 161091
URL: http://llvm.org/viewvc/llvm-project?rev=161091&view=rev
Log:
<rdar://problem/11275622>
Added new API to lldb::SBTypeMember for bitfields:
bool SBTypeMember::IsBitfield();
uint32_t SBTypeMember::GetBitfieldSizeInBits();
Also added new properties for easy access. Now SBTypeMember objects in python have a "fields" property for all type fields, "bases" for all direct bases, "vbases" for all virtual base classes and "members" for a combo of all three organized by bit offset. They all return a python list() of SBTypeMember objects. Usage:
(lldb) script
>>> t = lldb.target.FindFirstType("my_type")
>>> for field in t.fields:
... print field
>>> for vbase in t.vbases:
... print vbase
>>> for base in t.bases:
... print base
>>> for member in t.members:
... print member
Also added new "is_bitfield" property to the SBTypeMember objects that will return the result of SBTypeMember::IsBitfield(), and "bitfield_bit_size" which will return the result of SBTypeMember::GetBitfieldSizeInBits();
I also fixed "SBTypeMember::GetOffsetInBytes()" to return the correct byte offset.
Modified:
lldb/trunk/include/lldb/API/SBType.h
lldb/trunk/include/lldb/Symbol/ClangASTContext.h
lldb/trunk/include/lldb/Symbol/Type.h
lldb/trunk/scripts/Python/interface/SBType.i
lldb/trunk/source/API/SBType.cpp
lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
lldb/trunk/source/Symbol/ClangASTContext.cpp
Modified: lldb/trunk/include/lldb/API/SBType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBType.h (original)
+++ lldb/trunk/include/lldb/API/SBType.h Tue Jul 31 18:39:10 2012
@@ -44,6 +44,12 @@
GetOffsetInBits();
bool
+ IsBitfield();
+
+ uint32_t
+ GetBitfieldSizeInBits();
+
+ bool
GetDescription (lldb::SBStream &description,
lldb::DescriptionLevel description_level);
Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Jul 31 18:39:10 2012
@@ -603,7 +603,9 @@
lldb::clang_type_t clang_type,
uint32_t idx,
std::string& name,
- uint32_t *bit_offset_ptr);
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr);
static uint32_t
GetNumPointeeChildren (lldb::clang_type_t clang_type);
Modified: lldb/trunk/include/lldb/Symbol/Type.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Type.h (original)
+++ lldb/trunk/include/lldb/Symbol/Type.h Tue Jul 31 18:39:10 2012
@@ -477,16 +477,23 @@
TypeMemberImpl () :
m_type_impl_sp (),
m_bit_offset (0),
- m_name ()
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
+
{
}
TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
uint64_t bit_offset,
- const ConstString &name) :
+ const ConstString &name,
+ uint32_t bitfield_bit_size = 0,
+ bool is_bitfield = false) :
m_type_impl_sp (type_impl_sp),
m_bit_offset (bit_offset),
- m_name (name)
+ m_name (name),
+ m_bitfield_bit_size (bitfield_bit_size),
+ m_is_bitfield (is_bitfield)
{
}
@@ -494,7 +501,9 @@
uint64_t bit_offset):
m_type_impl_sp (type_impl_sp),
m_bit_offset (bit_offset),
- m_name ()
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
{
}
@@ -516,10 +525,36 @@
return m_bit_offset;
}
+ uint32_t
+ GetBitfieldBitSize () const
+ {
+ return m_bitfield_bit_size;
+ }
+
+ void
+ SetBitfieldBitSize (uint32_t bitfield_bit_size)
+ {
+ m_bitfield_bit_size = bitfield_bit_size;
+ }
+
+ bool
+ GetIsBitfield () const
+ {
+ return m_is_bitfield;
+ }
+
+ void
+ SetIsBitfield (bool is_bitfield)
+ {
+ m_is_bitfield = is_bitfield;
+ }
+
protected:
lldb::TypeImplSP m_type_impl_sp;
uint64_t m_bit_offset;
ConstString m_name;
+ uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
+ bool m_is_bitfield;
};
Modified: lldb/trunk/scripts/Python/interface/SBType.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBType.i?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBType.i (original)
+++ lldb/trunk/scripts/Python/interface/SBType.i Tue Jul 31 18:39:10 2012
@@ -37,6 +37,12 @@
uint64_t
GetOffsetInBits();
+ bool
+ IsBitfield();
+
+ uint32_t
+ GetBitfieldSizeInBits();
+
%pythoncode %{
__swig_getmethods__["name"] = GetName
if _newclass: name = property(GetName, None, doc='''A read only property that returns the name for this member as a string.''')
@@ -49,7 +55,14 @@
__swig_getmethods__["bit_offset"] = GetOffsetInBits
if _newclass: bit_offset = property(GetOffsetInBits, None, doc='''A read only property that returns offset in bits for this member as an integer.''')
- %}
+
+ __swig_getmethods__["is_bitfield"] = IsBitfield
+ if _newclass: is_bitfield = property(IsBitfield, None, doc='''A read only property that returns true if this member is a bitfield.''')
+
+ __swig_getmethods__["bitfield_bit_size"] = GetBitfieldSizeInBits
+ if _newclass: bitfield_bit_size = property(GetBitfieldSizeInBits, None, doc='''A read only property that returns the bitfield size in bits for this member as an integer, or zero if this member is not a bitfield.''')
+
+ %}
protected:
std::auto_ptr<lldb_private::TypeMemberImpl> m_opaque_ap;
@@ -245,6 +258,78 @@
__swig_getmethods__["is_complete"] = IsTypeComplete
if _newclass: is_complete = property(IsTypeComplete, None, doc='''A read only property that returns a boolean value that indicates if this type is a complete type (True) or a forward declaration (False).''')
+
+ def get_bases_array(self):
+ '''An accessor function that returns a list() that contains all direct base classes in a lldb.SBType object.'''
+ bases = []
+ for idx in range(self.GetNumberOfDirectBaseClasses()):
+ bases.append(self.GetDirectBaseClassAtIndex(idx))
+ return bases
+
+ def get_vbases_array(self):
+ '''An accessor function that returns a list() that contains all fields in a lldb.SBType object.'''
+ vbases = []
+ for idx in range(self.GetNumberOfVirtualBaseClasses()):
+ vbases.append(self.GetVirtualBaseClassAtIndex(idx))
+ return vbases
+
+ def get_fields_array(self):
+ '''An accessor function that returns a list() that contains all fields in a lldb.SBType object.'''
+ fields = []
+ for idx in range(self.GetNumberOfFields()):
+ fields.append(self.GetFieldAtIndex(idx))
+ return fields
+
+ def get_members_array(self):
+ '''An accessor function that returns a list() that contains all members (base classes and fields) in a lldb.SBType object in ascending bit offset order.'''
+ members = []
+ bases = self.get_bases_array()
+ fields = self.get_fields_array()
+ vbases = self.get_vbases_array()
+ for base in bases:
+ bit_offset = base.bit_offset
+ added = False
+ for idx, member in enumerate(members):
+ if member.bit_offset > bit_offset:
+ members.insert(idx, base)
+ added = True
+ break
+ if not added:
+ members.append(base)
+ for vbase in vbases:
+ bit_offset = vbase.bit_offset
+ added = False
+ for idx, member in enumerate(members):
+ if member.bit_offset > bit_offset:
+ members.insert(idx, vbase)
+ added = True
+ break
+ if not added:
+ members.append(vbase)
+ for field in fields:
+ bit_offset = field.bit_offset
+ added = False
+ for idx, member in enumerate(members):
+ if member.bit_offset > bit_offset:
+ members.insert(idx, field)
+ added = True
+ break
+ if not added:
+ members.append(field)
+ return members
+
+ __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.''')
+
+ __swig_getmethods__["vbases"] = get_vbases_array
+ if _newclass: vbases = property(get_vbases_array, None, doc='''A read only property that returns a list() of lldb.SBTypeMember objects that represent all of the virtual base classes for this type.''')
+
+ __swig_getmethods__["fields"] = get_fields_array
+ if _newclass: fields = property(get_fields_array, None, doc='''A read only property that returns a list() of lldb.SBTypeMember objects that represent all of the fields for this type.''')
+
+ __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.''')
+
%}
};
Modified: lldb/trunk/source/API/SBType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/source/API/SBType.cpp (original)
+++ lldb/trunk/source/API/SBType.cpp Tue Jul 31 18:39:10 2012
@@ -410,17 +410,19 @@
SBTypeMember sb_type_member;
if (IsValid())
{
- uint32_t bit_offset = 0;
+ uint64_t bit_offset = 0;
+ uint32_t bitfield_bit_size = 0;
+ bool is_bitfield = false;
clang::ASTContext* ast = m_opaque_sp->GetASTContext();
std::string name_sstr;
- clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset);
+ clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield);
if (clang_type)
{
ConstString name;
if (!name_sstr.empty())
name.SetCString(name_sstr.c_str());
TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
- sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name));
+ sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield));
}
}
return sb_type_member;
@@ -627,7 +629,7 @@
SBTypeMember::GetOffsetInBytes()
{
if (m_opaque_ap.get())
- return (m_opaque_ap->GetBitOffset() + 7) / 8u;
+ return m_opaque_ap->GetBitOffset() / 8u;
return 0;
}
@@ -640,21 +642,48 @@
}
bool
+SBTypeMember::IsBitfield()
+{
+ if (m_opaque_ap.get())
+ return m_opaque_ap->GetIsBitfield();
+ return false;
+}
+
+uint32_t
+SBTypeMember::GetBitfieldSizeInBits()
+{
+ if (m_opaque_ap.get())
+ return m_opaque_ap->GetBitfieldBitSize();
+ return 0;
+}
+
+
+bool
SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
{
Stream &strm = description.ref();
if (m_opaque_ap.get())
{
- const uint32_t byte_offset = (m_opaque_ap->GetBitOffset() + 7) / 8u;
+ const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
+ const uint32_t byte_offset = bit_offset / 8u;
+ const uint32_t byte_bit_offset = bit_offset % 8u;
const char *name = m_opaque_ap->GetName().GetCString();
- strm.Printf ("+%u: (", byte_offset);
+ if (byte_bit_offset)
+ strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
+ else
+ strm.Printf ("+%u: (", byte_offset);
TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
if (type_impl_sp)
type_impl_sp->GetDescription(strm, description_level);
strm.Printf (") %s", name);
+ if (m_opaque_ap->GetIsBitfield())
+ {
+ const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
+ strm.Printf (" : %u", bitfield_bit_size);
+ }
}
else
{
Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Tue Jul 31 18:39:10 2012
@@ -753,12 +753,12 @@
for (uint32_t idx = 0; idx < num_children; idx++)
{
std::string name;
- uint32_t field_bit_offset;
+ uint64_t field_bit_offset = 0;
bool is_signed;
bool is_complex;
uint32_t count;
- clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, ret_value_type, idx, name, &field_bit_offset);
+ clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, ret_value_type, idx, name, &field_bit_offset, NULL, NULL);
size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, field_clang_type);
// If there are any unaligned fields, this is stored in memory.
@@ -840,12 +840,14 @@
in_gpr = false;
else
{
- uint32_t next_field_bit_offset;
- clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
+ uint64_t next_field_bit_offset = 0;
+ clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
ret_value_type,
idx + 1,
name,
- &next_field_bit_offset);
+ &next_field_bit_offset,
+ NULL,
+ NULL);
if (ClangASTContext::IsIntegerType (next_field_clang_type, is_signed))
in_gpr = true;
else
@@ -864,12 +866,14 @@
in_gpr = false;
else
{
- uint32_t prev_field_bit_offset;
+ uint64_t prev_field_bit_offset = 0;
clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
ret_value_type,
idx - 1,
name,
- &prev_field_bit_offset);
+ &prev_field_bit_offset,
+ NULL,
+ NULL);
if (ClangASTContext::IsIntegerType (prev_field_clang_type, is_signed))
in_gpr = true;
else
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=161091&r1=161090&r2=161091&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Jul 31 18:39:10 2012
@@ -3499,7 +3499,9 @@
clang_type_t clang_type,
uint32_t idx,
std::string& name,
- uint32_t *bit_offset_ptr)
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr)
{
if (clang_type == NULL)
return 0;
@@ -3531,6 +3533,25 @@
*bit_offset_ptr = record_layout.getFieldOffset (field_idx);
}
+ const bool is_bitfield = field->isBitField();
+
+ if (bitfield_bit_size_ptr)
+ {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield && ast)
+ {
+ Expr *bitfield_bit_size_expr = field->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+ {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
return field->getType().getAsOpaquePtr();
}
}
@@ -3570,6 +3591,25 @@
*bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
}
+ const bool is_bitfield = ivar_pos->isBitField();
+
+ if (bitfield_bit_size_ptr)
+ {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield && ast)
+ {
+ Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+ {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
return ivar_qual_type.getAsOpaquePtr();
}
}
@@ -3585,14 +3625,18 @@
cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
idx,
name,
- bit_offset_ptr);
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
case clang::Type::Elaborated:
return ClangASTContext::GetFieldAtIndex (ast,
cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
idx,
name,
- bit_offset_ptr);
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
default:
break;
More information about the lldb-commits
mailing list