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/DebugInfo/MSF/ByteStream.h" 15 16 using namespace llvm; 17 using namespace llvm::codeview; 18 19 template <typename T> 20 static 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 28 CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks) 29 : Callbacks(Callbacks) {} 30 31 template <typename T> 32 static 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 41 Error 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 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