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