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