10d840744SZachary Turner //===- CVSymbolVisitor.cpp --------------------------------------*- C++ -*-===// 20d840744SZachary Turner // 30d840744SZachary Turner // The LLVM Compiler Infrastructure 40d840744SZachary Turner // 50d840744SZachary Turner // This file is distributed under the University of Illinois Open Source 60d840744SZachary Turner // License. See LICENSE.TXT for details. 70d840744SZachary Turner // 80d840744SZachary Turner //===----------------------------------------------------------------------===// 90d840744SZachary Turner 100d840744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" 110d840744SZachary Turner 120d840744SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 130d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" 140d840744SZachary Turner 150d840744SZachary Turner using namespace llvm; 160d840744SZachary Turner using namespace llvm::codeview; 170d840744SZachary Turner 180d840744SZachary Turner CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks) 190d840744SZachary Turner : Callbacks(Callbacks) {} 200d840744SZachary Turner 210d840744SZachary Turner template <typename T> 220d840744SZachary Turner static Error visitKnownRecord(CVSymbol &Record, 230d840744SZachary Turner SymbolVisitorCallbacks &Callbacks) { 240d840744SZachary Turner SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type); 250d840744SZachary Turner T KnownRecord(RK); 260d840744SZachary Turner if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord)) 270d840744SZachary Turner return EC; 280d840744SZachary Turner return Error::success(); 290d840744SZachary Turner } 300d840744SZachary Turner 31af8c75a8SZachary Turner static Error finishVisitation(CVSymbol &Record, 32af8c75a8SZachary Turner SymbolVisitorCallbacks &Callbacks) { 330d840744SZachary Turner switch (Record.Type) { 340d840744SZachary Turner default: 350d840744SZachary Turner if (auto EC = Callbacks.visitUnknownSymbol(Record)) 360d840744SZachary Turner return EC; 370d840744SZachary Turner break; 380d840744SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 390d840744SZachary Turner case EnumName: { \ 400d840744SZachary Turner if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \ 410d840744SZachary Turner return EC; \ 420d840744SZachary Turner break; \ 430d840744SZachary Turner } 440d840744SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ 450d840744SZachary Turner SYMBOL_RECORD(EnumVal, EnumVal, AliasName) 46d427383cSZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 470d840744SZachary Turner } 480d840744SZachary Turner 490d840744SZachary Turner if (auto EC = Callbacks.visitSymbolEnd(Record)) 500d840744SZachary Turner return EC; 510d840744SZachary Turner 520d840744SZachary Turner return Error::success(); 530d840744SZachary Turner } 540d840744SZachary Turner 55af8c75a8SZachary Turner Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) { 56af8c75a8SZachary Turner if (auto EC = Callbacks.visitSymbolBegin(Record)) 57af8c75a8SZachary Turner return EC; 58af8c75a8SZachary Turner return finishVisitation(Record, Callbacks); 59af8c75a8SZachary Turner } 60af8c75a8SZachary Turner 61af8c75a8SZachary Turner Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) { 62af8c75a8SZachary Turner if (auto EC = Callbacks.visitSymbolBegin(Record, Offset)) 63af8c75a8SZachary Turner return EC; 64af8c75a8SZachary Turner return finishVisitation(Record, Callbacks); 65af8c75a8SZachary Turner } 66af8c75a8SZachary Turner 670d840744SZachary Turner Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) { 680d840744SZachary Turner for (auto I : Symbols) { 690d840744SZachary Turner if (auto EC = visitSymbolRecord(I)) 700d840744SZachary Turner return EC; 710d840744SZachary Turner } 720d840744SZachary Turner return Error::success(); 730d840744SZachary Turner } 74af8c75a8SZachary Turner 75af8c75a8SZachary Turner Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols, 76af8c75a8SZachary Turner uint32_t InitialOffset) { 77af8c75a8SZachary Turner for (auto I : Symbols) { 78*579264bdSZachary Turner if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew())) 79af8c75a8SZachary Turner return EC; 80af8c75a8SZachary Turner InitialOffset += I.length(); 81af8c75a8SZachary Turner } 82af8c75a8SZachary Turner return Error::success(); 83af8c75a8SZachary Turner } 84