10
10
#include " llvm/DebugInfo/CodeView/TypeStreamMerger.h"
11
11
#include " llvm/ADT/SmallString.h"
12
12
#include " llvm/ADT/StringExtras.h"
13
- #include " llvm/DebugInfo/CodeView/CVTypeVisitor.h"
14
13
#include " llvm/DebugInfo/CodeView/TypeDeserializer.h"
15
14
#include " llvm/DebugInfo/CodeView/TypeIndex.h"
16
15
#include " llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
17
16
#include " llvm/DebugInfo/CodeView/TypeRecord.h"
18
17
#include " llvm/DebugInfo/CodeView/TypeTableBuilder.h"
19
- #include " llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
20
18
#include " llvm/Support/Error.h"
21
19
#include " llvm/Support/ScopedPrinter.h"
22
20
@@ -57,7 +55,7 @@ namespace {
57
55
// / streams: an item (or IPI) stream and a type stream, as this is what is
58
56
// / actually stored in the final PDB. We choose which records go where by
59
57
// / looking at the record kind.
60
- class TypeStreamMerger : public TypeVisitorCallbacks {
58
+ class TypeStreamMerger {
61
59
public:
62
60
explicit TypeStreamMerger (SmallVectorImpl<TypeIndex> &SourceToDest)
63
61
: IndexMap(SourceToDest) {
@@ -66,9 +64,6 @@ class TypeStreamMerger : public TypeVisitorCallbacks {
66
64
67
65
static const TypeIndex Untranslated;
68
66
69
- Error visitTypeBegin (CVType &Record) override ;
70
- Error visitTypeEnd (CVType &Record) override ;
71
-
72
67
Error mergeTypesAndIds (TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes,
73
68
const CVTypeArray &IdsAndTypes);
74
69
Error mergeIdRecords (TypeTableBuilder &Dest,
@@ -79,33 +74,16 @@ class TypeStreamMerger : public TypeVisitorCallbacks {
79
74
private:
80
75
Error doit (const CVTypeArray &Types);
81
76
77
+ Error remapAllTypes (const CVTypeArray &Types);
78
+
79
+ Error remapType (const CVType &Type);
80
+
82
81
void addMapping (TypeIndex Idx);
83
82
84
83
bool remapTypeIndex (TypeIndex &Idx);
85
84
bool remapItemIndex (TypeIndex &Idx);
86
85
87
- bool remapIndices (RemappedType &Record, ArrayRef<TiReference> Refs) {
88
- auto OriginalData = Record.OriginalRecord .content ();
89
- bool Success = true ;
90
- for (auto &Ref : Refs) {
91
- uint32_t Offset = Ref.Offset ;
92
- ArrayRef<uint8_t > Bytes =
93
- OriginalData.slice (Ref.Offset , sizeof (TypeIndex));
94
- ArrayRef<TypeIndex> TIs (reinterpret_cast <const TypeIndex *>(Bytes.data ()),
95
- Ref.Count );
96
- for (auto TI : TIs) {
97
- TypeIndex NewTI = TI;
98
- bool ThisSuccess = (Ref.Kind == TiRefKind::IndexRef)
99
- ? remapItemIndex (NewTI)
100
- : remapTypeIndex (NewTI);
101
- if (ThisSuccess && NewTI != TI)
102
- Record.Mappings .emplace_back (Offset, NewTI);
103
- Offset += sizeof (TypeIndex);
104
- Success &= ThisSuccess;
105
- }
106
- }
107
- return Success;
108
- }
86
+ bool remapIndices (RemappedType &Record, ArrayRef<TiReference> Refs);
109
87
110
88
bool remapIndex (TypeIndex &Idx, ArrayRef<TypeIndex> Map);
111
89
@@ -127,21 +105,6 @@ class TypeStreamMerger : public TypeVisitorCallbacks {
127
105
return Error::success ();
128
106
}
129
107
130
- Error writeTypeRecord (const CVType &Record) {
131
- TypeIndex DestIdx =
132
- DestTypeStream->writeSerializedRecord (Record.RecordData );
133
- addMapping (DestIdx);
134
- return Error::success ();
135
- }
136
-
137
- Error writeTypeRecord (const RemappedType &Record, bool RemapSuccess) {
138
- return writeRecord (*DestTypeStream, Record, RemapSuccess);
139
- }
140
-
141
- Error writeIdRecord (const RemappedType &Record, bool RemapSuccess) {
142
- return writeRecord (*DestIdStream, Record, RemapSuccess);
143
- }
144
-
145
108
Optional<Error> LastError;
146
109
147
110
bool IsSecondPass = false ;
@@ -166,32 +129,19 @@ class TypeStreamMerger : public TypeVisitorCallbacks {
166
129
167
130
const TypeIndex TypeStreamMerger::Untranslated (SimpleTypeKind::NotTranslated);
168
131
169
- Error TypeStreamMerger::visitTypeBegin (CVType &Rec) {
170
- RemappedType R (Rec);
171
- SmallVector<TiReference, 32 > Refs;
172
- discoverTypeIndices (Rec.RecordData , Refs);
173
- bool Success = remapIndices (R, Refs);
174
- switch (Rec.kind ()) {
132
+ static bool isIdRecord (TypeLeafKind K) {
133
+ switch (K) {
175
134
case TypeLeafKind::LF_FUNC_ID:
176
135
case TypeLeafKind::LF_MFUNC_ID:
177
136
case TypeLeafKind::LF_STRING_ID:
178
137
case TypeLeafKind::LF_SUBSTR_LIST:
179
138
case TypeLeafKind::LF_BUILDINFO:
180
139
case TypeLeafKind::LF_UDT_SRC_LINE:
181
140
case TypeLeafKind::LF_UDT_MOD_SRC_LINE:
182
- return writeIdRecord (R, Success) ;
141
+ return true ;
183
142
default :
184
- return writeTypeRecord (R, Success) ;
143
+ return false ;
185
144
}
186
- return Error::success ();
187
- }
188
-
189
- Error TypeStreamMerger::visitTypeEnd (CVType &Rec) {
190
- ++CurIndex;
191
- if (!IsSecondPass)
192
- assert (IndexMap.size () == slotForIndex (CurIndex) &&
193
- " visitKnownRecord should add one index map entry" );
194
- return Error::success ();
195
145
}
196
146
197
147
void TypeStreamMerger::addMapping (TypeIndex Idx) {
@@ -278,15 +228,7 @@ Error TypeStreamMerger::mergeTypesAndIds(TypeTableBuilder &DestIds,
278
228
}
279
229
280
230
Error TypeStreamMerger::doit (const CVTypeArray &Types) {
281
- // We don't want to deserialize records. I guess this flag is poorly named,
282
- // but it really means "Don't deserialize records before switching on the
283
- // concrete type.
284
- // FIXME: We can probably get even more speed here if we don't use the visitor
285
- // pipeline here, but instead write the switch ourselves. I don't think it
286
- // would buy us much since it's already pretty fast, but it's probably worth
287
- // a few cycles.
288
- if (auto EC =
289
- codeview::visitTypeStream (Types, *this , VDS_BytesExternal))
231
+ if (auto EC = remapAllTypes (Types))
290
232
return EC;
291
233
292
234
// If we found bad indices but no other errors, try doing another pass and see
@@ -302,8 +244,7 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
302
244
NumBadIndices = 0 ;
303
245
CurIndex = TypeIndex (TypeIndex::FirstNonSimpleIndex);
304
246
305
- if (auto EC =
306
- codeview::visitTypeStream (Types, *this , VDS_BytesExternal))
247
+ if (auto EC = remapAllTypes (Types))
307
248
return EC;
308
249
309
250
assert (NumBadIndices <= BadIndicesRemaining &&
@@ -319,6 +260,52 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
319
260
return Error::success ();
320
261
}
321
262
263
+ Error TypeStreamMerger::remapAllTypes (const CVTypeArray &Types) {
264
+ for (const CVType &Type : Types)
265
+ if (auto EC = remapType (Type))
266
+ return EC;
267
+ return Error::success ();
268
+ }
269
+
270
+ Error TypeStreamMerger::remapType (const CVType &Type) {
271
+ RemappedType R (Type);
272
+ SmallVector<TiReference, 32 > Refs;
273
+ discoverTypeIndices (Type.RecordData , Refs);
274
+ bool MappedAllIndices = remapIndices (R, Refs);
275
+ TypeTableBuilder &Dest =
276
+ isIdRecord (Type.kind ()) ? *DestIdStream : *DestTypeStream;
277
+ if (auto EC = writeRecord (Dest, R, MappedAllIndices))
278
+ return EC;
279
+
280
+ ++CurIndex;
281
+ assert ((IsSecondPass || IndexMap.size () == slotForIndex (CurIndex)) &&
282
+ " visitKnownRecord should add one index map entry" );
283
+ return Error::success ();
284
+ }
285
+
286
+ bool TypeStreamMerger::remapIndices (RemappedType &Record,
287
+ ArrayRef<TiReference> Refs) {
288
+ ArrayRef<uint8_t > OriginalData = Record.OriginalRecord .content ();
289
+ bool Success = true ;
290
+ for (auto &Ref : Refs) {
291
+ uint32_t Offset = Ref.Offset ;
292
+ ArrayRef<uint8_t > Bytes = OriginalData.slice (Ref.Offset , sizeof (TypeIndex));
293
+ ArrayRef<TypeIndex> TIs (reinterpret_cast <const TypeIndex *>(Bytes.data ()),
294
+ Ref.Count );
295
+ for (auto TI : TIs) {
296
+ TypeIndex NewTI = TI;
297
+ bool ThisSuccess = (Ref.Kind == TiRefKind::IndexRef)
298
+ ? remapItemIndex (NewTI)
299
+ : remapTypeIndex (NewTI);
300
+ if (ThisSuccess && NewTI != TI)
301
+ Record.Mappings .emplace_back (Offset, NewTI);
302
+ Offset += sizeof (TypeIndex);
303
+ Success &= ThisSuccess;
304
+ }
305
+ }
306
+ return Success;
307
+ }
308
+
322
309
Error llvm::codeview::mergeTypeRecords (TypeTableBuilder &Dest,
323
310
SmallVectorImpl<TypeIndex> &SourceToDest,
324
311
const CVTypeArray &Types) {
0 commit comments