PDBSymbolFunc.cpp 3.5 KB

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