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