1 //===-- DWARFIndex.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
10 #include "Plugins/Language/ObjC/ObjCLanguage.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
12 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
13 
14 using namespace lldb_private;
15 using namespace lldb;
16 
17 DWARFIndex::~DWARFIndex() = default;
18 
19 bool DWARFIndex::ProcessFunctionDIE(
20     llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf,
21     const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
22     llvm::function_ref<bool(DWARFDIE die)> callback) {
23   DWARFDIE die = dwarf.GetDIE(ref);
24   if (!die) {
25     ReportInvalidDIERef(ref, name);
26     return true;
27   }
28 
29   // Exit early if we're searching exclusively for methods or selectors and
30   // we have a context specified (no methods in namespaces).
31   uint32_t looking_for_nonmethods =
32       name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
33   if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
34     return true;
35 
36   // Otherwise, we need to also check that the context matches. If it does not
37   // match, we do nothing.
38   if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
39     return true;
40 
41   // In case of a full match, we just insert everything we find.
42   if (name_type_mask & eFunctionNameTypeFull)
43     return callback(die);
44 
45   // If looking for ObjC selectors, we need to also check if the name is a
46   // possible selector.
47   if (name_type_mask & eFunctionNameTypeSelector &&
48       ObjCLanguage::IsPossibleObjCMethodName(die.GetName()))
49     return callback(die);
50 
51   bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
52   bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
53   if (looking_for_methods || looking_for_functions) {
54     // If we're looking for either methods or functions, we definitely want this
55     // die. Otherwise, only keep it if the die type matches what we are
56     // searching for.
57     if ((looking_for_methods && looking_for_functions) ||
58         looking_for_methods == die.IsMethod())
59       return callback(die);
60   }
61 
62   return true;
63 }
64