1 //===- 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/Support/BinaryByteStream.h" 15 16 using namespace llvm; 17 using namespace llvm::codeview; 18 19 CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks) 20 : Callbacks(Callbacks) {} 21 22 template <typename T> 23 static 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 32 static Error finishVisitation(CVSymbol &Record, 33 SymbolVisitorCallbacks &Callbacks) { 34 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) 47 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 48 } 49 50 if (auto EC = Callbacks.visitSymbolEnd(Record)) 51 return EC; 52 53 return Error::success(); 54 } 55 56 Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) { 57 if (auto EC = Callbacks.visitSymbolBegin(Record)) 58 return EC; 59 return finishVisitation(Record, Callbacks); 60 } 61 62 Error 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 68 Error 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 } 75 76 Error 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 } 85