[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