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)18 template <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)24 uint32_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)55 llvm::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)86 llvm::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