blob: cbcaa569282818a8e4b3bc5617792b53241d932d [file] [log] [blame]
Zachary Turner0d840742016-10-07 21:34:46 +00001//===- 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"
Zachary Turner0d840742016-10-07 21:34:46 +000014
15using namespace llvm;
16using namespace llvm::codeview;
17
Zachary Turner0d840742016-10-07 21:34:46 +000018CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
19 : Callbacks(Callbacks) {}
20
21template <typename T>
22static 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
Zachary Turneraf8c75a2017-06-30 21:35:00 +000031static Error finishVisitation(CVSymbol &Record,
32 SymbolVisitorCallbacks &Callbacks) {
Zachary Turner0d840742016-10-07 21:34:46 +000033 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)
Zachary Turnerd4273832017-05-30 21:53:05 +000046#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turner0d840742016-10-07 21:34:46 +000047 }
48
49 if (auto EC = Callbacks.visitSymbolEnd(Record))
50 return EC;
51
52 return Error::success();
53}
54
Zachary Turneraf8c75a2017-06-30 21:35:00 +000055Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
56 if (auto EC = Callbacks.visitSymbolBegin(Record))
57 return EC;
58 return finishVisitation(Record, Callbacks);
59}
60
61Error 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
Zachary Turner0d840742016-10-07 21:34:46 +000067Error 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}
Zachary Turneraf8c75a2017-06-30 21:35:00 +000074
75Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
76 uint32_t InitialOffset) {
77 for (auto I : Symbols) {
Zachary Turner579264b2018-12-06 16:55:00 +000078 if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
Zachary Turneraf8c75a2017-06-30 21:35:00 +000079 return EC;
80 InitialOffset += I.length();
81 }
82 return Error::success();
83}