1 //==- SymbolCache.h - Cache of native symbols and ids ------------*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
14 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
15 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
17 #include "llvm/Support/Allocator.h"
28 NativeSession
&Session
;
29 DbiStream
*Dbi
= nullptr;
31 /// Cache of all stable symbols, indexed by SymIndexId. Just because a
32 /// symbol has been parsed does not imply that it will be stable and have
33 /// an Id. Id allocation is an implementation, with the only guarantee
34 /// being that once an Id is allocated, the symbol can be assumed to be
36 std::vector
<std::unique_ptr
<NativeRawSymbol
>> Cache
;
38 /// For type records from the TPI stream which have been paresd and cached,
39 /// stores a mapping to SymIndexId of the cached symbol.
40 DenseMap
<codeview::TypeIndex
, SymIndexId
> TypeIndexToSymbolId
;
42 /// For field list members which have been parsed and cached, stores a mapping
43 /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
45 DenseMap
<std::pair
<codeview::TypeIndex
, uint32_t>, SymIndexId
>
46 FieldListMembersToSymbolId
;
48 /// List of SymIndexIds for each compiland, indexed by compiland index as they
49 /// appear in the PDB file.
50 std::vector
<SymIndexId
> Compilands
;
52 /// Map from global symbol offset to SymIndexId.
53 DenseMap
<uint32_t, SymIndexId
> GlobalOffsetToSymbolId
;
55 SymIndexId
createSymbolPlaceholder() {
56 SymIndexId Id
= Cache
.size();
57 Cache
.push_back(nullptr);
61 template <typename ConcreteSymbolT
, typename CVRecordT
, typename
... Args
>
62 SymIndexId
createSymbolForType(codeview::TypeIndex TI
, codeview::CVType CVT
,
63 Args
&&... ConstructorArgs
) {
66 codeview::TypeDeserializer::deserializeAs
<CVRecordT
>(CVT
, Record
)) {
67 consumeError(std::move(EC
));
71 return createSymbol
<ConcreteSymbolT
>(
72 TI
, std::move(Record
), std::forward
<Args
>(ConstructorArgs
)...);
75 SymIndexId
createSymbolForModifiedType(codeview::TypeIndex ModifierTI
,
76 codeview::CVType CVT
);
78 SymIndexId
createSimpleType(codeview::TypeIndex TI
,
79 codeview::ModifierOptions Mods
);
82 SymbolCache(NativeSession
&Session
, DbiStream
*Dbi
);
84 template <typename ConcreteSymbolT
, typename
... Args
>
85 SymIndexId
createSymbol(Args
&&... ConstructorArgs
) {
86 SymIndexId Id
= Cache
.size();
88 // Initial construction must not access the cache, since it must be done
90 auto Result
= std::make_unique
<ConcreteSymbolT
>(
91 Session
, Id
, std::forward
<Args
>(ConstructorArgs
)...);
92 Result
->SymbolId
= Id
;
94 NativeRawSymbol
*NRS
= static_cast<NativeRawSymbol
*>(Result
.get());
95 Cache
.push_back(std::move(Result
));
97 // After the item is in the cache, we can do further initialization which
98 // is then allowed to access the cache.
103 std::unique_ptr
<IPDBEnumSymbols
>
104 createTypeEnumerator(codeview::TypeLeafKind Kind
);
106 std::unique_ptr
<IPDBEnumSymbols
>
107 createTypeEnumerator(std::vector
<codeview::TypeLeafKind
> Kinds
);
109 std::unique_ptr
<IPDBEnumSymbols
>
110 createGlobalsEnumerator(codeview::SymbolKind Kind
);
112 SymIndexId
findSymbolByTypeIndex(codeview::TypeIndex TI
);
114 template <typename ConcreteSymbolT
, typename
... Args
>
115 SymIndexId
getOrCreateFieldListMember(codeview::TypeIndex FieldListTI
,
117 Args
&&... ConstructorArgs
) {
118 SymIndexId SymId
= Cache
.size();
119 std::pair
<codeview::TypeIndex
, uint32_t> Key
{FieldListTI
, Index
};
120 auto Result
= FieldListMembersToSymbolId
.try_emplace(Key
, SymId
);
123 createSymbol
<ConcreteSymbolT
>(std::forward
<Args
>(ConstructorArgs
)...);
125 SymId
= Result
.first
->second
;
129 SymIndexId
getOrCreateGlobalSymbolByOffset(uint32_t Offset
);
131 std::unique_ptr
<PDBSymbolCompiland
> getOrCreateCompiland(uint32_t Index
);
132 uint32_t getNumCompilands() const;
134 std::unique_ptr
<PDBSymbol
> getSymbolById(SymIndexId SymbolId
) const;
136 NativeRawSymbol
&getNativeSymbolById(SymIndexId SymbolId
) const;
138 template <typename ConcreteT
>
139 ConcreteT
&getNativeSymbolById(SymIndexId SymbolId
) const {
140 return static_cast<ConcreteT
&>(getNativeSymbolById(SymbolId
));