jankratochvil updated this revision to Diff 255815.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77327/new/

https://reviews.llvm.org/D77327

Files:
  lldb/include/lldb/Core/UniqueCStringMap.h
  lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
  lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
  lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
  lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -31,8 +31,8 @@
 
   DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash);
 
-  size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
-                                 DIEArray &method_die_offsets) override;
+  bool GetObjCMethods(lldb_private::ConstString class_name,
+                      llvm::function_ref<bool(DIERef ref)> callback) override;
 
   llvm::Expected<lldb_private::TypeSystem &>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -95,10 +95,10 @@
   return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
 }
 
-size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets(
-    lldb_private::ConstString class_name, DIEArray &method_die_offsets) {
-  return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name,
-                                                     method_die_offsets);
+bool SymbolFileDWARFDwo::GetObjCMethods(
+    lldb_private::ConstString class_name,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  return GetBaseSymbolFile().GetObjCMethods(class_name, callback);
 }
 
 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -237,8 +237,8 @@
   lldb_private::CompileUnit *
   GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
 
-  virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
-                                         DIEArray &method_die_offsets);
+  virtual bool GetObjCMethods(lldb_private::ConstString class_name,
+                              llvm::function_ref<bool(DIERef ref)> callback);
 
   bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu);
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1463,11 +1463,9 @@
   return static_cast<CompileUnit *>(non_dwo_cu->GetUserData());
 }
 
-size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
-                                                DIEArray &method_die_offsets) {
-  method_die_offsets.clear();
-  m_index->GetObjCMethods(class_name, method_die_offsets);
-  return method_die_offsets.size();
+bool SymbolFileDWARF::GetObjCMethods(
+    ConstString class_name, llvm::function_ref<bool(DIERef ref)> callback) {
+  return m_index->GetObjCMethods(class_name, callback);
 }
 
 bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
@@ -2048,32 +2046,28 @@
                                                       context, basename))
     basename = name.GetStringRef();
 
-  DIEArray die_offsets;
-  m_index->GetGlobalVariables(ConstString(basename), die_offsets);
-  const size_t num_die_matches = die_offsets.size();
-
-  SymbolContext sc;
-  sc.module_sp = m_objfile_sp->GetModule();
-  assert(sc.module_sp);
-
   // Loop invariant: Variables up to this index have been checked for context
   // matches.
   uint32_t pruned_idx = original_size;
 
-  for (size_t i = 0; i < num_die_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
+  SymbolContext sc;
+  m_index->GetGlobalVariables(ConstString(basename), [&](DIERef die_ref) {
+    if (!sc.module_sp)
+      sc.module_sp = m_objfile_sp->GetModule();
+    assert(sc.module_sp);
+
     DWARFDIE die = GetDIE(die_ref);
     if (!die) {
       m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
-      continue;
+      return false;
     }
 
     if (die.Tag() != DW_TAG_variable)
-      continue;
+      return false;
 
     auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
     if (!dwarf_cu)
-      continue;
+      return false;
     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
 
     if (parent_decl_ctx) {
@@ -2082,7 +2076,7 @@
             dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
         if (!actual_parent_decl_ctx ||
             actual_parent_decl_ctx != parent_decl_ctx)
-          continue;
+          return false;
       }
     }
 
@@ -2096,9 +2090,8 @@
         variables.RemoveVariableAtIndex(pruned_idx);
     }
 
-    if (variables.GetSize() - original_size >= max_matches)
-      break;
-  }
+    return variables.GetSize() - original_size >= max_matches;
+  });
 
   // Return the number of variable that were appended to the list
   const uint32_t num_matches = variables.GetSize() - original_size;
@@ -2129,32 +2122,27 @@
   // Remember how many variables are in the list before we search.
   const uint32_t original_size = variables.GetSize();
 
-  DIEArray die_offsets;
-  m_index->GetGlobalVariables(regex, die_offsets);
-
   SymbolContext sc;
-  sc.module_sp = m_objfile_sp->GetModule();
-  assert(sc.module_sp);
+  m_index->GetGlobalVariables(regex, [&](DIERef die_ref) {
+    if (!sc.module_sp)
+      sc.module_sp = m_objfile_sp->GetModule();
+    assert(sc.module_sp);
 
-  const size_t num_matches = die_offsets.size();
-  for (size_t i = 0; i < num_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
     DWARFDIE die = GetDIE(die_ref);
     if (!die) {
       m_index->ReportInvalidDIERef(die_ref, regex.GetText());
-      continue;
+      return false;
     }
 
     DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
     if (!dwarf_cu)
-      continue;
+      return false;
     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
 
     ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
 
-    if (variables.GetSize() - original_size >= max_matches)
-      break;
-  }
+    return variables.GetSize() - original_size >= max_matches;
+  });
 }
 
 bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
@@ -2268,12 +2256,12 @@
 
   llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
 
-  std::vector<DWARFDIE> dies;
-  m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, dies);
-  for (const DWARFDIE &die : dies) {
-    if (resolved_dies.insert(die.GetDIE()).second)
-      ResolveFunction(die, include_inlines, sc_list);
-  }
+  m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask,
+                        [&](DWARFDIE die) {
+                          if (resolved_dies.insert(die.GetDIE()).second)
+                            ResolveFunction(die, include_inlines, sc_list);
+                          return false;
+                        });
 
   // Return the number of variable that were appended to the list
   const uint32_t num_matches = sc_list.GetSize() - original_size;
@@ -2305,19 +2293,17 @@
   }
 
   DWARFDebugInfo &info = DebugInfo();
-  DIEArray offsets;
-  m_index->GetFunctions(regex, offsets);
-
   llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
-  for (DIERef ref : offsets) {
+  m_index->GetFunctions(regex, [&](DIERef ref) {
     DWARFDIE die = info.GetDIE(ref);
     if (!die) {
       m_index->ReportInvalidDIERef(ref, regex.GetText());
-      continue;
+      return false;
     }
     if (resolved_dies.insert(die.GetDIE()).second)
       ResolveFunction(die, include_inlines, sc_list);
-  }
+    return false;
+  });
 }
 
 void SymbolFileDWARF::GetMangledNamesForFunction(
@@ -2373,31 +2359,25 @@
   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
     return;
 
-  DIEArray die_offsets;
-  m_index->GetTypes(name, die_offsets);
-  const size_t num_die_matches = die_offsets.size();
-
-  for (size_t i = 0; i < num_die_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
+  m_index->GetTypes(name, [&](DIERef die_ref) {
     DWARFDIE die = GetDIE(die_ref);
     if (!die) {
       m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
-      continue;
+      return false;
     }
 
     if (!DIEInDeclContext(parent_decl_ctx, die))
-      continue; // The containing decl contexts don't match
+      return false; // The containing decl contexts don't match
 
     Type *matching_type = ResolveType(die, true, true);
     if (!matching_type)
-      continue;
+      return false;
 
     // We found a type pointer, now find the shared pointer form our type
     // list
     types.InsertUnique(matching_type->shared_from_this());
-    if (types.GetSize() >= max_matches)
-      break;
-  }
+    return types.GetSize() >= max_matches;
+  });
 
   // Next search through the reachable Clang modules. This only applies for
   // DWARF objects compiled with -gmodules that haven't been processed by
@@ -2447,32 +2427,28 @@
   if (!name)
     return;
 
-  DIEArray die_offsets;
-  m_index->GetTypes(name, die_offsets);
-  const size_t num_die_matches = die_offsets.size();
-
-  for (size_t i = 0; i < num_die_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
+  m_index->GetTypes(name, [&](DIERef die_ref) {
     DWARFDIE die = GetDIE(die_ref);
     if (!die) {
       m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
-      continue;
+      return false;
     }
 
     if (!languages[GetLanguage(*die.GetCU())])
-      continue;
+      return false;
 
     llvm::SmallVector<CompilerContext, 4> die_context;
     die.GetDeclContext(die_context);
     if (!contextMatches(die_context, pattern))
-      continue;
+      return false;
 
     if (Type *matching_type = ResolveType(die, true, true)) {
       // We found a type pointer, now find the shared pointer form our type
       // list.
       types.InsertUnique(matching_type->shared_from_this());
     }
-  }
+    return false;
+  });
 
   // Next search through the reachable Clang modules. This only applies for
   // DWARF objects compiled with -gmodules that haven't been processed by
@@ -2502,28 +2478,24 @@
   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
     return namespace_decl_ctx;
 
-  DIEArray die_offsets;
-  m_index->GetNamespaces(name, die_offsets);
-  const size_t num_matches = die_offsets.size();
-  for (size_t i = 0; i < num_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
+  m_index->GetNamespaces(name, [&](DIERef die_ref) {
     DWARFDIE die = GetDIE(die_ref);
     if (!die) {
       m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
-      continue;
+      return false;
     }
 
     if (!DIEInDeclContext(parent_decl_ctx, die))
-      continue; // The containing decl contexts don't match
+      return false; // The containing decl contexts don't match
 
     DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());
     if (!dwarf_ast)
-      continue;
+      return false;
 
     namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
-    if (namespace_decl_ctx)
-      break;
-  }
+    return namespace_decl_ctx.IsValid();
+  });
+
   if (log && namespace_decl_ctx) {
     GetObjectFile()->GetModule()->LogMessage(
         log,
@@ -2677,59 +2649,54 @@
   if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
     return type_sp;
 
-  DIEArray die_offsets;
-  m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets);
-
-  const size_t num_matches = die_offsets.size();
-
-  for (size_t i = 0; i < num_matches; ++i) {
-    const DIERef &die_ref = die_offsets[i];
-    DWARFDIE type_die = GetDIE(die_ref);
-    if (!type_die) {
-      m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
-      continue;
-    }
+  m_index->GetCompleteObjCClass(
+      type_name, must_be_implementation, [&](DIERef die_ref) {
+        DWARFDIE type_die = GetDIE(die_ref);
+        if (!type_die) {
+          m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
+          return false;
+        }
 
-    bool try_resolving_type = false;
+        bool try_resolving_type = false;
 
-    // Don't try and resolve the DIE we are looking for with the DIE
-    // itself!
-    if (type_die != die) {
-      switch (type_die.Tag()) {
-      case DW_TAG_class_type:
-      case DW_TAG_structure_type:
-        try_resolving_type = true;
-        break;
-      default:
-        break;
-      }
-    }
-    if (!try_resolving_type)
-      continue;
+        // Don't try and resolve the DIE we are looking for with the DIE
+        // itself!
+        if (type_die != die) {
+          switch (type_die.Tag()) {
+          case DW_TAG_class_type:
+          case DW_TAG_structure_type:
+            try_resolving_type = true;
+            break;
+          default:
+            break;
+          }
+        }
+        if (!try_resolving_type)
+          return false;
 
-    if (must_be_implementation &&
-        type_die.Supports_DW_AT_APPLE_objc_complete_type())
-      try_resolving_type = type_die.GetAttributeValueAsUnsigned(
-          DW_AT_APPLE_objc_complete_type, 0);
-    if (!try_resolving_type)
-      continue;
+        if (must_be_implementation &&
+            type_die.Supports_DW_AT_APPLE_objc_complete_type())
+          try_resolving_type = type_die.GetAttributeValueAsUnsigned(
+              DW_AT_APPLE_objc_complete_type, 0);
+        if (!try_resolving_type)
+          return false;
 
-    Type *resolved_type = ResolveType(type_die, false, true);
-    if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
-      continue;
+        Type *resolved_type = ResolveType(type_die, false, true);
+        if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
+          return false;
 
-    DEBUG_PRINTF(
-        "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
-        " (cu 0x%8.8" PRIx64 ")\n",
-        die.GetID(),
-        m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
-        type_die.GetID(), type_cu->GetID());
+        DEBUG_PRINTF(
+            "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
+            " (cu 0x%8.8" PRIx64 ")\n",
+            die.GetID(),
+            m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
+            type_die.GetID(), type_cu->GetID());
 
-    if (die)
-      GetDIEToType()[die.GetDIE()] = resolved_type;
-    type_sp = resolved_type->shared_from_this();
-    break;
-  }
+        if (die)
+          GetDIEToType()[die.GetDIE()] = resolved_type;
+        type_sp = resolved_type->shared_from_this();
+        return true;
+      });
   return type_sp;
 }
 
@@ -2843,10 +2810,6 @@
             dwarf_decl_ctx.GetQualifiedName());
       }
 
-      DIEArray 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
       // use this to ensure any matches we find are in a language that this
       // type system supports
@@ -2863,12 +2826,12 @@
           type_system = &type_system_or_err.get();
         }
       }
-      for (size_t i = 0; i < num_matches; ++i) {
-        const DIERef &die_ref = die_offsets[i];
+
+      m_index->GetTypes(dwarf_decl_ctx, [&](DIERef die_ref) {
         DWARFDIE type_die = GetDIE(die_ref);
         if (!type_die) {
           m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
-          continue;
+          return false;
         }
 
         // Make sure type_die's langauge matches the type system we are
@@ -2876,7 +2839,7 @@
         // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
         if (type_system &&
             !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
-          continue;
+          return false;
         bool try_resolving_type = false;
 
         // Don't try and resolve the DIE we are looking for with the DIE
@@ -2921,7 +2884,7 @@
                 dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
                 qualified_name.c_str());
           }
-          continue;
+          return false;
         }
 
         DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die);
@@ -2939,15 +2902,15 @@
 
         // Make sure the decl contexts match all the way up
         if (dwarf_decl_ctx != type_dwarf_decl_ctx)
-          continue;
+          return false;
 
         Type *resolved_type = ResolveType(type_die, false);
         if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
-          continue;
+          return false;
 
         type_sp = resolved_type->shared_from_this();
-        break;
-      }
+        return true;
+      });
     }
   }
   return type_sp;
@@ -3091,24 +3054,21 @@
         variables = std::make_shared<VariableList>();
         sc.comp_unit->SetVariableList(variables);
 
-        DIEArray die_offsets;
-        m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(),
-                                    die_offsets);
-        const size_t num_matches = die_offsets.size();
-        for (size_t i = 0; i < num_matches; ++i) {
-          const DIERef &die_ref = die_offsets[i];
-          DWARFDIE die = GetDIE(die_ref);
-          if (!die) {
-            m_index->ReportInvalidDIERef(die_ref, "");
-            continue;
-          }
-
-          VariableSP var_sp(ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
-          if (var_sp) {
-            variables->AddVariableIfUnique(var_sp);
-            ++vars_added;
-          }
-        }
+        m_index->GetGlobalVariables(
+            dwarf_cu->GetNonSkeletonUnit(), [&](DIERef die_ref) {
+              DWARFDIE die = GetDIE(die_ref);
+              if (!die) {
+                m_index->ReportInvalidDIERef(die_ref, "");
+                return false;
+              }
+              VariableSP var_sp(
+                  ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
+              if (var_sp) {
+                variables->AddVariableIfUnique(var_sp);
+                ++vars_added;
+              }
+              return false;
+            });
       }
       return vars_added;
     }
Index: lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -32,14 +32,15 @@
 
   void Finalize();
 
-  size_t Find(lldb_private::ConstString name,
-              DIEArray &info_array) const;
+  bool Find(lldb_private::ConstString name,
+            llvm::function_ref<bool(DIERef ref)> callback) const;
 
-  size_t Find(const lldb_private::RegularExpression &regex,
-              DIEArray &info_array) const;
+  bool Find(const lldb_private::RegularExpression &regex,
+            llvm::function_ref<bool(DIERef ref)> callback) const;
 
-  size_t FindAllEntriesForUnit(const DWARFUnit &unit,
-                               DIEArray &info_array) const;
+  bool
+  FindAllEntriesForUnit(const DWARFUnit &unit,
+                        llvm::function_ref<bool(DIERef ref)> callback) const;
 
   void
   ForEach(std::function<bool(lldb_private::ConstString name,
Index: lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -26,28 +26,39 @@
   m_map.Append(name, die_ref);
 }
 
-size_t NameToDIE::Find(ConstString name, DIEArray &info_array) const {
-  return m_map.GetValues(name, info_array);
+bool NameToDIE::Find(ConstString name,
+                     llvm::function_ref<bool(DIERef ref)> callback) const {
+  for (const auto &entry : m_map.equal_range(name))
+    if (callback(entry.value))
+      return true;
+  return false;
 }
 
-size_t NameToDIE::Find(const RegularExpression &regex,
-                       DIEArray &info_array) const {
-  return m_map.GetValues(regex, info_array);
+bool NameToDIE::Find(const RegularExpression &regex,
+                     llvm::function_ref<bool(DIERef ref)> callback) const {
+  for (const auto &entry : m_map)
+    if (regex.Execute(entry.cstring.GetCString())) {
+      if (callback(entry.value))
+        return true;
+    }
+  return false;
 }
 
-size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit,
-                                        DIEArray &info_array) const {
-  const size_t initial_size = info_array.size();
+bool NameToDIE::FindAllEntriesForUnit(
+    const DWARFUnit &unit,
+    llvm::function_ref<bool(DIERef ref)> callback) const {
   const uint32_t size = m_map.GetSize();
   for (uint32_t i = 0; i < size; ++i) {
     const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
     if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() &&
         unit.GetDebugSection() == die_ref.section() &&
         unit.GetOffset() <= die_ref.die_offset() &&
-        die_ref.die_offset() < unit.GetNextUnitOffset())
-      info_array.push_back(die_ref);
+        die_ref.die_offset() < unit.GetNextUnitOffset()) {
+      if (callback(die_ref))
+        return true;
+    }
   }
-  return info_array.size() - initial_size;
+  return false;
 }
 
 void NameToDIE::Dump(Stream *s) {
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -26,21 +26,32 @@
 
   void Preload() override { Index(); }
 
-  void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
-  void GetGlobalVariables(const RegularExpression &regex,
-                          DIEArray &offsets) override;
-  void GetGlobalVariables(const DWARFUnit &unit, 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, SymbolFileDWARF &dwarf,
+  bool
+  GetGlobalVariables(ConstString basename,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const RegularExpression &regex,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const DWARFUnit &unit,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetObjCMethods(ConstString class_name,
+                      llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                       llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(ConstString name,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(const DWARFDeclContext &context,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetNamespaces(ConstString name,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
                     const CompilerDeclContext &parent_decl_ctx,
                     uint32_t name_type_mask,
-                    std::vector<DWARFDIE> &dies) override;
-  void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+                    llvm::function_ref<bool(DWARFDIE die)> callback) override;
+  bool GetFunctions(const RegularExpression &regex,
+                    llvm::function_ref<bool(DIERef ref)> callback) override;
 
   void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
   void Dump(Stream &s) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -367,113 +367,118 @@
   }
 }
 
-void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+bool ManualDWARFIndex::GetGlobalVariables(
+    ConstString basename, llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.globals.Find(basename, offsets);
+  return m_set.globals.Find(basename, callback);
 }
 
-void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
-                                          DIEArray &offsets) {
+bool ManualDWARFIndex::GetGlobalVariables(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.globals.Find(regex, offsets);
+  return m_set.globals.Find(regex, callback);
 }
 
-void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit,
-                                          DIEArray &offsets) {
+bool ManualDWARFIndex::GetGlobalVariables(
+    const DWARFUnit &unit, llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.globals.FindAllEntriesForUnit(unit, offsets);
+  return m_set.globals.FindAllEntriesForUnit(unit, callback);
 }
 
-void ManualDWARFIndex::GetObjCMethods(ConstString class_name,
-                                      DIEArray &offsets) {
+bool ManualDWARFIndex::GetObjCMethods(
+    ConstString class_name, llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.objc_class_selectors.Find(class_name, offsets);
+  return m_set.objc_class_selectors.Find(class_name, callback);
 }
 
-void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name,
-                                            bool must_be_implementation,
-                                            DIEArray &offsets) {
+bool ManualDWARFIndex::GetCompleteObjCClass(
+    ConstString class_name, bool must_be_implementation,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.types.Find(class_name, offsets);
+  return m_set.types.Find(class_name, callback);
 }
 
-void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+bool ManualDWARFIndex::GetTypes(ConstString name,
+                                llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.types.Find(name, offsets);
+  return m_set.types.Find(name, callback);
 }
 
-void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context,
-                                DIEArray &offsets) {
+bool ManualDWARFIndex::GetTypes(const DWARFDeclContext &context,
+                                llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.types.Find(ConstString(context[0].name), offsets);
+  return m_set.types.Find(ConstString(context[0].name), callback);
 }
 
-void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+bool ManualDWARFIndex::GetNamespaces(
+    ConstString name, llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
-  m_set.namespaces.Find(name, offsets);
+  return m_set.namespaces.Find(name, callback);
 }
 
-void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
-                                    const CompilerDeclContext &parent_decl_ctx,
-                                    uint32_t name_type_mask,
-                                    std::vector<DWARFDIE> &dies) {
+bool ManualDWARFIndex::GetFunctions(
+    ConstString name, SymbolFileDWARF &dwarf,
+    const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+    llvm::function_ref<bool(DWARFDIE die)> callback) {
   Index();
 
   if (name_type_mask & eFunctionNameTypeFull) {
-    DIEArray offsets;
-    m_set.function_fullnames.Find(name, offsets);
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = dwarf.GetDIE(die_ref);
-      if (!die)
-        continue;
-      if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
-        continue;
-      dies.push_back(die);
-    }
+    if (m_set.function_fullnames.Find(name, [&](DIERef die_ref) {
+          DWARFDIE die = dwarf.GetDIE(die_ref);
+          if (!die)
+            return false;
+          if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+            return false;
+          return callback(die);
+        }))
+      return true;
   }
   if (name_type_mask & eFunctionNameTypeBase) {
-    DIEArray offsets;
-    m_set.function_basenames.Find(name, offsets);
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = dwarf.GetDIE(die_ref);
-      if (!die)
-        continue;
-      if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
-        continue;
-      dies.push_back(die);
-    }
+    if (m_set.function_basenames.Find(name, [&](DIERef die_ref) {
+          DWARFDIE die = dwarf.GetDIE(die_ref);
+          if (!die)
+            return false;
+          if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+            return false;
+          return callback(die);
+        }))
+      return true;
   }
 
   if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) {
-    DIEArray offsets;
-    m_set.function_methods.Find(name, offsets);
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = dwarf.GetDIE(die_ref);
-      if (!die)
-        continue;
-      dies.push_back(die);
-    }
+    if (m_set.function_methods.Find(name, [&](DIERef die_ref) {
+          DWARFDIE die = dwarf.GetDIE(die_ref);
+          if (!die)
+            return false;
+          return callback(die);
+        }))
+      return true;
   }
 
   if (name_type_mask & eFunctionNameTypeSelector &&
       !parent_decl_ctx.IsValid()) {
-    DIEArray offsets;
-    m_set.function_selectors.Find(name, offsets);
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = dwarf.GetDIE(die_ref);
-      if (!die)
-        continue;
-      dies.push_back(die);
-    }
+    if (m_set.function_selectors.Find(name, [&](DIERef die_ref) {
+          DWARFDIE die = dwarf.GetDIE(die_ref);
+          if (!die)
+            return false;
+          return callback(die);
+        }))
+      return true;
   }
+  return false;
 }
 
-void ManualDWARFIndex::GetFunctions(const RegularExpression &regex,
-                                    DIEArray &offsets) {
+bool ManualDWARFIndex::GetFunctions(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   Index();
 
-  m_set.function_basenames.Find(regex, offsets);
-  m_set.function_fullnames.Find(regex, offsets);
+  if (m_set.function_basenames.Find(regex, callback))
+    return true;
+  if (m_set.function_fullnames.Find(regex, callback))
+    return true;
+  return false;
 }
 
 void ManualDWARFIndex::Dump(Stream &s) {
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -132,33 +132,36 @@
     bool ReadHashData(uint32_t hash_data_offset,
                       HashData &hash_data) const override;
 
-    size_t
+    void
     AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression &regex,
                                    DIEInfoArray &die_info_array) const;
 
-    size_t AppendAllDIEsInRange(const uint32_t die_offset_start,
-                                const uint32_t die_offset_end,
-                                DIEInfoArray &die_info_array) const;
+    void AppendAllDIEsInRange(const uint32_t die_offset_start,
+                              const uint32_t die_offset_end,
+                              DIEInfoArray &die_info_array) const;
 
-    size_t FindByName(llvm::StringRef name, DIEArray &die_offsets);
+    bool FindByName(llvm::StringRef name,
+                    llvm::function_ref<bool(DIERef ref)> callback);
 
-    size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
-                            DIEArray &die_offsets);
+    bool FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
+                          llvm::function_ref<bool(DIERef ref)> callback);
 
-    size_t FindByNameAndTagAndQualifiedNameHash(
+    bool FindByNameAndTagAndQualifiedNameHash(
         llvm::StringRef name, const dw_tag_t tag,
-        const uint32_t qualified_name_hash, DIEArray &die_offsets);
+        const uint32_t qualified_name_hash,
+        llvm::function_ref<bool(DIERef ref)> callback);
 
-    size_t FindCompleteObjCClassByName(llvm::StringRef name,
-                                       DIEArray &die_offsets,
-                                       bool must_be_implementation);
+    bool
+    FindCompleteObjCClassByName(llvm::StringRef name,
+                                llvm::function_ref<bool(DIERef ref)> callback,
+                                bool must_be_implementation);
 
   protected:
     Result AppendHashDataForRegularExpression(
         const lldb_private::RegularExpression &regex,
         lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
 
-    size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
+    void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
 
     Result GetHashDataForName(llvm::StringRef name,
                               lldb::offset_t *hash_data_offset_ptr,
@@ -169,27 +172,28 @@
     std::string m_name;
   };
 
-  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
-                              DIEArray &die_offsets);
+  static bool ExtractDIEArray(const DIEInfoArray &die_info_array,
+                              llvm::function_ref<bool(DIERef ref)> callback);
 
 protected:
-  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
-                              const dw_tag_t tag, DIEArray &die_offsets);
+  static bool ExtractDIEArray(const DIEInfoArray &die_info_array,
+                              const dw_tag_t tag,
+                              llvm::function_ref<bool(DIERef ref)> callback);
 
-  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+  static bool ExtractDIEArray(const DIEInfoArray &die_info_array,
                               const dw_tag_t tag,
                               const uint32_t qualified_name_hash,
-                              DIEArray &die_offsets);
+                              llvm::function_ref<bool(DIERef ref)> callback);
 
-  static void
+  static bool
   ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
                                bool return_implementation_only_if_available,
-                               DIEArray &die_offsets);
+                               llvm::function_ref<bool(DIERef ref)> callback);
 
-  static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
-                                       uint32_t type_flag_mask,
-                                       uint32_t type_flag_value,
-                                       DIEArray &die_offsets);
+  static bool
+  ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
+                           uint32_t type_flag_mask, uint32_t type_flag_value,
+                           llvm::function_ref<bool(DIERef ref)> callback);
 
   static const char *GetAtomTypeName(uint16_t atom);
 };
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -9,20 +9,21 @@
 #include "HashedNameToDIE.h"
 #include "llvm/ADT/StringRef.h"
 
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
-                                      DIEArray &die_offsets) {
+bool DWARFMappedHash::ExtractDIEArray(
+    const DIEInfoArray &die_info_array,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   const size_t count = die_info_array.size();
   for (size_t i = 0; i < count; ++i)
-    die_offsets.emplace_back(die_info_array[i]);
+    if (callback(DIERef(die_info_array[i])))
+      return true;
+  return false;
 }
 
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
-                                      const dw_tag_t tag,
-                                      DIEArray &die_offsets) {
-  if (tag == 0) {
-    ExtractDIEArray(die_info_array, die_offsets);
-    return;
-  }
+bool DWARFMappedHash::ExtractDIEArray(
+    const DIEInfoArray &die_info_array, const dw_tag_t tag,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (tag == 0)
+    return ExtractDIEArray(die_info_array, callback);
 
   const size_t count = die_info_array.size();
   for (size_t i = 0; i < count; ++i) {
@@ -32,19 +33,21 @@
       if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
         tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
     }
-    if (tag_matches)
-      die_offsets.emplace_back(die_info_array[i]);
+    if (tag_matches) {
+      if (callback(DIERef(die_info_array[i])))
+        return false;
+    }
   }
+
+  return false;
 }
 
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
-                                      const dw_tag_t tag,
-                                      const uint32_t qualified_name_hash,
-                                      DIEArray &die_offsets) {
-  if (tag == 0) {
-    ExtractDIEArray(die_info_array, die_offsets);
-    return;
-  }
+bool DWARFMappedHash::ExtractDIEArray(
+    const DIEInfoArray &die_info_array, const dw_tag_t tag,
+    const uint32_t qualified_name_hash,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (tag == 0)
+    return ExtractDIEArray(die_info_array, callback);
 
   const size_t count = die_info_array.size();
   for (size_t i = 0; i < count; ++i) {
@@ -56,45 +59,51 @@
       if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
         tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
     }
-    if (tag_matches)
-      die_offsets.emplace_back(die_info_array[i]);
+    if (tag_matches) {
+      if (callback(DIERef(die_info_array[i])))
+        return true;
+    }
   }
+
+  return false;
 }
 
-void DWARFMappedHash::ExtractClassOrStructDIEArray(
+bool DWARFMappedHash::ExtractClassOrStructDIEArray(
     const DIEInfoArray &die_info_array,
-    bool return_implementation_only_if_available, DIEArray &die_offsets) {
+    bool return_implementation_only_if_available,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   const size_t count = die_info_array.size();
   for (size_t i = 0; i < count; ++i) {
     const dw_tag_t die_tag = die_info_array[i].tag;
     if (!(die_tag == 0 || die_tag == DW_TAG_class_type ||
           die_tag == DW_TAG_structure_type))
       continue;
-    if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) {
-      if (return_implementation_only_if_available) {
-        // We found the one true definition for this class, so only return
-        // that
-        die_offsets.clear();
-        die_offsets.emplace_back(die_info_array[i]);
-        return;
-      } else {
-        // Put the one true definition as the first entry so it matches first
-        die_offsets.emplace(die_offsets.begin(), die_info_array[i]);
-      }
-    } else {
-      die_offsets.emplace_back(die_info_array[i]);
+    bool is_implementation =
+        (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0;
+    if (is_implementation != return_implementation_only_if_available)
+      continue;
+    if (return_implementation_only_if_available) {
+      // We found the one true definition for this class, so only return
+      // that
+      return callback(DIERef(die_info_array[i]));
     }
+    if (callback(DIERef(die_info_array[i])))
+      return true;
   }
+  return false;
 }
 
-void DWARFMappedHash::ExtractTypesFromDIEArray(
+bool DWARFMappedHash::ExtractTypesFromDIEArray(
     const DIEInfoArray &die_info_array, uint32_t type_flag_mask,
-    uint32_t type_flag_value, DIEArray &die_offsets) {
+    uint32_t type_flag_value, llvm::function_ref<bool(DIERef ref)> callback) {
   const size_t count = die_info_array.size();
   for (size_t i = 0; i < count; ++i) {
-    if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
-      die_offsets.emplace_back(die_info_array[i]);
+    if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) {
+      if (callback(DIERef(die_info_array[i])))
+        return true;
+    }
   }
+  return false;
 }
 
 const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
@@ -453,7 +462,7 @@
   }
 }
 
-size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
+void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
     const lldb_private::RegularExpression &regex,
     DIEInfoArray &die_info_array) const {
   const uint32_t hash_count = m_header.hashes_count;
@@ -482,10 +491,9 @@
     }
   }
   die_info_array.swap(pair.value);
-  return die_info_array.size();
 }
 
-size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
+void DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
     const uint32_t die_offset_start, const uint32_t die_offset_end,
     DIEInfoArray &die_info_array) const {
   const uint32_t hash_count = m_header.hashes_count;
@@ -512,73 +520,73 @@
       }
     }
   }
-  return die_info_array.size();
 }
 
-size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
-                                                DIEArray &die_offsets) {
+bool DWARFMappedHash::MemoryTable::FindByName(
+    llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback) {
   if (name.empty())
-    return 0;
+    return false;
 
   DIEInfoArray die_info_array;
-  if (FindByName(name, die_info_array))
-    DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets);
-  return die_info_array.size();
+  FindByName(name, die_info_array);
+  return DWARFMappedHash::ExtractDIEArray(die_info_array, callback);
 }
 
-size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name,
-                                                      const dw_tag_t tag,
-                                                      DIEArray &die_offsets) {
+bool DWARFMappedHash::MemoryTable::FindByNameAndTag(
+    llvm::StringRef name, const dw_tag_t tag,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   DIEInfoArray die_info_array;
-  if (FindByName(name, die_info_array))
-    DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets);
-  return die_info_array.size();
+  FindByName(name, die_info_array);
+  return DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback);
 }
 
-size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
+bool DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
     llvm::StringRef name, const dw_tag_t tag,
-    const uint32_t qualified_name_hash, DIEArray &die_offsets) {
+    const uint32_t qualified_name_hash,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   DIEInfoArray die_info_array;
-  if (FindByName(name, die_info_array))
-    DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
-                                     die_offsets);
-  return die_info_array.size();
+  FindByName(name, die_info_array);
+  return DWARFMappedHash::ExtractDIEArray(die_info_array, tag,
+                                          qualified_name_hash, callback);
 }
 
-size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
-    llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) {
+bool DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
+    llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback,
+    bool must_be_implementation) {
   DIEInfoArray die_info_array;
-  if (!FindByName(name, die_info_array))
-    return 0;
+  FindByName(name, die_info_array);
   if (must_be_implementation &&
       GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
     // If we have two atoms, then we have the DIE offset and the type flags
     // so we can find the objective C class efficiently.
-    DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX,
-                                              eTypeFlagClassIsImplementation,
-                                              die_offsets);
-    return die_offsets.size();
+    return DWARFMappedHash::ExtractTypesFromDIEArray(
+        die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback);
   }
   // We don't only want the one true definition, so try and see what we can
   // find, and only return class or struct DIEs. If we do have the full
   // implementation, then return it alone, else return all possible
   // matches.
-  const bool return_implementation_only_if_available = true;
-  DWARFMappedHash::ExtractClassOrStructDIEArray(
-      die_info_array, return_implementation_only_if_available, die_offsets);
-  return die_offsets.size();
+  bool found_implementation = false;
+  if (DWARFMappedHash::ExtractClassOrStructDIEArray(
+          die_info_array, true /*return_implementation_only_if_available*/,
+          [&](DIERef ref) {
+            found_implementation = true;
+            return callback(ref);
+          }))
+    return true;
+  if (found_implementation)
+    return false;
+  return DWARFMappedHash::ExtractClassOrStructDIEArray(
+      die_info_array, false /*return_implementation_only_if_available*/,
+      callback);
 }
 
-size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
-                                                DIEInfoArray &die_info_array) {
+void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
+                                              DIEInfoArray &die_info_array) {
   if (name.empty())
-    return 0;
+    return;
 
   Pair kv_pair;
-  size_t old_size = die_info_array.size();
-  if (Find(name, kv_pair)) {
+  if (Find(name, kv_pair))
     die_info_array.swap(kv_pair.value);
-    return die_info_array.size() - old_size;
-  }
-  return 0;
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
@@ -25,22 +25,34 @@
 
   void Preload() override { m_fallback.Preload(); }
 
-  void GetGlobalVariables(ConstString basename, 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, SymbolFileDWARF &dwarf,
+  bool
+  GetGlobalVariables(ConstString basename,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const RegularExpression &regex,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const DWARFUnit &cu,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetObjCMethods(ConstString class_name,
+                      llvm::function_ref<bool(DIERef ref)> callback) override {
+    return false;
+  }
+  bool
+  GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                       llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(ConstString name,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(const DWARFDeclContext &context,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetNamespaces(ConstString name,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
                     const CompilerDeclContext &parent_decl_ctx,
                     uint32_t name_type_mask,
-                    std::vector<DWARFDIE> &dies) override;
-  void GetFunctions(const RegularExpression &regex,
-                    DIEArray &offsets) override;
+                    llvm::function_ref<bool(DWARFDIE die)> callback) override;
+  bool GetFunctions(const RegularExpression &regex,
+                    llvm::function_ref<bool(DIERef ref)> callback) override;
 
   void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
   void Dump(Stream &s) override;
@@ -68,7 +80,8 @@
   ManualDWARFIndex m_fallback;
 
   llvm::Optional<DIERef> ToDIERef(const DebugNames::Entry &entry);
-  void Append(const DebugNames::Entry &entry, DIEArray &offsets);
+  bool ProcessEntry(const DebugNames::Entry &entry,
+                    llvm::function_ref<bool(DIERef ref)> callback);
 
   static void MaybeLogLookupError(llvm::Error error,
                                   const DebugNames::NameIndex &ni,
Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -57,10 +57,12 @@
   return llvm::None;
 }
 
-void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
-                                  DIEArray &offsets) {
+bool DebugNamesDWARFIndex::ProcessEntry(
+    const DebugNames::Entry &entry,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   if (llvm::Optional<DIERef> ref = ToDIERef(entry))
-    offsets.push_back(*ref);
+    return callback(*ref);
+  return false;
 }
 
 void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
@@ -74,22 +76,27 @@
       ni.getUnitOffset(), name);
 }
 
-void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
-                                              DIEArray &offsets) {
-  m_fallback.GetGlobalVariables(basename, offsets);
+bool DebugNamesDWARFIndex::GetGlobalVariables(
+    ConstString basename, llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetGlobalVariables(basename, callback))
+    return true;
 
   for (const DebugNames::Entry &entry :
        m_debug_names_up->equal_range(basename.GetStringRef())) {
     if (entry.tag() != DW_TAG_variable)
       continue;
 
-    Append(entry, offsets);
+    if (ProcessEntry(entry, callback))
+      return true;
   }
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
-                                              DIEArray &offsets) {
-  m_fallback.GetGlobalVariables(regex, offsets);
+bool DebugNamesDWARFIndex::GetGlobalVariables(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetGlobalVariables(regex, callback))
+    return true;
 
   for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
     for (DebugNames::NameTableEntry nte: ni) {
@@ -102,16 +109,20 @@
         if (entry_or->tag() != DW_TAG_variable)
           continue;
 
-        Append(*entry_or, offsets);
+        if (ProcessEntry(*entry_or, callback))
+          return true;
       }
       MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
     }
   }
+
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
-                                              DIEArray &offsets) {
-  m_fallback.GetGlobalVariables(cu, offsets);
+bool DebugNamesDWARFIndex::GetGlobalVariables(
+    const DWARFUnit &cu, llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetGlobalVariables(cu, callback))
+    return true;
 
   uint64_t cu_offset = cu.GetOffset();
   for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
@@ -124,17 +135,22 @@
         if (entry_or->getCUOffset() != cu_offset)
           continue;
 
-        Append(*entry_or, offsets);
+        if (ProcessEntry(*entry_or, callback))
+          return true;
       }
       MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
     }
   }
+
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
-                                                bool must_be_implementation,
-                                                DIEArray &offsets) {
-  m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets);
+bool DebugNamesDWARFIndex::GetCompleteObjCClass(
+    ConstString class_name, bool must_be_implementation,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetCompleteObjCClass(class_name, must_be_implementation,
+                                      callback))
+    return true;
 
   // Keep a list of incomplete types as fallback for when we don't find the
   // complete type.
@@ -163,75 +179,100 @@
 
     if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
       // If we find the complete version we're done.
-      offsets.push_back(*ref);
-      return;
+      return callback(*ref);
     }
     incomplete_types.push_back(*ref);
   }
 
-  offsets.insert(offsets.end(), incomplete_types.begin(),
-                 incomplete_types.end());
+  for (DIERef ref : incomplete_types)
+    if (callback(ref))
+      return true;
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
-  m_fallback.GetTypes(name, offsets);
+bool DebugNamesDWARFIndex::GetTypes(
+    ConstString name, llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetTypes(name, callback))
+    return true;
 
   for (const DebugNames::Entry &entry :
        m_debug_names_up->equal_range(name.GetStringRef())) {
-    if (isType(entry.tag()))
-      Append(entry, offsets);
+    if (isType(entry.tag())) {
+      if (ProcessEntry(entry, callback))
+        return true;
+    }
   }
+
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context,
-                                    DIEArray &offsets) {
-  m_fallback.GetTypes(context, offsets);
+bool DebugNamesDWARFIndex::GetTypes(
+    const DWARFDeclContext &context,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetTypes(context, callback))
+    return true;
 
   for (const DebugNames::Entry &entry :
        m_debug_names_up->equal_range(context[0].name)) {
-    if (entry.tag() == context[0].tag)
-      Append(entry, offsets);
+    if (entry.tag() == context[0].tag) {
+      if (ProcessEntry(entry, callback))
+        return true;
+    }
   }
+
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
-  m_fallback.GetNamespaces(name, offsets);
+bool DebugNamesDWARFIndex::GetNamespaces(
+    ConstString name, llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetNamespaces(name, callback))
+    return true;
 
   for (const DebugNames::Entry &entry :
        m_debug_names_up->equal_range(name.GetStringRef())) {
-    if (entry.tag() == DW_TAG_namespace)
-      Append(entry, offsets);
+    if (entry.tag() == DW_TAG_namespace) {
+      if (ProcessEntry(entry, callback))
+        return true;
+    }
   }
+
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetFunctions(
+bool DebugNamesDWARFIndex::GetFunctions(
     ConstString name, SymbolFileDWARF &dwarf,
     const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
-    std::vector<DWARFDIE> &dies) {
+    llvm::function_ref<bool(DWARFDIE die)> callback) {
 
-  std::vector<DWARFDIE> v;
-  m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v);
+  if (m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask,
+                              callback))
+    return true;
 
+  std::set<DWARFDebugInfoEntry *> seen;
   for (const DebugNames::Entry &entry :
        m_debug_names_up->equal_range(name.GetStringRef())) {
     Tag tag = entry.tag();
     if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
       continue;
 
-    if (llvm::Optional<DIERef> ref = ToDIERef(entry))
-      ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
-                         name_type_mask, v);
+    if (llvm::Optional<DIERef> ref = ToDIERef(entry)) {
+      if (ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
+                             name_type_mask, [&](DWARFDIE die) {
+                               if (!seen.insert(die.GetDIE()).second)
+                                 return false;
+                               return callback(die);
+                             }))
+        return true;
+    }
   }
-
-  std::set<DWARFDebugInfoEntry *> seen;
-  for (DWARFDIE die : v)
-    if (seen.insert(die.GetDIE()).second)
-      dies.push_back(die);
+  return false;
 }
 
-void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
-                                        DIEArray &offsets) {
-  m_fallback.GetFunctions(regex, offsets);
+bool DebugNamesDWARFIndex::GetFunctions(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
+  if (m_fallback.GetFunctions(regex, callback))
+    return true;
 
   for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
     for (DebugNames::NameTableEntry nte: ni) {
@@ -245,11 +286,14 @@
         if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
           continue;
 
-        Append(*entry_or, offsets);
+        if (ProcessEntry(*entry_or, callback))
+          return true;
       }
       MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
     }
   }
+
+  return false;
 }
 
 void DebugNamesDWARFIndex::Dump(Stream &s) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -27,24 +27,35 @@
   /// Finds global variables with the given base name. Any additional filtering
   /// (e.g., to only retrieve variables from a given context) should be done by
   /// the consumer.
-  virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
+  virtual bool
+  GetGlobalVariables(ConstString basename,
+                     llvm::function_ref<bool(DIERef ref)> callback) = 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, SymbolFileDWARF &dwarf,
-                            const CompilerDeclContext &parent_decl_ctx,
-                            uint32_t name_type_mask,
-                            std::vector<DWARFDIE> &dies) = 0;
-  virtual void GetFunctions(const RegularExpression &regex,
-                            DIEArray &offsets) = 0;
+  virtual bool
+  GetGlobalVariables(const RegularExpression &regex,
+                     llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool
+  GetGlobalVariables(const DWARFUnit &cu,
+                     llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool
+  GetObjCMethods(ConstString class_name,
+                 llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool
+  GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                       llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool GetTypes(ConstString name,
+                        llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool GetTypes(const DWARFDeclContext &context,
+                        llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool GetNamespaces(ConstString name,
+                             llvm::function_ref<bool(DIERef ref)> callback) = 0;
+  virtual bool
+  GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
+               const CompilerDeclContext &parent_decl_ctx,
+               uint32_t name_type_mask,
+               llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+  virtual bool GetFunctions(const RegularExpression &regex,
+                            llvm::function_ref<bool(DIERef ref)> callback) = 0;
 
   virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0;
   virtual void Dump(Stream &s) = 0;
@@ -56,10 +67,11 @@
   /// the function given by "ref" matches search criteria given by
   /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
   /// vector.
-  void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+  bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
                           SymbolFileDWARF &dwarf,
                           const CompilerDeclContext &parent_decl_ctx,
-                          uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
+                          uint32_t name_type_mask,
+                          llvm::function_ref<bool(DWARFDIE die)> callback);
 };
 } // namespace lldb_private
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -16,15 +16,14 @@
 
 DWARFIndex::~DWARFIndex() = default;
 
-void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
-                                    SymbolFileDWARF &dwarf,
-                                    const CompilerDeclContext &parent_decl_ctx,
-                                    uint32_t name_type_mask,
-                                    std::vector<DWARFDIE> &dies) {
+bool DWARFIndex::ProcessFunctionDIE(
+    llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf,
+    const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+    llvm::function_ref<bool(DWARFDIE die)> callback) {
   DWARFDIE die = dwarf.GetDIE(ref);
   if (!die) {
     ReportInvalidDIERef(ref, name);
-    return;
+    return false;
   }
 
   // Exit early if we're searching exclusively for methods or selectors and
@@ -32,26 +31,22 @@
   uint32_t looking_for_nonmethods =
       name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
   if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
-    return;
+    return false;
 
   // Otherwise, we need to also check that the context matches. If it does not
   // match, we do nothing.
   if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
-    return;
+    return false;
 
   // In case of a full match, we just insert everything we find.
-  if (name_type_mask & eFunctionNameTypeFull) {
-    dies.push_back(die);
-    return;
-  }
+  if (name_type_mask & eFunctionNameTypeFull)
+    return callback(die);
 
   // If looking for ObjC selectors, we need to also check if the name is a
   // possible selector.
   if (name_type_mask & eFunctionNameTypeSelector &&
-      ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
-    dies.push_back(die);
-    return;
-  }
+      ObjCLanguage::IsPossibleObjCMethodName(die.GetName()))
+    return callback(die);
 
   bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
   bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
@@ -61,6 +56,8 @@
     // searching for.
     if ((looking_for_methods && looking_for_functions) ||
         looking_for_methods == die.IsMethod())
-      dies.push_back(die);
+      return callback(die);
   }
+
+  return false;
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2008,18 +2008,13 @@
     if (class_language == eLanguageTypeObjC) {
       ConstString class_name(clang_type.GetTypeName());
       if (class_name) {
-        DIEArray method_die_offsets;
-        dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
-
-        const size_t num_matches = method_die_offsets.size();
-        for (size_t i = 0; i < num_matches; ++i) {
-          const DIERef &die_ref = method_die_offsets[i];
+        dwarf->GetObjCMethods(class_name, [&](DIERef die_ref) {
           DWARFDebugInfo &debug_info = dwarf->DebugInfo();
           DWARFDIE method_die = debug_info.GetDIE(die_ref);
-
           if (method_die)
             method_die.ResolveType();
-        }
+          return false;
+        });
 
         for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
                                            pe = delayed_properties.end();
Index: lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -32,21 +32,32 @@
 
   void Preload() override {}
 
-  void GetGlobalVariables(ConstString basename, 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, SymbolFileDWARF &dwarf,
+  bool
+  GetGlobalVariables(ConstString basename,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const RegularExpression &regex,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetGlobalVariables(const DWARFUnit &cu,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetObjCMethods(ConstString class_name,
+                      llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool
+  GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+                       llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(ConstString name,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetTypes(const DWARFDeclContext &context,
+                llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetNamespaces(ConstString name,
+                     llvm::function_ref<bool(DIERef ref)> callback) override;
+  bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
                     const CompilerDeclContext &parent_decl_ctx,
                     uint32_t name_type_mask,
-                    std::vector<DWARFDIE> &dies) override;
-  void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+                    llvm::function_ref<bool(DWARFDIE die)> callback) override;
+  bool GetFunctions(const RegularExpression &regex,
+                    llvm::function_ref<bool(DIERef ref)> callback) override;
 
   void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override;
   void Dump(Stream &s) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -52,59 +52,62 @@
   return nullptr;
 }
 
-void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+bool AppleDWARFIndex::GetGlobalVariables(
+    ConstString basename, llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_names_up)
-    return;
-  m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
+    return false;
+  return m_apple_names_up->FindByName(basename.GetStringRef(), callback);
 }
 
-void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
-                                         DIEArray &offsets) {
+bool AppleDWARFIndex::GetGlobalVariables(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_names_up)
-    return;
+    return false;
 
   DWARFMappedHash::DIEInfoArray hash_data;
-  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
-    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+  m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
+  return DWARFMappedHash::ExtractDIEArray(hash_data, callback);
 }
 
-void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
-                                         DIEArray &offsets) {
+bool AppleDWARFIndex::GetGlobalVariables(
+    const DWARFUnit &cu, llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_names_up)
-    return;
+    return false;
 
   DWARFMappedHash::DIEInfoArray hash_data;
-  if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
-                                             cu.GetNextUnitOffset(), hash_data))
-    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+  m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(),
+                                         hash_data);
+  return DWARFMappedHash::ExtractDIEArray(hash_data, callback);
 }
 
-void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
-                                     DIEArray &offsets) {
+bool AppleDWARFIndex::GetObjCMethods(
+    ConstString class_name, llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_objc_up)
-    return;
-  m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
+    return false;
+  return m_apple_objc_up->FindByName(class_name.GetStringRef(), callback);
 }
 
-void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
-                                           bool must_be_implementation,
-                                           DIEArray &offsets) {
+bool AppleDWARFIndex::GetCompleteObjCClass(
+    ConstString class_name, bool must_be_implementation,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_types_up)
-    return;
-  m_apple_types_up->FindCompleteObjCClassByName(
-      class_name.GetStringRef(), offsets, must_be_implementation);
+    return false;
+  return m_apple_types_up->FindCompleteObjCClassByName(
+      class_name.GetStringRef(), callback, must_be_implementation);
 }
 
-void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+bool AppleDWARFIndex::GetTypes(ConstString name,
+                               llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_types_up)
-    return;
-  m_apple_types_up->FindByName(name.GetStringRef(), offsets);
+    return false;
+  return m_apple_types_up->FindByName(name.GetStringRef(), callback);
 }
 
-void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
-                               DIEArray &offsets) {
+bool AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
+                               llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_types_up)
-    return;
+    return false;
 
   Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                           DWARF_LOG_LOOKUPS);
@@ -121,9 +124,8 @@
     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);
-    return;
+    return m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
+        type_name.GetStringRef(), tag, qualified_name_hash, callback);
   }
 
   if (has_tag) {
@@ -136,47 +138,46 @@
     if (!has_qualified_name_hash && (context.GetSize() > 1) &&
         (context[1].tag == DW_TAG_class_type ||
          context[1].tag == DW_TAG_structure_type)) {
-      DIEArray class_matches;
-      m_apple_types_up->FindByName(context[1].name, class_matches);
-      if (class_matches.empty())
-        return;
+      if (!m_apple_types_up->FindByName(context[1].name,
+                                        [&](DIERef ref) { return true; }))
+        return false;
     }
 
     if (log)
       m_module.LogMessage(log, "FindByNameAndTag()");
-    m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
-    return;
+    return m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag,
+                                              callback);
   }
 
-  m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+  return m_apple_types_up->FindByName(type_name.GetStringRef(), callback);
 }
 
-void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+bool AppleDWARFIndex::GetNamespaces(
+    ConstString name, llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_namespaces_up)
-    return;
-  m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
+    return false;
+  return m_apple_namespaces_up->FindByName(name.GetStringRef(), callback);
 }
 
-void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
-                                   const CompilerDeclContext &parent_decl_ctx,
-                                   uint32_t name_type_mask,
-                                   std::vector<DWARFDIE> &dies) {
-  DIEArray offsets;
-  m_apple_names_up->FindByName(name.GetStringRef(), offsets);
-  for (const DIERef &die_ref : offsets) {
-    ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
-                       name_type_mask, dies);
-  }
+bool AppleDWARFIndex::GetFunctions(
+    ConstString name, SymbolFileDWARF &dwarf,
+    const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+    llvm::function_ref<bool(DWARFDIE die)> callback) {
+  return m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
+    return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf,
+                              parent_decl_ctx, name_type_mask, callback);
+  });
 }
 
-void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
-                                   DIEArray &offsets) {
+bool AppleDWARFIndex::GetFunctions(
+    const RegularExpression &regex,
+    llvm::function_ref<bool(DIERef ref)> callback) {
   if (!m_apple_names_up)
-    return;
+    return false;
 
   DWARFMappedHash::DIEInfoArray hash_data;
-  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
-    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+  m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
+  return DWARFMappedHash::ExtractDIEArray(hash_data, callback);
 }
 
 void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
Index: lldb/include/lldb/Core/UniqueCStringMap.h
===================================================================
--- lldb/include/lldb/Core/UniqueCStringMap.h
+++ lldb/include/lldb/Core/UniqueCStringMap.h
@@ -32,6 +32,10 @@
     T value;
   };
 
+  typedef std::vector<Entry> collection;
+  typedef typename collection::iterator iterator;
+  typedef typename collection::const_iterator const_iterator;
+
   // Call this function multiple times to add a bunch of entries to this map,
   // then later call UniqueCStringMap<T>::Sort() before doing any searches by
   // name.
@@ -175,6 +179,22 @@
     }
   }
 
+  iterator begin() { return m_map.begin(); }
+  iterator end() { return m_map.end(); }
+  const_iterator begin() const { return m_map.begin(); }
+  const_iterator end() const { return m_map.end(); }
+
+  // Range-based for loop for all entries of the specified ConstString name.
+  llvm::iterator_range<const_iterator>
+  equal_range(ConstString unique_cstr) const {
+    const_iterator left = llvm::lower_bound(m_map, unique_cstr, Compare());
+    if (left != m_map.end() && left->cstring != unique_cstr)
+      left = m_map.end();
+    const_iterator right =
+        std::upper_bound(left, m_map.end(), unique_cstr, Compare());
+    return llvm::make_range(left, right);
+  };
+
 protected:
   struct Compare {
     bool operator()(const Entry &lhs, const Entry &rhs) {
@@ -196,9 +216,6 @@
       return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString());
     }
   };
-  typedef std::vector<Entry> collection;
-  typedef typename collection::iterator iterator;
-  typedef typename collection::const_iterator const_iterator;
   collection m_map;
 };
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to