blob: 75cfd0dd184e880dbea1d2a643e648c2d027230e [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"
14#include "llvm/DebugInfo/MSF/ByteStream.h"
15
16using namespace llvm;
17using namespace llvm::codeview;
18
19template <typename T>
20static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
21 if (Data.size() < sizeof(*Res))
22 return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);
23 Res = reinterpret_cast<const T *>(Data.data());
24 Data = Data.drop_front(sizeof(*Res));
25 return Error::success();
26}
27
28CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
29 : Callbacks(Callbacks) {}
30
31template <typename T>
32static Error visitKnownRecord(CVSymbol &Record,
33 SymbolVisitorCallbacks &Callbacks) {
34 SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type);
35 T KnownRecord(RK);
36 if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
37 return EC;
38 return Error::success();
39}
40
41Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
42 if (auto EC = Callbacks.visitSymbolBegin(Record))
43 return EC;
44
45 switch (Record.Type) {
46 default:
47 if (auto EC = Callbacks.visitUnknownSymbol(Record))
48 return EC;
49 break;
50#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
51 case EnumName: { \
52 if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
53 return EC; \
54 break; \
55 }
56#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
57 SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
58#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
59 }
60
61 if (auto EC = Callbacks.visitSymbolEnd(Record))
62 return EC;
63
64 return Error::success();
65}
66
67Error 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}