1d88c1a5aSDimitry Andric //===- CVSymbolVisitor.cpp --------------------------------------*- C++ -*-===//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric // The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
9d88c1a5aSDimitry Andric
10d88c1a5aSDimitry Andric #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
11d88c1a5aSDimitry Andric
12d88c1a5aSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
13d88c1a5aSDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
14d88c1a5aSDimitry Andric
15d88c1a5aSDimitry Andric using namespace llvm;
16d88c1a5aSDimitry Andric using namespace llvm::codeview;
17d88c1a5aSDimitry Andric
CVSymbolVisitor(SymbolVisitorCallbacks & Callbacks)18d88c1a5aSDimitry Andric CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
19d88c1a5aSDimitry Andric : Callbacks(Callbacks) {}
20d88c1a5aSDimitry Andric
21d88c1a5aSDimitry Andric template <typename T>
visitKnownRecord(CVSymbol & Record,SymbolVisitorCallbacks & Callbacks)22d88c1a5aSDimitry Andric static Error visitKnownRecord(CVSymbol &Record,
23d88c1a5aSDimitry Andric SymbolVisitorCallbacks &Callbacks) {
24d88c1a5aSDimitry Andric SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type);
25d88c1a5aSDimitry Andric T KnownRecord(RK);
26d88c1a5aSDimitry Andric if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
27d88c1a5aSDimitry Andric return EC;
28d88c1a5aSDimitry Andric return Error::success();
29d88c1a5aSDimitry Andric }
30d88c1a5aSDimitry Andric
finishVisitation(CVSymbol & Record,SymbolVisitorCallbacks & Callbacks)31a580b014SDimitry Andric static Error finishVisitation(CVSymbol &Record,
32a580b014SDimitry Andric SymbolVisitorCallbacks &Callbacks) {
33d88c1a5aSDimitry Andric switch (Record.Type) {
34d88c1a5aSDimitry Andric default:
35d88c1a5aSDimitry Andric if (auto EC = Callbacks.visitUnknownSymbol(Record))
36d88c1a5aSDimitry Andric return EC;
37d88c1a5aSDimitry Andric break;
38d88c1a5aSDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
39d88c1a5aSDimitry Andric case EnumName: { \
40d88c1a5aSDimitry Andric if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
41d88c1a5aSDimitry Andric return EC; \
42d88c1a5aSDimitry Andric break; \
43d88c1a5aSDimitry Andric }
44d88c1a5aSDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
45d88c1a5aSDimitry Andric SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
46f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
47d88c1a5aSDimitry Andric }
48d88c1a5aSDimitry Andric
49d88c1a5aSDimitry Andric if (auto EC = Callbacks.visitSymbolEnd(Record))
50d88c1a5aSDimitry Andric return EC;
51d88c1a5aSDimitry Andric
52d88c1a5aSDimitry Andric return Error::success();
53d88c1a5aSDimitry Andric }
54d88c1a5aSDimitry Andric
visitSymbolRecord(CVSymbol & Record)55a580b014SDimitry Andric Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
56a580b014SDimitry Andric if (auto EC = Callbacks.visitSymbolBegin(Record))
57a580b014SDimitry Andric return EC;
58a580b014SDimitry Andric return finishVisitation(Record, Callbacks);
59a580b014SDimitry Andric }
60a580b014SDimitry Andric
visitSymbolRecord(CVSymbol & Record,uint32_t Offset)61a580b014SDimitry Andric Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) {
62a580b014SDimitry Andric if (auto EC = Callbacks.visitSymbolBegin(Record, Offset))
63a580b014SDimitry Andric return EC;
64a580b014SDimitry Andric return finishVisitation(Record, Callbacks);
65a580b014SDimitry Andric }
66a580b014SDimitry Andric
visitSymbolStream(const CVSymbolArray & Symbols)67d88c1a5aSDimitry Andric Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
68d88c1a5aSDimitry Andric for (auto I : Symbols) {
69d88c1a5aSDimitry Andric if (auto EC = visitSymbolRecord(I))
70d88c1a5aSDimitry Andric return EC;
71d88c1a5aSDimitry Andric }
72d88c1a5aSDimitry Andric return Error::success();
73d88c1a5aSDimitry Andric }
74a580b014SDimitry Andric
visitSymbolStream(const CVSymbolArray & Symbols,uint32_t InitialOffset)75a580b014SDimitry Andric Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
76a580b014SDimitry Andric uint32_t InitialOffset) {
77a580b014SDimitry Andric for (auto I : Symbols) {
78*b5893f02SDimitry Andric if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
79a580b014SDimitry Andric return EC;
80a580b014SDimitry Andric InitialOffset += I.length();
81a580b014SDimitry Andric }
82a580b014SDimitry Andric return Error::success();
83a580b014SDimitry Andric }
84