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 15 using namespace llvm; 16 using namespace llvm::codeview; 17 18 CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks) 19 : Callbacks(Callbacks) {} 20 21 template <typename T> 22 static Error visitKnownRecord(CVSymbol &Record, 23 SymbolVisitorCallbacks &Callbacks) { 24 SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type); 25 T KnownRecord(RK); 26 if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord)) 27 return EC; 28 return Error::success(); 29 } 30 31 static Error finishVisitation(CVSymbol &Record, 32 SymbolVisitorCallbacks &Callbacks) { 33 switch (Record.Type) { 34 default: 35 if (auto EC = Callbacks.visitUnknownSymbol(Record)) 36 return EC; 37 break; 38 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 39 case EnumName: { \ 40 if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \ 41 return EC; \ 42 break; \ 43 } 44 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ 45 SYMBOL_RECORD(EnumVal, EnumVal, AliasName) 46 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 47 } 48 49 if (auto EC = Callbacks.visitSymbolEnd(Record)) 50 return EC; 51 52 return Error::success(); 53 } 54 55 Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) { 56 if (auto EC = Callbacks.visitSymbolBegin(Record)) 57 return EC; 58 return finishVisitation(Record, Callbacks); 59 } 60 61 Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) { 62 if (auto EC = Callbacks.visitSymbolBegin(Record, Offset)) 63 return EC; 64 return finishVisitation(Record, Callbacks); 65 } 66 67 Error 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 } 74 75 Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols, 76 uint32_t InitialOffset) { 77 for (auto I : Symbols) { 78 if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew())) 79 return EC; 80 InitialOffset += I.length(); 81 } 82 return Error::success(); 83 } 84