PDBSymbolFunc.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
  9. #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
  10. #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
  11. #include "llvm/DebugInfo/PDB/IPDBSession.h"
  12. #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
  13. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
  15. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  16. #include <unordered_set>
  17. #include <utility>
  18. #include <vector>
  19. using namespace llvm;
  20. using namespace llvm::pdb;
  21. namespace {
  22. class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
  23. public:
  24. typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
  25. FunctionArgEnumerator(const IPDBSession &PDBSession,
  26. const PDBSymbolFunc &PDBFunc)
  27. : Session(PDBSession), Func(PDBFunc) {
  28. // Arguments can appear multiple times if they have live range
  29. // information, so we only take the first occurrence.
  30. std::unordered_set<std::string> SeenNames;
  31. auto DataChildren = Func.findAllChildren<PDBSymbolData>();
  32. while (auto Child = DataChildren->getNext()) {
  33. if (Child->getDataKind() == PDB_DataKind::Param) {
  34. std::string Name = Child->getName();
  35. if (SeenNames.find(Name) != SeenNames.end())
  36. continue;
  37. Args.push_back(std::move(Child));
  38. SeenNames.insert(Name);
  39. }
  40. }
  41. reset();
  42. }
  43. uint32_t getChildCount() const override { return Args.size(); }
  44. std::unique_ptr<PDBSymbolData>
  45. getChildAtIndex(uint32_t Index) const override {
  46. if (Index >= Args.size())
  47. return nullptr;
  48. return Session.getConcreteSymbolById<PDBSymbolData>(
  49. Args[Index]->getSymIndexId());
  50. }
  51. std::unique_ptr<PDBSymbolData> getNext() override {
  52. if (CurIter == Args.end())
  53. return nullptr;
  54. const auto &Result = **CurIter;
  55. ++CurIter;
  56. return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
  57. }
  58. void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
  59. private:
  60. typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
  61. const IPDBSession &Session;
  62. const PDBSymbolFunc &Func;
  63. ArgListType Args;
  64. ArgListType::const_iterator CurIter;
  65. };
  66. }
  67. std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
  68. PDBSymbolFunc::getArguments() const {
  69. return std::make_unique<FunctionArgEnumerator>(Session, *this);
  70. }
  71. void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
  72. bool PDBSymbolFunc::isDestructor() const {
  73. std::string Name = getName();
  74. if (Name.empty())
  75. return false;
  76. if (Name[0] == '~')
  77. return true;
  78. if (Name == "__vecDelDtor")
  79. return true;
  80. return false;
  81. }
  82. std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
  83. auto Len = RawSymbol->getLength();
  84. return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
  85. Len ? Len : 1);
  86. }
  87. uint32_t PDBSymbolFunc::getCompilandId() const {
  88. if (auto Lines = getLineNumbers()) {
  89. if (auto FirstLine = Lines->getNext()) {
  90. return FirstLine->getCompilandId();
  91. }
  92. }
  93. return 0;
  94. }