[Lldb-commits] [lldb] r327809 - DWARFUnit split out of DWARFCompileUnit

Jan Kratochvil via lldb-commits lldb-commits at lists.llvm.org
Sun Mar 18 13:09:02 PDT 2018


Author: jankratochvil
Date: Sun Mar 18 13:09:02 2018
New Revision: 327809

URL: http://llvm.org/viewvc/llvm-project?rev=327809&view=rev
Log:
DWARFUnit split out of DWARFCompileUnit

DW_TAG_partial_unit for DWZ can be then presented by DWARFPartialUnit also
inherited from DWARFUnit.

Differential revision: https://reviews.llvm.org/D40466

Added:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt?rev=327809&r1=327808&r2=327809&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt Sun Mar 18 13:09:02 2018
@@ -23,6 +23,7 @@ add_lldb_library(lldbPluginSymbolFileDWA
   DWARFDIE.cpp
   DWARFDIECollection.cpp
   DWARFFormValue.cpp
+  DWARFUnit.cpp
   HashedNameToDIE.cpp
   LogChannelDWARF.cpp
   NameToDIE.cpp

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=327809&r1=327808&r2=327809&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Sun Mar 18 13:09:02 2018
@@ -9,7 +9,6 @@
 
 #include "DWARFCompileUnit.h"
 
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "lldb/Core/DumpDataExtractor.h"
 #include "lldb/Core/Mangled.h"
 #include "lldb/Core/Module.h"
@@ -41,8 +40,6 @@ extern int g_verbose;
 DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
     : m_dwarf2Data(dwarf2Data) {}
 
-DWARFCompileUnit::~DWARFCompileUnit() {}
-
 DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
     lldb::offset_t *offset_ptr) {
   DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(dwarf2Data));
@@ -344,28 +341,6 @@ void DWARFCompileUnit::Dump(Stream *s) c
             GetNextCompileUnitOffset());
 }
 
-static uint8_t g_default_addr_size = 4;
-
-uint8_t DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit *cu) {
-  if (cu)
-    return cu->GetAddressByteSize();
-  return DWARFCompileUnit::GetDefaultAddressSize();
-}
-
-bool DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit *cu) {
-  if (cu)
-    return cu->IsDWARF64();
-  return false;
-}
-
-uint8_t DWARFCompileUnit::GetDefaultAddressSize() {
-  return g_default_addr_size;
-}
-
-void DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) {
-  g_default_addr_size = addr_size;
-}
-
 lldb::user_id_t DWARFCompileUnit::GetID() const {
   dw_offset_t local_id =
       m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
@@ -516,47 +491,6 @@ DWARFCompileUnit::LookupAddress(const dw
   return DWARFDIE();
 }
 
-//----------------------------------------------------------------------
-// Compare function DWARFDebugAranges::Range structures
-//----------------------------------------------------------------------
-static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
-                             const dw_offset_t die_offset) {
-  return die.GetOffset() < die_offset;
-}
-
-//----------------------------------------------------------------------
-// GetDIE()
-//
-// Get the DIE (Debug Information Entry) with the specified offset by
-// first checking if the DIE is contained within this compile unit and
-// grabbing the DIE from this compile unit. Otherwise we grab the DIE
-// from the DWARF file.
-//----------------------------------------------------------------------
-DWARFDIE
-DWARFCompileUnit::GetDIE(dw_offset_t die_offset) {
-  if (die_offset != DW_INVALID_OFFSET) {
-    if (m_dwo_symbol_file)
-      return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
-
-    if (ContainsDIEOffset(die_offset)) {
-      ExtractDIEsIfNeeded(false);
-      DWARFDebugInfoEntry::iterator end = m_die_array.end();
-      DWARFDebugInfoEntry::iterator pos =
-          lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset);
-      if (pos != end) {
-        if (die_offset == (*pos).GetOffset())
-          return DWARFDIE(this, &(*pos));
-      }
-    } else {
-      // Don't specify the compile unit offset as we don't know it because the
-      // DIE belongs to
-      // a different compile unit in the same symbol file.
-      return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
-    }
-  }
-  return DWARFDIE(); // Not found
-}
-
 size_t DWARFCompileUnit::AppendDIEsWithTag(const dw_tag_t tag,
                                            DWARFDIECollection &dies,
                                            uint32_t depth) const {
@@ -594,381 +528,6 @@ size_t DWARFCompileUnit::AppendDIEsWithT
 //        m_global_die_indexes.push_back (die - first_die);
 //}
 
-void DWARFCompileUnit::Index(NameToDIE &func_basenames,
-                             NameToDIE &func_fullnames, NameToDIE &func_methods,
-                             NameToDIE &func_selectors,
-                             NameToDIE &objc_class_selectors,
-                             NameToDIE &globals, NameToDIE &types,
-                             NameToDIE &namespaces) {
-  assert(!m_dwarf2Data->GetBaseCompileUnit() &&
-         "DWARFCompileUnit associated with .dwo or .dwp "
-         "should not be indexed directly");
-
-  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
-  if (log) {
-    m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
-        log,
-        "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]",
-        GetOffset());
-  }
-
-  const LanguageType cu_language = GetLanguageType();
-  DWARFFormValue::FixedFormSizes fixed_form_sizes =
-      DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
-                                                      m_is_dwarf64);
-
-  IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames,
-               func_fullnames, func_methods, func_selectors,
-               objc_class_selectors, globals, types, namespaces);
-
-  SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile();
-  if (dwo_symbol_file) {
-    IndexPrivate(dwo_symbol_file->GetCompileUnit(), cu_language,
-                 fixed_form_sizes, GetOffset(), func_basenames, func_fullnames,
-                 func_methods, func_selectors, objc_class_selectors, globals,
-                 types, namespaces);
-  }
-}
-
-void DWARFCompileUnit::IndexPrivate(
-    DWARFCompileUnit *dwarf_cu, const LanguageType cu_language,
-    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
-    const dw_offset_t cu_offset, NameToDIE &func_basenames,
-    NameToDIE &func_fullnames, NameToDIE &func_methods,
-    NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
-    NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) {
-  DWARFDebugInfoEntry::const_iterator pos;
-  DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin();
-  DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end();
-  for (pos = begin; pos != end; ++pos) {
-    const DWARFDebugInfoEntry &die = *pos;
-
-    const dw_tag_t tag = die.Tag();
-
-    switch (tag) {
-    case DW_TAG_array_type:
-    case DW_TAG_base_type:
-    case DW_TAG_class_type:
-    case DW_TAG_constant:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_inlined_subroutine:
-    case DW_TAG_namespace:
-    case DW_TAG_string_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_subprogram:
-    case DW_TAG_subroutine_type:
-    case DW_TAG_typedef:
-    case DW_TAG_union_type:
-    case DW_TAG_unspecified_type:
-    case DW_TAG_variable:
-      break;
-
-    default:
-      continue;
-    }
-
-    DWARFAttributes attributes;
-    const char *name = NULL;
-    const char *mangled_cstr = NULL;
-    bool is_declaration = false;
-    // bool is_artificial = false;
-    bool has_address = false;
-    bool has_location_or_const_value = false;
-    bool is_global_or_static_variable = false;
-
-    DWARFFormValue specification_die_form;
-    const size_t num_attributes =
-        die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes);
-    if (num_attributes > 0) {
-      for (uint32_t i = 0; i < num_attributes; ++i) {
-        dw_attr_t attr = attributes.AttributeAtIndex(i);
-        DWARFFormValue form_value;
-        switch (attr) {
-        case DW_AT_name:
-          if (attributes.ExtractFormValueAtIndex(i, form_value))
-            name = form_value.AsCString();
-          break;
-
-        case DW_AT_declaration:
-          if (attributes.ExtractFormValueAtIndex(i, form_value))
-            is_declaration = form_value.Unsigned() != 0;
-          break;
-
-        //                case DW_AT_artificial:
-        //                    if (attributes.ExtractFormValueAtIndex(i,
-        //                    form_value))
-        //                        is_artificial = form_value.Unsigned() != 0;
-        //                    break;
-
-        case DW_AT_MIPS_linkage_name:
-        case DW_AT_linkage_name:
-          if (attributes.ExtractFormValueAtIndex(i, form_value))
-            mangled_cstr = form_value.AsCString();
-          break;
-
-        case DW_AT_low_pc:
-        case DW_AT_high_pc:
-        case DW_AT_ranges:
-          has_address = true;
-          break;
-
-        case DW_AT_entry_pc:
-          has_address = true;
-          break;
-
-        case DW_AT_location:
-        case DW_AT_const_value:
-          has_location_or_const_value = true;
-          if (tag == DW_TAG_variable) {
-            const DWARFDebugInfoEntry *parent_die = die.GetParent();
-            while (parent_die != NULL) {
-              switch (parent_die->Tag()) {
-              case DW_TAG_subprogram:
-              case DW_TAG_lexical_block:
-              case DW_TAG_inlined_subroutine:
-                // Even if this is a function level static, we don't add it. We
-                // could theoretically
-                // add these if we wanted to by introspecting into the
-                // DW_AT_location and seeing
-                // if the location describes a hard coded address, but we dont
-                // want the performance
-                // penalty of that right now.
-                is_global_or_static_variable = false;
-                //                              if
-                //                              (attributes.ExtractFormValueAtIndex(dwarf2Data,
-                //                              i, form_value))
-                //                              {
-                //                                  // If we have valid block
-                //                                  data, then we have location
-                //                                  expression bytes
-                //                                  // that are fixed (not a
-                //                                  location list).
-                //                                  const uint8_t *block_data =
-                //                                  form_value.BlockData();
-                //                                  if (block_data)
-                //                                  {
-                //                                      uint32_t block_length =
-                //                                      form_value.Unsigned();
-                //                                      if (block_length == 1 +
-                //                                      attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
-                //                                      {
-                //                                          if (block_data[0] ==
-                //                                          DW_OP_addr)
-                //                                              add_die = true;
-                //                                      }
-                //                                  }
-                //                              }
-                parent_die = NULL; // Terminate the while loop.
-                break;
-
-              case DW_TAG_compile_unit:
-                is_global_or_static_variable = true;
-                parent_die = NULL; // Terminate the while loop.
-                break;
-
-              default:
-                parent_die =
-                    parent_die->GetParent(); // Keep going in the while loop.
-                break;
-              }
-            }
-          }
-          break;
-
-        case DW_AT_specification:
-          if (attributes.ExtractFormValueAtIndex(i, form_value))
-            specification_die_form = form_value;
-          break;
-        }
-      }
-    }
-
-    switch (tag) {
-    case DW_TAG_subprogram:
-      if (has_address) {
-        if (name) {
-          ObjCLanguage::MethodName objc_method(name, true);
-          if (objc_method.IsValid(true)) {
-            ConstString objc_class_name_with_category(
-                objc_method.GetClassNameWithCategory());
-            ConstString objc_selector_name(objc_method.GetSelector());
-            ConstString objc_fullname_no_category_name(
-                objc_method.GetFullNameWithoutCategory(true));
-            ConstString objc_class_name_no_category(objc_method.GetClassName());
-            func_fullnames.Insert(ConstString(name),
-                                  DIERef(cu_offset, die.GetOffset()));
-            if (objc_class_name_with_category)
-              objc_class_selectors.Insert(objc_class_name_with_category,
-                                          DIERef(cu_offset, die.GetOffset()));
-            if (objc_class_name_no_category &&
-                objc_class_name_no_category != objc_class_name_with_category)
-              objc_class_selectors.Insert(objc_class_name_no_category,
-                                          DIERef(cu_offset, die.GetOffset()));
-            if (objc_selector_name)
-              func_selectors.Insert(objc_selector_name,
-                                    DIERef(cu_offset, die.GetOffset()));
-            if (objc_fullname_no_category_name)
-              func_fullnames.Insert(objc_fullname_no_category_name,
-                                    DIERef(cu_offset, die.GetOffset()));
-          }
-          // If we have a mangled name, then the DW_AT_name attribute
-          // is usually the method name without the class or any parameters
-          const DWARFDebugInfoEntry *parent = die.GetParent();
-          bool is_method = false;
-          if (parent) {
-            dw_tag_t parent_tag = parent->Tag();
-            if (parent_tag == DW_TAG_class_type ||
-                parent_tag == DW_TAG_structure_type) {
-              is_method = true;
-            } else {
-              if (specification_die_form.IsValid()) {
-                DWARFDIE specification_die =
-                    dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE(
-                        DIERef(specification_die_form));
-                if (specification_die.GetParent().IsStructOrClass())
-                  is_method = true;
-              }
-            }
-          }
-
-          if (is_method)
-            func_methods.Insert(ConstString(name),
-                                DIERef(cu_offset, die.GetOffset()));
-          else
-            func_basenames.Insert(ConstString(name),
-                                  DIERef(cu_offset, die.GetOffset()));
-
-          if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
-            func_fullnames.Insert(ConstString(name),
-                                  DIERef(cu_offset, die.GetOffset()));
-        }
-        if (mangled_cstr) {
-          // Make sure our mangled name isn't the same string table entry
-          // as our name. If it starts with '_', then it is ok, else compare
-          // the string to make sure it isn't the same and we don't end up
-          // with duplicate entries
-          if (name && name != mangled_cstr &&
-              ((mangled_cstr[0] == '_') ||
-               (::strcmp(name, mangled_cstr) != 0))) {
-            Mangled mangled(ConstString(mangled_cstr), true);
-            func_fullnames.Insert(mangled.GetMangledName(),
-                                  DIERef(cu_offset, die.GetOffset()));
-            ConstString demangled = mangled.GetDemangledName(cu_language);
-            if (demangled)
-              func_fullnames.Insert(demangled,
-                                    DIERef(cu_offset, die.GetOffset()));
-          }
-        }
-      }
-      break;
-
-    case DW_TAG_inlined_subroutine:
-      if (has_address) {
-        if (name)
-          func_basenames.Insert(ConstString(name),
-                                DIERef(cu_offset, die.GetOffset()));
-        if (mangled_cstr) {
-          // Make sure our mangled name isn't the same string table entry
-          // as our name. If it starts with '_', then it is ok, else compare
-          // the string to make sure it isn't the same and we don't end up
-          // with duplicate entries
-          if (name && name != mangled_cstr &&
-              ((mangled_cstr[0] == '_') ||
-               (::strcmp(name, mangled_cstr) != 0))) {
-            Mangled mangled(ConstString(mangled_cstr), true);
-            func_fullnames.Insert(mangled.GetMangledName(),
-                                  DIERef(cu_offset, die.GetOffset()));
-            ConstString demangled = mangled.GetDemangledName(cu_language);
-            if (demangled)
-              func_fullnames.Insert(demangled,
-                                    DIERef(cu_offset, die.GetOffset()));
-          }
-        } else
-          func_fullnames.Insert(ConstString(name),
-                                DIERef(cu_offset, die.GetOffset()));
-      }
-      break;
-
-    case DW_TAG_array_type:
-    case DW_TAG_base_type:
-    case DW_TAG_class_type:
-    case DW_TAG_constant:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_string_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_subroutine_type:
-    case DW_TAG_typedef:
-    case DW_TAG_union_type:
-    case DW_TAG_unspecified_type:
-      if (name && !is_declaration)
-        types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
-      if (mangled_cstr && !is_declaration)
-        types.Insert(ConstString(mangled_cstr),
-                     DIERef(cu_offset, die.GetOffset()));
-      break;
-
-    case DW_TAG_namespace:
-      if (name)
-        namespaces.Insert(ConstString(name),
-                          DIERef(cu_offset, die.GetOffset()));
-      break;
-
-    case DW_TAG_variable:
-      if (name && has_location_or_const_value && is_global_or_static_variable) {
-        globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
-        // Be sure to include variables by their mangled and demangled
-        // names if they have any since a variable can have a basename
-        // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled
-        // mangled name "(anonymous namespace)::i"...
-
-        // Make sure our mangled name isn't the same string table entry
-        // as our name. If it starts with '_', then it is ok, else compare
-        // the string to make sure it isn't the same and we don't end up
-        // with duplicate entries
-        if (mangled_cstr && name != mangled_cstr &&
-            ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
-          Mangled mangled(ConstString(mangled_cstr), true);
-          globals.Insert(mangled.GetMangledName(),
-                         DIERef(cu_offset, die.GetOffset()));
-          ConstString demangled = mangled.GetDemangledName(cu_language);
-          if (demangled)
-            globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
-        }
-      }
-      break;
-
-    default:
-      continue;
-    }
-  }
-}
-
-bool DWARFCompileUnit::Supports_unnamed_objc_bitfields() {
-  if (GetProducer() == eProducerClang) {
-    const uint32_t major_version = GetProducerVersionMajor();
-    if (major_version > 425 ||
-        (major_version == 425 && GetProducerVersionUpdate() >= 13))
-      return true;
-    else
-      return false;
-  }
-  return true; // Assume all other compilers didn't have incorrect ObjC bitfield
-               // info
-}
-
-bool DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type() {
-  if (GetProducer() == eProducerLLVMGCC)
-    return false;
-  return true;
-}
-
-bool DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() {
-  // llvm-gcc makes completely invalid decl file attributes and won't ever
-  // be fixed, so we need to know to ignore these.
-  return GetProducer() == eProducerLLVMGCC;
-}
-
 void DWARFCompileUnit::ParseProducerInfo() {
   m_producer_version_major = UINT32_MAX;
   m_producer_version_minor = UINT32_MAX;
@@ -1036,19 +595,6 @@ uint32_t DWARFCompileUnit::GetProducerVe
   return m_producer_version_update;
 }
 
-LanguageType DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) {
-  // Note: user languages between lo_user and hi_user
-  // must be handled explicitly here.
-  switch (val) {
-  case DW_LANG_Mips_Assembler:
-    return eLanguageTypeMipsAssembler;
-  case DW_LANG_GOOGLE_RenderScript:
-    return eLanguageTypeExtRenderScript;
-  default:
-    return static_cast<LanguageType>(val);
-  }
-}
-
 LanguageType DWARFCompileUnit::GetLanguageType() {
   if (m_language_type != eLanguageTypeUnknown)
     return m_language_type;
@@ -1060,8 +606,6 @@ LanguageType DWARFCompileUnit::GetLangua
   return m_language_type;
 }
 
-bool DWARFCompileUnit::IsDWARF64() const { return m_is_dwarf64; }
-
 bool DWARFCompileUnit::GetIsOptimized() {
   if (m_is_optimized == eLazyBoolCalculate) {
     const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
@@ -1080,11 +624,6 @@ bool DWARFCompileUnit::GetIsOptimized()
   }
 }
 
-DWARFFormValue::FixedFormSizes DWARFCompileUnit::GetFixedFormSizes() {
-  return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
-                                                         IsDWARF64());
-}
-
 TypeSystem *DWARFCompileUnit::GetTypeSystem() {
   if (m_dwarf2Data)
     return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType());
@@ -1105,7 +644,3 @@ void DWARFCompileUnit::SetAddrBase(dw_ad
   m_ranges_base = ranges_base;
   m_base_obj_offset = base_obj_offset;
 }
-
-lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const {
-  return m_dwarf2Data->GetObjectFile()->GetByteOrder();
-}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h?rev=327809&r1=327808&r2=327809&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h Sun Mar 18 13:09:02 2018
@@ -10,29 +10,16 @@
 #ifndef SymbolFileDWARF_DWARFCompileUnit_h_
 #define SymbolFileDWARF_DWARFCompileUnit_h_
 
-#include "DWARFDIE.h"
-#include "DWARFDebugInfoEntry.h"
-#include "lldb/lldb-enumerations.h"
-
-class NameToDIE;
-class SymbolFileDWARF;
-class SymbolFileDWARFDwo;
+#include "DWARFUnit.h"
 
 typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
 
-enum DWARFProducer {
-  eProducerInvalid = 0,
-  eProducerClang,
-  eProducerGCC,
-  eProducerLLVMGCC,
-  eProcucerOther
-};
+class DWARFCompileUnit : public DWARFUnit {
+  friend class DWARFUnit;
 
-class DWARFCompileUnit {
 public:
   static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
       lldb::offset_t *offset_ptr);
-  ~DWARFCompileUnit();
 
   size_t ExtractDIEsIfNeeded(bool cu_die_only);
   DWARFDIE LookupAddress(const dw_addr_t address);
@@ -41,47 +28,15 @@ public:
                            uint32_t depth = UINT32_MAX) const;
   bool Verify(lldb_private::Stream *s) const;
   void Dump(lldb_private::Stream *s) const;
-  // Offset of the initial length field.
-  dw_offset_t GetOffset() const { return m_offset; }
   lldb::user_id_t GetID() const;
-  // Size in bytes of the initial length + compile unit header.
-  uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; }
-  bool ContainsDIEOffset(dw_offset_t die_offset) const {
-    return die_offset >= GetFirstDIEOffset() &&
-           die_offset < GetNextCompileUnitOffset();
-  }
-  dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
-  dw_offset_t GetNextCompileUnitOffset() const {
-    return m_offset + (m_is_dwarf64 ? 12 : 4) + m_length;
-  }
-  // Size of the CU data (without initial length and without header).
-  size_t GetDebugInfoSize() const {
-    return (m_is_dwarf64 ? 12 : 4) + m_length - Size();
-  }
-  // Size of the CU data incl. header but without initial length.
-  uint32_t GetLength() const { return m_length; }
-  uint16_t GetVersion() const { return m_version; }
-  const DWARFAbbreviationDeclarationSet *GetAbbreviations() const {
-    return m_abbrevs;
-  }
   dw_offset_t GetAbbrevOffset() const;
-  uint8_t GetAddressByteSize() const { return m_addr_size; }
-  dw_addr_t GetBaseAddress() const { return m_base_addr; }
-  dw_addr_t GetAddrBase() const { return m_addr_base; }
-  dw_addr_t GetRangesBase() const { return m_ranges_base; }
   void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
   void ClearDIEs(bool keep_compile_unit_die);
   void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
                               DWARFDebugAranges *debug_aranges);
 
-  lldb::ByteOrder GetByteOrder() const;
-
   lldb_private::TypeSystem *GetTypeSystem();
 
-  DWARFFormValue::FixedFormSizes GetFixedFormSizes();
-
-  void SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
-
   DWARFDIE
   GetCompileUnitDIEOnly() { return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); }
 
@@ -105,38 +60,10 @@ public:
 
   void AddCompileUnitDIE(DWARFDebugInfoEntry &die);
 
-  bool HasDIEsParsed() const { return m_die_array.size() > 1; }
-
-  DWARFDIE
-  GetDIE(dw_offset_t die_offset);
-
-  static uint8_t GetAddressByteSize(const DWARFCompileUnit *cu);
-
-  static bool IsDWARF64(const DWARFCompileUnit *cu);
-
-  static uint8_t GetDefaultAddressSize();
-
-  static void SetDefaultAddressSize(uint8_t addr_size);
-
-  void *GetUserData() const { return m_user_data; }
-
   void SetUserData(void *d);
 
-  bool Supports_DW_AT_APPLE_objc_complete_type();
-
-  bool DW_AT_decl_file_attributes_are_invalid();
-
-  bool Supports_unnamed_objc_bitfields();
-
-  void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames,
-             NameToDIE &func_methods, NameToDIE &func_selectors,
-             NameToDIE &objc_class_selectors, NameToDIE &globals,
-             NameToDIE &types, NameToDIE &namespaces);
-
   const DWARFDebugAranges &GetFunctionAranges();
 
-  SymbolFileDWARF *GetSymbolFileDWARF() const { return m_dwarf2Data; }
-
   DWARFProducer GetProducer();
 
   uint32_t GetProducerVersionMajor();
@@ -145,21 +72,14 @@ public:
 
   uint32_t GetProducerVersionUpdate();
 
-  static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
-
   lldb::LanguageType GetLanguageType();
 
-  bool IsDWARF64() const;
-
   bool GetIsOptimized();
 
-  SymbolFileDWARFDwo *GetDwoSymbolFile() const {
-    return m_dwo_symbol_file.get();
-  }
-
-  dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; }
-
 protected:
+  virtual DWARFCompileUnit &Data() override { return *this; }
+  virtual const DWARFCompileUnit &Data() const override { return *this; }
+
   SymbolFileDWARF *m_dwarf2Data;
   std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
   const DWARFAbbreviationDeclarationSet *m_abbrevs;
@@ -173,8 +93,6 @@ protected:
                                                         // DW_TAG_subprogram
                                                         // DIEs
   dw_addr_t m_base_addr = 0;
-  // Offset of the initial length field.
-  dw_offset_t m_offset;
   dw_offset_t m_length;
   uint16_t m_version;
   uint8_t m_addr_size;
@@ -193,14 +111,6 @@ protected:
 
   void ParseProducerInfo();
 
-  static void
-  IndexPrivate(DWARFCompileUnit *dwarf_cu, const lldb::LanguageType cu_language,
-               const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
-               const dw_offset_t cu_offset, NameToDIE &func_basenames,
-               NameToDIE &func_fullnames, NameToDIE &func_methods,
-               NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
-               NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
-
 private:
   DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
 

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp?rev=327809&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp Sun Mar 18 13:09:02 2018
@@ -0,0 +1,630 @@
+//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFUnit.h"
+
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+#include "LogChannelDWARF.h"
+#include "SymbolFileDWARFDwo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace std;
+
+extern int g_verbose;
+
+DWARFUnit::DWARFUnit() {}
+
+DWARFUnit::~DWARFUnit() {}
+
+size_t DWARFUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
+  return Data().ExtractDIEsIfNeeded(cu_die_only);
+}
+
+DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
+  return Data().LookupAddress(address);
+}
+
+size_t DWARFUnit::AppendDIEsWithTag(const dw_tag_t tag,
+				    DWARFDIECollection &dies,
+				    uint32_t depth) const {
+  return Data().AppendDIEsWithTag(tag, dies, depth);
+}
+
+bool DWARFUnit::Verify(Stream *s) const {
+  return Data().Verify(s);
+}
+
+void DWARFUnit::Dump(Stream *s) const {
+  Data().Dump(s);
+}
+
+lldb::user_id_t DWARFUnit::GetID() const {
+  return Data().GetID();
+}
+
+uint32_t DWARFUnit::Size() const { return IsDWARF64() ? 23 : 11; }
+
+dw_offset_t DWARFUnit::GetNextCompileUnitOffset() const {
+  return m_offset + (IsDWARF64() ? 12 : 4) + GetLength();
+}
+
+size_t DWARFUnit::GetDebugInfoSize() const {
+  return (IsDWARF64() ? 12 : 4) + GetLength() - Size();
+}
+
+uint32_t DWARFUnit::GetLength() const { return Data().m_length; }
+uint16_t DWARFUnit::GetVersion() const { return Data().m_version; }
+
+const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const {
+  return Data().m_abbrevs;
+}
+
+dw_offset_t DWARFUnit::GetAbbrevOffset() const {
+  return Data().GetAbbrevOffset();
+}
+
+uint8_t DWARFUnit::GetAddressByteSize() const { return Data().m_addr_size; }
+
+dw_addr_t DWARFUnit::GetBaseAddress() const { return Data().m_base_addr; }
+
+dw_addr_t DWARFUnit::GetAddrBase() const { return Data().m_addr_base; }
+
+dw_addr_t DWARFUnit::GetRangesBase() const { return Data().m_ranges_base; }
+
+void DWARFUnit::SetAddrBase(dw_addr_t addr_base,
+                            dw_addr_t ranges_base,
+                            dw_offset_t base_obj_offset) {
+  Data().SetAddrBase(addr_base, ranges_base, base_obj_offset);
+}
+
+void DWARFUnit::ClearDIEs(bool keep_compile_unit_die) {
+  Data().ClearDIEs(keep_compile_unit_die);
+}
+
+void DWARFUnit::BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+                                       DWARFDebugAranges *debug_aranges) {
+  Data().BuildAddressRangeTable(dwarf2Data, debug_aranges);
+}
+
+lldb::ByteOrder DWARFUnit::GetByteOrder() const {
+  return Data().m_dwarf2Data->GetObjectFile()->GetByteOrder();
+}
+
+TypeSystem *DWARFUnit::GetTypeSystem() {
+  return Data().GetTypeSystem();
+}
+
+DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() {
+  return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+                                                         IsDWARF64());
+}
+
+void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) {
+  Data().m_base_addr = base_addr;
+}
+
+DWARFDIE DWARFUnit::GetCompileUnitDIEOnly() {
+  return Data().GetCompileUnitDIEOnly();
+}
+
+DWARFDIE DWARFUnit::DIE() {
+  return Data().DIE();
+}
+
+bool DWARFUnit::HasDIEsParsed() const { return Data().m_die_array.size() > 1; }
+
+//----------------------------------------------------------------------
+// Compare function DWARFDebugAranges::Range structures
+//----------------------------------------------------------------------
+static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
+                             const dw_offset_t die_offset) {
+  return die.GetOffset() < die_offset;
+}
+
+//----------------------------------------------------------------------
+// GetDIE()
+//
+// Get the DIE (Debug Information Entry) with the specified offset by
+// first checking if the DIE is contained within this compile unit and
+// grabbing the DIE from this compile unit. Otherwise we grab the DIE
+// from the DWARF file.
+//----------------------------------------------------------------------
+DWARFDIE
+DWARFUnit::GetDIE(dw_offset_t die_offset) {
+  if (die_offset != DW_INVALID_OFFSET) {
+    if (GetDwoSymbolFile())
+      return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset);
+
+    if (ContainsDIEOffset(die_offset)) {
+      ExtractDIEsIfNeeded(false);
+      DWARFDebugInfoEntry::iterator end = Data().m_die_array.end();
+      DWARFDebugInfoEntry::iterator pos = lower_bound(
+          Data().m_die_array.begin(), end, die_offset, CompareDIEOffset);
+      if (pos != end) {
+        if (die_offset == (*pos).GetOffset())
+          return DWARFDIE(&Data(), &(*pos));
+      }
+    } else {
+      // Don't specify the compile unit offset as we don't know it because the
+      // DIE belongs to
+      // a different compile unit in the same symbol file.
+      return Data().m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
+    }
+  }
+  return DWARFDIE(); // Not found
+}
+
+static uint8_t g_default_addr_size = 4;
+
+uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
+  if (cu)
+    return cu->GetAddressByteSize();
+  return DWARFCompileUnit::GetDefaultAddressSize();
+}
+
+bool DWARFUnit::IsDWARF64(const DWARFUnit *cu) {
+  if (cu)
+    return cu->IsDWARF64();
+  return false;
+}
+
+uint8_t DWARFUnit::GetDefaultAddressSize() {
+  return g_default_addr_size;
+}
+
+void DWARFUnit::SetDefaultAddressSize(uint8_t addr_size) {
+  g_default_addr_size = addr_size;
+}
+
+void *DWARFUnit::GetUserData() const { return Data().m_user_data; }
+
+void DWARFUnit::SetUserData(void *d) {
+  Data().SetUserData(d);
+}
+
+bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
+  if (GetProducer() == eProducerLLVMGCC)
+    return false;
+  return true;
+}
+
+bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() {
+  // llvm-gcc makes completely invalid decl file attributes and won't ever
+  // be fixed, so we need to know to ignore these.
+  return GetProducer() == eProducerLLVMGCC;
+}
+
+bool DWARFUnit::Supports_unnamed_objc_bitfields() {
+  if (GetProducer() == eProducerClang) {
+    const uint32_t major_version = GetProducerVersionMajor();
+    if (major_version > 425 ||
+        (major_version == 425 && GetProducerVersionUpdate() >= 13))
+      return true;
+    else
+      return false;
+  }
+  return true; // Assume all other compilers didn't have incorrect ObjC bitfield
+               // info
+}
+
+SymbolFileDWARF *DWARFUnit::GetSymbolFileDWARF() const {
+  return Data().m_dwarf2Data;
+}
+
+DWARFProducer DWARFUnit::GetProducer() {
+  return Data().GetProducer();
+}
+
+uint32_t DWARFUnit::GetProducerVersionMajor() {
+  return Data().GetProducerVersionMajor();
+}
+
+uint32_t DWARFUnit::GetProducerVersionMinor() {
+  return Data().GetProducerVersionMinor();
+}
+
+uint32_t DWARFUnit::GetProducerVersionUpdate() {
+  return Data().GetProducerVersionUpdate();
+}
+
+LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) {
+  // Note: user languages between lo_user and hi_user
+  // must be handled explicitly here.
+  switch (val) {
+  case DW_LANG_Mips_Assembler:
+    return eLanguageTypeMipsAssembler;
+  case DW_LANG_GOOGLE_RenderScript:
+    return eLanguageTypeExtRenderScript;
+  default:
+    return static_cast<LanguageType>(val);
+  }
+}
+
+LanguageType DWARFUnit::GetLanguageType() {
+  return Data().GetLanguageType();
+}
+
+bool DWARFUnit::IsDWARF64() const { return Data().m_is_dwarf64; }
+
+bool DWARFUnit::GetIsOptimized() {
+  return Data().GetIsOptimized();
+}
+
+SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const {
+  return Data().m_dwo_symbol_file.get();
+}
+
+dw_offset_t DWARFUnit::GetBaseObjOffset() const {
+  return Data().m_base_obj_offset;
+}
+
+const DWARFDebugInfoEntry *DWARFUnit::GetCompileUnitDIEPtrOnly() {
+  return Data().GetCompileUnitDIEPtrOnly();
+}
+
+const DWARFDebugInfoEntry *DWARFUnit::DIEPtr() {
+  return Data().DIEPtr();
+}
+
+void DWARFUnit::Index(NameToDIE &func_basenames,
+                             NameToDIE &func_fullnames, NameToDIE &func_methods,
+                             NameToDIE &func_selectors,
+                             NameToDIE &objc_class_selectors,
+                             NameToDIE &globals, NameToDIE &types,
+                             NameToDIE &namespaces) {
+  assert(!Data().m_dwarf2Data->GetBaseCompileUnit() &&
+         "DWARFUnit associated with .dwo or .dwp "
+         "should not be indexed directly");
+
+  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+  if (log) {
+    Data().m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
+        log,
+        "DWARFUnit::Index() for compile unit at .debug_info[0x%8.8x]",
+        GetOffset());
+  }
+
+  const LanguageType cu_language = GetLanguageType();
+  DWARFFormValue::FixedFormSizes fixed_form_sizes =
+      DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+                                                      IsDWARF64());
+
+  IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames,
+               func_fullnames, func_methods, func_selectors,
+               objc_class_selectors, globals, types, namespaces);
+
+  SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile();
+  if (dwo_symbol_file) {
+    IndexPrivate(
+        dwo_symbol_file->GetCompileUnit(), cu_language, fixed_form_sizes,
+        GetOffset(), func_basenames, func_fullnames, func_methods,
+        func_selectors, objc_class_selectors, globals, types, namespaces);
+  }
+}
+
+void DWARFUnit::IndexPrivate(
+    DWARFUnit *dwarf_cu, const LanguageType cu_language,
+    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+    const dw_offset_t cu_offset, NameToDIE &func_basenames,
+    NameToDIE &func_fullnames, NameToDIE &func_methods,
+    NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
+    NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) {
+  DWARFDebugInfoEntry::const_iterator pos;
+  DWARFDebugInfoEntry::const_iterator begin =
+      dwarf_cu->Data().m_die_array.begin();
+  DWARFDebugInfoEntry::const_iterator end = dwarf_cu->Data().m_die_array.end();
+  for (pos = begin; pos != end; ++pos) {
+    const DWARFDebugInfoEntry &die = *pos;
+
+    const dw_tag_t tag = die.Tag();
+
+    switch (tag) {
+    case DW_TAG_array_type:
+    case DW_TAG_base_type:
+    case DW_TAG_class_type:
+    case DW_TAG_constant:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_inlined_subroutine:
+    case DW_TAG_namespace:
+    case DW_TAG_string_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_subprogram:
+    case DW_TAG_subroutine_type:
+    case DW_TAG_typedef:
+    case DW_TAG_union_type:
+    case DW_TAG_unspecified_type:
+    case DW_TAG_variable:
+      break;
+
+    default:
+      continue;
+    }
+
+    DWARFAttributes attributes;
+    const char *name = NULL;
+    const char *mangled_cstr = NULL;
+    bool is_declaration = false;
+    // bool is_artificial = false;
+    bool has_address = false;
+    bool has_location_or_const_value = false;
+    bool is_global_or_static_variable = false;
+
+    DWARFFormValue specification_die_form;
+    const size_t num_attributes =
+        die.GetAttributes(&dwarf_cu->Data(), fixed_form_sizes, attributes);
+    if (num_attributes > 0) {
+      for (uint32_t i = 0; i < num_attributes; ++i) {
+        dw_attr_t attr = attributes.AttributeAtIndex(i);
+        DWARFFormValue form_value;
+        switch (attr) {
+        case DW_AT_name:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            name = form_value.AsCString();
+          break;
+
+        case DW_AT_declaration:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            is_declaration = form_value.Unsigned() != 0;
+          break;
+
+        //                case DW_AT_artificial:
+        //                    if (attributes.ExtractFormValueAtIndex(i,
+        //                    form_value))
+        //                        is_artificial = form_value.Unsigned() != 0;
+        //                    break;
+
+        case DW_AT_MIPS_linkage_name:
+        case DW_AT_linkage_name:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            mangled_cstr = form_value.AsCString();
+          break;
+
+        case DW_AT_low_pc:
+        case DW_AT_high_pc:
+        case DW_AT_ranges:
+          has_address = true;
+          break;
+
+        case DW_AT_entry_pc:
+          has_address = true;
+          break;
+
+        case DW_AT_location:
+        case DW_AT_const_value:
+          has_location_or_const_value = true;
+          if (tag == DW_TAG_variable) {
+            const DWARFDebugInfoEntry *parent_die = die.GetParent();
+            while (parent_die != NULL) {
+              switch (parent_die->Tag()) {
+              case DW_TAG_subprogram:
+              case DW_TAG_lexical_block:
+              case DW_TAG_inlined_subroutine:
+                // Even if this is a function level static, we don't add it. We
+                // could theoretically
+                // add these if we wanted to by introspecting into the
+                // DW_AT_location and seeing
+                // if the location describes a hard coded address, but we dont
+                // want the performance
+                // penalty of that right now.
+                is_global_or_static_variable = false;
+                //                              if
+                //                              (attributes.ExtractFormValueAtIndex(dwarf2Data,
+                //                              i, form_value))
+                //                              {
+                //                                  // If we have valid block
+                //                                  data, then we have location
+                //                                  expression bytes
+                //                                  // that are fixed (not a
+                //                                  location list).
+                //                                  const uint8_t *block_data =
+                //                                  form_value.BlockData();
+                //                                  if (block_data)
+                //                                  {
+                //                                      uint32_t block_length =
+                //                                      form_value.Unsigned();
+                //                                      if (block_length == 1 +
+                //                                      attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
+                //                                      {
+                //                                          if (block_data[0] ==
+                //                                          DW_OP_addr)
+                //                                              add_die = true;
+                //                                      }
+                //                                  }
+                //                              }
+                parent_die = NULL; // Terminate the while loop.
+                break;
+
+              case DW_TAG_compile_unit:
+                is_global_or_static_variable = true;
+                parent_die = NULL; // Terminate the while loop.
+                break;
+
+              default:
+                parent_die =
+                    parent_die->GetParent(); // Keep going in the while loop.
+                break;
+              }
+            }
+          }
+          break;
+
+        case DW_AT_specification:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            specification_die_form = form_value;
+          break;
+        }
+      }
+    }
+
+    switch (tag) {
+    case DW_TAG_subprogram:
+      if (has_address) {
+        if (name) {
+          ObjCLanguage::MethodName objc_method(name, true);
+          if (objc_method.IsValid(true)) {
+            ConstString objc_class_name_with_category(
+                objc_method.GetClassNameWithCategory());
+            ConstString objc_selector_name(objc_method.GetSelector());
+            ConstString objc_fullname_no_category_name(
+                objc_method.GetFullNameWithoutCategory(true));
+            ConstString objc_class_name_no_category(objc_method.GetClassName());
+            func_fullnames.Insert(ConstString(name),
+                                  DIERef(cu_offset, die.GetOffset()));
+            if (objc_class_name_with_category)
+              objc_class_selectors.Insert(objc_class_name_with_category,
+                                          DIERef(cu_offset, die.GetOffset()));
+            if (objc_class_name_no_category &&
+                objc_class_name_no_category != objc_class_name_with_category)
+              objc_class_selectors.Insert(objc_class_name_no_category,
+                                          DIERef(cu_offset, die.GetOffset()));
+            if (objc_selector_name)
+              func_selectors.Insert(objc_selector_name,
+                                    DIERef(cu_offset, die.GetOffset()));
+            if (objc_fullname_no_category_name)
+              func_fullnames.Insert(objc_fullname_no_category_name,
+                                    DIERef(cu_offset, die.GetOffset()));
+          }
+          // If we have a mangled name, then the DW_AT_name attribute
+          // is usually the method name without the class or any parameters
+          const DWARFDebugInfoEntry *parent = die.GetParent();
+          bool is_method = false;
+          if (parent) {
+            dw_tag_t parent_tag = parent->Tag();
+            if (parent_tag == DW_TAG_class_type ||
+                parent_tag == DW_TAG_structure_type) {
+              is_method = true;
+            } else {
+              if (specification_die_form.IsValid()) {
+                DWARFDIE specification_die =
+                    dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE(
+                        DIERef(specification_die_form));
+                if (specification_die.GetParent().IsStructOrClass())
+                  is_method = true;
+              }
+            }
+          }
+
+          if (is_method)
+            func_methods.Insert(ConstString(name),
+                                DIERef(cu_offset, die.GetOffset()));
+          else
+            func_basenames.Insert(ConstString(name),
+                                  DIERef(cu_offset, die.GetOffset()));
+
+          if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
+            func_fullnames.Insert(ConstString(name),
+                                  DIERef(cu_offset, die.GetOffset()));
+        }
+        if (mangled_cstr) {
+          // Make sure our mangled name isn't the same string table entry
+          // as our name. If it starts with '_', then it is ok, else compare
+          // the string to make sure it isn't the same and we don't end up
+          // with duplicate entries
+          if (name && name != mangled_cstr &&
+              ((mangled_cstr[0] == '_') ||
+               (::strcmp(name, mangled_cstr) != 0))) {
+            Mangled mangled(ConstString(mangled_cstr), true);
+            func_fullnames.Insert(mangled.GetMangledName(),
+                                  DIERef(cu_offset, die.GetOffset()));
+            ConstString demangled = mangled.GetDemangledName(cu_language);
+            if (demangled)
+              func_fullnames.Insert(demangled,
+                                    DIERef(cu_offset, die.GetOffset()));
+          }
+        }
+      }
+      break;
+
+    case DW_TAG_inlined_subroutine:
+      if (has_address) {
+        if (name)
+          func_basenames.Insert(ConstString(name),
+                                DIERef(cu_offset, die.GetOffset()));
+        if (mangled_cstr) {
+          // Make sure our mangled name isn't the same string table entry
+          // as our name. If it starts with '_', then it is ok, else compare
+          // the string to make sure it isn't the same and we don't end up
+          // with duplicate entries
+          if (name && name != mangled_cstr &&
+              ((mangled_cstr[0] == '_') ||
+               (::strcmp(name, mangled_cstr) != 0))) {
+            Mangled mangled(ConstString(mangled_cstr), true);
+            func_fullnames.Insert(mangled.GetMangledName(),
+                                  DIERef(cu_offset, die.GetOffset()));
+            ConstString demangled = mangled.GetDemangledName(cu_language);
+            if (demangled)
+              func_fullnames.Insert(demangled,
+                                    DIERef(cu_offset, die.GetOffset()));
+          }
+        } else
+          func_fullnames.Insert(ConstString(name),
+                                DIERef(cu_offset, die.GetOffset()));
+      }
+      break;
+
+    case DW_TAG_array_type:
+    case DW_TAG_base_type:
+    case DW_TAG_class_type:
+    case DW_TAG_constant:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_string_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_subroutine_type:
+    case DW_TAG_typedef:
+    case DW_TAG_union_type:
+    case DW_TAG_unspecified_type:
+      if (name && !is_declaration)
+        types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+      if (mangled_cstr && !is_declaration)
+        types.Insert(ConstString(mangled_cstr),
+                     DIERef(cu_offset, die.GetOffset()));
+      break;
+
+    case DW_TAG_namespace:
+      if (name)
+        namespaces.Insert(ConstString(name),
+                          DIERef(cu_offset, die.GetOffset()));
+      break;
+
+    case DW_TAG_variable:
+      if (name && has_location_or_const_value && is_global_or_static_variable) {
+        globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+        // Be sure to include variables by their mangled and demangled
+        // names if they have any since a variable can have a basename
+        // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled
+        // mangled name "(anonymous namespace)::i"...
+
+        // Make sure our mangled name isn't the same string table entry
+        // as our name. If it starts with '_', then it is ok, else compare
+        // the string to make sure it isn't the same and we don't end up
+        // with duplicate entries
+        if (mangled_cstr && name != mangled_cstr &&
+            ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
+          Mangled mangled(ConstString(mangled_cstr), true);
+          globals.Insert(mangled.GetMangledName(),
+                         DIERef(cu_offset, die.GetOffset()));
+          ConstString demangled = mangled.GetDemangledName(cu_language);
+          if (demangled)
+            globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
+        }
+      }
+      break;
+
+    default:
+      continue;
+    }
+  }
+}

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h?rev=327809&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h Sun Mar 18 13:09:02 2018
@@ -0,0 +1,159 @@
+//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFUnit_h_
+#define SymbolFileDWARF_DWARFUnit_h_
+
+#include "DWARFDIE.h"
+#include "DWARFDebugInfoEntry.h"
+#include "lldb/lldb-enumerations.h"
+
+class DWARFUnit;
+class DWARFCompileUnit;
+class NameToDIE;
+class SymbolFileDWARF;
+class SymbolFileDWARFDwo;
+
+typedef std::shared_ptr<DWARFUnit> DWARFUnitSP;
+
+enum DWARFProducer {
+  eProducerInvalid = 0,
+  eProducerClang,
+  eProducerGCC,
+  eProducerLLVMGCC,
+  eProcucerOther
+};
+
+class DWARFUnit {
+public:
+  virtual ~DWARFUnit();
+
+  size_t ExtractDIEsIfNeeded(bool cu_die_only);
+  DWARFDIE LookupAddress(const dw_addr_t address);
+  size_t AppendDIEsWithTag(const dw_tag_t tag,
+                           DWARFDIECollection &matching_dies,
+                           uint32_t depth = UINT32_MAX) const;
+  bool Verify(lldb_private::Stream *s) const;
+  void Dump(lldb_private::Stream *s) const;
+  // Offset of the initial length field.
+  dw_offset_t GetOffset() const { return m_offset; }
+  lldb::user_id_t GetID() const;
+  // Size in bytes of the initial length + compile unit header.
+  uint32_t Size() const;
+  bool ContainsDIEOffset(dw_offset_t die_offset) const {
+    return die_offset >= GetFirstDIEOffset() &&
+           die_offset < GetNextCompileUnitOffset();
+  }
+  dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
+  dw_offset_t GetNextCompileUnitOffset() const;
+  // Size of the CU data (without initial length and without header).
+  size_t GetDebugInfoSize() const;
+  // Size of the CU data incl. header but without initial length.
+  uint32_t GetLength() const;
+  uint16_t GetVersion() const;
+  const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
+  dw_offset_t GetAbbrevOffset() const;
+  uint8_t GetAddressByteSize() const;
+  dw_addr_t GetBaseAddress() const;
+  dw_addr_t GetAddrBase() const;
+  dw_addr_t GetRangesBase() const;
+  void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
+  void ClearDIEs(bool keep_compile_unit_die);
+  void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+                              DWARFDebugAranges *debug_aranges);
+
+  lldb::ByteOrder GetByteOrder() const;
+
+  lldb_private::TypeSystem *GetTypeSystem();
+
+  DWARFFormValue::FixedFormSizes GetFixedFormSizes();
+
+  void SetBaseAddress(dw_addr_t base_addr);
+
+  DWARFDIE
+  GetCompileUnitDIEOnly();
+
+  DWARFDIE
+  DIE();
+
+  bool HasDIEsParsed() const;
+
+  DWARFDIE GetDIE(dw_offset_t die_offset);
+
+  static uint8_t GetAddressByteSize(const DWARFUnit *cu);
+
+  static bool IsDWARF64(const DWARFUnit *cu);
+
+  static uint8_t GetDefaultAddressSize();
+
+  static void SetDefaultAddressSize(uint8_t addr_size);
+
+  void *GetUserData() const;
+
+  void SetUserData(void *d);
+
+  bool Supports_DW_AT_APPLE_objc_complete_type();
+
+  bool DW_AT_decl_file_attributes_are_invalid();
+
+  bool Supports_unnamed_objc_bitfields();
+
+  void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames,
+             NameToDIE &func_methods, NameToDIE &func_selectors,
+             NameToDIE &objc_class_selectors, NameToDIE &globals,
+             NameToDIE &types, NameToDIE &namespaces);
+
+  SymbolFileDWARF *GetSymbolFileDWARF() const;
+
+  DWARFProducer GetProducer();
+
+  uint32_t GetProducerVersionMajor();
+
+  uint32_t GetProducerVersionMinor();
+
+  uint32_t GetProducerVersionUpdate();
+
+  static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
+
+  lldb::LanguageType GetLanguageType();
+
+  bool IsDWARF64() const;
+
+  bool GetIsOptimized();
+
+  SymbolFileDWARFDwo *GetDwoSymbolFile() const;
+
+  dw_offset_t GetBaseObjOffset() const;
+
+protected:
+  virtual DWARFCompileUnit &Data() = 0;
+  virtual const DWARFCompileUnit &Data() const = 0;
+
+  DWARFUnit();
+
+  static void
+  IndexPrivate(DWARFUnit *dwarf_cu, const lldb::LanguageType cu_language,
+               const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+               const dw_offset_t cu_offset, NameToDIE &func_basenames,
+               NameToDIE &func_fullnames, NameToDIE &func_methods,
+               NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
+               NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
+
+  // Offset of the initial length field.
+  dw_offset_t m_offset;
+
+private:
+  const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly();
+
+  const DWARFDebugInfoEntry *DIEPtr();
+
+  DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
+};
+
+#endif // SymbolFileDWARF_DWARFUnit_h_




More information about the lldb-commits mailing list