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