LLVM: lib/DebugInfo/PDB/Native/TpiStream.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
26#include
27#include
28
29using namespace llvm;
34
36 : Pdb(File), Stream(std::move(Stream)) {}
37
39
42
45 "TPI Stream does not contain a header.");
46
49 "TPI Stream does not contain a header.");
50
53 "Unsupported TPI Version.");
54
57 "Corrupt TPI Header size.");
58
59 if (Header->HashKeySize != sizeof(ulittle32_t))
61 "TPI Stream expected 4 byte hash key size.");
62
66 "TPI Stream Invalid number of hash buckets.");
67
68
69 if (auto EC =
70 Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
71 return EC;
72
74 if (auto EC =
75 RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
76 return EC;
77
78
80 auto HS = Pdb.safelyCreateIndexedStream(Header->HashStreamIndex);
81 if (!HS) {
84 "Invalid TPI hash stream index.");
85 }
87
88
90 Header->HashValueBuffer.Length / sizeof(ulittle32_t);
94 "TPI hash count does not match with the number of type records.");
95 HSR.setOffset(Header->HashValueBuffer.Off);
96 if (auto EC = HSR.readArray(HashValues, NumHashValues))
97 return EC;
98
99 HSR.setOffset(Header->IndexOffsetBuffer.Off);
100 uint32_t NumTypeIndexOffsets =
101 Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
102 if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
103 return EC;
104
105 if (Header->HashAdjBuffer.Length > 0) {
106 HSR.setOffset(Header->HashAdjBuffer.Off);
107 if (auto EC = HashAdjusters.load(HSR))
108 return EC;
109 }
110
111 HashStream = std::move(*HS);
112 }
113
114 Types = std::make_unique(
117}
118
123
125
127
131
133 return Header->HashStreamIndex;
134}
135
137 return Header->HashAuxStreamIndex;
138}
139
142
144 if (!HashMap.empty())
145 return;
146 if (HashValues.empty())
147 return;
148
149 HashMap.resize(Header->NumHashBuckets);
150
151 TypeIndex TIB{Header->TypeIndexBegin};
152 TypeIndex TIE{Header->TypeIndexEnd};
153 while (TIB < TIE) {
155 HashMap[HV].push_back(TIB++);
156 }
157}
158
162
164 if (Bucket > HashMap.size())
165 return {};
166
167 std::vector Result;
168 for (TypeIndex TI : HashMap[Bucket]) {
170 if (ThisName == Name)
171 Result.push_back(TI);
172 }
173 return Result;
174}
175
177
182
183 CVType F = Types->getType(ForwardRefTI);
185 return ForwardRefTI;
186
188 if (!ForwardTRH)
190
191 uint32_t BucketIdx = ForwardTRH->FullRecordHash % Header->NumHashBuckets;
192
193 for (TypeIndex TI : HashMap[BucketIdx]) {
194 CVType CVT = Types->getType(TI);
195 if (CVT.kind() != F.kind())
196 continue;
197
199 if (!FullTRH)
201 if (ForwardTRH->FullRecordHash != FullTRH->FullRecordHash)
202 continue;
203 TagRecord &ForwardTR = ForwardTRH->getRecord();
204 TagRecord &FullTR = FullTRH->getRecord();
205
208 return TI;
209 continue;
210 }
211
213 continue;
215 return TI;
216 }
217 return ForwardRefTI;
218}
219
221 assert(!Index.isSimple());
222 return Types->getType(Index);
223}
224
226 return TypeRecordsSubstream;
227}
228
230 return HashValues;
231}
232
234 return TypeIndexOffsets;
235}
236
238 return HashAdjusters;
239}
240
242 return make_range(TypeRecords.begin(HadError), TypeRecords.end());
243}
244
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides read only access to a subclass of BinaryStream.
Error readObject(const T *&Dest)
Get a pointer to an object of type T from the underlying stream, as if by memcpy, and store the resul...
LLVM_ABI Error readSubstream(BinarySubstreamRef &Ref, uint32_t Length)
Read Length bytes from the underlying stream into Ref.
uint64_t bytesRemaining() const
void setOffset(uint64_t Off)
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
FixedStreamArray is similar to VarStreamArray, except with each record having a fixed-length.
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
StringRef getName() const
StringRef getUniqueName() const
bool hasUniqueName() const
uint32_t toArrayIndex() const
LLVM_ABI uint32_t getHashKeySize() const
Definition TpiStream.cpp:141
LLVM_ABI BinarySubstreamRef getTypeRecordsSubstream() const
Definition TpiStream.cpp:225
LLVM_ABI HashTable< support::ulittle32_t > & getHashAdjusters()
Definition TpiStream.cpp:237
LLVM_ABI std::vector< codeview::TypeIndex > findRecordsByName(StringRef Name) const
Definition TpiStream.cpp:159
LLVM_ABI uint32_t TypeIndexBegin() const
Definition TpiStream.cpp:124
LLVM_ABI Error commit()
Definition TpiStream.cpp:245
LLVM_ABI PdbRaw_TpiVer getTpiVersion() const
Definition TpiStream.cpp:119
LLVM_ABI codeview::CVTypeRange types(bool *HadError) const
Definition TpiStream.cpp:241
LLVM_ABI void buildHashMap()
Definition TpiStream.cpp:143
LLVM_ABI TpiStream(PDBFile &File, std::unique_ptr< msf::MappedBlockStream > Stream)
Definition TpiStream.cpp:35
LLVM_ABI FixedStreamArray< codeview::TypeIndexOffset > getTypeIndexOffsets() const
Definition TpiStream.cpp:233
LLVM_ABI codeview::CVType getType(codeview::TypeIndex Index)
Definition TpiStream.cpp:220
LLVM_ABI uint16_t getTypeHashStreamAuxIndex() const
Definition TpiStream.cpp:136
LLVM_ABI uint16_t getTypeHashStreamIndex() const
Definition TpiStream.cpp:132
LLVM_ABI Error reload()
Definition TpiStream.cpp:40
LLVM_ABI bool supportsTypeLookup() const
Definition TpiStream.cpp:176
LLVM_ABI FixedStreamArray< support::ulittle32_t > getHashValues() const
Definition TpiStream.cpp:229
LLVM_ABI Expected< codeview::TypeIndex > findFullDeclForForwardRef(codeview::TypeIndex ForwardRefTI) const
Definition TpiStream.cpp:179
LLVM_ABI uint32_t getNumTypeRecords() const
Definition TpiStream.cpp:128
LLVM_ABI uint32_t TypeIndexEnd() const
Definition TpiStream.cpp:126
LLVM_ABI uint32_t getNumHashBuckets() const
Definition TpiStream.cpp:140
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
iterator_range< CVTypeArray::Iterator > CVTypeRange
LLVM_ABI bool isUdtForwardRef(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
CVRecord< TypeLeafKind > CVType
LLVM_ABI std::string computeTypeName(TypeCollection &Types, TypeIndex Index)
const uint16_t kInvalidStreamIndex
LLVM_ABI uint32_t hashStringV1(StringRef Str)
const uint32_t MaxTpiHashBuckets
const uint32_t MinTpiHashBuckets
LLVM_ABI Expected< TagRecordHash > hashTagRecord(const codeview::CVType &Type)
Given a CVType referring to a class, structure, union, or enum, compute the hash of its forward decl ...
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.