[Lldb-commits] [lldb] r332719 - [DWARF] Extract indexing code into a separate class hierarchy

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri May 18 07:15:46 PDT 2018


Author: labath
Date: Fri May 18 07:15:46 2018
New Revision: 332719

URL: http://llvm.org/viewvc/llvm-project?rev=332719&view=rev
Log:
[DWARF] Extract indexing code into a separate class hierarchy

Summary:
This places the `if(m_using_apple_tables)` branches inside the
SymbolFileDWARF class behind an abstract DWARFIndex class. The class
currently has two implementations:
- AppleIndex, which searches using .apple_names and friends
- ManualIndex, which searches using a manually built index

Most of the methods of the class are very simple, and simply extract the
list of DIEs for the given name from the appropriate sub-table. The main
exception are the two GetFunctions overloads, which take a couple of
extra paramenters, including some callbacks. It was not possible to
split these up the same way as other methods, as here we were doing a
lot of post-processing on the results. The post-processing is similar
for the two cases, but not identical. I hope to factor these further in
separate patches.

Other interesting methods are:
- Preload(): do any preprocessing to make lookups faster (noop for
  AppleIndex, forces a build of the lookup tables for ManualIndex).
- ReportInvalidDIEOffset(): Used to notify the users of an invalid index
  (prints a message for AppleIndex, noop for ManualIndex).
- Dump(): dumps the index state (noop for AppleIndex, prints the lookup
  tables for ManualIndex).

Reviewers: clayborg, JDevlieghere

Subscribers: mgorny, aprantl, lldb-commits

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

Added:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp Fri May 18 07:15:46 2018
@@ -0,0 +1,306 @@
+//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/Function.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
+    Module &module, DWARFDataExtractor apple_names,
+    DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
+    DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
+  auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+      apple_names, debug_str, ".apple_names");
+  if (!apple_names_table_up->IsValid())
+    apple_names_table_up.reset();
+
+  auto apple_namespaces_table_up =
+      llvm::make_unique<DWARFMappedHash::MemoryTable>(
+          apple_namespaces, debug_str, ".apple_namespaces");
+  if (!apple_namespaces_table_up->IsValid())
+    apple_namespaces_table_up.reset();
+
+  auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+      apple_types, debug_str, ".apple_types");
+  if (!apple_types_table_up->IsValid())
+    apple_types_table_up.reset();
+
+  auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+      apple_objc, debug_str, ".apple_objc");
+  if (!apple_objc_table_up->IsValid())
+    apple_objc_table_up.reset();
+
+  if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
+      apple_objc_table_up)
+    return llvm::make_unique<AppleDWARFIndex>(
+        module, std::move(apple_names_table_up),
+        std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
+        std::move(apple_objc_table_up));
+
+  return nullptr;
+}
+
+void AppleDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
+  if (!m_apple_names_up)
+    return;
+
+  const char *name_cstr = name.GetCString();
+  llvm::StringRef basename;
+  llvm::StringRef context;
+
+  if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+                                                      basename))
+    basename = name_cstr;
+
+  m_apple_names_up->FindByName(basename, offsets);
+}
+
+void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+                                         DIEArray &offsets) {
+  if (!m_apple_names_up)
+    return;
+
+  DWARFMappedHash::DIEInfoArray hash_data;
+  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
+    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+}
+
+void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+                                         DIEArray &offsets) {
+  if (!m_apple_names_up)
+    return;
+
+  DWARFMappedHash::DIEInfoArray hash_data;
+  if (m_apple_names_up->AppendAllDIEsInRange(
+          cu.GetOffset(), cu.GetNextCompileUnitOffset(), hash_data))
+    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+}
+
+void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
+                                     DIEArray &offsets) {
+  if (m_apple_objc_up)
+    m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
+                                           bool must_be_implementation,
+                                           DIEArray &offsets) {
+  if (m_apple_types_up) {
+    m_apple_types_up->FindCompleteObjCClassByName(
+        class_name.GetStringRef(), offsets, must_be_implementation);
+  }
+}
+
+void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+  if (m_apple_types_up)
+    m_apple_types_up->FindByName(name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
+                               DIEArray &offsets) {
+  if (!m_apple_types_up)
+    return;
+
+  Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+                                          DWARF_LOG_LOOKUPS);
+  const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
+      DWARFMappedHash::eAtomTypeTag);
+  const bool has_qualified_name_hash =
+      m_apple_types_up->GetHeader().header_data.ContainsAtom(
+          DWARFMappedHash::eAtomTypeQualNameHash);
+  const ConstString type_name(context[0].name);
+  const dw_tag_t tag = context[0].tag;
+  if (has_tag && has_qualified_name_hash) {
+    const char *qualified_name = context.GetQualifiedName();
+    const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
+    if (log)
+      m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
+    m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
+        type_name.GetStringRef(), tag, qualified_name_hash, offsets);
+  } else if (has_tag) {
+    if (log)
+      m_module.LogMessage(log, "FindByNameAndTag()");
+    m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
+  } else
+    m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+  if (m_apple_namespaces_up)
+    m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetFunctions(
+    ConstString name, DWARFDebugInfo &info,
+    llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                            lldb_private::SymbolContextList &sc_list)>
+        resolve_function,
+    llvm::function_ref<CompilerDeclContext(lldb::user_id_t type_uid)>
+        get_decl_context_containing_uid,
+    const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+    bool include_inlines, SymbolContextList &sc_list) {
+  if (!m_apple_names_up)
+    return;
+
+  std::set<const DWARFDebugInfoEntry *> resolved_dies;
+  DIEArray offsets;
+
+  uint32_t num_matches = 0;
+
+  if (name_type_mask & eFunctionNameTypeFull) {
+    // If they asked for the full name, match what they typed.  At some
+    // point we may want to canonicalize this (strip double spaces, etc.
+    // For now, we just add all the dies that we find by exact match.
+    num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets);
+    for (uint32_t i = 0; i < num_matches; i++) {
+      const DIERef &die_ref = offsets[i];
+      DWARFDIE die = info.GetDIE(die_ref);
+      if (die) {
+        if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+          continue; // The containing decl contexts don't match
+
+        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+          if (resolve_function(die, include_inlines, sc_list))
+            resolved_dies.insert(die.GetDIE());
+        }
+      } else
+        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
+    }
+  }
+
+  if (name_type_mask & eFunctionNameTypeSelector) {
+    if (parent_decl_ctx && parent_decl_ctx->IsValid())
+      return; // no selectors in namespaces
+
+    num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets);
+    // Now make sure these are actually ObjC methods.  In this case we can
+    // simply look up the name, and if it is an ObjC method name, we're
+    // good.
+
+    for (uint32_t i = 0; i < num_matches; i++) {
+      const DIERef &die_ref = offsets[i];
+      DWARFDIE die = info.GetDIE(die_ref);
+      if (die) {
+        const char *die_name = die.GetName();
+        if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) {
+          if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+            if (resolve_function(die, include_inlines, sc_list))
+              resolved_dies.insert(die.GetDIE());
+          }
+        }
+      } else
+        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
+    }
+    offsets.clear();
+  }
+
+  if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) ||
+      name_type_mask & eFunctionNameTypeBase) {
+    // The apple_names table stores just the "base name" of C++ methods in
+    // the table.  So we have to extract the base name, look that up, and
+    // if there is any other information in the name we were passed in we
+    // have to post-filter based on that.
+
+    // FIXME: Arrange the logic above so that we don't calculate the base
+    // name twice:
+    num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets);
+
+    for (uint32_t i = 0; i < num_matches; i++) {
+      const DIERef &die_ref = offsets[i];
+      DWARFDIE die = info.GetDIE(die_ref);
+      if (die) {
+        if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+          continue; // The containing decl contexts don't match
+
+        // If we get to here, the die is good, and we should add it:
+        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
+            resolve_function(die, include_inlines, sc_list)) {
+          bool keep_die = true;
+          if ((name_type_mask &
+               (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
+              (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
+            // We are looking for either basenames or methods, so we need
+            // to trim out the ones we won't want by looking at the type
+            SymbolContext sc;
+            if (sc_list.GetLastContext(sc)) {
+              if (sc.block) {
+                // We have an inlined function
+              } else if (sc.function) {
+                Type *type = sc.function->GetType();
+
+                if (type) {
+                  CompilerDeclContext decl_ctx =
+                      get_decl_context_containing_uid(type->GetID());
+                  if (decl_ctx.IsStructUnionOrClass()) {
+                    if (name_type_mask & eFunctionNameTypeBase) {
+                      sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+                      keep_die = false;
+                    }
+                  } else {
+                    if (name_type_mask & eFunctionNameTypeMethod) {
+                      sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+                      keep_die = false;
+                    }
+                  }
+                } else {
+                  m_module.ReportWarning(
+                      "function at die offset 0x%8.8x had no function type",
+                      die_ref.die_offset);
+                }
+              }
+            }
+          }
+          if (keep_die)
+            resolved_dies.insert(die.GetDIE());
+        }
+      } else
+        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
+    }
+    offsets.clear();
+  }
+}
+
+void AppleDWARFIndex::GetFunctions(
+    const RegularExpression &regex, DWARFDebugInfo &info,
+    llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                            lldb_private::SymbolContextList &sc_list)>
+        resolve_function,
+    bool include_inlines, SymbolContextList &sc_list) {
+  if (!m_apple_names_up)
+    return;
+
+  DIEArray offsets;
+  DWARFMappedHash::DIEInfoArray hash_data;
+  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) {
+    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+    ParseFunctions(offsets, info, resolve_function, include_inlines, sc_list);
+  }
+}
+
+void AppleDWARFIndex::ReportInvalidDIEOffset(dw_offset_t offset,
+                                             llvm::StringRef name) {
+  m_module.ReportErrorIfModifyDetected(
+      "the DWARF debug information has been modified (accelerator table had "
+      "bad die 0x%8.8x for '%s')\n",
+      offset, name.str().c_str());
+}
+
+void AppleDWARFIndex::Dump(Stream &s) {
+  // TODO: Implement dumping.
+}

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h Fri May 18 07:15:46 2018
@@ -0,0 +1,74 @@
+//===-- AppleDWARFIndex.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_APPLEDWARFINDEX_H
+#define LLDB_APPLEDWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h"
+
+namespace lldb_private {
+class AppleDWARFIndex : public DWARFIndex {
+public:
+  static std::unique_ptr<AppleDWARFIndex>
+  Create(Module &module, DWARFDataExtractor apple_names,
+         DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
+         DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str);
+
+  AppleDWARFIndex(
+      Module &module, std::unique_ptr<DWARFMappedHash::MemoryTable> apple_names,
+      std::unique_ptr<DWARFMappedHash::MemoryTable> apple_namespaces,
+      std::unique_ptr<DWARFMappedHash::MemoryTable> apple_types,
+      std::unique_ptr<DWARFMappedHash::MemoryTable> apple_objc)
+      : DWARFIndex(module), m_apple_names_up(std::move(apple_names)),
+        m_apple_namespaces_up(std::move(apple_namespaces)),
+        m_apple_types_up(std::move(apple_types)),
+        m_apple_objc_up(std::move(apple_objc)) {}
+
+  void Preload() override {}
+
+  void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+  void GetGlobalVariables(const RegularExpression &regex,
+                          DIEArray &offsets) override;
+  void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+  void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
+  void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                            DIEArray &offsets) override;
+  void GetTypes(ConstString name, DIEArray &offsets) override;
+  void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
+  void GetNamespaces(ConstString name, DIEArray &offsets) override;
+  void GetFunctions(
+      ConstString name, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      llvm::function_ref<CompilerDeclContext(lldb::user_id_t type_uid)>
+          get_decl_context_containing_uid,
+      const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+      bool include_inlines, SymbolContextList &sc_list) override;
+  void GetFunctions(
+      const RegularExpression &regex, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      bool include_inlines, SymbolContextList &sc_list) override;
+
+  void ReportInvalidDIEOffset(dw_offset_t offset,
+                              llvm::StringRef name) override;
+  void Dump(Stream &s) override;
+
+private:
+  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_up;
+  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_up;
+  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_up;
+  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_up;
+};
+} // namespace lldb_private
+
+#endif // LLDB_APPLEDWARFINDEX_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=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt Fri May 18 07:15:46 2018
@@ -1,4 +1,5 @@
 add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
+  AppleDWARFIndex.cpp
   DIERef.cpp
   DWARFAbbreviationDeclaration.cpp
   DWARFASTParserClang.cpp
@@ -23,9 +24,11 @@ add_lldb_library(lldbPluginSymbolFileDWA
   DWARFDIE.cpp
   DWARFDIECollection.cpp
   DWARFFormValue.cpp
+  DWARFIndex.cpp
   DWARFUnit.cpp
   HashedNameToDIE.cpp
   LogChannelDWARF.cpp
+  ManualDWARFIndex.cpp
   NameToDIE.cpp
   SymbolFileDWARF.cpp
   SymbolFileDWARFDwo.cpp

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp?rev=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp Fri May 18 07:15:46 2018
@@ -10,6 +10,7 @@
 #include "DWARFAbbreviationDeclaration.h"
 
 #include "lldb/Core/dwarf.h"
+#include "lldb/Utility/Stream.h"
 
 #include "DWARFFormValue.h"
 

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=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Fri May 18 07:15:46 2018
@@ -10,6 +10,7 @@
 #include "DWARFCompileUnit.h"
 
 #include "SymbolFileDWARF.h"
+#include "lldb/Utility/Stream.h"
 
 using namespace lldb;
 using namespace lldb_private;

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp Fri May 18 07:15:46 2018
@@ -0,0 +1,31 @@
+//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+DWARFIndex::~DWARFIndex() = default;
+
+void DWARFIndex::ParseFunctions(
+    const DIEArray &offsets, DWARFDebugInfo &info,
+    llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                            lldb_private::SymbolContextList &sc_list)>
+        resolve_function,
+    bool include_inlines, SymbolContextList &sc_list) {
+  const size_t num_matches = offsets.size();
+  for (size_t i = 0; i < num_matches; ++i) {
+    DWARFDIE die = info.GetDIE(offsets[i]);
+    if (die)
+      resolve_function(die, include_inlines, sc_list);
+  }
+}

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h Fri May 18 07:15:46 2018
@@ -0,0 +1,71 @@
+//===-- DWARFIndex.h -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_DWARFINDEX_H
+#define LLDB_DWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DIERef.h"
+#include "Plugins/SymbolFile/DWARF/DWARFFormValue.h"
+
+class DWARFDebugInfo;
+class DWARFDeclContext;
+class DWARFDIE;
+
+namespace lldb_private {
+class DWARFIndex {
+public:
+  DWARFIndex(Module &module) : m_module(module) {}
+  virtual ~DWARFIndex();
+
+  virtual void Preload() = 0;
+
+  virtual void GetGlobalVariables(ConstString name, DIEArray &offsets) = 0;
+  virtual void GetGlobalVariables(const RegularExpression &regex,
+                                  DIEArray &offsets) = 0;
+  virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;
+  virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0;
+  virtual void GetCompleteObjCClass(ConstString class_name,
+                                    bool must_be_implementation,
+                                    DIEArray &offsets) = 0;
+  virtual void GetTypes(ConstString name, DIEArray &offsets) = 0;
+  virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0;
+  virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0;
+  virtual void GetFunctions(
+      ConstString name, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      llvm::function_ref<CompilerDeclContext(lldb::user_id_t type_uid)>
+          get_decl_context_containing_uid,
+      const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+      bool include_inlines, SymbolContextList &sc_list) = 0;
+  virtual void GetFunctions(
+      const RegularExpression &regex, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      bool include_inlines, SymbolContextList &sc_list) = 0;
+
+  virtual void ReportInvalidDIEOffset(dw_offset_t offset,
+                                      llvm::StringRef name) = 0;
+  virtual void Dump(Stream &s) = 0;
+
+protected:
+  Module &m_module;
+
+  void ParseFunctions(
+      const DIEArray &offsets, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      bool include_inlines, SymbolContextList &sc_list);
+};
+} // namespace lldb_private
+
+#endif // LLDB_DWARFINDEX_H

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp?rev=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp Fri May 18 07:15:46 2018
@@ -22,6 +22,7 @@
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
 #include "LogChannelDWARF.h"
+#include "NameToDIE.h"
 #include "SymbolFileDWARFDebugMap.h"
 #include "SymbolFileDWARFDwo.h"
 

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp Fri May 18 07:15:46 2018
@@ -0,0 +1,278 @@
+//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Host/TaskPool.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/Timer.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+void ManualDWARFIndex::Index() {
+  if (!m_debug_info)
+    return;
+
+  DWARFDebugInfo &debug_info = *m_debug_info;
+  m_debug_info = nullptr;
+
+  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+  Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));
+
+  const uint32_t num_compile_units = debug_info.GetNumCompileUnits();
+  if (num_compile_units == 0)
+    return;
+
+  std::vector<NameToDIE> function_basenames(num_compile_units);
+  std::vector<NameToDIE> function_fullnames(num_compile_units);
+  std::vector<NameToDIE> function_methods(num_compile_units);
+  std::vector<NameToDIE> function_selectors(num_compile_units);
+  std::vector<NameToDIE> objc_class_selectors(num_compile_units);
+  std::vector<NameToDIE> globals(num_compile_units);
+  std::vector<NameToDIE> types(num_compile_units);
+  std::vector<NameToDIE> namespaces(num_compile_units);
+
+  // std::vector<bool> might be implemented using bit test-and-set, so use
+  // uint8_t instead.
+  std::vector<uint8_t> clear_cu_dies(num_compile_units, false);
+  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]);
+    }
+  };
+
+  auto extract_fn = [&debug_info, &clear_cu_dies](size_t cu_idx) {
+    DWARFUnit *dwarf_cu = debug_info.GetCompileUnitAtIndex(cu_idx);
+    if (dwarf_cu) {
+      // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the DIEs
+      // for a compile unit have already been parsed.
+      if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1)
+        clear_cu_dies[cu_idx] = true;
+    }
+  };
+
+  // Create a task runner that extracts dies for each DWARF compile unit in a
+  // separate thread
+  //----------------------------------------------------------------------
+  // First figure out which compile units didn't have their DIEs already
+  // parsed and remember this.  If no DIEs were parsed prior to this index
+  // function call, we are going to want to clear the CU dies after we are
+  // done indexing to make sure we don't pull in all DWARF dies, but we need
+  // to wait until all compile units have been indexed in case a DIE in one
+  // compile unit refers to another and the indexes accesses those DIEs.
+  //----------------------------------------------------------------------
+  TaskMapOverInt(0, num_compile_units, extract_fn);
+
+  // Now create a task runner that can index each DWARF compile unit in a
+  // separate thread so we can index quickly.
+
+  TaskMapOverInt(0, num_compile_units, parser_fn);
+
+  auto finalize_fn = [](NameToDIE &index, std::vector<NameToDIE> &srcs) {
+    for (auto &src : srcs)
+      index.Append(src);
+    index.Finalize();
+  };
+
+  TaskPool::RunTasks(
+      [&]() { finalize_fn(m_function_basenames, function_basenames); },
+      [&]() { finalize_fn(m_function_fullnames, function_fullnames); },
+      [&]() { finalize_fn(m_function_methods, function_methods); },
+      [&]() { finalize_fn(m_function_selectors, function_selectors); },
+      [&]() { finalize_fn(m_objc_class_selectors, objc_class_selectors); },
+      [&]() { finalize_fn(m_globals, globals); },
+      [&]() { finalize_fn(m_types, types); },
+      [&]() { finalize_fn(m_namespaces, namespaces); });
+
+  //----------------------------------------------------------------------
+  // Keep memory down by clearing DIEs for any compile units if indexing
+  // caused us to load the compile unit's DIEs.
+  //----------------------------------------------------------------------
+  for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+    if (clear_cu_dies[cu_idx])
+      debug_info.GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
+  }
+}
+
+void ManualDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
+  Index();
+  m_globals.Find(name, offsets);
+}
+
+void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+                                          DIEArray &offsets) {
+  Index();
+  m_globals.Find(regex, offsets);
+}
+
+void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+                                          DIEArray &offsets) {
+  Index();
+  m_globals.FindAllEntriesForCompileUnit(cu.GetOffset(), offsets);
+}
+
+void ManualDWARFIndex::GetObjCMethods(ConstString class_name,
+                                      DIEArray &offsets) {
+  Index();
+  m_objc_class_selectors.Find(class_name, offsets);
+}
+
+void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name,
+                                            bool must_be_implementation,
+                                            DIEArray &offsets) {
+  Index();
+  m_types.Find(class_name, offsets);
+}
+
+void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+  Index();
+  m_types.Find(name, offsets);
+}
+
+void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context,
+                                DIEArray &offsets) {
+  Index();
+  m_types.Find(ConstString(context[0].name), offsets);
+}
+
+void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+  Index();
+  m_namespaces.Find(name, offsets);
+}
+
+void ManualDWARFIndex::GetFunctions(
+    ConstString name, DWARFDebugInfo &info,
+    llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                            lldb_private::SymbolContextList &sc_list)>
+        resolve_function,
+    llvm::function_ref<CompilerDeclContext(lldb::user_id_t type_uid)>
+        get_decl_context_containing_uid,
+    const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+    bool include_inlines, SymbolContextList &sc_list) {
+
+  Index();
+
+  std::set<const DWARFDebugInfoEntry *> resolved_dies;
+  DIEArray offsets;
+  if (name_type_mask & eFunctionNameTypeFull) {
+    uint32_t num_matches = m_function_basenames.Find(name, offsets);
+    num_matches += m_function_methods.Find(name, offsets);
+    num_matches += m_function_fullnames.Find(name, offsets);
+    for (uint32_t i = 0; i < num_matches; i++) {
+      const DIERef &die_ref = offsets[i];
+      DWARFDIE die = info.GetDIE(die_ref);
+      if (die) {
+        if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+          continue; // The containing decl contexts don't match
+
+        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+          if (resolve_function(die, include_inlines, sc_list))
+            resolved_dies.insert(die.GetDIE());
+        }
+      }
+    }
+    offsets.clear();
+  }
+  if (name_type_mask & eFunctionNameTypeBase) {
+    uint32_t num_base = m_function_basenames.Find(name, offsets);
+    for (uint32_t i = 0; i < num_base; i++) {
+      DWARFDIE die = info.GetDIE(offsets[i]);
+      if (die) {
+        if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+          continue; // The containing decl contexts don't match
+
+        // If we get to here, the die is good, and we should add it:
+        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+          if (resolve_function(die, include_inlines, sc_list))
+            resolved_dies.insert(die.GetDIE());
+        }
+      }
+    }
+    offsets.clear();
+  }
+
+  if (name_type_mask & eFunctionNameTypeMethod) {
+    if (parent_decl_ctx && parent_decl_ctx->IsValid())
+      return; // no methods in namespaces
+
+    uint32_t num_base = m_function_methods.Find(name, offsets);
+    {
+      for (uint32_t i = 0; i < num_base; i++) {
+        DWARFDIE die = info.GetDIE(offsets[i]);
+        if (die) {
+          // If we get to here, the die is good, and we should add it:
+          if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+            if (resolve_function(die, include_inlines, sc_list))
+              resolved_dies.insert(die.GetDIE());
+          }
+        }
+      }
+    }
+    offsets.clear();
+  }
+
+  if ((name_type_mask & eFunctionNameTypeSelector) &&
+      (!parent_decl_ctx || !parent_decl_ctx->IsValid())) {
+    uint32_t num_selectors = m_function_selectors.Find(name, offsets);
+    for (uint32_t i = 0; i < num_selectors; i++) {
+      DWARFDIE die = info.GetDIE(offsets[i]);
+      if (die) {
+        // If we get to here, the die is good, and we should add it:
+        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+          if (resolve_function(die, include_inlines, sc_list))
+            resolved_dies.insert(die.GetDIE());
+        }
+      }
+    }
+  }
+}
+
+void ManualDWARFIndex::GetFunctions(
+    const RegularExpression &regex, DWARFDebugInfo &info,
+    llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                            lldb_private::SymbolContextList &sc_list)>
+        resolve_function,
+    bool include_inlines, SymbolContextList &sc_list) {
+  Index();
+
+  DIEArray offsets;
+  m_function_basenames.Find(regex, offsets);
+  m_function_fullnames.Find(regex, offsets);
+  ParseFunctions(offsets, info, resolve_function, include_inlines, sc_list);
+}
+
+void ManualDWARFIndex::Dump(Stream &s) {
+  s.Format("DWARF index for ({0}) '{1:F}':",
+           m_module.GetArchitecture().GetArchitectureName(),
+           m_module.GetObjectFile()->GetFileSpec());
+  s.Printf("\nFunction basenames:\n");
+  m_function_basenames.Dump(&s);
+  s.Printf("\nFunction fullnames:\n");
+  m_function_fullnames.Dump(&s);
+  s.Printf("\nFunction methods:\n");
+  m_function_methods.Dump(&s);
+  s.Printf("\nFunction selectors:\n");
+  m_function_selectors.Dump(&s);
+  s.Printf("\nObjective C class selectors:\n");
+  m_objc_class_selectors.Dump(&s);
+  s.Printf("\nGlobals and statics:\n");
+  m_globals.Dump(&s);
+  s.Printf("\nTypes:\n");
+  m_types.Dump(&s);
+  s.Printf("\nNamespaces:\n");
+  m_namespaces.Dump(&s);
+}

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h?rev=332719&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h Fri May 18 07:15:46 2018
@@ -0,0 +1,71 @@
+//===-- ManulaDWARFIndex.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_MANUALDWARFINDEX_H
+#define LLDB_MANUALDWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
+
+namespace lldb_private {
+class ManualDWARFIndex : public DWARFIndex {
+public:
+  ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info)
+      : DWARFIndex(module), m_debug_info(debug_info) {}
+
+  void Preload() override { Index(); }
+
+  void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+  void GetGlobalVariables(const RegularExpression &regex,
+                          DIEArray &offsets) override;
+  void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+  void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
+  void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                            DIEArray &offsets) override;
+  void GetTypes(ConstString name, DIEArray &offsets) override;
+  void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
+  void GetNamespaces(ConstString name, DIEArray &offsets) override;
+  void GetFunctions(
+      ConstString name, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      llvm::function_ref<CompilerDeclContext(lldb::user_id_t type_uid)>
+          get_decl_context_containing_uid,
+      const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+      bool include_inlines, SymbolContextList &sc_list) override;
+  void GetFunctions(
+      const RegularExpression &regex, DWARFDebugInfo &info,
+      llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
+                              lldb_private::SymbolContextList &sc_list)>
+          resolve_function,
+      bool include_inlines, SymbolContextList &sc_list) override;
+
+  void ReportInvalidDIEOffset(dw_offset_t offset,
+                              llvm::StringRef name) override {}
+  void Dump(Stream &s) override;
+
+private:
+  void Index();
+
+  /// Non-null value means we haven't built the index yet.
+  DWARFDebugInfo *m_debug_info;
+
+  NameToDIE m_function_basenames;
+  NameToDIE m_function_fullnames;
+  NameToDIE m_function_methods;
+  NameToDIE m_function_selectors;
+  NameToDIE m_objc_class_selectors;
+  NameToDIE m_globals;
+  NameToDIE m_types;
+  NameToDIE m_namespaces;
+};
+} // namespace lldb_private
+
+#endif // LLDB_MANUALDWARFINDEX_H

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri May 18 07:15:46 2018
@@ -49,16 +49,11 @@
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
 
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
-
 #include "lldb/Target/Language.h"
 
-#include "lldb/Host/TaskPool.h"
-
+#include "AppleDWARFIndex.h"
 #include "DWARFASTParser.h"
 #include "DWARFASTParserClang.h"
-#include "DWARFUnit.h"
 #include "DWARFDIECollection.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugAranges.h"
@@ -68,7 +63,9 @@
 #include "DWARFDebugRanges.h"
 #include "DWARFDeclContext.h"
 #include "DWARFFormValue.h"
+#include "DWARFUnit.h"
 #include "LogChannelDWARF.h"
+#include "ManualDWARFIndex.h"
 #include "SymbolFileDWARFDebugMap.h"
 #include "SymbolFileDWARFDwo.h"
 #include "SymbolFileDWARFDwp.h"
@@ -393,21 +390,16 @@ SymbolFileDWARF::GetParentSymbolContextD
 }
 
 SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
-    : SymbolFile(objfile),
-      UserID(uint64_t(DW_INVALID_OFFSET) << 32), // Used by SymbolFileDWARFDebugMap to when
-                                                 // this class parses .o files to contain
-                                                 // the .o file index/ID
+    : SymbolFile(objfile), UserID(uint64_t(DW_INVALID_OFFSET)
+                                  << 32), // Used by SymbolFileDWARFDebugMap to
+                                          // when this class parses .o files to
+                                          // contain the .o file index/ID
       m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
       m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
       m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
       m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(),
       m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(),
-      m_line(), m_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(),
-      m_apple_objc_ap(), m_function_basename_index(),
-      m_function_fullname_index(), m_function_method_index(),
-      m_function_selector_index(), m_objc_class_selectors_index(),
-      m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false),
-      m_using_apple_tables(false), m_fetched_external_modules(false),
+      m_line(), m_fetched_external_modules(false),
       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
       m_unique_ast_type_map() {}
 
@@ -450,45 +442,19 @@ void SymbolFileDWARF::InitializeObject()
       m_obj_file->ReadSectionData(section, m_dwarf_data);
   }
 
-  get_apple_names_data();
-  if (m_data_apple_names.m_data.GetByteSize() > 0) {
-    m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable(
-        m_data_apple_names.m_data, get_debug_str_data(), ".apple_names"));
-    if (m_apple_names_ap->IsValid())
-      m_using_apple_tables = true;
-    else
-      m_apple_names_ap.reset();
-  }
-  get_apple_types_data();
-  if (m_data_apple_types.m_data.GetByteSize() > 0) {
-    m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable(
-        m_data_apple_types.m_data, get_debug_str_data(), ".apple_types"));
-    if (m_apple_types_ap->IsValid())
-      m_using_apple_tables = true;
-    else
-      m_apple_types_ap.reset();
-  }
-
-  get_apple_namespaces_data();
-  if (m_data_apple_namespaces.m_data.GetByteSize() > 0) {
-    m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable(
-        m_data_apple_namespaces.m_data, get_debug_str_data(),
-        ".apple_namespaces"));
-    if (m_apple_namespaces_ap->IsValid())
-      m_using_apple_tables = true;
-    else
-      m_apple_namespaces_ap.reset();
-  }
-
-  get_apple_objc_data();
-  if (m_data_apple_objc.m_data.GetByteSize() > 0) {
-    m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable(
-        m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc"));
-    if (m_apple_objc_ap->IsValid())
-      m_using_apple_tables = true;
-    else
-      m_apple_objc_ap.reset();
-  }
+  DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
+  LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);
+  LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);
+  LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);
+  LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);
+
+  m_index = AppleDWARFIndex::Create(*GetObjectFile()->GetModule(), apple_names,
+                                    apple_namespaces, apple_types, apple_objc,
+                                    get_debug_str_data());
+
+  if (!m_index)
+    m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+                                                  DebugInfo());
 }
 
 bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@@ -1509,16 +1475,7 @@ SymbolFileDWARF::GetCompUnitForDWARFComp
 size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
                                                 DIEArray &method_die_offsets) {
   method_die_offsets.clear();
-  if (m_using_apple_tables) {
-    if (m_apple_objc_ap.get())
-      m_apple_objc_ap->FindByName(class_name.GetStringRef(),
-                                  method_die_offsets);
-  } else {
-    if (!m_indexed)
-      Index();
-
-    m_objc_class_selectors_index.Find(class_name, method_die_offsets);
-  }
+  m_index->GetObjCMethods(class_name, method_die_offsets);
   return method_die_offsets.size();
 }
 
@@ -1981,133 +1938,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolC
 void SymbolFileDWARF::PreloadSymbols() {
   std::lock_guard<std::recursive_mutex> guard(
       GetObjectFile()->GetModule()->GetMutex());
-  Index();
-}
-
-void SymbolFileDWARF::Index() {
-  if (m_indexed)
-    return;
-  m_indexed = true;
-  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-  Timer scoped_timer(
-      func_cat, "SymbolFileDWARF::Index (%s)",
-      GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
-
-  DWARFDebugInfo *debug_info = DebugInfo();
-  if (debug_info) {
-    const uint32_t num_compile_units = GetNumCompileUnits();
-    if (num_compile_units == 0)
-      return;
-
-    std::vector<NameToDIE> function_basename_index(num_compile_units);
-    std::vector<NameToDIE> function_fullname_index(num_compile_units);
-    std::vector<NameToDIE> function_method_index(num_compile_units);
-    std::vector<NameToDIE> function_selector_index(num_compile_units);
-    std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
-    std::vector<NameToDIE> global_index(num_compile_units);
-    std::vector<NameToDIE> type_index(num_compile_units);
-    std::vector<NameToDIE> namespace_index(num_compile_units);
-
-    // std::vector<bool> might be implemented using bit test-and-set, so use
-    // uint8_t instead.
-    std::vector<uint8_t> clear_cu_dies(num_compile_units, false);
-    auto parser_fn = [debug_info, &function_basename_index,
-                      &function_fullname_index, &function_method_index,
-                      &function_selector_index, &objc_class_selectors_index,
-                      &global_index, &type_index,
-                      &namespace_index](size_t cu_idx) {
-      DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-      if (dwarf_cu) {
-        dwarf_cu->Index(
-            function_basename_index[cu_idx], function_fullname_index[cu_idx],
-            function_method_index[cu_idx], function_selector_index[cu_idx],
-            objc_class_selectors_index[cu_idx], global_index[cu_idx],
-            type_index[cu_idx], namespace_index[cu_idx]);
-      }
-    };
-
-    auto extract_fn = [debug_info, &clear_cu_dies](size_t cu_idx) {
-      DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-      if (dwarf_cu) {
-        // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the DIEs
-        // for a compile unit have already been parsed.
-        if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1)
-          clear_cu_dies[cu_idx] = true;
-      }
-    };
-
-    // Create a task runner that extracts dies for each DWARF compile unit in a
-    // separate thread
-    //----------------------------------------------------------------------
-    // First figure out which compile units didn't have their DIEs already
-    // parsed and remember this.  If no DIEs were parsed prior to this index
-    // function call, we are going to want to clear the CU dies after we are
-    // done indexing to make sure we don't pull in all DWARF dies, but we need
-    // to wait until all compile units have been indexed in case a DIE in one
-    // compile unit refers to another and the indexes accesses those DIEs.
-    //----------------------------------------------------------------------
-    TaskMapOverInt(0, num_compile_units, extract_fn);
-
-    // Now create a task runner that can index each DWARF compile unit in a
-    // separate thread so we can index quickly.
-
-    TaskMapOverInt(0, num_compile_units, parser_fn);
-
-    auto finalize_fn = [](NameToDIE &index, std::vector<NameToDIE> &srcs) {
-      for (auto &src : srcs)
-        index.Append(src);
-      index.Finalize();
-    };
-
-    TaskPool::RunTasks(
-        [&]() {
-          finalize_fn(m_function_basename_index, function_basename_index);
-        },
-        [&]() {
-          finalize_fn(m_function_fullname_index, function_fullname_index);
-        },
-        [&]() { finalize_fn(m_function_method_index, function_method_index); },
-        [&]() {
-          finalize_fn(m_function_selector_index, function_selector_index);
-        },
-        [&]() {
-          finalize_fn(m_objc_class_selectors_index, objc_class_selectors_index);
-        },
-        [&]() { finalize_fn(m_global_index, global_index); },
-        [&]() { finalize_fn(m_type_index, type_index); },
-        [&]() { finalize_fn(m_namespace_index, namespace_index); });
-
-    //----------------------------------------------------------------------
-    // Keep memory down by clearing DIEs for any compile units if indexing
-    // caused us to load the compile unit's DIEs.
-    //----------------------------------------------------------------------
-    for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
-      if (clear_cu_dies[cu_idx])
-        debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
-    }
-
-#if defined(ENABLE_DEBUG_PRINTF)
-    StreamFile s(stdout, false);
-    s.Printf("DWARF index for '%s':",
-             GetObjectFile()->GetFileSpec().GetPath().c_str());
-    s.Printf("\nFunction basenames:\n");
-    m_function_basename_index.Dump(&s);
-    s.Printf("\nFunction fullnames:\n");
-    m_function_fullname_index.Dump(&s);
-    s.Printf("\nFunction methods:\n");
-    m_function_method_index.Dump(&s);
-    s.Printf("\nFunction selectors:\n");
-    m_function_selector_index.Dump(&s);
-    s.Printf("\nObjective C class selectors:\n");
-    m_objc_class_selectors_index.Dump(&s);
-    s.Printf("\nGlobals and statics:\n");
-    m_global_index.Dump(&s);
-    s.Printf("\nTypes:\n");
-    m_type_index.Dump(&s);
-    s.Printf("\nNamespaces:\n");
-    m_namespace_index.Dump(&s);
-#endif
-  }
+  m_index->Preload();
 }
 
 bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
@@ -2163,27 +1994,7 @@ uint32_t SymbolFileDWARF::FindGlobalVari
   const uint32_t original_size = variables.GetSize();
 
   DIEArray die_offsets;
-
-  if (m_using_apple_tables) {
-    if (m_apple_names_ap.get()) {
-      const char *name_cstr = name.GetCString();
-      llvm::StringRef basename;
-      llvm::StringRef context;
-
-      if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
-                                                          basename))
-        basename = name_cstr;
-
-      m_apple_names_ap->FindByName(basename, die_offsets);
-    }
-  } else {
-    // Index the DWARF if we haven't already
-    if (!m_indexed)
-      Index();
-
-    m_global_index.Find(name, die_offsets);
-  }
-
+  m_index->GetGlobalVariables(name, die_offsets);
   const size_t num_die_matches = die_offsets.size();
   if (num_die_matches) {
     SymbolContext sc;
@@ -2226,12 +2037,8 @@ uint32_t SymbolFileDWARF::FindGlobalVari
         } break;
         }
       } else {
-        if (m_using_apple_tables) {
-          GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-              "the DWARF debug information has been modified (.apple_names "
-              "accelerator table had bad die 0x%8.8x for '%s')\n",
-              die_ref.die_offset, name.GetCString());
-        }
+        m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                        name.GetStringRef());
       }
     }
   }
@@ -2273,21 +2080,7 @@ uint32_t SymbolFileDWARF::FindGlobalVari
   const uint32_t original_size = variables.GetSize();
 
   DIEArray die_offsets;
-
-  if (m_using_apple_tables) {
-    if (m_apple_names_ap.get()) {
-      DWARFMappedHash::DIEInfoArray hash_data_array;
-      if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex,
-                                                           hash_data_array))
-        DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
-    }
-  } else {
-    // Index the DWARF if we haven't already
-    if (!m_indexed)
-      Index();
-
-    m_global_index.Find(regex, die_offsets);
-  }
+  m_index->GetGlobalVariables(regex, die_offsets);
 
   SymbolContext sc;
   sc.module_sp = m_obj_file->GetModule();
@@ -2306,14 +2099,8 @@ uint32_t SymbolFileDWARF::FindGlobalVari
 
         if (variables.GetSize() - original_size >= max_matches)
           break;
-      } else {
-        if (m_using_apple_tables) {
-          GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-              "the DWARF debug information has been modified (.apple_names "
-              "accelerator table had bad die 0x%8.8x for regex '%s')\n",
-              die_ref.die_offset, regex.GetText().str().c_str());
-        }
-      }
+      } else
+        m_index->ReportInvalidDIEOffset(die_ref.die_offset, regex.GetText());
     }
   }
 
@@ -2381,48 +2168,6 @@ bool SymbolFileDWARF::ResolveFunction(co
   return false;
 }
 
-void SymbolFileDWARF::FindFunctions(const ConstString &name,
-                                    const NameToDIE &name_to_die,
-                                    bool include_inlines,
-                                    SymbolContextList &sc_list) {
-  DIEArray die_offsets;
-  if (name_to_die.Find(name, die_offsets)) {
-    ParseFunctions(die_offsets, include_inlines, sc_list);
-  }
-}
-
-void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
-                                    const NameToDIE &name_to_die,
-                                    bool include_inlines,
-                                    SymbolContextList &sc_list) {
-  DIEArray die_offsets;
-  if (name_to_die.Find(regex, die_offsets)) {
-    ParseFunctions(die_offsets, include_inlines, sc_list);
-  }
-}
-
-void SymbolFileDWARF::FindFunctions(
-    const RegularExpression &regex,
-    const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines,
-    SymbolContextList &sc_list) {
-  DIEArray die_offsets;
-  DWARFMappedHash::DIEInfoArray hash_data_array;
-  if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) {
-    DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
-    ParseFunctions(die_offsets, include_inlines, sc_list);
-  }
-}
-
-void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets,
-                                     bool include_inlines,
-                                     SymbolContextList &sc_list) {
-  const size_t num_matches = die_offsets.size();
-  if (num_matches) {
-    for (size_t i = 0; i < num_matches; ++i)
-      ResolveFunction(die_offsets[i], include_inlines, sc_list);
-  }
-}
-
 bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
                                        const DWARFDIE &die) {
   // If we have no parent decl context to match this DIE matches, and if the
@@ -2485,210 +2230,16 @@ SymbolFileDWARF::FindFunctions(const Con
   if (info == NULL)
     return 0;
 
-  std::set<const DWARFDebugInfoEntry *> resolved_dies;
-  if (m_using_apple_tables) {
-    if (m_apple_names_ap.get()) {
-
-      DIEArray die_offsets;
-
-      uint32_t num_matches = 0;
-
-      if (name_type_mask & eFunctionNameTypeFull) {
-        // If they asked for the full name, match what they typed.  At some
-        // point we may want to canonicalize this (strip double spaces, etc.
-        // For now, we just add all the dies that we find by exact match.
-        num_matches =
-            m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets);
-        for (uint32_t i = 0; i < num_matches; i++) {
-          const DIERef &die_ref = die_offsets[i];
-          DWARFDIE die = info->GetDIE(die_ref);
-          if (die) {
-            if (!DIEInDeclContext(parent_decl_ctx, die))
-              continue; // The containing decl contexts don't match
-
-            if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
-              if (ResolveFunction(die, include_inlines, sc_list))
-                resolved_dies.insert(die.GetDIE());
-            }
-          } else {
-            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-                "the DWARF debug information has been modified (.apple_names "
-                "accelerator table had bad die 0x%8.8x for '%s')",
-                die_ref.die_offset, name.GetCString());
-          }
-        }
-      }
-
-      if (name_type_mask & eFunctionNameTypeSelector) {
-        if (parent_decl_ctx && parent_decl_ctx->IsValid())
-          return 0; // no selectors in namespaces
-
-        num_matches =
-            m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets);
-        // Now make sure these are actually ObjC methods.  In this case we can
-        // simply look up the name, and if it is an ObjC method name, we're
-        // good.
-
-        for (uint32_t i = 0; i < num_matches; i++) {
-          const DIERef &die_ref = die_offsets[i];
-          DWARFDIE die = info->GetDIE(die_ref);
-          if (die) {
-            const char *die_name = die.GetName();
-            if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) {
-              if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
-                if (ResolveFunction(die, include_inlines, sc_list))
-                  resolved_dies.insert(die.GetDIE());
-              }
-            }
-          } else {
-            GetObjectFile()->GetModule()->ReportError(
-                "the DWARF debug information has been modified (.apple_names "
-                "accelerator table had bad die 0x%8.8x for '%s')",
-                die_ref.die_offset, name.GetCString());
-          }
-        }
-        die_offsets.clear();
-      }
-
-      if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) ||
-          name_type_mask & eFunctionNameTypeBase) {
-        // The apple_names table stores just the "base name" of C++ methods in
-        // the table.  So we have to extract the base name, look that up, and
-        // if there is any other information in the name we were passed in we
-        // have to post-filter based on that.
-
-        // FIXME: Arrange the logic above so that we don't calculate the base
-        // name twice:
-        num_matches =
-            m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets);
-
-        for (uint32_t i = 0; i < num_matches; i++) {
-          const DIERef &die_ref = die_offsets[i];
-          DWARFDIE die = info->GetDIE(die_ref);
-          if (die) {
-            if (!DIEInDeclContext(parent_decl_ctx, die))
-              continue; // The containing decl contexts don't match
-
-            // If we get to here, the die is good, and we should add it:
-            if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
-                ResolveFunction(die, include_inlines, sc_list)) {
-              bool keep_die = true;
-              if ((name_type_mask &
-                   (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
-                  (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
-                // We are looking for either basenames or methods, so we need
-                // to trim out the ones we won't want by looking at the type
-                SymbolContext sc;
-                if (sc_list.GetLastContext(sc)) {
-                  if (sc.block) {
-                    // We have an inlined function
-                  } else if (sc.function) {
-                    Type *type = sc.function->GetType();
-
-                    if (type) {
-                      CompilerDeclContext decl_ctx =
-                          GetDeclContextContainingUID(type->GetID());
-                      if (decl_ctx.IsStructUnionOrClass()) {
-                        if (name_type_mask & eFunctionNameTypeBase) {
-                          sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
-                          keep_die = false;
-                        }
-                      } else {
-                        if (name_type_mask & eFunctionNameTypeMethod) {
-                          sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
-                          keep_die = false;
-                        }
-                      }
-                    } else {
-                      GetObjectFile()->GetModule()->ReportWarning(
-                          "function at die offset 0x%8.8x had no function type",
-                          die_ref.die_offset);
-                    }
-                  }
-                }
-              }
-              if (keep_die)
-                resolved_dies.insert(die.GetDIE());
-            }
-          } else {
-            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-                "the DWARF debug information has been modified (.apple_names "
-                "accelerator table had bad die 0x%8.8x for '%s')",
-                die_ref.die_offset, name.GetCString());
-          }
-        }
-        die_offsets.clear();
-      }
-    }
-  } else {
-
-    // Index the DWARF if we haven't already
-    if (!m_indexed)
-      Index();
-
-    DIEArray die_offsets;
-    if (name_type_mask & eFunctionNameTypeFull) {
-      uint32_t num_matches = m_function_basename_index.Find(name, die_offsets);
-      num_matches += m_function_method_index.Find(name, die_offsets);
-      num_matches += m_function_fullname_index.Find(name, die_offsets);
-      for (uint32_t i = 0; i < num_matches; i++) {
-        const DIERef &die_ref = die_offsets[i];
-        DWARFDIE die = info->GetDIE(die_ref);
-        if (die) {
-          if (!DIEInDeclContext(parent_decl_ctx, die))
-            continue; // The containing decl contexts don't match
-
-          if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
-            if (ResolveFunction(die, include_inlines, sc_list))
-              resolved_dies.insert(die.GetDIE());
-          }
-        }
-      }
-      die_offsets.clear();
-    }
-    if (name_type_mask & eFunctionNameTypeBase) {
-      uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
-      for (uint32_t i = 0; i < num_base; i++) {
-        DWARFDIE die = info->GetDIE(die_offsets[i]);
-        if (die) {
-          if (!DIEInDeclContext(parent_decl_ctx, die))
-            continue; // The containing decl contexts don't match
-
-          // If we get to here, the die is good, and we should add it:
-          if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
-            if (ResolveFunction(die, include_inlines, sc_list))
-              resolved_dies.insert(die.GetDIE());
-          }
-        }
-      }
-      die_offsets.clear();
-    }
-
-    if (name_type_mask & eFunctionNameTypeMethod) {
-      if (parent_decl_ctx && parent_decl_ctx->IsValid())
-        return 0; // no methods in namespaces
-
-      uint32_t num_base = m_function_method_index.Find(name, die_offsets);
-      {
-        for (uint32_t i = 0; i < num_base; i++) {
-          DWARFDIE die = info->GetDIE(die_offsets[i]);
-          if (die) {
-            // If we get to here, the die is good, and we should add it:
-            if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
-              if (ResolveFunction(die, include_inlines, sc_list))
-                resolved_dies.insert(die.GetDIE());
-            }
-          }
-        }
-      }
-      die_offsets.clear();
-    }
-
-    if ((name_type_mask & eFunctionNameTypeSelector) &&
-        (!parent_decl_ctx || !parent_decl_ctx->IsValid())) {
-      FindFunctions(name, m_function_selector_index, include_inlines, sc_list);
-    }
-  }
+  m_index->GetFunctions(name, *info,
+                        [this](const DWARFDIE &die, bool include_inlines,
+                               lldb_private::SymbolContextList &sc_list) {
+                          return ResolveFunction(die, include_inlines, sc_list);
+                        },
+                        [this](lldb::user_id_t type_uid) {
+                          return GetDeclContextContainingUID(type_uid);
+                        },
+                        parent_decl_ctx, name_type_mask, include_inlines,
+                        sc_list);
 
   // Return the number of variable that were appended to the list
   const uint32_t num_matches = sc_list.GetSize() - original_size;
@@ -2724,22 +2275,20 @@ uint32_t SymbolFileDWARF::FindFunctions(
   if (!append)
     sc_list.Clear();
 
+  DWARFDebugInfo *info = DebugInfo();
+  if (!info)
+    return 0;
+
   // Remember how many sc_list are in the list before we search in case we are
   // appending the results to a variable list.
   uint32_t original_size = sc_list.GetSize();
 
-  if (m_using_apple_tables) {
-    if (m_apple_names_ap.get())
-      FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list);
-  } else {
-    // Index the DWARF if we haven't already
-    if (!m_indexed)
-      Index();
-
-    FindFunctions(regex, m_function_basename_index, include_inlines, sc_list);
-
-    FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list);
-  }
+  m_index->GetFunctions(regex, *info,
+                        [this](const DWARFDIE &die, bool include_inlines,
+                               lldb_private::SymbolContextList &sc_list) {
+                          return ResolveFunction(die, include_inlines, sc_list);
+                        },
+                        include_inlines, sc_list);
 
   // Return the number of variable that were appended to the list
   return sc_list.GetSize() - original_size;
@@ -2816,18 +2365,7 @@ uint32_t SymbolFileDWARF::FindTypes(
     return 0;
 
   DIEArray die_offsets;
-
-  if (m_using_apple_tables) {
-    if (m_apple_types_ap.get()) {
-      m_apple_types_ap->FindByName(name.GetStringRef(), die_offsets);
-    }
-  } else {
-    if (!m_indexed)
-      Index();
-
-    m_type_index.Find(name, die_offsets);
-  }
-
+  m_index->GetTypes(name, die_offsets);
   const size_t num_die_matches = die_offsets.size();
 
   if (num_die_matches) {
@@ -2849,12 +2387,8 @@ uint32_t SymbolFileDWARF::FindTypes(
             break;
         }
       } else {
-        if (m_using_apple_tables) {
-          GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-              "the DWARF debug information has been modified (.apple_types "
-              "accelerator table had bad die 0x%8.8x for '%s')\n",
-              die_ref.die_offset, name.GetCString());
-        }
+        m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                        name.GetStringRef());
       }
     }
     const uint32_t num_matches = types.GetSize() - initial_types_size;
@@ -2903,24 +2437,13 @@ size_t SymbolFileDWARF::FindTypes(const
   if (context.empty())
     return 0;
 
-  DIEArray die_offsets;
-
   ConstString name = context.back().name;
 
   if (!name)
     return 0;
 
-  if (m_using_apple_tables) {
-    if (m_apple_types_ap.get()) {
-      m_apple_types_ap->FindByName(name.GetStringRef(), die_offsets);
-    }
-  } else {
-    if (!m_indexed)
-      Index();
-
-    m_type_index.Find(name, die_offsets);
-  }
-
+  DIEArray die_offsets;
+  m_index->GetTypes(name, die_offsets);
   const size_t num_die_matches = die_offsets.size();
 
   if (num_die_matches) {
@@ -2943,12 +2466,8 @@ size_t SymbolFileDWARF::FindTypes(const
           ++num_matches;
         }
       } else {
-        if (m_using_apple_tables) {
-          GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-              "the DWARF debug information has been modified (.apple_types "
-              "accelerator table had bad die 0x%8.8x for '%s')\n",
-              die_ref.die_offset, name.GetCString());
-        }
+        m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                        name.GetStringRef());
       }
     }
     return num_matches;
@@ -2975,20 +2494,7 @@ SymbolFileDWARF::FindNamespace(const Sym
   DWARFDebugInfo *info = DebugInfo();
   if (info) {
     DIEArray die_offsets;
-
-    // Index if we already haven't to make sure the compile units get indexed
-    // and make their global DIE index list
-    if (m_using_apple_tables) {
-      if (m_apple_namespaces_ap.get()) {
-        m_apple_namespaces_ap->FindByName(name.GetStringRef(), die_offsets);
-      }
-    } else {
-      if (!m_indexed)
-        Index();
-
-      m_namespace_index.Find(name, die_offsets);
-    }
-
+    m_index->GetNamespaces(name, die_offsets);
     const size_t num_matches = die_offsets.size();
     if (num_matches) {
       for (size_t i = 0; i < num_matches; ++i) {
@@ -3006,13 +2512,8 @@ SymbolFileDWARF::FindNamespace(const Sym
               break;
           }
         } else {
-          if (m_using_apple_tables) {
-            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-                "the DWARF debug information has been modified "
-                "(.apple_namespaces accelerator table had bad die 0x%8.8x for "
-                "'%s')\n",
-                die_ref.die_offset, name.GetCString());
-          }
+          m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                          name.GetStringRef());
         }
       }
     }
@@ -3169,18 +2670,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjC
     return type_sp;
 
   DIEArray die_offsets;
-
-  if (m_using_apple_tables) {
-    if (m_apple_types_ap.get()) {
-      m_apple_types_ap->FindCompleteObjCClassByName(
-          type_name.GetStringRef(), die_offsets, must_be_implementation);
-    }
-  } else {
-    if (!m_indexed)
-      Index();
-
-    m_type_index.Find(type_name, die_offsets);
-  }
+  m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets);
 
   const size_t num_matches = die_offsets.size();
 
@@ -3229,12 +2719,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjC
           }
         }
       } else {
-        if (m_using_apple_tables) {
-          GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-              "the DWARF debug information has been modified (.apple_types "
-              "accelerator table had bad die 0x%8.8x for '%s')\n",
-              die_ref.die_offset, type_name.GetCString());
-        }
+        m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                        type_name.GetStringRef());
       }
     }
   }
@@ -3353,41 +2839,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTy
       }
 
       DIEArray die_offsets;
-
-      if (m_using_apple_tables) {
-        if (m_apple_types_ap.get()) {
-          const bool has_tag =
-              m_apple_types_ap->GetHeader().header_data.ContainsAtom(
-                  DWARFMappedHash::eAtomTypeTag);
-          const bool has_qualified_name_hash =
-              m_apple_types_ap->GetHeader().header_data.ContainsAtom(
-                  DWARFMappedHash::eAtomTypeQualNameHash);
-          if (has_tag && has_qualified_name_hash) {
-            const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
-            const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
-            if (log)
-              GetObjectFile()->GetModule()->LogMessage(
-                  log, "FindByNameAndTagAndQualifiedNameHash()");
-            m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash(
-                type_name.GetStringRef(), tag, qualified_name_hash,
-                die_offsets);
-          } else if (has_tag) {
-            if (log)
-              GetObjectFile()->GetModule()->LogMessage(log,
-                                                       "FindByNameAndTag()");
-            m_apple_types_ap->FindByNameAndTag(type_name.GetStringRef(), tag,
-                                               die_offsets);
-          } else {
-            m_apple_types_ap->FindByName(type_name.GetStringRef(), die_offsets);
-          }
-        }
-      } else {
-        if (!m_indexed)
-          Index();
-
-        m_type_index.Find(type_name, die_offsets);
-      }
-
+      m_index->GetTypes(dwarf_decl_ctx, die_offsets);
       const size_t num_matches = die_offsets.size();
 
       // Get the type system that we are looking to find a type for. We will
@@ -3477,12 +2929,8 @@ TypeSP SymbolFileDWARF::FindDefinitionTy
               }
             }
           } else {
-            if (m_using_apple_tables) {
-              GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-                  "the DWARF debug information has been modified (.apple_types "
-                  "accelerator table had bad die 0x%8.8x for '%s')\n",
-                  die_ref.die_offset, type_name.GetCString());
-            }
+            m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+                                            type_name.GetStringRef());
           }
         }
       }
@@ -3637,25 +3085,7 @@ size_t SymbolFileDWARF::ParseVariablesFo
         sc.comp_unit->SetVariableList(variables);
 
         DIEArray die_offsets;
-        if (m_using_apple_tables) {
-          if (m_apple_names_ap.get()) {
-            DWARFMappedHash::DIEInfoArray hash_data_array;
-            if (m_apple_names_ap->AppendAllDIEsInRange(
-                    dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(),
-                    hash_data_array)) {
-              DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
-            }
-          }
-        } else {
-          // Index if we already haven't to make sure the compile units get
-          // indexed and make their global DIE index list
-          if (!m_indexed)
-            Index();
-
-          m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(),
-                                                      die_offsets);
-        }
-
+        m_index->GetGlobalVariables(*dwarf_cu, die_offsets);
         const size_t num_matches = die_offsets.size();
         if (num_matches) {
           for (size_t i = 0; i < num_matches; ++i) {
@@ -3668,14 +3098,8 @@ size_t SymbolFileDWARF::ParseVariablesFo
                 variables->AddVariableIfUnique(var_sp);
                 ++vars_added;
               }
-            } else {
-              if (m_using_apple_tables) {
-                GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-                    "the DWARF debug information has been modified "
-                    "(.apple_names accelerator table had bad die 0x%8.8x)\n",
-                    die_ref.die_offset);
-              }
-            }
+            } else
+              m_index->ReportInvalidDIEOffset(die_ref.die_offset, "");
           }
         }
       }
@@ -4269,27 +3693,7 @@ uint32_t SymbolFileDWARF::GetPluginVersi
 
 void SymbolFileDWARF::DumpIndexes() {
   StreamFile s(stdout, false);
-
-  s.Printf(
-      "DWARF index for (%s) '%s':",
-      GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
-      GetObjectFile()->GetFileSpec().GetPath().c_str());
-  s.Printf("\nFunction basenames:\n");
-  m_function_basename_index.Dump(&s);
-  s.Printf("\nFunction fullnames:\n");
-  m_function_fullname_index.Dump(&s);
-  s.Printf("\nFunction methods:\n");
-  m_function_method_index.Dump(&s);
-  s.Printf("\nFunction selectors:\n");
-  m_function_selector_index.Dump(&s);
-  s.Printf("\nObjective C class selectors:\n");
-  m_objc_class_selectors_index.Dump(&s);
-  s.Printf("\nGlobals and statics:\n");
-  m_global_index.Dump(&s);
-  s.Printf("\nTypes:\n");
-  m_type_index.Dump(&s);
-  s.Printf("\nNamespaces:\n");
-  m_namespace_index.Dump(&s);
+  m_index->Dump(s);
 }
 
 SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=332719&r1=332718&r2=332719&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri May 18 07:15:46 2018
@@ -38,8 +38,7 @@
 // Project includes
 #include "DWARFDataExtractor.h"
 #include "DWARFDefines.h"
-#include "HashedNameToDIE.h"
-#include "NameToDIE.h"
+#include "DWARFIndex.h"
 #include "UniqueDWARFASTType.h"
 
 //----------------------------------------------------------------------
@@ -313,6 +312,10 @@ public:
   // the method returns a pointer to the base compile unit.
   virtual DWARFUnit *GetBaseCompileUnit();
 
+  static bool
+  DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
+                   const DWARFDIE &die);
+
 protected:
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
       DIEToTypePtr;
@@ -340,10 +343,6 @@ protected:
   bool DeclContextMatchesThisSymbolFile(
       const lldb_private::CompilerDeclContext *decl_ctx);
 
-  bool
-  DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
-                   const DWARFDIE &die);
-
   virtual DWARFUnit *
   GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
 
@@ -390,19 +389,6 @@ protected:
   bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
                        lldb_private::SymbolContextList &sc_list);
 
-  void FindFunctions(const lldb_private::ConstString &name,
-                     const NameToDIE &name_to_die, bool include_inlines,
-                     lldb_private::SymbolContextList &sc_list);
-
-  void FindFunctions(const lldb_private::RegularExpression &regex,
-                     const NameToDIE &name_to_die, bool include_inlines,
-                     lldb_private::SymbolContextList &sc_list);
-
-  void FindFunctions(const lldb_private::RegularExpression &regex,
-                     const DWARFMappedHash::MemoryTable &memory_table,
-                     bool include_inlines,
-                     lldb_private::SymbolContextList &sc_list);
-
   virtual lldb::TypeSP
   FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
 
@@ -413,14 +399,9 @@ protected:
   lldb_private::Symbol *
   GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
 
-  void ParseFunctions(const DIEArray &die_offsets, bool include_inlines,
-                      lldb_private::SymbolContextList &sc_list);
-
   lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
                              bool resolve_function_context = false);
 
-  void Index();
-
   void DumpIndexes();
 
   void SetDebugMapModule(const lldb::ModuleSP &module_sp) {
@@ -506,10 +487,6 @@ protected:
   std::unique_ptr<DWARFDebugAbbrev> m_abbr;
   std::unique_ptr<DWARFDebugInfo> m_info;
   std::unique_ptr<DWARFDebugLine> m_line;
-  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
-  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
-  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
-  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
   std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
 
   typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
@@ -517,17 +494,8 @@ protected:
   DebugMacrosMap m_debug_macros_map;
 
   ExternalTypeModuleMap m_external_type_modules;
-  NameToDIE m_function_basename_index; // All concrete functions
-  NameToDIE m_function_fullname_index; // All concrete functions
-  NameToDIE m_function_method_index;   // All inlined functions
-  NameToDIE
-      m_function_selector_index; // All method names for functions of classes
-  NameToDIE m_objc_class_selectors_index; // Given a class name, find all
-                                          // selectors for the class
-  NameToDIE m_global_index;               // Global and static variables
-  NameToDIE m_type_index;                 // All type DIE offsets
-  NameToDIE m_namespace_index;            // All type DIE offsets
-  bool m_indexed : 1, m_using_apple_tables : 1, m_fetched_external_modules : 1;
+  std::unique_ptr<lldb_private::DWARFIndex> m_index;
+  bool m_fetched_external_modules : 1;
   lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
 
   typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP;




More information about the lldb-commits mailing list