1 //===- SymbolRecordHelpers.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/SymbolRecordHelpers.h" 11 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 14 15 using namespace llvm; 16 using namespace llvm::codeview; 17 createRecord(const CVSymbol & sym)18template <typename RecordT> RecordT createRecord(const CVSymbol &sym) { 19 RecordT record(static_cast<SymbolRecordKind>(sym.kind())); 20 cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); 21 return record; 22 } 23 getScopeEndOffset(const CVSymbol & Sym)24uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) { 25 assert(symbolOpensScope(Sym.kind())); 26 switch (Sym.kind()) { 27 case SymbolKind::S_GPROC32: 28 case SymbolKind::S_LPROC32: 29 case SymbolKind::S_GPROC32_ID: 30 case SymbolKind::S_LPROC32_ID: 31 case SymbolKind::S_LPROC32_DPC: 32 case SymbolKind::S_LPROC32_DPC_ID: { 33 ProcSym Proc = createRecord<ProcSym>(Sym); 34 return Proc.End; 35 } 36 case SymbolKind::S_BLOCK32: { 37 BlockSym Block = createRecord<BlockSym>(Sym); 38 return Block.End; 39 } 40 case SymbolKind::S_THUNK32: { 41 Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 42 return Thunk.End; 43 } 44 case SymbolKind::S_INLINESITE: { 45 InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 46 return Site.End; 47 } 48 default: 49 assert(false && "Unknown record type"); 50 return 0; 51 } 52 } 53 54 uint32_t getScopeParentOffset(const llvm::codeview::CVSymbol & Sym)55llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) { 56 assert(symbolOpensScope(Sym.kind())); 57 switch (Sym.kind()) { 58 case SymbolKind::S_GPROC32: 59 case SymbolKind::S_LPROC32: 60 case SymbolKind::S_GPROC32_ID: 61 case SymbolKind::S_LPROC32_ID: 62 case SymbolKind::S_LPROC32_DPC: 63 case SymbolKind::S_LPROC32_DPC_ID: { 64 ProcSym Proc = createRecord<ProcSym>(Sym); 65 return Proc.Parent; 66 } 67 case SymbolKind::S_BLOCK32: { 68 BlockSym Block = createRecord<BlockSym>(Sym); 69 return Block.Parent; 70 } 71 case SymbolKind::S_THUNK32: { 72 Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 73 return Thunk.Parent; 74 } 75 case SymbolKind::S_INLINESITE: { 76 InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 77 return Site.Parent; 78 } 79 default: 80 assert(false && "Unknown record type"); 81 return 0; 82 } 83 } 84 85 CVSymbolArray limitSymbolArrayToScope(const CVSymbolArray & Symbols,uint32_t ScopeBegin)86llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols, 87 uint32_t ScopeBegin) { 88 CVSymbol Opener = *Symbols.at(ScopeBegin); 89 assert(symbolOpensScope(Opener.kind())); 90 uint32_t EndOffset = getScopeEndOffset(Opener); 91 CVSymbol Closer = *Symbols.at(EndOffset); 92 EndOffset += Closer.RecordData.size(); 93 return Symbols.substream(ScopeBegin, EndOffset); 94 } 95