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/IPDBSession.h"
14 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
15 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
16 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
17 #include "llvm/DebugInfo/PDB/PDBTypes.h"
19 #include <unordered_set>
24 using namespace llvm::pdb
;
27 class FunctionArgEnumerator
: public IPDBEnumChildren
<PDBSymbolData
> {
29 typedef ConcreteSymbolEnumerator
<PDBSymbolData
> ArgEnumeratorType
;
31 FunctionArgEnumerator(const IPDBSession
&PDBSession
,
32 const PDBSymbolFunc
&PDBFunc
)
33 : Session(PDBSession
), Func(PDBFunc
) {
34 // Arguments can appear multiple times if they have live range
35 // information, so we only take the first occurrence.
36 std::unordered_set
<std::string
> SeenNames
;
37 auto DataChildren
= Func
.findAllChildren
<PDBSymbolData
>();
38 while (auto Child
= DataChildren
->getNext()) {
39 if (Child
->getDataKind() == PDB_DataKind::Param
) {
40 std::string Name
= Child
->getName();
41 if (SeenNames
.find(Name
) != SeenNames
.end())
43 Args
.push_back(std::move(Child
));
44 SeenNames
.insert(Name
);
50 uint32_t getChildCount() const override
{ return Args
.size(); }
52 std::unique_ptr
<PDBSymbolData
>
53 getChildAtIndex(uint32_t Index
) const override
{
54 if (Index
>= Args
.size())
57 return Session
.getConcreteSymbolById
<PDBSymbolData
>(
58 Args
[Index
]->getSymIndexId());
61 std::unique_ptr
<PDBSymbolData
> getNext() override
{
62 if (CurIter
== Args
.end())
64 const auto &Result
= **CurIter
;
66 return Session
.getConcreteSymbolById
<PDBSymbolData
>(Result
.getSymIndexId());
69 void reset() override
{ CurIter
= Args
.empty() ? Args
.end() : Args
.begin(); }
72 typedef std::vector
<std::unique_ptr
<PDBSymbolData
>> ArgListType
;
73 const IPDBSession
&Session
;
74 const PDBSymbolFunc
&Func
;
76 ArgListType::const_iterator CurIter
;
80 std::unique_ptr
<IPDBEnumChildren
<PDBSymbolData
>>
81 PDBSymbolFunc::getArguments() const {
82 return std::make_unique
<FunctionArgEnumerator
>(Session
, *this);
85 void PDBSymbolFunc::dump(PDBSymDumper
&Dumper
) const { Dumper
.dump(*this); }
87 bool PDBSymbolFunc::isDestructor() const {
88 std::string Name
= getName();
93 if (Name
== "__vecDelDtor")
98 std::unique_ptr
<IPDBEnumLineNumbers
> PDBSymbolFunc::getLineNumbers() const {
99 auto Len
= RawSymbol
->getLength();
100 return Session
.findLineNumbersByAddress(RawSymbol
->getVirtualAddress(),
104 uint32_t PDBSymbolFunc::getCompilandId() const {
105 if (auto Lines
= getLineNumbers()) {
106 if (auto FirstLine
= Lines
->getNext()) {
107 return FirstLine
->getCompilandId();