PDBSymbolFunc.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
  10. #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
  11. #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
  12. #include "llvm/DebugInfo/PDB/IPDBSession.h"
  13. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  16. #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
  17. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  18. #include <unordered_set>
  19. #include <utility>
  20. #include <vector>
  21. using namespace llvm;
  22. namespace {
  23. class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
  24. public:
  25. typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
  26. FunctionArgEnumerator(const IPDBSession &PDBSession,
  27. const PDBSymbolFunc &PDBFunc)
  28. : Session(PDBSession), Func(PDBFunc) {
  29. // Arguments can appear multiple times if they have live range
  30. // information, so we only take the first occurrence.
  31. std::unordered_set<std::string> SeenNames;
  32. auto DataChildren = Func.findAllChildren<PDBSymbolData>();
  33. while (auto Child = DataChildren->getNext()) {
  34. if (Child->getDataKind() == PDB_DataKind::Param) {
  35. std::string Name = Child->getName();
  36. if (SeenNames.find(Name) != SeenNames.end())
  37. continue;
  38. Args.push_back(std::move(Child));
  39. SeenNames.insert(Name);
  40. }
  41. }
  42. reset();
  43. }
  44. uint32_t getChildCount() const override { return Args.size(); }
  45. std::unique_ptr<PDBSymbolData>
  46. getChildAtIndex(uint32_t Index) const override {
  47. if (Index >= Args.size())
  48. return nullptr;
  49. return Session.getConcreteSymbolById<PDBSymbolData>(
  50. Args[Index]->getSymIndexId());
  51. }
  52. std::unique_ptr<PDBSymbolData> getNext() override {
  53. if (CurIter == Args.end())
  54. return nullptr;
  55. const auto &Result = **CurIter;
  56. ++CurIter;
  57. return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
  58. }
  59. void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
  60. FunctionArgEnumerator *clone() const override {
  61. return new FunctionArgEnumerator(Session, Func);
  62. }
  63. private:
  64. typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
  65. const IPDBSession &Session;
  66. const PDBSymbolFunc &Func;
  67. ArgListType Args;
  68. ArgListType::const_iterator CurIter;
  69. };
  70. }
  71. PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
  72. std::unique_ptr<IPDBRawSymbol> Symbol)
  73. : PDBSymbol(PDBSession, std::move(Symbol)) {}
  74. std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const {
  75. return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId());
  76. }
  77. std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
  78. PDBSymbolFunc::getArguments() const {
  79. return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
  80. }
  81. std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const {
  82. return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
  83. }
  84. void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }