OSDN Git Service

[PDB] Make the native reader support enumerators.
[android-x86/external-llvm.git] / 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   std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
33   DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
34   DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
35       FieldListMembersToSymbolId;
36   std::vector<SymIndexId> Compilands;
37
38   SymIndexId createSymbolPlaceholder() {
39     SymIndexId Id = Cache.size();
40     Cache.push_back(nullptr);
41     return Id;
42   }
43
44   template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
45   SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
46                                  Args &&... ConstructorArgs) {
47     CVRecordT Record;
48     if (auto EC =
49             codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
50       consumeError(std::move(EC));
51       return 0;
52     }
53
54     return createSymbol<ConcreteSymbolT>(
55         TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
56   }
57
58   SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
59                                          codeview::CVType CVT);
60
61   SymIndexId createSimpleType(codeview::TypeIndex TI,
62                               codeview::ModifierOptions Mods);
63
64 public:
65   SymbolCache(NativeSession &Session, DbiStream *Dbi);
66
67   template <typename ConcreteSymbolT, typename... Args>
68   SymIndexId createSymbol(Args &&... ConstructorArgs) {
69     SymIndexId Id = Cache.size();
70
71     auto Result = llvm::make_unique<ConcreteSymbolT>(
72         Session, Id, std::forward<Args>(ConstructorArgs)...);
73     Cache.push_back(std::move(Result));
74     return Id;
75   }
76
77   std::unique_ptr<IPDBEnumSymbols>
78   createTypeEnumerator(codeview::TypeLeafKind Kind);
79
80   SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
81
82   template <typename ConcreteSymbolT, typename... Args>
83   SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
84                                         uint32_t Index,
85                                         Args &&... ConstructorArgs) {
86     SymIndexId SymId = Cache.size();
87     std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
88     auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
89     if (Result.second) {
90       auto NewSymbol = llvm::make_unique<ConcreteSymbolT>(
91           Session, SymId, std::forward<Args>(ConstructorArgs)...);
92       Cache.push_back(std::move(NewSymbol));
93     } else {
94       SymId = Result.first->second;
95     }
96     return SymId;
97   }
98
99   std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
100   uint32_t getNumCompilands() const;
101
102   std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
103
104   NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const;
105
106   template <typename ConcreteT>
107   ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
108     return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
109   }
110 };
111
112 } // namespace pdb
113 } // namespace llvm
114
115 #endif