[Lldb-commits] [lldb] r362075 - DWARFASTParserClang: Move attribute parsing into a single function

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu May 30 02:39:36 PDT 2019


Author: labath
Date: Thu May 30 02:39:36 2019
New Revision: 362075

URL: http://llvm.org/viewvc/llvm-project?rev=362075&view=rev
Log:
DWARFASTParserClang: Move attribute parsing into a single function

Summary:
The ParseTypeFromDWARF function consists of a huge switch on the kind of
type being parsed. Each case in this switch starts with parsing the
attributes of the current DIE. A lot of these attributes are specific to
one kind of a type, but a lot of them are common too, leading to code
duplication.

This patch reduces the duplication (and the size of ParseTypeFromDWARF)
by moving the attribute parsing to a separate function. It creates a
struct (ParsedTypeAttributes), which contains a parsed form of all
attributes which are useful for parsing any kind of a type. The parsing
code for a specific type kind can then access the fields which are
relevant for that specific case.

Reviewers: JDevlieghere, clayborg, aprantl

Subscribers: jdoerfert, lldb-commits

Differential Revision: https://reviews.llvm.org/D62477

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

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=362075&r1=362074&r2=362075&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Thu May 30 02:39:36 2019
@@ -228,13 +228,169 @@ static void CompleteExternalTagDeclType(
   }
 }
 
+namespace {
+/// Parsed form of all attributes that are relevant for type reconstruction.
+/// Some attributes are relevant for all kinds of types (declaration), while
+/// others are only meaningful to a specific type (is_virtual)
+struct ParsedTypeAttributes {
+  ParsedTypeAttributes(const DWARFDIE &die, CompileUnit &comp_unit);
+
+  AccessType accessibility = eAccessNone;
+  bool is_artificial = false;
+  bool is_complete_objc_class = false;
+  bool is_explicit = false;
+  bool is_forward_declaration = false;
+  bool is_inline = false;
+  bool is_scoped_enum = false;
+  bool is_vector = false;
+  bool is_virtual = false;
+  clang::StorageClass storage = clang::SC_None;
+  const char *mangled_name = nullptr;
+  ConstString name;
+  Declaration decl;
+  DWARFDIE object_pointer;
+  DWARFFormValue abstract_origin;
+  DWARFFormValue containing_type;
+  DWARFFormValue signature;
+  DWARFFormValue specification;
+  DWARFFormValue type;
+  LanguageType class_language = eLanguageTypeUnknown;
+  llvm::Optional<uint64_t> byte_size;
+  size_t calling_convention = llvm::dwarf::DW_CC_normal;
+  uint32_t bit_stride = 0;
+  uint32_t byte_stride = 0;
+  uint32_t encoding = 0;
+};
+} // namespace
+
+ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die,
+                                           CompileUnit &comp_unit) {
+  DWARFAttributes attributes;
+  size_t num_attributes = die.GetAttributes(attributes);
+  for (size_t i = 0; i < num_attributes; ++i) {
+    dw_attr_t attr = attributes.AttributeAtIndex(i);
+    DWARFFormValue form_value;
+    if (!attributes.ExtractFormValueAtIndex(i, form_value))
+      continue;
+    switch (attr) {
+    case DW_AT_abstract_origin:
+      abstract_origin = form_value;
+      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_bit_stride:
+      bit_stride = form_value.Unsigned();
+      break;
+
+    case DW_AT_byte_size:
+      byte_size = form_value.Unsigned();
+      break;
+
+    case DW_AT_byte_stride:
+      byte_stride = form_value.Unsigned();
+      break;
+
+    case DW_AT_calling_convention:
+      calling_convention = form_value.Unsigned();
+      break;
+
+    case DW_AT_containing_type:
+      containing_type = form_value;
+      break;
+
+    case DW_AT_decl_file:
+      decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(
+          form_value.Unsigned()));
+      break;
+    case DW_AT_decl_line:
+      decl.SetLine(form_value.Unsigned());
+      break;
+    case DW_AT_decl_column:
+      decl.SetColumn(form_value.Unsigned());
+      break;
+
+    case DW_AT_declaration:
+      is_forward_declaration = form_value.Boolean();
+      break;
+
+    case DW_AT_encoding:
+      encoding = form_value.Unsigned();
+      break;
+
+    case DW_AT_enum_class:
+      is_scoped_enum = form_value.Boolean();
+      break;
+
+    case DW_AT_explicit:
+      is_explicit = form_value.Boolean();
+      break;
+
+    case DW_AT_external:
+      if (form_value.Unsigned())
+        storage = clang::SC_Extern;
+      break;
+
+    case DW_AT_inline:
+      is_inline = form_value.Boolean();
+      break;
+
+    case DW_AT_linkage_name:
+    case DW_AT_MIPS_linkage_name:
+      mangled_name = form_value.AsCString();
+      break;
+
+    case DW_AT_name:
+      name.SetCString(form_value.AsCString());
+      break;
+
+    case DW_AT_object_pointer:
+      object_pointer = form_value.Reference();
+      break;
+
+    case DW_AT_signature:
+      signature = form_value;
+      break;
+
+    case DW_AT_specification:
+      specification = form_value;
+      break;
+
+    case DW_AT_type:
+      type = form_value;
+      break;
+
+    case DW_AT_virtuality:
+      is_virtual = form_value.Boolean();
+      break;
+
+    case DW_AT_APPLE_objc_complete_type:
+      is_complete_objc_class = form_value.Signed();
+      break;
+
+    case DW_AT_APPLE_runtime_class:
+      class_language = (LanguageType)form_value.Signed();
+      break;
+
+    case DW_AT_GNU_vector:
+      is_vector = form_value.Boolean();
+      break;
+    }
+  }
+}
+
 TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
                                                const DWARFDIE &die, Log *log,
                                                bool *type_is_new_ptr) {
   if (type_is_new_ptr)
     *type_is_new_ptr = false;
 
-  AccessType accessibility = eAccessNone;
   if (!die)
     return nullptr;
   SymbolFileDWARF *dwarf = die.GetDWARF();
@@ -260,8 +416,9 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   // Set a bit that lets us know that we are currently parsing this
   dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
 
-  if (DWARFDIE signature_die =
-          die.GetAttributeValueAsReferenceDIE(DW_AT_signature)) {
+  ParsedTypeAttributes attrs(die, *sc.comp_unit);
+
+  if (DWARFDIE signature_die = attrs.signature.Reference()) {
     if (TypeSP type_sp =
             ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
@@ -279,20 +436,11 @@ TypeSP DWARFASTParserClang::ParseTypeFro
 
   const dw_tag_t tag = die.Tag();
 
-  bool is_forward_declaration = false;
-  DWARFAttributes attributes;
-  const char *type_name_cstr = NULL;
-  const char *mangled_name_cstr = NULL;
-  ConstString type_name_const_str;
   Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
-  llvm::Optional<uint64_t> byte_size;
-  Declaration decl;
 
   Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
   CompilerType clang_type;
-  DWARFFormValue form_value;
 
-  dw_attr_t attr;
   TypeSP type_sp;
   LanguageType cu_language = die.GetLanguage();
   switch (tag) {
@@ -305,49 +453,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   case DW_TAG_restrict_type:
   case DW_TAG_volatile_type:
   case DW_TAG_unspecified_type: {
-    const size_t num_attributes = die.GetAttributes(attributes);
-    uint32_t encoding = 0;
-    DWARFFormValue encoding_uid;
-
-    if (num_attributes > 0) {
-      uint32_t i;
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_decl_file:
-            decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                form_value.Unsigned()));
-            break;
-          case DW_AT_decl_line:
-            decl.SetLine(form_value.Unsigned());
-            break;
-          case DW_AT_decl_column:
-            decl.SetColumn(form_value.Unsigned());
-            break;
-          case DW_AT_name:
-            type_name_cstr = form_value.AsCString();
-            if (type_name_cstr)
-              type_name_const_str.SetCString(type_name_cstr);
-            break;
-          case DW_AT_byte_size:
-            byte_size = form_value.Unsigned();
-            break;
-          case DW_AT_encoding:
-            encoding = form_value.Unsigned();
-            break;
-          case DW_AT_type:
-            encoding_uid = form_value;
-            break;
-          default:
-          case DW_AT_sibling:
-            break;
-          }
-        }
-      }
-    }
-
-    if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
+    if (tag == DW_TAG_typedef && attrs.type.IsValid()) {
       // Try to parse a typedef from the DWO file first as modules can
       // contain typedef'ed structures that have no names like:
       //
@@ -367,7 +473,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       // will have a hard time tracking down an unnammed structure type in
       // the module DWO file, so we make sure we don't get into this
       // situation by always resolving typedefs from the DWO file.
-      const DWARFDIE encoding_die = encoding_uid.Reference();
+      const DWARFDIE encoding_die = attrs.type.Reference();
 
       // First make sure that the die that this is typedef'ed to _is_ just
       // a declaration (DW_AT_declaration == 1), not a full definition
@@ -391,8 +497,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       break;
 
     case DW_TAG_unspecified_type:
-      if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
-          strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
+      if (attrs.name == "nullptr_t" || attrs.name == "decltype(nullptr)") {
         resolve_state = Type::eResolveStateFull;
         clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
         break;
@@ -404,7 +509,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     case DW_TAG_base_type:
       resolve_state = Type::eResolveStateFull;
       clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
-          type_name_cstr, encoding, byte_size.getValueOr(0) * 8);
+          attrs.name.GetCString(), attrs.encoding,
+          attrs.byte_size.getValueOr(0) * 8);
       break;
 
     case DW_TAG_pointer_type:
@@ -458,7 +564,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                   clang_type = m_ast.CreateBlockPointerType(
                       lldb_function_type_sp->GetForwardCompilerType());
                   encoding_data_type = Type::eEncodingIsUID;
-                  encoding_uid.Clear();
+                  attrs.type.Clear();
                   resolve_state = Type::eResolveStateFull;
                 }
               }
@@ -471,12 +577,12 @@ TypeSP DWARFASTParserClang::ParseTypeFro
 
       if (cu_language == eLanguageTypeObjC ||
           cu_language == eLanguageTypeObjC_plus_plus) {
-        if (type_name_cstr != nullptr) {
+        if (attrs.name) {
           static ConstString g_objc_type_name_id("id");
           static ConstString g_objc_type_name_Class("Class");
           static ConstString g_objc_type_name_selector("SEL");
 
-          if (type_name_const_str == g_objc_type_name_id) {
+          if (attrs.name == g_objc_type_name_id) {
             if (log)
               dwarf->GetObjectFile()->GetModule()->LogMessage(
                   log,
@@ -485,10 +591,10 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                   die.GetOffset(), die.GetTagAsCString(), die.GetName());
             clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
             encoding_data_type = Type::eEncodingIsUID;
-            encoding_uid.Clear();
+            attrs.type.Clear();
             resolve_state = Type::eResolveStateFull;
 
-          } else if (type_name_const_str == g_objc_type_name_Class) {
+          } else if (attrs.name == g_objc_type_name_Class) {
             if (log)
               dwarf->GetObjectFile()->GetModule()->LogMessage(
                   log,
@@ -497,9 +603,9 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                   die.GetOffset(), die.GetTagAsCString(), die.GetName());
             clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
             encoding_data_type = Type::eEncodingIsUID;
-            encoding_uid.Clear();
+            attrs.type.Clear();
             resolve_state = Type::eResolveStateFull;
-          } else if (type_name_const_str == g_objc_type_name_selector) {
+          } else if (attrs.name == g_objc_type_name_selector) {
             if (log)
               dwarf->GetObjectFile()->GetModule()->LogMessage(
                   log,
@@ -508,15 +614,15 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                   die.GetOffset(), die.GetTagAsCString(), die.GetName());
             clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
             encoding_data_type = Type::eEncodingIsUID;
-            encoding_uid.Clear();
+            attrs.type.Clear();
             resolve_state = Type::eResolveStateFull;
           }
         } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
-                   encoding_uid.IsValid()) {
+                   attrs.type.IsValid()) {
           // Clang sometimes erroneously emits id as objc_object*.  In that
           // case we fix up the type to "id".
 
-          const DWARFDIE encoding_die = encoding_uid.Reference();
+          const DWARFDIE encoding_die = attrs.type.Reference();
 
           if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
             if (const char *struct_name = encoding_die.GetName()) {
@@ -530,7 +636,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                       die.GetOffset(), die.GetTagAsCString(), die.GetName());
                 clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
                 encoding_data_type = Type::eEncodingIsUID;
-                encoding_uid.Clear();
+                attrs.type.Clear();
                 resolve_state = Type::eResolveStateFull;
               }
             }
@@ -540,8 +646,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     }
 
     type_sp = std::make_shared<Type>(
-        die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
-        dwarf->GetUID(DIERef(encoding_uid)), encoding_data_type, &decl,
+        die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
+        dwarf->GetUID(DIERef(attrs.type)), encoding_data_type, &attrs.decl,
         clang_type, resolve_state);
 
     dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
@@ -550,72 +656,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   case DW_TAG_structure_type:
   case DW_TAG_union_type:
   case DW_TAG_class_type: {
-    LanguageType class_language = eLanguageTypeUnknown;
-    bool is_complete_objc_class = false;
-    size_t calling_convention = llvm::dwarf::CallingConvention::DW_CC_normal;
-
-    const size_t num_attributes = die.GetAttributes(attributes);
-    if (num_attributes > 0) {
-      uint32_t i;
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_decl_file:
-            decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                form_value.Unsigned()));
-            break;
-
-          case DW_AT_decl_line:
-            decl.SetLine(form_value.Unsigned());
-            break;
-
-          case DW_AT_decl_column:
-            decl.SetColumn(form_value.Unsigned());
-            break;
-
-          case DW_AT_name:
-            type_name_cstr = form_value.AsCString();
-            type_name_const_str.SetCString(type_name_cstr);
-            break;
-
-          case DW_AT_byte_size:
-            byte_size = form_value.Unsigned();
-            break;
-
-          case DW_AT_accessibility:
-            accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
-            break;
-
-          case DW_AT_declaration:
-            is_forward_declaration = form_value.Boolean();
-            break;
-
-          case DW_AT_APPLE_runtime_class:
-            class_language = (LanguageType)form_value.Signed();
-            break;
-
-          case DW_AT_APPLE_objc_complete_type:
-            is_complete_objc_class = form_value.Signed();
-            break;
-          case DW_AT_calling_convention:
-            calling_convention = form_value.Unsigned();
-            break;
-
-          case DW_AT_allocated:
-          case DW_AT_associated:
-          case DW_AT_data_location:
-          case DW_AT_description:
-          case DW_AT_start_scope:
-          case DW_AT_visibility:
-          default:
-          case DW_AT_sibling:
-            break;
-          }
-        }
-      }
-    }
-
     // UniqueDWARFASTType is large, so don't create a local variables on
     // the stack, put it on the heap. This function is often called
     // recursively and clang isn't good and sharing the stack space for
@@ -623,10 +663,10 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
         new UniqueDWARFASTType());
 
-    ConstString unique_typename(type_name_const_str);
-    Declaration unique_decl(decl);
+    ConstString unique_typename(attrs.name);
+    Declaration unique_decl(attrs.decl);
 
-    if (type_name_const_str) {
+    if (attrs.name) {
       if (Language::LanguageIsCPlusPlus(cu_language)) {
         // For C++, we rely solely upon the one definition rule that says
         // only one thing can exist at a given decl context. We ignore the
@@ -638,7 +678,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       }
 
       if (dwarf->GetUniqueDWARFASTTypeMap().Find(
-              unique_typename, die, unique_decl, byte_size ? *byte_size : -1,
+              unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
               *unique_ast_entry_up)) {
         type_sp = unique_ast_entry_up->m_type_sp;
         if (type_sp) {
@@ -664,8 +704,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       default_accessibility = eAccessPrivate;
     }
 
-    if (byte_size && *byte_size == 0 && type_name_cstr && !die.HasChildren() &&
-        cu_language == eLanguageTypeObjC) {
+    if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+        !die.HasChildren() && cu_language == eLanguageTypeObjC) {
       // Work around an issue with clang at the moment where forward
       // declarations for objective C classes are emitted as:
       //  DW_TAG_structure_type [2]
@@ -676,20 +716,20 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       //
       // Note that there is no DW_AT_declaration and there are no children,
       // and the byte size is zero.
-      is_forward_declaration = true;
+      attrs.is_forward_declaration = true;
     }
 
-    if (class_language == eLanguageTypeObjC ||
-        class_language == eLanguageTypeObjC_plus_plus) {
-      if (!is_complete_objc_class &&
+    if (attrs.class_language == eLanguageTypeObjC ||
+        attrs.class_language == eLanguageTypeObjC_plus_plus) {
+      if (!attrs.is_complete_objc_class &&
           die.Supports_DW_AT_APPLE_objc_complete_type()) {
         // We have a valid eSymbolTypeObjCClass class symbol whose name
         // matches the current objective C class that we are trying to find
         // and this DIE isn't the complete definition (we checked
         // is_complete_objc_class above and know it is false), so the real
         // definition is in here somewhere
-        type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
-            die, type_name_const_str, true);
+        type_sp =
+            dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
 
         if (!type_sp) {
           SymbolFileDWARFDebugMap *debug_map_symfile =
@@ -698,7 +738,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
             // We weren't able to find a full declaration in this DWARF,
             // see if we have a declaration anywhere else...
             type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
-                die, type_name_const_str, true);
+                die, attrs.name, true);
           }
         }
 
@@ -709,7 +749,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
                 "incomplete objc type, complete type is 0x%8.8" PRIx64,
                 static_cast<void *>(this), die.GetOffset(),
-                DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+                DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+                type_sp->GetID());
           }
 
           // We found a real definition for this type elsewhere so lets use
@@ -721,7 +762,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       }
     }
 
-    if (is_forward_declaration) {
+    if (attrs.is_forward_declaration) {
       // We have a forward declaration to a type and we need to try and
       // find a full declaration. We look in the current type index just in
       // case we have a forward declaration followed by an actual
@@ -733,7 +774,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
             "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
             "forward declaration, trying to find complete type",
             static_cast<void *>(this), die.GetOffset(),
-            DW_TAG_value_to_name(tag), type_name_cstr);
+            DW_TAG_value_to_name(tag), attrs.name.GetCString());
       }
 
       // See if the type comes from a DWO module and if so, track down that
@@ -767,7 +808,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
               "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
               "forward declaration, complete type is 0x%8.8" PRIx64,
               static_cast<void *>(this), die.GetOffset(),
-              DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+              DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+              type_sp->GetID());
         }
 
         // We found a real definition for this type elsewhere so lets use
@@ -794,27 +836,27 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       // not an issue in the non-gmodules case because the debug info will
       // always contain a full definition of parent types in that case.
       CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
-                                  type_name_cstr);
+                                  attrs.name.GetCString());
 
-      if (accessibility == eAccessNone && decl_ctx) {
+      if (attrs.accessibility == eAccessNone && decl_ctx) {
         // Check the decl context that contains this class/struct/union. If
         // it is a class we must give it an accessibility.
         const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
         if (DeclKindIsCXXClass(containing_decl_kind))
-          accessibility = default_accessibility;
+          attrs.accessibility = default_accessibility;
       }
 
       ClangASTMetadata metadata;
       metadata.SetUserID(die.GetID());
       metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
 
-      if (type_name_cstr && strchr(type_name_cstr, '<')) {
+      if (attrs.name.GetStringRef().contains('<')) {
         ClangASTContext::TemplateParameterInfos template_param_infos;
         if (ParseTemplateParameterInfos(die, template_param_infos)) {
           clang::ClassTemplateDecl *class_template_decl =
-              m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
-                                           type_name_cstr, tag_decl_kind,
-                                           template_param_infos);
+              m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
+                                           attrs.name.GetCString(),
+                                           tag_decl_kind, template_param_infos);
           if (!class_template_decl) {
             if (log) {
               dwarf->GetObjectFile()->GetModule()->LogMessage(
@@ -822,7 +864,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                   "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
                   "clang::ClassTemplateDecl failed to return a decl.",
                   static_cast<void *>(this), die.GetOffset(),
-                  DW_TAG_value_to_name(tag), type_name_cstr);
+                  DW_TAG_value_to_name(tag), attrs.name.GetCString());
             }
             return TypeSP();
           }
@@ -842,9 +884,9 @@ TypeSP DWARFASTParserClang::ParseTypeFro
 
       if (!clang_type_was_created) {
         clang_type_was_created = true;
-        clang_type =
-            m_ast.CreateRecordType(decl_ctx, accessibility, type_name_cstr,
-                                   tag_decl_kind, class_language, &metadata);
+        clang_type = m_ast.CreateRecordType(
+            decl_ctx, attrs.accessibility, attrs.name.GetCString(),
+            tag_decl_kind, attrs.class_language, &metadata);
       }
     }
 
@@ -852,12 +894,12 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     // parameters in any class methods need it for the clang types for
     // function prototypes.
     LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
-    type_sp = std::make_shared<Type>(die.GetID(), dwarf, type_name_const_str,
-                                     byte_size, nullptr, LLDB_INVALID_UID,
-                                     Type::eEncodingIsUID, &decl, clang_type,
+    type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
+                                     attrs.byte_size, nullptr, LLDB_INVALID_UID,
+                                     Type::eEncodingIsUID, &attrs.decl, clang_type,
                                      Type::eResolveStateForward);
 
-    type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
+    type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
 
     // Add our type to the unique type map so we don't end up creating many
     // copies of the same type over and over in the ASTContext for our
@@ -865,11 +907,11 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     unique_ast_entry_up->m_type_sp = type_sp;
     unique_ast_entry_up->m_die = die;
     unique_ast_entry_up->m_declaration = unique_decl;
-    unique_ast_entry_up->m_byte_size = byte_size.getValueOr(0);
+    unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
     dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
                                              *unique_ast_entry_up);
 
-    if (is_forward_declaration && die.HasChildren()) {
+    if (attrs.is_forward_declaration && die.HasChildren()) {
       // Check to see if the DIE actually has a definition, some version of
       // GCC will
       // emit DIEs with DW_AT_declaration set to true, but yet still have
@@ -887,7 +929,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         case DW_TAG_typedef:
         case DW_TAG_union_type:
           child_die.Clear();
-          is_forward_declaration = false;
+          attrs.is_forward_declaration = false;
           break;
         default:
           child_die = child_die.GetSibling();
@@ -896,7 +938,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       }
     }
 
-    if (!is_forward_declaration) {
+    if (!attrs.is_forward_declaration) {
       // Always start the definition for a class type so that if the class
       // has child classes or types that require the class to be created
       // for use as their decl contexts the class will be ready to accept
@@ -910,7 +952,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
               "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
               "definition.\nPlease file a bug and attach the file at the "
               "start of this error message",
-              die.GetOffset(), type_name_cstr);
+              die.GetOffset(), attrs.name.GetCString());
         }
 
         if (tag == DW_TAG_structure_type) // this only applies in C
@@ -932,8 +974,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         // class is needed as the declaration context for a contained class
         // or type without the need to complete that type..
 
-        if (class_language != eLanguageTypeObjC &&
-            class_language != eLanguageTypeObjC_plus_plus)
+        if (attrs.class_language != eLanguageTypeObjC &&
+            attrs.class_language != eLanguageTypeObjC_plus_plus)
           ClangASTContext::StartTagDeclarationDefinition(clang_type);
 
         // Leave this as a forward declaration until we need to know the
@@ -961,7 +1003,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     // do this for pass by value - which implies the Trivial ABI. There
     // isn't a way to assert that something that would normally be pass by
     // value is pass by reference, so we ignore that attribute if set.
-    if (calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+    if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
       clang::CXXRecordDecl *record_decl =
           m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
       if (record_decl) {
@@ -969,7 +1011,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
       }
     }
 
-    if (calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+    if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
       clang::CXXRecordDecl *record_decl =
           m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
       if (record_decl)
@@ -980,281 +1022,119 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   } break;
 
   case DW_TAG_enumeration_type: {
-    bool is_scoped = false;
-    DWARFFormValue encoding_form;
-
-    const size_t num_attributes = die.GetAttributes(attributes);
-    if (num_attributes > 0) {
-      uint32_t i;
-
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_decl_file:
-            decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                form_value.Unsigned()));
-            break;
-          case DW_AT_decl_line:
-            decl.SetLine(form_value.Unsigned());
-            break;
-          case DW_AT_decl_column:
-            decl.SetColumn(form_value.Unsigned());
-            break;
-          case DW_AT_name:
-            type_name_cstr = form_value.AsCString();
-            type_name_const_str.SetCString(type_name_cstr);
-            break;
-          case DW_AT_type:
-            encoding_form = form_value;
-            break;
-          case DW_AT_byte_size:
-            byte_size = form_value.Unsigned();
-            break;
-          case DW_AT_accessibility:
-            break; // accessibility =
-                   // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
-          case DW_AT_declaration:
-            is_forward_declaration = form_value.Boolean();
-            break;
-          case DW_AT_enum_class:
-            is_scoped = form_value.Boolean();
-            break;
-          case DW_AT_allocated:
-          case DW_AT_associated:
-          case DW_AT_bit_stride:
-          case DW_AT_byte_stride:
-          case DW_AT_data_location:
-          case DW_AT_description:
-          case DW_AT_start_scope:
-          case DW_AT_visibility:
-          case DW_AT_specification:
-          case DW_AT_abstract_origin:
-          case DW_AT_sibling:
-            break;
-          }
-        }
-      }
-
-      if (is_forward_declaration) {
-        type_sp = ParseTypeFromDWO(die, log);
-        if (type_sp)
-          return type_sp;
-
-        DWARFDeclContext die_decl_ctx;
-        die.GetDWARFDeclContext(die_decl_ctx);
-
-        type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+    if (attrs.is_forward_declaration) {
+      type_sp = ParseTypeFromDWO(die, log);
+      if (type_sp)
+        return type_sp;
 
-        if (!type_sp) {
-          SymbolFileDWARFDebugMap *debug_map_symfile =
-              dwarf->GetDebugMapSymfile();
-          if (debug_map_symfile) {
-            // We weren't able to find a full declaration in this DWARF,
-            // see if we have a declaration anywhere else...
-            type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
-                die_decl_ctx);
-          }
-        }
+      DWARFDeclContext die_decl_ctx;
+      die.GetDWARFDeclContext(die_decl_ctx);
 
-        if (type_sp) {
-          if (log) {
-            dwarf->GetObjectFile()->GetModule()->LogMessage(
-                log,
-                "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
-                "forward declaration, complete type is 0x%8.8" PRIx64,
-                static_cast<void *>(this), die.GetOffset(),
-                DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
-          }
+      type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
 
-          // We found a real definition for this type elsewhere so lets use
-          // it and cache the fact that we found a complete type for this
-          // die
-          dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-          clang::DeclContext *defn_decl_ctx =
-              GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
-          if (defn_decl_ctx)
-            LinkDeclContextToDIE(defn_decl_ctx, die);
-          return type_sp;
+      if (!type_sp) {
+        SymbolFileDWARFDebugMap *debug_map_symfile =
+            dwarf->GetDebugMapSymfile();
+        if (debug_map_symfile) {
+          // We weren't able to find a full declaration in this DWARF,
+          // see if we have a declaration anywhere else...
+          type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+              die_decl_ctx);
         }
       }
-      DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
-                   DW_TAG_value_to_name(tag), type_name_cstr);
 
-      CompilerType enumerator_clang_type;
-      clang_type.SetCompilerType(
-          &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
-      if (!clang_type) {
-        if (encoding_form.IsValid()) {
-          Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form));
-          if (enumerator_type)
-            enumerator_clang_type = enumerator_type->GetFullCompilerType();
-        }
-
-        if (!enumerator_clang_type) {
-          if (byte_size) {
-            enumerator_clang_type =
-                m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
-                    NULL, DW_ATE_signed, *byte_size * 8);
-          } else {
-            enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
-          }
+      if (type_sp) {
+        if (log) {
+          dwarf->GetObjectFile()->GetModule()->LogMessage(
+              log,
+              "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+              "forward declaration, complete type is 0x%8.8" PRIx64,
+              static_cast<void *>(this), die.GetOffset(),
+              DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+              type_sp->GetID());
         }
 
-        clang_type = m_ast.CreateEnumerationType(
-            type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
-            decl, enumerator_clang_type, is_scoped);
-      } else {
-        enumerator_clang_type =
-            m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+        // We found a real definition for this type elsewhere so lets use
+        // it and cache the fact that we found a complete type for this
+        // die
+        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+        clang::DeclContext *defn_decl_ctx =
+            GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+        if (defn_decl_ctx)
+          LinkDeclContextToDIE(defn_decl_ctx, die);
+        return type_sp;
       }
+    }
+    DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+                 DW_TAG_value_to_name(tag), type_name_cstr);
 
-      LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type),
-                           die);
+    CompilerType enumerator_clang_type;
+    clang_type.SetCompilerType(
+        &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+    if (!clang_type) {
+      if (attrs.type.IsValid()) {
+        Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(attrs.type));
+        if (enumerator_type)
+          enumerator_clang_type = enumerator_type->GetFullCompilerType();
+      }
 
-      type_sp = std::make_shared<Type>(
-          die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
-          dwarf->GetUID(DIERef(encoding_form)), Type::eEncodingIsUID, &decl,
-          clang_type, Type::eResolveStateForward);
-
-      if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
-        if (die.HasChildren()) {
-          SymbolContext cu_sc(die.GetLLDBCompileUnit());
-          bool is_signed = false;
-          enumerator_clang_type.IsIntegerType(is_signed);
-          ParseChildEnumerators(cu_sc, clang_type, is_signed,
-                                type_sp->GetByteSize().getValueOr(0), die);
+      if (!enumerator_clang_type) {
+        if (attrs.byte_size) {
+          enumerator_clang_type =
+              m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+                  NULL, DW_ATE_signed, *attrs.byte_size * 8);
+        } else {
+          enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
         }
-        ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
-      } else {
-        dwarf->GetObjectFile()->GetModule()->ReportError(
-            "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
-            "definition.\nPlease file a bug and attach the file at the "
-            "start of this error message",
-            die.GetOffset(), type_name_cstr);
       }
+
+      clang_type = m_ast.CreateEnumerationType(
+          attrs.name.GetCString(),
+          GetClangDeclContextContainingDIE(die, nullptr), attrs.decl,
+          enumerator_clang_type, attrs.is_scoped_enum);
+    } else {
+      enumerator_clang_type =
+          m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+    }
+
+    LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type),
+                         die);
+
+    type_sp = std::make_shared<Type>(
+        die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
+        dwarf->GetUID(DIERef(attrs.type)), Type::eEncodingIsUID, &attrs.decl,
+        clang_type, Type::eResolveStateForward);
+
+    if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+      if (die.HasChildren()) {
+        SymbolContext cu_sc(die.GetLLDBCompileUnit());
+        bool is_signed = false;
+        enumerator_clang_type.IsIntegerType(is_signed);
+        ParseChildEnumerators(cu_sc, clang_type, is_signed,
+                              type_sp->GetByteSize().getValueOr(0), die);
+      }
+      ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+    } else {
+      dwarf->GetObjectFile()->GetModule()->ReportError(
+          "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+          "definition.\nPlease file a bug and attach the file at the "
+          "start of this error message",
+          die.GetOffset(), attrs.name.GetCString());
     }
   } break;
 
   case DW_TAG_inlined_subroutine:
   case DW_TAG_subprogram:
   case DW_TAG_subroutine_type: {
-    DWARFFormValue type_die_form;
     bool is_variadic = false;
-    bool is_inline = false;
     bool is_static = false;
-    bool is_virtual = false;
-    bool is_explicit = false;
-    bool is_artificial = false;
     bool has_template_params = false;
-    DWARFFormValue specification_die_form;
-    DWARFFormValue abstract_origin_die_form;
-    DWARFDIE object_pointer_die;
 
     unsigned type_quals = 0;
-    clang::StorageClass storage =
-        clang::SC_None; //, Extern, Static, PrivateExtern
-
-    const size_t num_attributes = die.GetAttributes(attributes);
-    if (num_attributes > 0) {
-      uint32_t i;
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_decl_file:
-            decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                form_value.Unsigned()));
-            break;
-          case DW_AT_decl_line:
-            decl.SetLine(form_value.Unsigned());
-            break;
-          case DW_AT_decl_column:
-            decl.SetColumn(form_value.Unsigned());
-            break;
-          case DW_AT_name:
-            type_name_cstr = form_value.AsCString();
-            type_name_const_str.SetCString(type_name_cstr);
-            break;
-
-          case DW_AT_linkage_name:
-          case DW_AT_MIPS_linkage_name:
-            mangled_name_cstr = form_value.AsCString();
-            break;
-          case DW_AT_type:
-            type_die_form = form_value;
-            break;
-          case DW_AT_accessibility:
-            accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
-            break;
-          case DW_AT_declaration:
-            break; // is_forward_declaration = form_value.Boolean(); break;
-          case DW_AT_inline:
-            is_inline = form_value.Boolean();
-            break;
-          case DW_AT_virtuality:
-            is_virtual = form_value.Boolean();
-            break;
-          case DW_AT_explicit:
-            is_explicit = form_value.Boolean();
-            break;
-          case DW_AT_artificial:
-            is_artificial = form_value.Boolean();
-            break;
-
-          case DW_AT_external:
-            if (form_value.Unsigned()) {
-              if (storage == clang::SC_None)
-                storage = clang::SC_Extern;
-              else
-                storage = clang::SC_PrivateExtern;
-            }
-            break;
-
-          case DW_AT_specification:
-            specification_die_form = form_value;
-            break;
-
-          case DW_AT_abstract_origin:
-            abstract_origin_die_form = form_value;
-            break;
-
-          case DW_AT_object_pointer:
-            object_pointer_die = form_value.Reference();
-            break;
-
-          case DW_AT_allocated:
-          case DW_AT_associated:
-          case DW_AT_address_class:
-          case DW_AT_calling_convention:
-          case DW_AT_data_location:
-          case DW_AT_elemental:
-          case DW_AT_entry_pc:
-          case DW_AT_frame_base:
-          case DW_AT_high_pc:
-          case DW_AT_low_pc:
-          case DW_AT_prototyped:
-          case DW_AT_pure:
-          case DW_AT_ranges:
-          case DW_AT_recursive:
-          case DW_AT_return_addr:
-          case DW_AT_segment:
-          case DW_AT_start_scope:
-          case DW_AT_static_link:
-          case DW_AT_trampoline:
-          case DW_AT_visibility:
-          case DW_AT_vtable_elem_location:
-          case DW_AT_description:
-          case DW_AT_sibling:
-            break;
-          }
-        }
-      }
-    }
 
     std::string object_pointer_name;
-    if (object_pointer_die) {
-      const char *object_pointer_name_cstr = object_pointer_die.GetName();
+    if (attrs.object_pointer) {
+      const char *object_pointer_name_cstr = attrs.object_pointer.GetName();
       if (object_pointer_name_cstr)
         object_pointer_name = object_pointer_name_cstr;
     }
@@ -1265,8 +1145,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
     CompilerType return_clang_type;
     Type *func_type = NULL;
 
-    if (type_die_form.IsValid())
-      func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+    if (attrs.type.IsValid())
+      func_type = dwarf->ResolveTypeUID(DIERef(attrs.type));
 
     if (func_type)
       return_clang_type = func_type->GetForwardCompilerType();
@@ -1322,10 +1202,10 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         return_clang_type, function_param_types.data(),
         function_param_types.size(), is_variadic, type_quals);
 
-    if (type_name_cstr) {
+    if (attrs.name) {
       bool type_handled = false;
       if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
-        ObjCLanguage::MethodName objc_method(type_name_cstr, true);
+        ObjCLanguage::MethodName objc_method(attrs.name.GetStringRef(), true);
         if (objc_method.IsValid(true)) {
           CompilerType class_opaque_type;
           ConstString class_name(objc_method.GetClassName());
@@ -1346,13 +1226,13 @@ TypeSP DWARFASTParserClang::ParseTypeFro
           if (class_opaque_type) {
             // If accessibility isn't set to anything valid, assume public
             // for now...
-            if (accessibility == eAccessNone)
-              accessibility = eAccessPublic;
+            if (attrs.accessibility == eAccessNone)
+              attrs.accessibility = eAccessPublic;
 
             clang::ObjCMethodDecl *objc_method_decl =
                 m_ast.AddMethodToObjCObjectType(
-                    class_opaque_type, type_name_cstr, clang_type,
-                    accessibility, is_artificial, is_variadic);
+                    class_opaque_type, attrs.name.GetCString(), clang_type,
+                    attrs.accessibility, attrs.is_artificial, is_variadic);
             type_handled = objc_method_decl != NULL;
             if (type_handled) {
               LinkDeclContextToDIE(
@@ -1401,7 +1281,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
               }
             }
 
-            if (specification_die_form.IsValid()) {
+            if (attrs.specification.IsValid()) {
               // We have a specification which we are going to base our
               // function prototype off of, so we need this type to be
               // completed so that the m_die_to_decl_ctx for the method in
@@ -1411,7 +1291,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
               // have been made with the specification and not with this
               // die.
               DWARFDIE spec_die =
-                  dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form));
+                  dwarf->DebugInfo()->GetDIE(DIERef(attrs.specification));
               clang::DeclContext *spec_clang_decl_ctx =
                   GetClangDeclContextForDIE(spec_die);
               if (spec_clang_decl_ctx) {
@@ -1420,11 +1300,10 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                 dwarf->GetObjectFile()->GetModule()->ReportWarning(
                     "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x"
                     ") has no decl\n",
-                    die.GetID(),
-                    specification_die_form.Reference().GetOffset());
+                    die.GetID(), attrs.specification.Reference().GetOffset());
               }
               type_handled = true;
-            } else if (abstract_origin_die_form.IsValid()) {
+            } else if (attrs.abstract_origin.IsValid()) {
               // We have a specification which we are going to base our
               // function prototype off of, so we need this type to be
               // completed so that the m_die_to_decl_ctx for the method in
@@ -1432,7 +1311,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
               class_type->GetForwardCompilerType();
 
               DWARFDIE abs_die =
-                  dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
+                  dwarf->DebugInfo()->GetDIE(DIERef(attrs.abstract_origin));
               clang::DeclContext *abs_clang_decl_ctx =
                   GetClangDeclContextForDIE(abs_die);
               if (abs_clang_decl_ctx) {
@@ -1441,8 +1320,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                 dwarf->GetObjectFile()->GetModule()->ReportWarning(
                     "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x"
                     ") has no decl\n",
-                    die.GetID(),
-                    abstract_origin_die_form.Reference().GetOffset());
+                    die.GetID(), attrs.abstract_origin.Reference().GetOffset());
               }
               type_handled = true;
             } else {
@@ -1471,7 +1349,7 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                              method_iter++) {
                           clang::CXXMethodDecl *method_decl = *method_iter;
                           if (method_decl->getNameInfo().getAsString() ==
-                              std::string(type_name_cstr)) {
+                              attrs.name.GetStringRef()) {
                             if (method_decl->getType() ==
                                 ClangUtil::GetQualType(clang_type)) {
                               add_method = false;
@@ -1492,8 +1370,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                       llvm::PrettyStackTraceFormat stack_trace(
                           "SymbolFileDWARF::ParseType() is adding a method "
                           "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
-                          type_name_cstr, class_type->GetName().GetCString(),
-                          die.GetID(),
+                          attrs.name.GetCString(),
+                          class_type->GetName().GetCString(), die.GetID(),
                           dwarf->GetObjectFile()
                               ->GetFileSpec()
                               .GetPath()
@@ -1503,15 +1381,16 @@ TypeSP DWARFASTParserClang::ParseTypeFro
                       // Neither GCC 4.2 nor clang++ currently set a valid
                       // accessibility in the DWARF for C++ methods...
                       // Default to public for now...
-                      if (accessibility == eAccessNone)
-                        accessibility = eAccessPublic;
+                      if (attrs.accessibility == eAccessNone)
+                        attrs.accessibility = eAccessPublic;
 
                       clang::CXXMethodDecl *cxx_method_decl =
                           m_ast.AddMethodToCXXRecordType(
                               class_opaque_type.GetOpaqueQualType(),
-                              type_name_cstr, mangled_name_cstr, clang_type,
-                              accessibility, is_virtual, is_static, is_inline,
-                              is_explicit, is_attr_used, is_artificial);
+                              attrs.name.GetCString(), attrs.mangled_name,
+                              clang_type, attrs.accessibility, attrs.is_virtual,
+                              is_static, attrs.is_inline, attrs.is_explicit,
+                              is_attr_used, attrs.is_artificial);
 
                       type_handled = cxx_method_decl != NULL;
 
@@ -1582,8 +1461,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         clang::FunctionDecl *function_decl = nullptr;
         clang::FunctionDecl *template_function_decl = nullptr;
 
-        if (abstract_origin_die_form.IsValid()) {
-          DWARFDIE abs_die = abstract_origin_die_form.Reference();
+        if (attrs.abstract_origin.IsValid()) {
+          DWARFDIE abs_die = attrs.abstract_origin.Reference();
 
           SymbolContext sc;
 
@@ -1602,7 +1481,8 @@ TypeSP DWARFASTParserClang::ParseTypeFro
           function_decl = m_ast.CreateFunctionDeclaration(
               ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                         : containing_decl_ctx,
-              type_name_cstr, clang_type, storage, is_inline);
+              attrs.name.GetCString(), clang_type, attrs.storage,
+              attrs.is_inline);
 
           if (has_template_params) {
             ClangASTContext::TemplateParameterInfos template_param_infos;
@@ -1610,11 +1490,12 @@ TypeSP DWARFASTParserClang::ParseTypeFro
             template_function_decl = m_ast.CreateFunctionDeclaration(
                 ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                           : containing_decl_ctx,
-                type_name_cstr, clang_type, storage, is_inline);
+                attrs.name.GetCString(), clang_type, attrs.storage,
+                attrs.is_inline);
             clang::FunctionTemplateDecl *func_template_decl =
                 m_ast.CreateFunctionTemplateDecl(
-                    containing_decl_ctx, template_function_decl, type_name_cstr,
-                    template_param_infos);
+                    containing_decl_ctx, template_function_decl,
+                    attrs.name.GetCString(), template_param_infos);
             m_ast.CreateFunctionTemplateSpecializationInfo(
                 function_decl, func_template_decl, template_param_infos);
           }
@@ -1650,203 +1531,115 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         }
       }
     }
-    type_sp = std::make_shared<Type>(die.GetID(), dwarf, type_name_const_str,
-                                     llvm::None, nullptr, LLDB_INVALID_UID,
-                                     Type::eEncodingIsUID, &decl, clang_type,
-                                     Type::eResolveStateFull);
+    type_sp = std::make_shared<Type>(
+        die.GetID(), dwarf, attrs.name, llvm::None, nullptr, LLDB_INVALID_UID,
+        Type::eEncodingIsUID, &attrs.decl, clang_type, Type::eResolveStateFull);
     assert(type_sp.get());
   } break;
 
   case DW_TAG_array_type: {
-    DWARFFormValue type_die_form;
-    uint32_t byte_stride = 0;
-    uint32_t bit_stride = 0;
-    bool is_vector = false;
-    const size_t num_attributes = die.GetAttributes(attributes);
-
-    if (num_attributes > 0) {
-      uint32_t i;
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_decl_file:
-            decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                form_value.Unsigned()));
-            break;
-          case DW_AT_decl_line:
-            decl.SetLine(form_value.Unsigned());
-            break;
-          case DW_AT_decl_column:
-            decl.SetColumn(form_value.Unsigned());
-            break;
-          case DW_AT_name:
-            type_name_cstr = form_value.AsCString();
-            type_name_const_str.SetCString(type_name_cstr);
-            break;
-
-          case DW_AT_type:
-            type_die_form = form_value;
-            break;
-          case DW_AT_byte_size:
-            break; // byte_size = form_value.Unsigned(); break;
-          case DW_AT_byte_stride:
-            byte_stride = form_value.Unsigned();
-            break;
-          case DW_AT_bit_stride:
-            bit_stride = form_value.Unsigned();
-            break;
-          case DW_AT_GNU_vector:
-            is_vector = form_value.Boolean();
-            break;
-          case DW_AT_accessibility:
-            break; // accessibility =
-                   // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
-          case DW_AT_declaration:
-            break; // is_forward_declaration = form_value.Boolean(); break;
-          case DW_AT_allocated:
-          case DW_AT_associated:
-          case DW_AT_data_location:
-          case DW_AT_description:
-          case DW_AT_ordering:
-          case DW_AT_start_scope:
-          case DW_AT_visibility:
-          case DW_AT_specification:
-          case DW_AT_abstract_origin:
-          case DW_AT_sibling:
-            break;
-          }
-        }
-      }
-
-      DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
-                   DW_TAG_value_to_name(tag), type_name_cstr);
-
-      DIERef type_die_ref(type_die_form);
-      Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
+    DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+                 DW_TAG_value_to_name(tag), type_name_cstr);
 
-      if (element_type) {
-        auto array_info = ParseChildArrayInfo(die);
-        if (array_info) {
-          byte_stride = array_info->byte_stride;
-          bit_stride = array_info->bit_stride;
-        }
-        if (byte_stride == 0 && bit_stride == 0)
-          byte_stride = element_type->GetByteSize().getValueOr(0);
-        CompilerType array_element_type =
-            element_type->GetForwardCompilerType();
-
-        if (ClangASTContext::IsCXXClassType(array_element_type) &&
-            !array_element_type.GetCompleteType()) {
-          ModuleSP module_sp = die.GetModule();
-          if (module_sp) {
-            if (die.GetCU()->GetProducer() == eProducerClang)
-              module_sp->ReportError(
-                  "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
-                  "class/union/struct element type DIE 0x%8.8x that is a "
-                  "forward declaration, not a complete definition.\nTry "
-                  "compiling the source file with -fstandalone-debug or "
-                  "disable -gmodules",
-                  die.GetOffset(), type_die_ref.die_offset);
-            else
-              module_sp->ReportError(
-                  "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
-                  "class/union/struct element type DIE 0x%8.8x that is a "
-                  "forward declaration, not a complete definition.\nPlease "
-                  "file a bug against the compiler and include the "
-                  "preprocessed output for %s",
-                  die.GetOffset(), type_die_ref.die_offset,
-                  die.GetLLDBCompileUnit()
-                      ? die.GetLLDBCompileUnit()->GetPath().c_str()
-                      : "the source file");
-          }
+    DIERef type_die_ref(attrs.type);
+    Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
 
-          // We have no choice other than to pretend that the element class
-          // type is complete. If we don't do this, clang will crash when
-          // trying to layout the class. Since we provide layout
-          // assistance, all ivars in this class and other classes will be
-          // fine, this is the best we can do short of crashing.
-          if (ClangASTContext::StartTagDeclarationDefinition(
-                  array_element_type)) {
-            ClangASTContext::CompleteTagDeclarationDefinition(
-                array_element_type);
-          } else {
-            module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
-                                   "start its definition.\nPlease file a "
-                                   "bug and attach the file at the start "
-                                   "of this error message",
-                                   type_die_ref.die_offset);
-          }
+    if (element_type) {
+      auto array_info = ParseChildArrayInfo(die);
+      if (array_info) {
+        attrs.byte_stride = array_info->byte_stride;
+        attrs.bit_stride = array_info->bit_stride;
+      }
+      if (attrs.byte_stride == 0 && attrs.bit_stride == 0)
+        attrs.byte_stride = element_type->GetByteSize().getValueOr(0);
+      CompilerType array_element_type = element_type->GetForwardCompilerType();
+
+      if (ClangASTContext::IsCXXClassType(array_element_type) &&
+          !array_element_type.GetCompleteType()) {
+        ModuleSP module_sp = die.GetModule();
+        if (module_sp) {
+          if (die.GetCU()->GetProducer() == eProducerClang)
+            module_sp->ReportError(
+                "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+                "class/union/struct element type DIE 0x%8.8x that is a "
+                "forward declaration, not a complete definition.\nTry "
+                "compiling the source file with -fstandalone-debug or "
+                "disable -gmodules",
+                die.GetOffset(), type_die_ref.die_offset);
+          else
+            module_sp->ReportError(
+                "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+                "class/union/struct element type DIE 0x%8.8x that is a "
+                "forward declaration, not a complete definition.\nPlease "
+                "file a bug against the compiler and include the "
+                "preprocessed output for %s",
+                die.GetOffset(), type_die_ref.die_offset,
+                die.GetLLDBCompileUnit()
+                    ? die.GetLLDBCompileUnit()->GetPath().c_str()
+                    : "the source file");
+        }
+
+        // We have no choice other than to pretend that the element class
+        // type is complete. If we don't do this, clang will crash when
+        // trying to layout the class. Since we provide layout
+        // assistance, all ivars in this class and other classes will be
+        // fine, this is the best we can do short of crashing.
+        if (ClangASTContext::StartTagDeclarationDefinition(
+                array_element_type)) {
+          ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
+        } else {
+          module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
+                                 "start its definition.\nPlease file a "
+                                 "bug and attach the file at the start "
+                                 "of this error message",
+                                 type_die_ref.die_offset);
         }
+      }
 
-        uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
-        if (array_info && array_info->element_orders.size() > 0) {
-          uint64_t num_elements = 0;
-          auto end = array_info->element_orders.rend();
-          for (auto pos = array_info->element_orders.rbegin(); pos != end;
-               ++pos) {
-            num_elements = *pos;
-            clang_type = m_ast.CreateArrayType(array_element_type, num_elements,
-                                               is_vector);
-            array_element_type = clang_type;
-            array_element_bit_stride =
-                num_elements ? array_element_bit_stride * num_elements
-                             : array_element_bit_stride;
-          }
-        } else {
-          clang_type = m_ast.CreateArrayType(array_element_type, 0, is_vector);
+      uint64_t array_element_bit_stride =
+          attrs.byte_stride * 8 + attrs.bit_stride;
+      if (array_info && array_info->element_orders.size() > 0) {
+        uint64_t num_elements = 0;
+        auto end = array_info->element_orders.rend();
+        for (auto pos = array_info->element_orders.rbegin(); pos != end;
+             ++pos) {
+          num_elements = *pos;
+          clang_type = m_ast.CreateArrayType(array_element_type, num_elements,
+                                             attrs.is_vector);
+          array_element_type = clang_type;
+          array_element_bit_stride =
+              num_elements ? array_element_bit_stride * num_elements
+                           : array_element_bit_stride;
         }
-        ConstString empty_name;
-        type_sp = std::make_shared<Type>(
-            die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
-            nullptr, dwarf->GetUID(DIERef(type_die_form)), Type::eEncodingIsUID,
-            &decl, clang_type, Type::eResolveStateFull);
-        type_sp->SetEncodingType(element_type);
-        m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), die.GetID());
+      } else {
+        clang_type = m_ast.CreateArrayType(array_element_type, 0, attrs.is_vector);
       }
+      ConstString empty_name;
+      type_sp = std::make_shared<Type>(
+          die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, nullptr,
+          dwarf->GetUID(type_die_ref), Type::eEncodingIsUID, &attrs.decl,
+          clang_type, Type::eResolveStateFull);
+      type_sp->SetEncodingType(element_type);
+      m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), die.GetID());
     }
   } break;
 
   case DW_TAG_ptr_to_member_type: {
-    DWARFFormValue type_die_form;
-    DWARFFormValue containing_type_die_form;
+    Type *pointee_type = dwarf->ResolveTypeUID(DIERef(attrs.type));
+    Type *class_type = dwarf->ResolveTypeUID(DIERef(attrs.containing_type));
 
-    const size_t num_attributes = die.GetAttributes(attributes);
+    CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
+    CompilerType class_clang_type = class_type->GetLayoutCompilerType();
 
-    if (num_attributes > 0) {
-      uint32_t i;
-      for (i = 0; i < num_attributes; ++i) {
-        attr = attributes.AttributeAtIndex(i);
-        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-          switch (attr) {
-          case DW_AT_type:
-            type_die_form = form_value;
-            break;
-          case DW_AT_containing_type:
-            containing_type_die_form = form_value;
-            break;
-          }
-        }
-      }
+    clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type,
+                                                          pointee_clang_type);
 
-      Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
-      Type *class_type =
-          dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
-
-      CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
-      CompilerType class_clang_type = class_type->GetLayoutCompilerType();
-
-      clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type,
-                                                            pointee_clang_type);
-
-      if (llvm::Optional<uint64_t> clang_type_size =
-              clang_type.GetByteSize(nullptr)) {
-        byte_size = *clang_type_size;
-        type_sp = std::make_shared<Type>(
-            die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
-            LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type,
-            Type::eResolveStateForward);
-      }
+    if (llvm::Optional<uint64_t> clang_type_size =
+            clang_type.GetByteSize(nullptr)) {
+      type_sp = std::make_shared<Type>(
+          die.GetID(), dwarf, attrs.name, *clang_type_size, nullptr,
+          LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type,
+          Type::eResolveStateForward);
     }
 
     break;




More information about the lldb-commits mailing list