xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
120b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
13*81ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSession.h"
15*81ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
190b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include <unordered_set>
220b57cec5SDimitry Andric #include <utility>
230b57cec5SDimitry Andric #include <vector>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric using namespace llvm::pdb;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric namespace {
290b57cec5SDimitry Andric class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
300b57cec5SDimitry Andric public:
310b57cec5SDimitry Andric   typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
320b57cec5SDimitry Andric 
FunctionArgEnumerator(const IPDBSession & PDBSession,const PDBSymbolFunc & PDBFunc)330b57cec5SDimitry Andric   FunctionArgEnumerator(const IPDBSession &PDBSession,
340b57cec5SDimitry Andric                         const PDBSymbolFunc &PDBFunc)
350b57cec5SDimitry Andric       : Session(PDBSession), Func(PDBFunc) {
360b57cec5SDimitry Andric     // Arguments can appear multiple times if they have live range
370b57cec5SDimitry Andric     // information, so we only take the first occurrence.
380b57cec5SDimitry Andric     std::unordered_set<std::string> SeenNames;
390b57cec5SDimitry Andric     auto DataChildren = Func.findAllChildren<PDBSymbolData>();
400b57cec5SDimitry Andric     while (auto Child = DataChildren->getNext()) {
410b57cec5SDimitry Andric       if (Child->getDataKind() == PDB_DataKind::Param) {
420b57cec5SDimitry Andric         std::string Name = Child->getName();
430b57cec5SDimitry Andric         if (SeenNames.find(Name) != SeenNames.end())
440b57cec5SDimitry Andric           continue;
450b57cec5SDimitry Andric         Args.push_back(std::move(Child));
460b57cec5SDimitry Andric         SeenNames.insert(Name);
470b57cec5SDimitry Andric       }
480b57cec5SDimitry Andric     }
490b57cec5SDimitry Andric     reset();
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric 
getChildCount() const520b57cec5SDimitry Andric   uint32_t getChildCount() const override { return Args.size(); }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   std::unique_ptr<PDBSymbolData>
getChildAtIndex(uint32_t Index) const550b57cec5SDimitry Andric   getChildAtIndex(uint32_t Index) const override {
560b57cec5SDimitry Andric     if (Index >= Args.size())
570b57cec5SDimitry Andric       return nullptr;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric     return Session.getConcreteSymbolById<PDBSymbolData>(
600b57cec5SDimitry Andric         Args[Index]->getSymIndexId());
610b57cec5SDimitry Andric   }
620b57cec5SDimitry Andric 
getNext()630b57cec5SDimitry Andric   std::unique_ptr<PDBSymbolData> getNext() override {
640b57cec5SDimitry Andric     if (CurIter == Args.end())
650b57cec5SDimitry Andric       return nullptr;
660b57cec5SDimitry Andric     const auto &Result = **CurIter;
670b57cec5SDimitry Andric     ++CurIter;
680b57cec5SDimitry Andric     return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
reset()710b57cec5SDimitry Andric   void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric private:
740b57cec5SDimitry Andric   typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
750b57cec5SDimitry Andric   const IPDBSession &Session;
760b57cec5SDimitry Andric   const PDBSymbolFunc &Func;
770b57cec5SDimitry Andric   ArgListType Args;
780b57cec5SDimitry Andric   ArgListType::const_iterator CurIter;
790b57cec5SDimitry Andric };
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
getArguments() const830b57cec5SDimitry Andric PDBSymbolFunc::getArguments() const {
848bcb0991SDimitry Andric   return std::make_unique<FunctionArgEnumerator>(Session, *this);
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
dump(PDBSymDumper & Dumper) const870b57cec5SDimitry Andric void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
880b57cec5SDimitry Andric 
isDestructor() const890b57cec5SDimitry Andric bool PDBSymbolFunc::isDestructor() const {
900b57cec5SDimitry Andric   std::string Name = getName();
910b57cec5SDimitry Andric   if (Name.empty())
920b57cec5SDimitry Andric     return false;
930b57cec5SDimitry Andric   if (Name[0] == '~')
940b57cec5SDimitry Andric     return true;
950b57cec5SDimitry Andric   if (Name == "__vecDelDtor")
960b57cec5SDimitry Andric     return true;
970b57cec5SDimitry Andric   return false;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
getLineNumbers() const1000b57cec5SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
1010b57cec5SDimitry Andric   auto Len = RawSymbol->getLength();
1020b57cec5SDimitry Andric   return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
1030b57cec5SDimitry Andric                                           Len ? Len : 1);
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
getCompilandId() const1060b57cec5SDimitry Andric uint32_t PDBSymbolFunc::getCompilandId() const {
1070b57cec5SDimitry Andric   if (auto Lines = getLineNumbers()) {
1080b57cec5SDimitry Andric     if (auto FirstLine = Lines->getNext()) {
1090b57cec5SDimitry Andric       return FirstLine->getCompilandId();
1100b57cec5SDimitry Andric     }
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric   return 0;
1130b57cec5SDimitry Andric }
114