Reland "[DWARF] Extract indexing code into a separate class hierarchy"

After this commit, the xcode project will need to be updated to include
the new files added here.

llvm-svn: 332841
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index edee052..4ad85fb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -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::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 @@
       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();
-  }
+  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);
 
-  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();
-  }
+  m_index = AppleDWARFIndex::Create(*GetObjectFile()->GetModule(), apple_names,
+                                    apple_namespaces, apple_types, apple_objc,
+                                    get_debug_str_data());
 
-  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();
-  }
+  if (!m_index)
+    m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+                                                  DebugInfo());
 }
 
 bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@@ -1509,16 +1475,7 @@
 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 @@
 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 @@
   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 @@
         } 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 @@
   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 @@
 
         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 @@
   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 @@
   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 @@
   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 @@
     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 @@
             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 @@
   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 @@
           ++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 @@
   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 @@
               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 @@
     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 @@
           }
         }
       } 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 @@
       }
 
       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 @@
               }
             }
           } 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 @@
         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 @@
                 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 @@
 
 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() {