]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / PDB / Native / SymbolCache.h
1 //==- SymbolCache.h - Cache of native symbols and ids ------------*- 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 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
11 #define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
12
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
15 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
18 #include "llvm/Support/Allocator.h"
19
20 #include <memory>
21 #include <vector>
22
23 namespace llvm {
24 namespace pdb {
25 class DbiStream;
26 class PDBFile;
27
28 class SymbolCache {
29   NativeSession &Session;
30   DbiStream *Dbi = nullptr;
31
32   /// Cache of all stable symbols, indexed by SymIndexId.  Just because a
33   /// symbol has been parsed does not imply that it will be stable and have
34   /// an Id.  Id allocation is an implementation, with the only guarantee
35   /// being that once an Id is allocated, the symbol can be assumed to be
36   /// cached.
37   std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
38
39   /// For type records from the TPI stream which have been paresd and cached,
40   /// stores a mapping to SymIndexId of the cached symbol.
41   DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
42
43   /// For field list members which have been parsed and cached, stores a mapping
44   /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
45   /// cached symbol.
46   DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
47       FieldListMembersToSymbolId;
48
49   /// List of SymIndexIds for each compiland, indexed by compiland index as they
50   /// appear in the PDB file.
51   std::vector<SymIndexId> Compilands;
52
53   /// Map from global symbol offset to SymIndexId.
54   DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
55
56   SymIndexId createSymbolPlaceholder() {
57     SymIndexId Id = Cache.size();
58     Cache.push_back(nullptr);
59     return Id;
60   }
61
62   template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
63   SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
64                                  Args &&... ConstructorArgs) {
65     CVRecordT Record;
66     if (auto EC =
67             codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
68       consumeError(std::move(EC));
69       return 0;
70     }
71
72     return createSymbol<ConcreteSymbolT>(
73         TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
74   }
75
76   SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
77                                          codeview::CVType CVT);
78
79   SymIndexId createSimpleType(codeview::TypeIndex TI,
80                               codeview::ModifierOptions Mods);
81
82 public:
83   SymbolCache(NativeSession &Session, DbiStream *Dbi);
84
85   template <typename ConcreteSymbolT, typename... Args>
86   SymIndexId createSymbol(Args &&... ConstructorArgs) {
87     SymIndexId Id = Cache.size();
88
89     // Initial construction must not access the cache, since it must be done
90     // atomically.
91     auto Result = llvm::make_unique<ConcreteSymbolT>(
92         Session, Id, std::forward<Args>(ConstructorArgs)...);
93     Result->SymbolId = Id;
94
95     NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
96     Cache.push_back(std::move(Result));
97
98     // After the item is in the cache, we can do further initialization which
99     // is then allowed to access the cache.
100     NRS->initialize();
101     return Id;
102   }
103
104   std::unique_ptr<IPDBEnumSymbols>
105   createTypeEnumerator(codeview::TypeLeafKind Kind);
106
107   std::unique_ptr<IPDBEnumSymbols>
108   createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds);
109
110   std::unique_ptr<IPDBEnumSymbols>
111   createGlobalsEnumerator(codeview::SymbolKind Kind);
112
113   SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
114
115   template <typename ConcreteSymbolT, typename... Args>
116   SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
117                                         uint32_t Index,
118                                         Args &&... ConstructorArgs) {
119     SymIndexId SymId = Cache.size();
120     std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
121     auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
122     if (Result.second)
123       SymId =
124           createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
125     else
126       SymId = Result.first->second;
127     return SymId;
128   }
129
130   SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
131
132   std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
133   uint32_t getNumCompilands() const;
134
135   std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
136
137   NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const;
138
139   template <typename ConcreteT>
140   ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
141     return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
142   }
143 };
144
145 } // namespace pdb
146 } // namespace llvm
147
148 #endif