1 //===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
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/SymbolFile/DWARF/DWARFDIE.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
12 
13 #include "Plugins/Language/ObjC/ObjCLanguage.h"
14 
15 using namespace lldb_private;
16 using namespace lldb;
17 
18 DWARFIndex::~DWARFIndex() = default;
19 
20 void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
21                                     DWARFDebugInfo &info,
22                                     const CompilerDeclContext &parent_decl_ctx,
23                                     uint32_t name_type_mask,
24                                     std::vector<DWARFDIE> &dies) {
25   DWARFDIE die = info.GetDIE(ref);
26   if (!die) {
27     ReportInvalidDIEOffset(ref.die_offset, name);
28     return;
29   }
30 
31   // Exit early if we're searching exclusively for methods or selectors and
32   // we have a context specified (no methods in namespaces).
33   uint32_t looking_for_nonmethods =
34       name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
35   if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
36     return;
37 
38   // Otherwise, we need to also check that the context matches. If it does not
39   // match, we do nothing.
40   if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
41     return;
42 
43   // In case of a full match, we just insert everything we find.
44   if (name_type_mask & eFunctionNameTypeFull) {
45     dies.push_back(die);
46     return;
47   }
48 
49   // If looking for ObjC selectors, we need to also check if the name is a
50   // possible selector.
51   if (name_type_mask & eFunctionNameTypeSelector &&
52       ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
53     dies.push_back(die);
54     return;
55   }
56 
57   bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
58   bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
59   if (looking_for_methods || looking_for_functions) {
60     // If we're looking for either methods or functions, we definitely want this
61     // die. Otherwise, only keep it if the die type matches what we are
62     // searching for.
63     if ((looking_for_methods && looking_for_functions) ||
64         looking_for_methods == die.IsMethod())
65       dies.push_back(die);
66   }
67 }
68