xref: /src/contrib/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1d8e91e46SDimitry Andric //===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===//
2d8e91e46SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d8e91e46SDimitry Andric //
7d8e91e46SDimitry Andric //===----------------------------------------------------------------------===//
8d8e91e46SDimitry Andric 
9d8e91e46SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
10d8e91e46SDimitry Andric 
11145449b1SDimitry Andric #include "llvm/ADT/ArrayRef.h"
12d8e91e46SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
13d8e91e46SDimitry Andric 
14d8e91e46SDimitry Andric using namespace llvm;
15d8e91e46SDimitry Andric using namespace llvm::codeview;
16d8e91e46SDimitry Andric 
createRecord(const CVSymbol & sym)17706b4fc4SDimitry Andric template <typename RecordT> static RecordT createRecord(const CVSymbol &sym) {
18d8e91e46SDimitry Andric   RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
19d8e91e46SDimitry Andric   cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
20d8e91e46SDimitry Andric   return record;
21d8e91e46SDimitry Andric }
22d8e91e46SDimitry Andric 
getScopeEndOffset(const CVSymbol & Sym)23d8e91e46SDimitry Andric uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) {
24d8e91e46SDimitry Andric   assert(symbolOpensScope(Sym.kind()));
25d8e91e46SDimitry Andric   switch (Sym.kind()) {
26d8e91e46SDimitry Andric   case SymbolKind::S_GPROC32:
27d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32:
28d8e91e46SDimitry Andric   case SymbolKind::S_GPROC32_ID:
29d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_ID:
30d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_DPC:
31d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_DPC_ID: {
32d8e91e46SDimitry Andric     ProcSym Proc = createRecord<ProcSym>(Sym);
33d8e91e46SDimitry Andric     return Proc.End;
34d8e91e46SDimitry Andric   }
35d8e91e46SDimitry Andric   case SymbolKind::S_BLOCK32: {
36d8e91e46SDimitry Andric     BlockSym Block = createRecord<BlockSym>(Sym);
37d8e91e46SDimitry Andric     return Block.End;
38d8e91e46SDimitry Andric   }
39d8e91e46SDimitry Andric   case SymbolKind::S_THUNK32: {
40d8e91e46SDimitry Andric     Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
41d8e91e46SDimitry Andric     return Thunk.End;
42d8e91e46SDimitry Andric   }
43d8e91e46SDimitry Andric   case SymbolKind::S_INLINESITE: {
44d8e91e46SDimitry Andric     InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
45d8e91e46SDimitry Andric     return Site.End;
46d8e91e46SDimitry Andric   }
47d8e91e46SDimitry Andric   default:
48d8e91e46SDimitry Andric     assert(false && "Unknown record type");
49d8e91e46SDimitry Andric     return 0;
50d8e91e46SDimitry Andric   }
51d8e91e46SDimitry Andric }
52d8e91e46SDimitry Andric 
53d8e91e46SDimitry Andric uint32_t
getScopeParentOffset(const llvm::codeview::CVSymbol & Sym)54d8e91e46SDimitry Andric llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) {
55d8e91e46SDimitry Andric   assert(symbolOpensScope(Sym.kind()));
56d8e91e46SDimitry Andric   switch (Sym.kind()) {
57d8e91e46SDimitry Andric   case SymbolKind::S_GPROC32:
58d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32:
59d8e91e46SDimitry Andric   case SymbolKind::S_GPROC32_ID:
60d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_ID:
61d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_DPC:
62d8e91e46SDimitry Andric   case SymbolKind::S_LPROC32_DPC_ID: {
63d8e91e46SDimitry Andric     ProcSym Proc = createRecord<ProcSym>(Sym);
64d8e91e46SDimitry Andric     return Proc.Parent;
65d8e91e46SDimitry Andric   }
66d8e91e46SDimitry Andric   case SymbolKind::S_BLOCK32: {
67d8e91e46SDimitry Andric     BlockSym Block = createRecord<BlockSym>(Sym);
68d8e91e46SDimitry Andric     return Block.Parent;
69d8e91e46SDimitry Andric   }
70d8e91e46SDimitry Andric   case SymbolKind::S_THUNK32: {
71d8e91e46SDimitry Andric     Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
72d8e91e46SDimitry Andric     return Thunk.Parent;
73d8e91e46SDimitry Andric   }
74d8e91e46SDimitry Andric   case SymbolKind::S_INLINESITE: {
75d8e91e46SDimitry Andric     InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
76d8e91e46SDimitry Andric     return Site.Parent;
77d8e91e46SDimitry Andric   }
78d8e91e46SDimitry Andric   default:
79d8e91e46SDimitry Andric     assert(false && "Unknown record type");
80d8e91e46SDimitry Andric     return 0;
81d8e91e46SDimitry Andric   }
82d8e91e46SDimitry Andric }
83d8e91e46SDimitry Andric 
84d8e91e46SDimitry Andric CVSymbolArray
limitSymbolArrayToScope(const CVSymbolArray & Symbols,uint32_t ScopeBegin)85d8e91e46SDimitry Andric llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols,
86d8e91e46SDimitry Andric                                         uint32_t ScopeBegin) {
87d8e91e46SDimitry Andric   CVSymbol Opener = *Symbols.at(ScopeBegin);
88d8e91e46SDimitry Andric   assert(symbolOpensScope(Opener.kind()));
89d8e91e46SDimitry Andric   uint32_t EndOffset = getScopeEndOffset(Opener);
90d8e91e46SDimitry Andric   CVSymbol Closer = *Symbols.at(EndOffset);
91d8e91e46SDimitry Andric   EndOffset += Closer.RecordData.size();
92d8e91e46SDimitry Andric   return Symbols.substream(ScopeBegin, EndOffset);
93d8e91e46SDimitry Andric }
94