diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp new file mode 100644 index 000000000000..7c3ba981fd6b --- /dev/null +++ b/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp @@ -0,0 +1,111 @@ +//===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" + +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include <unordered_set> +#include <utility> +#include <vector> + +using namespace llvm; +using namespace llvm::pdb; + +namespace { +class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> { +public: + typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType; + + FunctionArgEnumerator(const IPDBSession &PDBSession, + const PDBSymbolFunc &PDBFunc) + : Session(PDBSession), Func(PDBFunc) { + // Arguments can appear multiple times if they have live range + // information, so we only take the first occurrence. + std::unordered_set<std::string> SeenNames; + auto DataChildren = Func.findAllChildren<PDBSymbolData>(); + while (auto Child = DataChildren->getNext()) { + if (Child->getDataKind() == PDB_DataKind::Param) { + std::string Name = Child->getName(); + if (SeenNames.find(Name) != SeenNames.end()) + continue; + Args.push_back(std::move(Child)); + SeenNames.insert(Name); + } + } + reset(); + } + + uint32_t getChildCount() const override { return Args.size(); } + + std::unique_ptr<PDBSymbolData> + getChildAtIndex(uint32_t Index) const override { + if (Index >= Args.size()) + return nullptr; + + return Session.getConcreteSymbolById<PDBSymbolData>( + Args[Index]->getSymIndexId()); + } + + std::unique_ptr<PDBSymbolData> getNext() override { + if (CurIter == Args.end()) + return nullptr; + const auto &Result = **CurIter; + ++CurIter; + return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId()); + } + + void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); } + +private: + typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType; + const IPDBSession &Session; + const PDBSymbolFunc &Func; + ArgListType Args; + ArgListType::const_iterator CurIter; +}; +} + +std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> +PDBSymbolFunc::getArguments() const { + return llvm::make_unique<FunctionArgEnumerator>(Session, *this); +} + +void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } + +bool PDBSymbolFunc::isDestructor() const { + std::string Name = getName(); + if (Name.empty()) + return false; + if (Name[0] == '~') + return true; + if (Name == "__vecDelDtor") + return true; + return false; +} + +std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const { + auto Len = RawSymbol->getLength(); + return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(), + Len ? Len : 1); +} + +uint32_t PDBSymbolFunc::getCompilandId() const { + if (auto Lines = getLineNumbers()) { + if (auto FirstLine = Lines->getNext()) { + return FirstLine->getCompilandId(); + } + } + return 0; +} |
