This revision was automatically updated to reflect the committed changes.
Closed by commit rL333178: DWARF: Move indexing code from DWARFUnit to 
ManualDWARFIndex (authored by labath, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D47253

Files:
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h

Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -33,6 +33,9 @@
 class DWARFUnit {
   friend class DWARFCompileUnit;
 
+  using die_iterator_range =
+      llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
+
 public:
   virtual ~DWARFUnit();
 
@@ -134,11 +137,6 @@
 
   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();
@@ -161,6 +159,11 @@
 
   dw_offset_t GetBaseObjOffset() const;
 
+  die_iterator_range dies() {
+    ExtractDIEsIfNeeded(false);
+    return die_iterator_range(m_die_array.begin(), m_die_array.end());
+  }
+
 protected:
   DWARFUnit(SymbolFileDWARF *dwarf);
 
@@ -190,14 +193,6 @@
   // in the main object file
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
 
-  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;
 
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -53,6 +53,18 @@
 
 private:
   void Index();
+  void IndexUnit(DWARFUnit &unit, NameToDIE &func_basenames,
+                 NameToDIE &func_fullnames, NameToDIE &func_methods,
+                 NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
+                 NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
+
+  static void
+  IndexUnitImpl(DWARFUnit &unit, 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);
 
   /// Non-null value means we haven't built the index yet.
   DWARFDebugInfo *m_debug_info;
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -9,20 +9,18 @@
 
 #include "DWARFUnit.h"
 
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timer.h"
 
 #include "DWARFDIECollection.h"
-#include "DWARFDebugAbbrev.h"
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
 #include "LogChannelDWARF.h"
-#include "NameToDIE.h"
 #include "SymbolFileDWARFDebugMap.h"
 #include "SymbolFileDWARFDwo.h"
 
@@ -627,332 +625,6 @@
 
 dw_offset_t DWARFUnit::GetBaseObjOffset() const { return m_base_obj_offset; }
 
-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(!m_dwarf->GetBaseCompileUnit() &&
-         "DWARFUnit associated with .dwo or .dwp "
-         "should not be indexed directly");
-
-  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
-  if (log) {
-    m_dwarf->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->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 don't want
-                // the performance penalty of that right now.
-                is_global_or_static_variable = false;
-                // if (attributes.ExtractFormValueAtIndex(dwarf, i,
-                //                                        form_value)) {
-                //   // If we have valid block data, then we have location
-                //   // expression bytesthat 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:
-              case DW_TAG_partial_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))) {
-            func_fullnames.Insert(ConstString(mangled_cstr),
-                                  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))) {
-            func_fullnames.Insert(ConstString(mangled_cstr),
-                                  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;
-    }
-  }
-}
-
 const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
   if (m_func_aranges_ap.get() == NULL) {
     m_func_aranges_ap.reset(new DWARFDebugAranges());
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -8,8 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Host/TaskPool.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -48,10 +51,10 @@
   auto parser_fn = [&](size_t cu_idx) {
     DWARFUnit *dwarf_cu = debug_info.GetCompileUnitAtIndex(cu_idx);
     if (dwarf_cu) {
-      dwarf_cu->Index(function_basenames[cu_idx], function_fullnames[cu_idx],
-                      function_methods[cu_idx], function_selectors[cu_idx],
-                      objc_class_selectors[cu_idx], globals[cu_idx],
-                      types[cu_idx], namespaces[cu_idx]);
+      IndexUnit(*dwarf_cu, function_basenames[cu_idx],
+                function_fullnames[cu_idx], function_methods[cu_idx],
+                function_selectors[cu_idx], objc_class_selectors[cu_idx],
+                globals[cu_idx], types[cu_idx], namespaces[cu_idx]);
     }
   };
 
@@ -108,6 +111,324 @@
   }
 }
 
+void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, NameToDIE &func_basenames,
+                                 NameToDIE &func_fullnames,
+                                 NameToDIE &func_methods,
+                                 NameToDIE &func_selectors,
+                                 NameToDIE &objc_class_selectors,
+                                 NameToDIE &globals, NameToDIE &types,
+                                 NameToDIE &namespaces) {
+  Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
+
+  if (log) {
+    m_module.LogMessage(
+        log, "ManualDWARFIndex::IndexUnit for compile unit at .debug_info[0x%8.8x]",
+        unit.GetOffset());
+  }
+
+  const LanguageType cu_language = unit.GetLanguageType();
+  DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();
+
+  IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(),
+                func_basenames, func_fullnames, func_methods, func_selectors,
+                objc_class_selectors, globals, types, namespaces);
+
+  SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
+  if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
+    IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
+                  fixed_form_sizes, unit.GetOffset(), func_basenames,
+                  func_fullnames, func_methods, func_selectors,
+                  objc_class_selectors, globals, types, namespaces);
+  }
+}
+
+void ManualDWARFIndex::IndexUnitImpl(
+    DWARFUnit &unit, 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) {
+  for (const DWARFDebugInfoEntry &die : unit.dies()) {
+    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(&unit, 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 don't want
+                // the performance penalty of that right now.
+                is_global_or_static_variable = false;
+                // if (attributes.ExtractFormValueAtIndex(dwarf, i,
+                //                                        form_value)) {
+                //   // If we have valid block data, then we have location
+                //   // expression bytesthat 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:
+              case DW_TAG_partial_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 =
+                    unit.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))) {
+            func_fullnames.Insert(ConstString(mangled_cstr),
+                                  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))) {
+            func_fullnames.Insert(ConstString(mangled_cstr),
+                                  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;
+    }
+  }
+}
+
 void ManualDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
   Index();
   m_globals.Find(name, offsets);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to