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