summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp89
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h9
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp2
3 files changed, 93 insertions, 7 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 5d5c3083018..69954f41a34 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1556,6 +1556,7 @@ SymbolFileDWARF::ParseChildMembers
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
+ BitfieldMap &bitfield_map,
DelayedPropertyList& delayed_properties,
AccessType& default_accessibility,
bool &is_a_class,
@@ -1759,7 +1760,84 @@ SymbolFileDWARF::ParseChildMembers
accessibility = default_accessibility;
member_accessibilities.push_back(accessibility);
- field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
+ // Code to detect unnamed bitifields
+ if (bit_size > 0 && member_byte_offset != UINT32_MAX)
+ {
+ // Objective C has invalid DW_AT_bit_offset values so we can't use them to detect
+ // unnamed bitfields. Once clang is fixed we will enable unnamed bitfields
+ // in ObjC classes (<rdar://problem/12636970>)
+
+ if (!(class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus))
+ {
+ // We have a bitfield, we need to watch out for
+ // unnamed bitfields that we need to insert if
+ // there is a gap in the bytes as many compilers
+ // doesn't emit DWARF DW_TAG_member tags for
+ // unnammed bitfields.
+ BitfieldMap::iterator bit_pos = bitfield_map.find(member_byte_offset);
+ uint32_t unnamed_bit_size = 0;
+ uint32_t unnamed_bit_offset = 0;
+ if (bit_pos == bitfield_map.end())
+ {
+ // First bitfield in an integral type.
+
+ // We might need to insert a leading unnamed bitfield
+ if (bit_offset < byte_size * 8)
+ {
+ unnamed_bit_size = byte_size * 8 - (bit_size + bit_offset);
+ unnamed_bit_offset = byte_size * 8 - unnamed_bit_size;
+ }
+
+ // Now put the current bitfield info into the map
+ bitfield_map[member_byte_offset].bit_size = bit_size;
+ bitfield_map[member_byte_offset].bit_offset = bit_offset;
+ }
+ else
+ {
+ // Subsequent bitfield in an integral type.
+
+ // We have a bitfield that isn't the first for this
+ // integral type, check to make sure there aren't any
+ // gaps.
+ assert (bit_pos->second.bit_size > 0);
+ if (bit_offset < bit_pos->second.bit_offset)
+ {
+ unnamed_bit_size = bit_pos->second.bit_offset - (bit_size + bit_offset);
+ unnamed_bit_offset = bit_pos->second.bit_offset - unnamed_bit_size;
+ }
+
+ // Now put the current bitfield info into the map
+ bit_pos->second.bit_size = bit_size;
+ bit_pos->second.bit_offset = bit_offset;
+ }
+
+ if (unnamed_bit_size > 0)
+ {
+ //printf ("0x%8.8x: Unnamed bitfield added bit_size = 0x%x, bit_offset = 0x%x\n", die->GetOffset(), unnamed_bit_size, unnamed_bit_offset);
+ clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
+ NULL,
+ member_type->GetClangLayoutType(),
+ accessibility,
+ unnamed_bit_size);
+ uint64_t total_bit_offset = 0;
+
+ total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+ {
+ total_bit_offset += byte_size * 8;
+ total_bit_offset -= (unnamed_bit_offset + unnamed_bit_size);
+ }
+ else
+ {
+ total_bit_offset += unnamed_bit_size;
+ }
+
+ layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, total_bit_offset));
+ }
+ }
+ }
+ field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
name,
member_type->GetClangLayoutType(),
accessibility,
@@ -1798,13 +1876,11 @@ SymbolFileDWARF::ParseChildMembers
// AT_bit_size indicates the size of the field in bits.
/////////////////////////////////////////////////////////////
- ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
-
uint64_t total_bit_offset = 0;
total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
- if (object_endian == eByteOrderLittle)
+ if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
{
total_bit_offset += byte_size * 8;
total_bit_offset -= (bit_offset + bit_size);
@@ -2167,8 +2243,8 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
DWARFDIECollection member_function_dies;
DelayedPropertyList delayed_properties;
-
- ParseChildMembers (sc,
+ BitfieldMap bitfield_map;
+ ParseChildMembers (sc,
dwarf_cu,
die,
clang_type,
@@ -2176,6 +2252,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
base_classes,
member_accessibilities,
member_function_dies,
+ bitfield_map,
delayed_properties,
default_accessibility,
is_a_class,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 5b8fbd90c37..69dad29d4fb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -59,6 +59,14 @@ class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
+struct BitfieldInfo
+{
+ uint32_t bit_size;
+ uint32_t bit_offset;
+};
+
+typedef std::map<int64_t, BitfieldInfo> BitfieldMap;
+
class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID
{
public:
@@ -345,6 +353,7 @@ protected:
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
+ BitfieldMap &bitfield_map,
DelayedPropertyList& delayed_properties,
lldb::AccessType &default_accessibility,
bool &is_a_class,
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 76ec6bc14d0..524b6f6a60b 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -2366,7 +2366,7 @@ ClangASTContext::AddObjCClassIVar
class_interface_decl,
SourceLocation(),
SourceLocation(),
- &identifier_table->get(name), // Identifier
+ name ? &identifier_table->get(name) : NULL, // Identifier
QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
NULL, // TypeSourceInfo *
ConvertAccessTypeToObjCIvarAccessControl (access),
OpenPOWER on IntegriCloud