1336823Sdim//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
2336823Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6336823Sdim//
7336823Sdim//===----------------------------------------------------------------------===//
8336823Sdim
9336823Sdim#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
10353358Sdim#include "Plugins/Language/ObjC/ObjCLanguage.h"
11336823Sdim#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
12353358Sdim#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
13336823Sdim
14336823Sdimusing namespace lldb_private;
15336823Sdimusing namespace lldb;
16336823Sdim
17336823SdimDWARFIndex::~DWARFIndex() = default;
18336823Sdim
19336823Sdimvoid DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
20353358Sdim                                    SymbolFileDWARF &dwarf,
21336823Sdim                                    const CompilerDeclContext &parent_decl_ctx,
22336823Sdim                                    uint32_t name_type_mask,
23336823Sdim                                    std::vector<DWARFDIE> &dies) {
24353358Sdim  DWARFDIE die = dwarf.GetDIE(ref);
25336823Sdim  if (!die) {
26353358Sdim    ReportInvalidDIERef(ref, name);
27336823Sdim    return;
28336823Sdim  }
29336823Sdim
30336823Sdim  // Exit early if we're searching exclusively for methods or selectors and
31336823Sdim  // we have a context specified (no methods in namespaces).
32336823Sdim  uint32_t looking_for_nonmethods =
33336823Sdim      name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
34336823Sdim  if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
35336823Sdim    return;
36336823Sdim
37336823Sdim  // Otherwise, we need to also check that the context matches. If it does not
38336823Sdim  // match, we do nothing.
39336823Sdim  if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
40336823Sdim    return;
41336823Sdim
42336823Sdim  // In case of a full match, we just insert everything we find.
43336823Sdim  if (name_type_mask & eFunctionNameTypeFull) {
44336823Sdim    dies.push_back(die);
45336823Sdim    return;
46336823Sdim  }
47336823Sdim
48336823Sdim  // If looking for ObjC selectors, we need to also check if the name is a
49336823Sdim  // possible selector.
50336823Sdim  if (name_type_mask & eFunctionNameTypeSelector &&
51336823Sdim      ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
52336823Sdim    dies.push_back(die);
53336823Sdim    return;
54336823Sdim  }
55336823Sdim
56336823Sdim  bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
57336823Sdim  bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
58336823Sdim  if (looking_for_methods || looking_for_functions) {
59336823Sdim    // If we're looking for either methods or functions, we definitely want this
60336823Sdim    // die. Otherwise, only keep it if the die type matches what we are
61336823Sdim    // searching for.
62336823Sdim    if ((looking_for_methods && looking_for_functions) ||
63336823Sdim        looking_for_methods == die.IsMethod())
64336823Sdim      dies.push_back(die);
65336823Sdim  }
66336823Sdim}
67