Line data Source code
1 : //===- PDBSymbolFunc.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 "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
11 :
12 : #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
13 : #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
14 : #include "llvm/DebugInfo/PDB/IPDBSession.h"
15 : #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
16 : #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
17 : #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
18 : #include "llvm/DebugInfo/PDB/PDBTypes.h"
19 :
20 : #include <unordered_set>
21 : #include <utility>
22 : #include <vector>
23 :
24 : using namespace llvm;
25 : using namespace llvm::pdb;
26 :
27 : namespace {
28 0 : class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
29 : public:
30 : typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
31 :
32 0 : FunctionArgEnumerator(const IPDBSession &PDBSession,
33 : const PDBSymbolFunc &PDBFunc)
34 0 : : Session(PDBSession), Func(PDBFunc) {
35 : // Arguments can appear multiple times if they have live range
36 : // information, so we only take the first occurrence.
37 : std::unordered_set<std::string> SeenNames;
38 0 : auto DataChildren = Func.findAllChildren<PDBSymbolData>();
39 0 : while (auto Child = DataChildren->getNext()) {
40 0 : if (Child->getDataKind() == PDB_DataKind::Param) {
41 0 : std::string Name = Child->getName();
42 0 : if (SeenNames.find(Name) != SeenNames.end())
43 : continue;
44 : Args.push_back(std::move(Child));
45 : SeenNames.insert(Name);
46 : }
47 : }
48 : reset();
49 0 : }
50 :
51 0 : uint32_t getChildCount() const override { return Args.size(); }
52 :
53 : std::unique_ptr<PDBSymbolData>
54 0 : getChildAtIndex(uint32_t Index) const override {
55 0 : if (Index >= Args.size())
56 : return nullptr;
57 :
58 0 : return Session.getConcreteSymbolById<PDBSymbolData>(
59 0 : Args[Index]->getSymIndexId());
60 : }
61 :
62 0 : std::unique_ptr<PDBSymbolData> getNext() override {
63 0 : if (CurIter == Args.end())
64 : return nullptr;
65 : const auto &Result = **CurIter;
66 : ++CurIter;
67 0 : return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
68 : }
69 :
70 0 : void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
71 :
72 : private:
73 : typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
74 : const IPDBSession &Session;
75 : const PDBSymbolFunc &Func;
76 : ArgListType Args;
77 : ArgListType::const_iterator CurIter;
78 : };
79 : }
80 :
81 : std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
82 0 : PDBSymbolFunc::getArguments() const {
83 0 : return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
84 : }
85 :
86 0 : void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
87 :
88 0 : bool PDBSymbolFunc::isDestructor() const {
89 0 : std::string Name = getName();
90 0 : if (Name.empty())
91 : return false;
92 0 : if (Name[0] == '~')
93 : return true;
94 0 : if (Name == "__vecDelDtor")
95 0 : return true;
96 : return false;
97 : }
98 :
99 0 : std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
100 0 : auto Len = RawSymbol->getLength();
101 0 : return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
102 0 : Len ? Len : 1);
103 : }
104 :
105 0 : uint32_t PDBSymbolFunc::getCompilandId() const {
106 0 : if (auto Lines = getLineNumbers()) {
107 0 : if (auto FirstLine = Lines->getNext()) {
108 0 : return FirstLine->getCompilandId();
109 : }
110 : }
111 0 : return 0;
112 : }
|