CVSymbolVisitor.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===- CVSymbolVisitor.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/CodeView/CVSymbolVisitor.h"
  9. #include "llvm/DebugInfo/CodeView/CodeViewError.h"
  10. #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
  11. using namespace llvm;
  12. using namespace llvm::codeview;
  13. CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
  14. : Callbacks(Callbacks) {}
  15. template <typename T>
  16. static Error visitKnownRecord(CVSymbol &Record,
  17. SymbolVisitorCallbacks &Callbacks) {
  18. SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.kind());
  19. T KnownRecord(RK);
  20. if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
  21. return EC;
  22. return Error::success();
  23. }
  24. static Error finishVisitation(CVSymbol &Record,
  25. SymbolVisitorCallbacks &Callbacks) {
  26. switch (Record.kind()) {
  27. default:
  28. if (auto EC = Callbacks.visitUnknownSymbol(Record))
  29. return EC;
  30. break;
  31. #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
  32. case EnumName: { \
  33. if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
  34. return EC; \
  35. break; \
  36. }
  37. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
  38. SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
  39. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  40. }
  41. if (auto EC = Callbacks.visitSymbolEnd(Record))
  42. return EC;
  43. return Error::success();
  44. }
  45. Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
  46. if (auto EC = Callbacks.visitSymbolBegin(Record))
  47. return EC;
  48. return finishVisitation(Record, Callbacks);
  49. }
  50. Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) {
  51. if (auto EC = Callbacks.visitSymbolBegin(Record, Offset))
  52. return EC;
  53. return finishVisitation(Record, Callbacks);
  54. }
  55. Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
  56. for (auto I : Symbols) {
  57. if (auto EC = visitSymbolRecord(I))
  58. return EC;
  59. }
  60. return Error::success();
  61. }
  62. Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
  63. uint32_t InitialOffset) {
  64. for (auto I : Symbols) {
  65. if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
  66. return EC;
  67. InitialOffset += I.length();
  68. }
  69. return Error::success();
  70. }