summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp111
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;
+}