1 //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
11 #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
12 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
13 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
14 #include "llvm/DebugInfo/PDB/IPDBSession.h"
15 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
16 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
19 #include "llvm/DebugInfo/PDB/PDBTypes.h"
21 #include <unordered_set>
26 using namespace llvm::pdb
;
29 class FunctionArgEnumerator
: public IPDBEnumChildren
<PDBSymbolData
> {
31 typedef ConcreteSymbolEnumerator
<PDBSymbolData
> ArgEnumeratorType
;
33 FunctionArgEnumerator(const IPDBSession
&PDBSession
,
34 const PDBSymbolFunc
&PDBFunc
)
35 : Session(PDBSession
), Func(PDBFunc
) {
36 // Arguments can appear multiple times if they have live range
37 // information, so we only take the first occurrence.
38 std::unordered_set
<std::string
> SeenNames
;
39 auto DataChildren
= Func
.findAllChildren
<PDBSymbolData
>();
40 while (auto Child
= DataChildren
->getNext()) {
41 if (Child
->getDataKind() == PDB_DataKind::Param
) {
42 std::string Name
= Child
->getName();
43 if (SeenNames
.find(Name
) != SeenNames
.end())
45 Args
.push_back(std::move(Child
));
46 SeenNames
.insert(Name
);
52 uint32_t getChildCount() const override
{ return Args
.size(); }
54 std::unique_ptr
<PDBSymbolData
>
55 getChildAtIndex(uint32_t Index
) const override
{
56 if (Index
>= Args
.size())
59 return Session
.getConcreteSymbolById
<PDBSymbolData
>(
60 Args
[Index
]->getSymIndexId());
63 std::unique_ptr
<PDBSymbolData
> getNext() override
{
64 if (CurIter
== Args
.end())
66 const auto &Result
= **CurIter
;
68 return Session
.getConcreteSymbolById
<PDBSymbolData
>(Result
.getSymIndexId());
71 void reset() override
{ CurIter
= Args
.empty() ? Args
.end() : Args
.begin(); }
74 typedef std::vector
<std::unique_ptr
<PDBSymbolData
>> ArgListType
;
75 const IPDBSession
&Session
;
76 const PDBSymbolFunc
&Func
;
78 ArgListType::const_iterator CurIter
;
82 std::unique_ptr
<IPDBEnumChildren
<PDBSymbolData
>>
83 PDBSymbolFunc::getArguments() const {
84 return std::make_unique
<FunctionArgEnumerator
>(Session
, *this);
87 void PDBSymbolFunc::dump(PDBSymDumper
&Dumper
) const { Dumper
.dump(*this); }
89 bool PDBSymbolFunc::isDestructor() const {
90 std::string Name
= getName();
95 if (Name
== "__vecDelDtor")
100 std::unique_ptr
<IPDBEnumLineNumbers
> PDBSymbolFunc::getLineNumbers() const {
101 auto Len
= RawSymbol
->getLength();
102 return Session
.findLineNumbersByAddress(RawSymbol
->getVirtualAddress(),
106 uint32_t PDBSymbolFunc::getCompilandId() const {
107 if (auto Lines
= getLineNumbers()) {
108 if (auto FirstLine
= Lines
->getNext()) {
109 return FirstLine
->getCompilandId();