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 Andric template <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 Andric uint32_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 Andric llvm::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 Andric llvm::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