blob: e0c7ef58c30417b854dc184f384751322e4ad173 [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 Turnerd9dc2822017-03-02 20:52:51 +000014#include "llvm/Support/BinaryByteStream.h"
Zachary Turner0d840742016-10-07 21:34:46 +000015
16using namespace llvm;
17using namespace llvm::codeview;
18
Zachary Turner0d840742016-10-07 21:34:46 +000019CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
20 : Callbacks(Callbacks) {}
21
22template <typename T>
23static Error visitKnownRecord(CVSymbol &Record,
24 SymbolVisitorCallbacks &Callbacks) {
25 SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type);
26 T KnownRecord(RK);
27 if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
28 return EC;
29 return Error::success();
30}
31
Zachary Turneraf8c75a2017-06-30 21:35:00 +000032static Error finishVisitation(CVSymbol &Record,
33 SymbolVisitorCallbacks &Callbacks) {
Zachary Turner0d840742016-10-07 21:34:46 +000034 switch (Record.Type) {
35 default:
36 if (auto EC = Callbacks.visitUnknownSymbol(Record))
37 return EC;
38 break;
39#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
40 case EnumName: { \
41 if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
42 return EC; \
43 break; \
44 }
45#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
46 SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
Zachary Turnerd4273832017-05-30 21:53:05 +000047#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turner0d840742016-10-07 21:34:46 +000048 }
49
50 if (auto EC = Callbacks.visitSymbolEnd(Record))
51 return EC;
52
53 return Error::success();
54}
55
Zachary Turneraf8c75a2017-06-30 21:35:00 +000056Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
57 if (auto EC = Callbacks.visitSymbolBegin(Record))
58 return EC;
59 return finishVisitation(Record, Callbacks);
60}
61
62Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) {
63 if (auto EC = Callbacks.visitSymbolBegin(Record, Offset))
64 return EC;
65 return finishVisitation(Record, Callbacks);
66}
67
Zachary Turner0d840742016-10-07 21:34:46 +000068Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
69 for (auto I : Symbols) {
70 if (auto EC = visitSymbolRecord(I))
71 return EC;
72 }
73 return Error::success();
74}
Zachary Turneraf8c75a2017-06-30 21:35:00 +000075
76Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
77 uint32_t InitialOffset) {
78 for (auto I : Symbols) {
79 if (auto EC = visitSymbolRecord(I, InitialOffset))
80 return EC;
81 InitialOffset += I.length();
82 }
83 return Error::success();
84}