[Lldb-commits] [lldb] aa933d8 - [lldb][NFC] Early-exit in DWARFASTParserClang::ParseSingleMember

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 13 04:21:44 PDT 2020


Author: Raphael Isemann
Date: 2020-07-13T13:21:12+02:00
New Revision: aa933d82f867ab4d33eafc5ee2666dbbc61d293d

URL: https://github.com/llvm/llvm-project/commit/aa933d82f867ab4d33eafc5ee2666dbbc61d293d
DIFF: https://github.com/llvm/llvm-project/commit/aa933d82f867ab4d33eafc5ee2666dbbc61d293d.diff

LOG: [lldb][NFC] Early-exit in DWARFASTParserClang::ParseSingleMember

This patch just early-exits after the 'if (num_attributes > 0)' check.

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 929001671af7..2d1db66e7fd9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2360,393 +2360,394 @@ void DWARFASTParserClang::ParseSingleMember(
 
   DWARFAttributes attributes;
   const size_t num_attributes = die.GetAttributes(attributes);
-  if (num_attributes > 0) {
-    const char *name = nullptr;
-    const char *prop_name = nullptr;
-    const char *prop_getter_name = nullptr;
-    const char *prop_setter_name = nullptr;
-    uint32_t prop_attributes = 0;
-
-    bool is_artificial = false;
-    DWARFFormValue encoding_form;
-    AccessType accessibility = eAccessNone;
-    uint32_t member_byte_offset =
-        (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
-    llvm::Optional<uint64_t> byte_size;
-    int64_t bit_offset = 0;
-    uint64_t data_bit_offset = UINT64_MAX;
-    size_t bit_size = 0;
-    bool is_external =
-        false; // On DW_TAG_members, this means the member is static
-    uint32_t i;
-    for (i = 0; i < num_attributes && !is_artificial; ++i) {
-      const dw_attr_t attr = attributes.AttributeAtIndex(i);
-      DWARFFormValue form_value;
-      if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-        // DW_AT_data_member_location indicates the byte offset of the
-        // word from the base address of the structure.
-        //
-        // DW_AT_bit_offset indicates how many bits into the word
-        // (according to the host endianness) the low-order bit of the
-        // field starts.  AT_bit_offset can be negative.
-        //
-        // DW_AT_bit_size indicates the size of the field in bits.
-        switch (attr) {
-        case DW_AT_name:
-          name = form_value.AsCString();
-          break;
-        case DW_AT_type:
-          encoding_form = form_value;
-          break;
-        case DW_AT_bit_offset:
-          bit_offset = form_value.Signed();
-          break;
-        case DW_AT_bit_size:
-          bit_size = form_value.Unsigned();
-          break;
-        case DW_AT_byte_size:
-          byte_size = form_value.Unsigned();
-          break;
-        case DW_AT_data_bit_offset:
-          data_bit_offset = form_value.Unsigned();
-          break;
-        case DW_AT_data_member_location:
-          if (form_value.BlockData()) {
-            Value initialValue(0);
-            Value memberOffset(0);
-            const DWARFDataExtractor &debug_info_data = die.GetData();
-            uint32_t block_length = form_value.Unsigned();
-            uint32_t block_offset =
-                form_value.BlockData() - debug_info_data.GetDataStart();
-            if (DWARFExpression::Evaluate(
-                    nullptr, // ExecutionContext *
-                    nullptr, // RegisterContext *
-                    module_sp,
-                    DataExtractor(debug_info_data, block_offset, block_length),
-                    die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
-                    memberOffset, nullptr)) {
-              member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
-            }
-          } else {
-            // With DWARF 3 and later, if the value is an integer constant,
-            // this form value is the offset in bytes from the beginning of
-            // the containing entity.
-            member_byte_offset = form_value.Unsigned();
+  if (num_attributes == 0)
+    return;
+
+  const char *name = nullptr;
+  const char *prop_name = nullptr;
+  const char *prop_getter_name = nullptr;
+  const char *prop_setter_name = nullptr;
+  uint32_t prop_attributes = 0;
+
+  bool is_artificial = false;
+  DWARFFormValue encoding_form;
+  AccessType accessibility = eAccessNone;
+  uint32_t member_byte_offset =
+      (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
+  llvm::Optional<uint64_t> byte_size;
+  int64_t bit_offset = 0;
+  uint64_t data_bit_offset = UINT64_MAX;
+  size_t bit_size = 0;
+  bool is_external =
+      false; // On DW_TAG_members, this means the member is static
+  uint32_t i;
+  for (i = 0; i < num_attributes && !is_artificial; ++i) {
+    const dw_attr_t attr = attributes.AttributeAtIndex(i);
+    DWARFFormValue form_value;
+    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+      // DW_AT_data_member_location indicates the byte offset of the
+      // word from the base address of the structure.
+      //
+      // DW_AT_bit_offset indicates how many bits into the word
+      // (according to the host endianness) the low-order bit of the
+      // field starts.  AT_bit_offset can be negative.
+      //
+      // DW_AT_bit_size indicates the size of the field in bits.
+      switch (attr) {
+      case DW_AT_name:
+        name = form_value.AsCString();
+        break;
+      case DW_AT_type:
+        encoding_form = form_value;
+        break;
+      case DW_AT_bit_offset:
+        bit_offset = form_value.Signed();
+        break;
+      case DW_AT_bit_size:
+        bit_size = form_value.Unsigned();
+        break;
+      case DW_AT_byte_size:
+        byte_size = form_value.Unsigned();
+        break;
+      case DW_AT_data_bit_offset:
+        data_bit_offset = form_value.Unsigned();
+        break;
+      case DW_AT_data_member_location:
+        if (form_value.BlockData()) {
+          Value initialValue(0);
+          Value memberOffset(0);
+          const DWARFDataExtractor &debug_info_data = die.GetData();
+          uint32_t block_length = form_value.Unsigned();
+          uint32_t block_offset =
+              form_value.BlockData() - debug_info_data.GetDataStart();
+          if (DWARFExpression::Evaluate(
+                  nullptr, // ExecutionContext *
+                  nullptr, // RegisterContext *
+                  module_sp,
+                  DataExtractor(debug_info_data, block_offset, block_length),
+                  die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+                  memberOffset, nullptr)) {
+            member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
           }
-          break;
+        } else {
+          // With DWARF 3 and later, if the value is an integer constant,
+          // this form value is the offset in bytes from the beginning of
+          // the containing entity.
+          member_byte_offset = form_value.Unsigned();
+        }
+        break;
 
-        case DW_AT_accessibility:
-          accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
-          break;
-        case DW_AT_artificial:
-          is_artificial = form_value.Boolean();
-          break;
-        case DW_AT_APPLE_property_name:
-          prop_name = form_value.AsCString();
-          break;
-        case DW_AT_APPLE_property_getter:
-          prop_getter_name = form_value.AsCString();
-          break;
-        case DW_AT_APPLE_property_setter:
-          prop_setter_name = form_value.AsCString();
-          break;
-        case DW_AT_APPLE_property_attribute:
-          prop_attributes = form_value.Unsigned();
-          break;
-        case DW_AT_external:
-          is_external = form_value.Boolean();
-          break;
+      case DW_AT_accessibility:
+        accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+        break;
+      case DW_AT_artificial:
+        is_artificial = form_value.Boolean();
+        break;
+      case DW_AT_APPLE_property_name:
+        prop_name = form_value.AsCString();
+        break;
+      case DW_AT_APPLE_property_getter:
+        prop_getter_name = form_value.AsCString();
+        break;
+      case DW_AT_APPLE_property_setter:
+        prop_setter_name = form_value.AsCString();
+        break;
+      case DW_AT_APPLE_property_attribute:
+        prop_attributes = form_value.Unsigned();
+        break;
+      case DW_AT_external:
+        is_external = form_value.Boolean();
+        break;
 
-        default:
-        case DW_AT_declaration:
-        case DW_AT_description:
-        case DW_AT_mutable:
-        case DW_AT_visibility:
-        case DW_AT_sibling:
-          break;
-        }
+      default:
+      case DW_AT_declaration:
+      case DW_AT_description:
+      case DW_AT_mutable:
+      case DW_AT_visibility:
+      case DW_AT_sibling:
+        break;
       }
     }
+  }
 
-    if (prop_name) {
-      ConstString fixed_setter;
+  if (prop_name) {
+    ConstString fixed_setter;
 
-      // Check if the property getter/setter were provided as full names.
-      // We want basenames, so we extract them.
+    // Check if the property getter/setter were provided as full names.
+    // We want basenames, so we extract them.
 
-      if (prop_getter_name && prop_getter_name[0] == '-') {
-        ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
-        prop_getter_name = prop_getter_method.GetSelector().GetCString();
-      }
+    if (prop_getter_name && prop_getter_name[0] == '-') {
+      ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
+      prop_getter_name = prop_getter_method.GetSelector().GetCString();
+    }
 
-      if (prop_setter_name && prop_setter_name[0] == '-') {
-        ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
-        prop_setter_name = prop_setter_method.GetSelector().GetCString();
-      }
+    if (prop_setter_name && prop_setter_name[0] == '-') {
+      ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
+      prop_setter_name = prop_setter_method.GetSelector().GetCString();
+    }
 
-      // If the names haven't been provided, they need to be filled in.
+    // If the names haven't been provided, they need to be filled in.
 
-      if (!prop_getter_name) {
-        prop_getter_name = prop_name;
-      }
-      if (!prop_setter_name && prop_name[0] &&
-          !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
-        StreamString ss;
+    if (!prop_getter_name) {
+      prop_getter_name = prop_name;
+    }
+    if (!prop_setter_name && prop_name[0] &&
+        !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
+      StreamString ss;
 
-        ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
+      ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
 
-        fixed_setter.SetString(ss.GetString());
-        prop_setter_name = fixed_setter.GetCString();
-      }
+      fixed_setter.SetString(ss.GetString());
+      prop_setter_name = fixed_setter.GetCString();
     }
+  }
 
-    // Clang has a DWARF generation bug where sometimes it represents
-    // fields that are references with bad byte size and bit size/offset
-    // information such as:
-    //
-    //  DW_AT_byte_size( 0x00 )
-    //  DW_AT_bit_size( 0x40 )
-    //  DW_AT_bit_offset( 0xffffffffffffffc0 )
-    //
-    // So check the bit offset to make sure it is sane, and if the values
-    // are not sane, remove them. If we don't do this then we will end up
-    // with a crash if we try to use this type in an expression when clang
-    // becomes unhappy with its recycled debug info.
+  // Clang has a DWARF generation bug where sometimes it represents
+  // fields that are references with bad byte size and bit size/offset
+  // information such as:
+  //
+  //  DW_AT_byte_size( 0x00 )
+  //  DW_AT_bit_size( 0x40 )
+  //  DW_AT_bit_offset( 0xffffffffffffffc0 )
+  //
+  // So check the bit offset to make sure it is sane, and if the values
+  // are not sane, remove them. If we don't do this then we will end up
+  // with a crash if we try to use this type in an expression when clang
+  // becomes unhappy with its recycled debug info.
 
-    if (byte_size.getValueOr(0) == 0 && bit_offset < 0) {
-      bit_size = 0;
-      bit_offset = 0;
-    }
+  if (byte_size.getValueOr(0) == 0 && bit_offset < 0) {
+    bit_size = 0;
+    bit_offset = 0;
+  }
 
-    const bool class_is_objc_object_or_interface =
-        TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type);
+  const bool class_is_objc_object_or_interface =
+      TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type);
 
-    // FIXME: Make Clang ignore Objective-C accessibility for expressions
-    if (class_is_objc_object_or_interface)
-      accessibility = eAccessNone;
+  // FIXME: Make Clang ignore Objective-C accessibility for expressions
+  if (class_is_objc_object_or_interface)
+    accessibility = eAccessNone;
 
-    // Handle static members
-    if (is_external && member_byte_offset == UINT32_MAX) {
-      Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
+  // Handle static members
+  if (is_external && member_byte_offset == UINT32_MAX) {
+    Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
 
-      if (var_type) {
-        if (accessibility == eAccessNone)
-          accessibility = eAccessPublic;
-        TypeSystemClang::AddVariableToRecordType(
-            class_clang_type, name, var_type->GetLayoutCompilerType(),
-            accessibility);
-      }
-      return;
+    if (var_type) {
+      if (accessibility == eAccessNone)
+        accessibility = eAccessPublic;
+      TypeSystemClang::AddVariableToRecordType(
+          class_clang_type, name, var_type->GetLayoutCompilerType(),
+          accessibility);
     }
+    return;
+  }
 
-    if (!is_artificial) {
-      Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
-
-      clang::FieldDecl *field_decl = nullptr;
-      const uint64_t character_width = 8;
-      const uint64_t word_width = 32;
-      if (tag == DW_TAG_member) {
-        if (member_type) {
-          CompilerType member_clang_type = member_type->GetLayoutCompilerType();
+  if (!is_artificial) {
+    Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
 
-          if (accessibility == eAccessNone)
-            accessibility = default_accessibility;
-          member_accessibilities.push_back(accessibility);
+    clang::FieldDecl *field_decl = nullptr;
+    const uint64_t character_width = 8;
+    const uint64_t word_width = 32;
+    if (tag == DW_TAG_member) {
+      if (member_type) {
+        CompilerType member_clang_type = member_type->GetLayoutCompilerType();
 
-          uint64_t field_bit_offset =
-              (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+        if (accessibility == eAccessNone)
+          accessibility = default_accessibility;
+        member_accessibilities.push_back(accessibility);
 
-          if (bit_size > 0) {
-            FieldInfo this_field_info;
-            this_field_info.bit_offset = field_bit_offset;
-            this_field_info.bit_size = bit_size;
+        uint64_t field_bit_offset =
+            (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
 
-            if (data_bit_offset != UINT64_MAX) {
-              this_field_info.bit_offset = data_bit_offset;
-            } else {
-              if (!byte_size)
-                byte_size = member_type->GetByteSize();
+        if (bit_size > 0) {
+          FieldInfo this_field_info;
+          this_field_info.bit_offset = field_bit_offset;
+          this_field_info.bit_size = bit_size;
 
-              ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
-              if (objfile->GetByteOrder() == eByteOrderLittle) {
-                this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
-                this_field_info.bit_offset -= (bit_offset + bit_size);
-              } else {
-                this_field_info.bit_offset += bit_offset;
-              }
-            }
+          if (data_bit_offset != UINT64_MAX) {
+            this_field_info.bit_offset = data_bit_offset;
+          } else {
+            if (!byte_size)
+              byte_size = member_type->GetByteSize();
 
-            if ((this_field_info.bit_offset >= parent_bit_size) ||
-                (last_field_info.IsBitfield() &&
-                 !last_field_info.NextBitfieldOffsetIsValid(
-                     this_field_info.bit_offset))) {
-              ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
-              objfile->GetModule()->ReportWarning(
-                  "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
-                  "bit offset (0x%8.8" PRIx64
-                  ") member will be ignored. Please file a bug against the "
-                  "compiler and include the preprocessed output for %s\n",
-                  die.GetID(), DW_TAG_value_to_name(tag), name,
-                  this_field_info.bit_offset, GetUnitName(parent_die).c_str());
-              return;
+            ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+            if (objfile->GetByteOrder() == eByteOrderLittle) {
+              this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
+              this_field_info.bit_offset -= (bit_offset + bit_size);
+            } else {
+              this_field_info.bit_offset += bit_offset;
             }
+          }
 
-            // Update the field bit offset we will report for layout
-            field_bit_offset = this_field_info.bit_offset;
-
-            // Objective-C has invalid DW_AT_bit_offset values in older
-            // versions of clang, so we have to be careful and only insert
-            // unnamed bitfields if we have a new enough clang.
-            bool detect_unnamed_bitfields = true;
+          if ((this_field_info.bit_offset >= parent_bit_size) ||
+              (last_field_info.IsBitfield() &&
+               !last_field_info.NextBitfieldOffsetIsValid(
+                   this_field_info.bit_offset))) {
+            ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+            objfile->GetModule()->ReportWarning(
+                "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
+                "bit offset (0x%8.8" PRIx64
+                ") member will be ignored. Please file a bug against the "
+                "compiler and include the preprocessed output for %s\n",
+                die.GetID(), DW_TAG_value_to_name(tag), name,
+                this_field_info.bit_offset, GetUnitName(parent_die).c_str());
+            return;
+          }
 
-            if (class_is_objc_object_or_interface)
-              detect_unnamed_bitfields =
-                  die.GetCU()->Supports_unnamed_objc_bitfields();
+          // Update the field bit offset we will report for layout
+          field_bit_offset = this_field_info.bit_offset;
 
-            if (detect_unnamed_bitfields) {
-              clang::Optional<FieldInfo> unnamed_field_info;
-              uint64_t last_field_end = 0;
+          // Objective-C has invalid DW_AT_bit_offset values in older
+          // versions of clang, so we have to be careful and only insert
+          // unnamed bitfields if we have a new enough clang.
+          bool detect_unnamed_bitfields = true;
 
-              last_field_end =
-                  last_field_info.bit_offset + last_field_info.bit_size;
+          if (class_is_objc_object_or_interface)
+            detect_unnamed_bitfields =
+                die.GetCU()->Supports_unnamed_objc_bitfields();
 
-              if (!last_field_info.IsBitfield()) {
-                // The last field was not a bit-field...
-                // but if it did take up the entire word then we need to extend
-                // last_field_end so the bit-field does not step into the last
-                // fields padding.
-                if (last_field_end != 0 && ((last_field_end % word_width) != 0))
-                  last_field_end += word_width - (last_field_end % word_width);
-              }
+          if (detect_unnamed_bitfields) {
+            clang::Optional<FieldInfo> unnamed_field_info;
+            uint64_t last_field_end = 0;
 
-              // If we have a gap between the last_field_end and the current
-              // field we have an unnamed bit-field.
-              // If we have a base class, we assume there is no unnamed
-              // bit-field if this is the first field since the gap can be
-              // attributed to the members from the base class. This assumption
-              // is not correct if the first field of the derived class is
-              // indeed an unnamed bit-field. We currently do not have the
-              // machinary to track the offset of the last field of classes we
-              // have seen before, so we are not handling this case.
-              if (this_field_info.bit_offset != last_field_end &&
-                  this_field_info.bit_offset > last_field_end &&
-                  !(last_field_info.bit_offset == 0 &&
-                    last_field_info.bit_size == 0 &&
-                    layout_info.base_offsets.size() != 0)) {
-                unnamed_field_info = FieldInfo{};
-                unnamed_field_info->bit_size =
-                    this_field_info.bit_offset - last_field_end;
-                unnamed_field_info->bit_offset = last_field_end;
-              }
+            last_field_end =
+                last_field_info.bit_offset + last_field_info.bit_size;
 
-              if (unnamed_field_info) {
-                clang::FieldDecl *unnamed_bitfield_decl =
-                    TypeSystemClang::AddFieldToRecordType(
-                        class_clang_type, llvm::StringRef(),
-                        m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
-                                                                  word_width),
-                        accessibility, unnamed_field_info->bit_size);
+            if (!last_field_info.IsBitfield()) {
+              // The last field was not a bit-field...
+              // but if it did take up the entire word then we need to extend
+              // last_field_end so the bit-field does not step into the last
+              // fields padding.
+              if (last_field_end != 0 && ((last_field_end % word_width) != 0))
+                last_field_end += word_width - (last_field_end % word_width);
+            }
 
-                layout_info.field_offsets.insert(std::make_pair(
-                    unnamed_bitfield_decl, unnamed_field_info->bit_offset));
-              }
+            // If we have a gap between the last_field_end and the current
+            // field we have an unnamed bit-field.
+            // If we have a base class, we assume there is no unnamed
+            // bit-field if this is the first field since the gap can be
+            // attributed to the members from the base class. This assumption
+            // is not correct if the first field of the derived class is
+            // indeed an unnamed bit-field. We currently do not have the
+            // machinary to track the offset of the last field of classes we
+            // have seen before, so we are not handling this case.
+            if (this_field_info.bit_offset != last_field_end &&
+                this_field_info.bit_offset > last_field_end &&
+                !(last_field_info.bit_offset == 0 &&
+                  last_field_info.bit_size == 0 &&
+                  layout_info.base_offsets.size() != 0)) {
+              unnamed_field_info = FieldInfo{};
+              unnamed_field_info->bit_size =
+                  this_field_info.bit_offset - last_field_end;
+              unnamed_field_info->bit_offset = last_field_end;
             }
 
-            last_field_info = this_field_info;
-            last_field_info.SetIsBitfield(true);
-          } else {
-            last_field_info.bit_offset = field_bit_offset;
+            if (unnamed_field_info) {
+              clang::FieldDecl *unnamed_bitfield_decl =
+                  TypeSystemClang::AddFieldToRecordType(
+                      class_clang_type, llvm::StringRef(),
+                      m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
+                                                                word_width),
+                      accessibility, unnamed_field_info->bit_size);
 
-            if (llvm::Optional<uint64_t> clang_type_size =
-                    member_clang_type.GetByteSize(nullptr)) {
-              last_field_info.bit_size = *clang_type_size * character_width;
+              layout_info.field_offsets.insert(std::make_pair(
+                  unnamed_bitfield_decl, unnamed_field_info->bit_offset));
             }
+          }
 
-            last_field_info.SetIsBitfield(false);
+          last_field_info = this_field_info;
+          last_field_info.SetIsBitfield(true);
+        } else {
+          last_field_info.bit_offset = field_bit_offset;
+
+          if (llvm::Optional<uint64_t> clang_type_size =
+                  member_clang_type.GetByteSize(nullptr)) {
+            last_field_info.bit_size = *clang_type_size * character_width;
           }
 
-          if (!member_clang_type.IsCompleteType())
-            member_clang_type.GetCompleteType();
-
-          {
-            // Older versions of clang emit array[0] and array[1] in the
-            // same way (<rdar://problem/12566646>). If the current field
-            // is at the end of the structure, then there is definitely no
-            // room for extra elements and we override the type to
-            // array[0].
-
-            CompilerType member_array_element_type;
-            uint64_t member_array_size;
-            bool member_array_is_incomplete;
-
-            if (member_clang_type.IsArrayType(&member_array_element_type,
-                                              &member_array_size,
-                                              &member_array_is_incomplete) &&
-                !member_array_is_incomplete) {
-              uint64_t parent_byte_size =
-                  parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
-                                                         UINT64_MAX);
-
-              if (member_byte_offset >= parent_byte_size) {
-                if (member_array_size != 1 &&
-                    (member_array_size != 0 ||
-                     member_byte_offset > parent_byte_size)) {
-                  module_sp->ReportError(
-                      "0x%8.8" PRIx64
-                      ": DW_TAG_member '%s' refers to type 0x%8.8x"
-                      " which extends beyond the bounds of 0x%8.8" PRIx64,
-                      die.GetID(), name, encoding_form.Reference().GetOffset(),
-                      parent_die.GetID());
-                }
+          last_field_info.SetIsBitfield(false);
+        }
 
-                member_clang_type =
-                    m_ast.CreateArrayType(member_array_element_type, 0, false);
+        if (!member_clang_type.IsCompleteType())
+          member_clang_type.GetCompleteType();
+
+        {
+          // Older versions of clang emit array[0] and array[1] in the
+          // same way (<rdar://problem/12566646>). If the current field
+          // is at the end of the structure, then there is definitely no
+          // room for extra elements and we override the type to
+          // array[0].
+
+          CompilerType member_array_element_type;
+          uint64_t member_array_size;
+          bool member_array_is_incomplete;
+
+          if (member_clang_type.IsArrayType(&member_array_element_type,
+                                            &member_array_size,
+                                            &member_array_is_incomplete) &&
+              !member_array_is_incomplete) {
+            uint64_t parent_byte_size =
+                parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
+                                                       UINT64_MAX);
+
+            if (member_byte_offset >= parent_byte_size) {
+              if (member_array_size != 1 &&
+                  (member_array_size != 0 ||
+                   member_byte_offset > parent_byte_size)) {
+                module_sp->ReportError(
+                    "0x%8.8" PRIx64
+                    ": DW_TAG_member '%s' refers to type 0x%8.8x"
+                    " which extends beyond the bounds of 0x%8.8" PRIx64,
+                    die.GetID(), name, encoding_form.Reference().GetOffset(),
+                    parent_die.GetID());
               }
+
+              member_clang_type =
+                  m_ast.CreateArrayType(member_array_element_type, 0, false);
             }
           }
+        }
 
-          CompleteType(member_clang_type);
+        CompleteType(member_clang_type);
 
-          field_decl = TypeSystemClang::AddFieldToRecordType(
-              class_clang_type, name, member_clang_type, accessibility,
-              bit_size);
+        field_decl = TypeSystemClang::AddFieldToRecordType(
+            class_clang_type, name, member_clang_type, accessibility,
+            bit_size);
 
-          m_ast.SetMetadataAsUserID(field_decl, die.GetID());
+        m_ast.SetMetadataAsUserID(field_decl, die.GetID());
 
-          layout_info.field_offsets.insert(
-              std::make_pair(field_decl, field_bit_offset));
-        } else {
-          if (name)
-            module_sp->ReportError(
-                "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
-                " which was unable to be parsed",
-                die.GetID(), name, encoding_form.Reference().GetOffset());
-          else
-            module_sp->ReportError(
-                "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
-                " which was unable to be parsed",
-                die.GetID(), encoding_form.Reference().GetOffset());
-        }
+        layout_info.field_offsets.insert(
+            std::make_pair(field_decl, field_bit_offset));
+      } else {
+        if (name)
+          module_sp->ReportError(
+              "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
+              " which was unable to be parsed",
+              die.GetID(), name, encoding_form.Reference().GetOffset());
+        else
+          module_sp->ReportError(
+              "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
+              " which was unable to be parsed",
+              die.GetID(), encoding_form.Reference().GetOffset());
       }
+    }
 
-      if (prop_name != nullptr && member_type) {
-        clang::ObjCIvarDecl *ivar_decl = nullptr;
+    if (prop_name != nullptr && member_type) {
+      clang::ObjCIvarDecl *ivar_decl = nullptr;
 
-        if (field_decl) {
-          ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
-          assert(ivar_decl != nullptr);
-        }
+      if (field_decl) {
+        ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
+        assert(ivar_decl != nullptr);
+      }
 
-        ClangASTMetadata metadata;
-        metadata.SetUserID(die.GetID());
-        delayed_properties.push_back(DelayedAddObjCClassProperty(
-            class_clang_type, prop_name, member_type->GetLayoutCompilerType(),
-            ivar_decl, prop_setter_name, prop_getter_name, prop_attributes,
-            &metadata));
+      ClangASTMetadata metadata;
+      metadata.SetUserID(die.GetID());
+      delayed_properties.push_back(DelayedAddObjCClassProperty(
+          class_clang_type, prop_name, member_type->GetLayoutCompilerType(),
+          ivar_decl, prop_setter_name, prop_getter_name, prop_attributes,
+          &metadata));
 
-        if (ivar_decl)
-          m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
-      }
+      if (ivar_decl)
+        m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
     }
   }
 }


        


More information about the lldb-commits mailing list