Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//==- SymbolCache.h - Cache of native symbols and ids ------------*- C++ -*-==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
10
#define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
11
 
12
#include "llvm/ADT/DenseMap.h"
13
#include "llvm/DebugInfo/CodeView/CVRecord.h"
14
#include "llvm/DebugInfo/CodeView/CodeView.h"
15
#include "llvm/DebugInfo/CodeView/Line.h"
16
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
17
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
18
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
19
#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
20
#include "llvm/DebugInfo/PDB/PDBTypes.h"
21
 
22
#include <memory>
23
#include <vector>
24
 
25
namespace llvm {
26
namespace codeview {
27
class InlineSiteSym;
28
struct FileChecksumEntry;
29
} // namespace codeview
30
namespace pdb {
31
class IPDBSourceFile;
32
class NativeSession;
33
class PDBSymbol;
34
class PDBSymbolCompiland;
35
class DbiStream;
36
 
37
class SymbolCache {
38
  NativeSession &Session;
39
  DbiStream *Dbi = nullptr;
40
 
41
  /// Cache of all stable symbols, indexed by SymIndexId.  Just because a
42
  /// symbol has been parsed does not imply that it will be stable and have
43
  /// an Id.  Id allocation is an implementation, with the only guarantee
44
  /// being that once an Id is allocated, the symbol can be assumed to be
45
  /// cached.
46
  mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
47
 
48
  /// For type records from the TPI stream which have been paresd and cached,
49
  /// stores a mapping to SymIndexId of the cached symbol.
50
  mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
51
 
52
  /// For field list members which have been parsed and cached, stores a mapping
53
  /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
54
  /// cached symbol.
55
  mutable DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
56
      FieldListMembersToSymbolId;
57
 
58
  /// List of SymIndexIds for each compiland, indexed by compiland index as they
59
  /// appear in the PDB file.
60
  mutable std::vector<SymIndexId> Compilands;
61
 
62
  /// List of source files, indexed by unique source file index.
63
  mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
64
 
65
  /// Map from string table offset to source file Id.
66
  mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
67
 
68
  /// Map from global symbol offset to SymIndexId.
69
  mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
70
 
71
  /// Map from segment and code offset to function symbols.
72
  mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
73
  /// Map from segment and code offset to public symbols.
74
  mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId>
75
      AddressToPublicSymId;
76
 
77
  /// Map from module index and symbol table offset to SymIndexId.
78
  mutable DenseMap<std::pair<uint16_t, uint32_t>, SymIndexId>
79
      SymTabOffsetToSymbolId;
80
 
81
  struct LineTableEntry {
82
    uint64_t Addr;
83
    codeview::LineInfo Line;
84
    uint32_t ColumnNumber;
85
    uint32_t FileNameIndex;
86
    bool IsTerminalEntry;
87
  };
88
 
89
  std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
90
  mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
91
 
92
  SymIndexId createSymbolPlaceholder() const {
93
    SymIndexId Id = Cache.size();
94
    Cache.push_back(nullptr);
95
    return Id;
96
  }
97
 
98
  template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
99
  SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
100
                                 Args &&...ConstructorArgs) const {
101
    CVRecordT Record;
102
    if (auto EC =
103
            codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
104
      consumeError(std::move(EC));
105
      return 0;
106
    }
107
 
108
    return createSymbol<ConcreteSymbolT>(
109
        TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
110
  }
111
 
112
  SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
113
                                         codeview::CVType CVT) const;
114
 
115
  SymIndexId createSimpleType(codeview::TypeIndex TI,
116
                              codeview::ModifierOptions Mods) const;
117
 
118
  std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
119
                                                            uint32_t Offset);
120
  std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
121
                                                          uint32_t Offset);
122
 
123
public:
124
  SymbolCache(NativeSession &Session, DbiStream *Dbi);
125
 
126
  template <typename ConcreteSymbolT, typename... Args>
127
  SymIndexId createSymbol(Args &&...ConstructorArgs) const {
128
    SymIndexId Id = Cache.size();
129
 
130
    // Initial construction must not access the cache, since it must be done
131
    // atomically.
132
    auto Result = std::make_unique<ConcreteSymbolT>(
133
        Session, Id, std::forward<Args>(ConstructorArgs)...);
134
    Result->SymbolId = Id;
135
 
136
    NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
137
    Cache.push_back(std::move(Result));
138
 
139
    // After the item is in the cache, we can do further initialization which
140
    // is then allowed to access the cache.
141
    NRS->initialize();
142
    return Id;
143
  }
144
 
145
  std::unique_ptr<IPDBEnumSymbols>
146
  createTypeEnumerator(codeview::TypeLeafKind Kind);
147
 
148
  std::unique_ptr<IPDBEnumSymbols>
149
  createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds);
150
 
151
  std::unique_ptr<IPDBEnumSymbols>
152
  createGlobalsEnumerator(codeview::SymbolKind Kind);
153
 
154
  SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const;
155
 
156
  template <typename ConcreteSymbolT, typename... Args>
157
  SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
158
                                        uint32_t Index,
159
                                        Args &&... ConstructorArgs) {
160
    SymIndexId SymId = Cache.size();
161
    std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
162
    auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
163
    if (Result.second)
164
      SymId =
165
          createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
166
    else
167
      SymId = Result.first->second;
168
    return SymId;
169
  }
170
 
171
  SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
172
  SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym,
173
                                     uint64_t ParentAddr, uint16_t Modi,
174
                                     uint32_t RecordOffset) const;
175
 
176
  std::unique_ptr<PDBSymbol>
177
  findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
178
 
179
  std::unique_ptr<IPDBEnumLineNumbers>
180
  findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
181
 
182
  std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
183
  uint32_t getNumCompilands() const;
184
 
185
  std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
186
 
187
  NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const;
188
 
189
  template <typename ConcreteT>
190
  ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
191
    return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
192
  }
193
 
194
  std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
195
  SymIndexId
196
  getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
197
};
198
 
199
} // namespace pdb
200
} // namespace llvm
201
 
202
#endif