]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
Merge ^/head r305892 through r306302.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / DebugInfo / CodeView / TypeRecord.cpp
1 //===-- TypeRecord.cpp ------------------------------------------*- 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 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
11 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
12 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
13
14 using namespace llvm;
15 using namespace llvm::codeview;
16
17 //===----------------------------------------------------------------------===//
18 // Type record deserialization
19 //===----------------------------------------------------------------------===//
20
21 ErrorOr<MemberPointerInfo>
22 MemberPointerInfo::deserialize(ArrayRef<uint8_t> &Data) {
23   const Layout *L = nullptr;
24   if (auto EC = consumeObject(Data, L))
25     return EC;
26
27   TypeIndex T = L->ClassType;
28   uint16_t R = L->Representation;
29   PointerToMemberRepresentation PMR =
30       static_cast<PointerToMemberRepresentation>(R);
31   return MemberPointerInfo(T, PMR);
32 }
33
34 ErrorOr<ModifierRecord> ModifierRecord::deserialize(TypeRecordKind Kind,
35                                                     ArrayRef<uint8_t> &Data) {
36   const Layout *L = nullptr;
37   if (auto EC = consumeObject(Data, L))
38     return EC;
39
40   TypeIndex M = L->ModifiedType;
41   uint16_t O = L->Modifiers;
42   ModifierOptions MO = static_cast<ModifierOptions>(O);
43   return ModifierRecord(M, MO);
44 }
45
46 ErrorOr<ProcedureRecord> ProcedureRecord::deserialize(TypeRecordKind Kind,
47                                                       ArrayRef<uint8_t> &Data) {
48   const Layout *L = nullptr;
49   if (auto EC = consumeObject(Data, L))
50     return EC;
51   return ProcedureRecord(L->ReturnType, L->CallConv, L->Options,
52                          L->NumParameters, L->ArgListType);
53 }
54
55 ErrorOr<MemberFunctionRecord>
56 MemberFunctionRecord::deserialize(TypeRecordKind Kind,
57                                   ArrayRef<uint8_t> &Data) {
58   const Layout *L = nullptr;
59   CV_DESERIALIZE(Data, L);
60   return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType,
61                               L->CallConv, L->Options, L->NumParameters,
62                               L->ArgListType, L->ThisAdjustment);
63 }
64
65 ErrorOr<MemberFuncIdRecord>
66 MemberFuncIdRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
67   const Layout *L = nullptr;
68   StringRef Name;
69   CV_DESERIALIZE(Data, L, Name);
70   return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
71 }
72
73 ErrorOr<ArgListRecord> ArgListRecord::deserialize(TypeRecordKind Kind,
74                                                   ArrayRef<uint8_t> &Data) {
75   if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
76     return std::make_error_code(std::errc::illegal_byte_sequence);
77
78   const Layout *L = nullptr;
79   ArrayRef<TypeIndex> Indices;
80   CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
81   return ArgListRecord(Kind, Indices);
82 }
83
84 ErrorOr<PointerRecord> PointerRecord::deserialize(TypeRecordKind Kind,
85                                                   ArrayRef<uint8_t> &Data) {
86   const Layout *L = nullptr;
87   if (auto EC = consumeObject(Data, L))
88     return EC;
89
90   PointerKind PtrKind = L->getPtrKind();
91   PointerMode Mode = L->getPtrMode();
92   uint32_t Opts = L->Attrs;
93   PointerOptions Options = static_cast<PointerOptions>(Opts);
94   uint8_t Size = L->getPtrSize();
95
96   if (L->isPointerToMember()) {
97     auto E = MemberPointerInfo::deserialize(Data);
98     if (E.getError())
99       return std::make_error_code(std::errc::illegal_byte_sequence);
100     return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *E);
101   }
102
103   return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size);
104 }
105
106 ErrorOr<NestedTypeRecord>
107 NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
108   const Layout *L = nullptr;
109   StringRef Name;
110   CV_DESERIALIZE(Data, L, Name);
111   return NestedTypeRecord(L->Type, Name);
112 }
113
114 ErrorOr<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
115                                               ArrayRef<uint8_t> &Data) {
116   const Layout *L = nullptr;
117   uint64_t Size;
118   StringRef Name;
119   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name);
120   return ArrayRecord(L->ElementType, L->IndexType, Size, Name);
121 }
122
123 ErrorOr<ClassRecord> ClassRecord::deserialize(TypeRecordKind Kind,
124                                               ArrayRef<uint8_t> &Data) {
125   uint64_t Size = 0;
126   StringRef Name;
127   StringRef UniqueName;
128   uint16_t Props;
129   const Layout *L = nullptr;
130
131   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name,
132                  CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName()));
133
134   Props = L->Properties;
135   uint16_t WrtValue = (Props & WinRTKindMask) >> WinRTKindShift;
136   WindowsRTClassKind WRT = static_cast<WindowsRTClassKind>(WrtValue);
137   uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
138   HfaKind Hfa = static_cast<HfaKind>(HfaMask);
139
140   ClassOptions Options = static_cast<ClassOptions>(Props);
141   return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList,
142                      L->DerivedFrom, L->VShape, Size, Name, UniqueName);
143 }
144
145 ErrorOr<UnionRecord> UnionRecord::deserialize(TypeRecordKind Kind,
146                                               ArrayRef<uint8_t> &Data) {
147   uint64_t Size = 0;
148   StringRef Name;
149   StringRef UniqueName;
150   uint16_t Props;
151
152   const Layout *L = nullptr;
153   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name,
154                  CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName()));
155
156   Props = L->Properties;
157
158   uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
159   HfaKind Hfa = static_cast<HfaKind>(HfaMask);
160   ClassOptions Options = static_cast<ClassOptions>(Props);
161   return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name,
162                      UniqueName);
163 }
164
165 ErrorOr<EnumRecord> EnumRecord::deserialize(TypeRecordKind Kind,
166                                             ArrayRef<uint8_t> &Data) {
167   const Layout *L = nullptr;
168   StringRef Name;
169   StringRef UniqueName;
170   CV_DESERIALIZE(Data, L, Name,
171                  CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName()));
172
173   uint16_t P = L->Properties;
174   ClassOptions Options = static_cast<ClassOptions>(P);
175   return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name,
176                     UniqueName, L->UnderlyingType);
177 }
178
179 ErrorOr<BitFieldRecord> BitFieldRecord::deserialize(TypeRecordKind Kind,
180                                                     ArrayRef<uint8_t> &Data) {
181   const Layout *L = nullptr;
182   CV_DESERIALIZE(Data, L);
183   return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
184 }
185
186 ErrorOr<VFTableShapeRecord>
187 VFTableShapeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
188   const Layout *L = nullptr;
189   if (auto EC = consumeObject(Data, L))
190     return EC;
191
192   std::vector<VFTableSlotKind> Slots;
193   uint16_t Count = L->VFEntryCount;
194   while (Count > 0) {
195     if (Data.empty())
196       return std::make_error_code(std::errc::illegal_byte_sequence);
197
198     // Process up to 2 nibbles at a time (if there are at least 2 remaining)
199     uint8_t Value = Data[0] & 0x0F;
200     Slots.push_back(static_cast<VFTableSlotKind>(Value));
201     if (--Count > 0) {
202       Value = (Data[0] & 0xF0) >> 4;
203       Slots.push_back(static_cast<VFTableSlotKind>(Value));
204       --Count;
205     }
206     Data = Data.slice(1);
207   }
208
209   return VFTableShapeRecord(Slots);
210 }
211
212 ErrorOr<TypeServer2Record>
213 TypeServer2Record::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
214   const Layout *L = nullptr;
215   StringRef Name;
216   CV_DESERIALIZE(Data, L, Name);
217   return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
218 }
219
220 ErrorOr<StringIdRecord> StringIdRecord::deserialize(TypeRecordKind Kind,
221                                                     ArrayRef<uint8_t> &Data) {
222   const Layout *L = nullptr;
223   StringRef Name;
224   CV_DESERIALIZE(Data, L, Name);
225   return StringIdRecord(L->id, Name);
226 }
227
228 ErrorOr<FuncIdRecord> FuncIdRecord::deserialize(TypeRecordKind Kind,
229                                                 ArrayRef<uint8_t> &Data) {
230   const Layout *L = nullptr;
231   StringRef Name;
232   CV_DESERIALIZE(Data, L, Name);
233   return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
234 }
235
236 ErrorOr<UdtSourceLineRecord>
237 UdtSourceLineRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
238   const Layout *L = nullptr;
239   CV_DESERIALIZE(Data, L);
240   return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
241 }
242
243 ErrorOr<BuildInfoRecord> BuildInfoRecord::deserialize(TypeRecordKind Kind,
244                                                       ArrayRef<uint8_t> &Data) {
245   const Layout *L = nullptr;
246   ArrayRef<TypeIndex> Indices;
247   CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
248   return BuildInfoRecord(Indices);
249 }
250
251 ErrorOr<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
252                                                   ArrayRef<uint8_t> &Data) {
253   const Layout *L = nullptr;
254   StringRef Name;
255   std::vector<StringRef> Names;
256   CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names));
257   return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
258                        Name, Names);
259 }
260
261 ErrorOr<OneMethodRecord> OneMethodRecord::deserialize(TypeRecordKind Kind,
262                                                       ArrayRef<uint8_t> &Data) {
263   const Layout *L = nullptr;
264   StringRef Name;
265   int32_t VFTableOffset = -1;
266
267   CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD(VFTableOffset,
268                                                L->Attrs.isIntroducedVirtual()),
269                  Name);
270
271   MethodOptions Options = L->Attrs.getFlags();
272   MethodKind MethKind = L->Attrs.getMethodKind();
273   MemberAccess Access = L->Attrs.getAccess();
274   OneMethodRecord Method(L->Type, MethKind, Options, Access, VFTableOffset,
275                          Name);
276   // Validate the vftable offset.
277   if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0)
278     return std::make_error_code(std::errc::illegal_byte_sequence);
279   return Method;
280 }
281
282 ErrorOr<MethodOverloadListRecord>
283 MethodOverloadListRecord::deserialize(TypeRecordKind Kind,
284                                       ArrayRef<uint8_t> &Data) {
285   std::vector<OneMethodRecord> Methods;
286   while (!Data.empty()) {
287     const Layout *L = nullptr;
288     int32_t VFTableOffset = -1;
289     CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD(
290                                 VFTableOffset, L->Attrs.isIntroducedVirtual()));
291
292     MethodOptions Options = L->Attrs.getFlags();
293     MethodKind MethKind = L->Attrs.getMethodKind();
294     MemberAccess Access = L->Attrs.getAccess();
295
296     Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset,
297                          StringRef());
298
299     // Validate the vftable offset.
300     auto &Method = Methods.back();
301     if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0)
302       return std::make_error_code(std::errc::illegal_byte_sequence);
303   }
304   return MethodOverloadListRecord(Methods);
305 }
306
307 ErrorOr<OverloadedMethodRecord>
308 OverloadedMethodRecord::deserialize(TypeRecordKind Kind,
309                                     ArrayRef<uint8_t> &Data) {
310   const Layout *L = nullptr;
311   StringRef Name;
312   CV_DESERIALIZE(Data, L, Name);
313   return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
314 }
315
316 ErrorOr<DataMemberRecord>
317 DataMemberRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
318   const Layout *L = nullptr;
319   uint64_t Offset;
320   StringRef Name;
321   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), Name);
322   return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name);
323 }
324
325 ErrorOr<StaticDataMemberRecord>
326 StaticDataMemberRecord::deserialize(TypeRecordKind Kind,
327                                     ArrayRef<uint8_t> &Data) {
328   const Layout *L = nullptr;
329   StringRef Name;
330   CV_DESERIALIZE(Data, L, Name);
331   return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
332 }
333
334 ErrorOr<EnumeratorRecord>
335 EnumeratorRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
336   const Layout *L = nullptr;
337   APSInt Value;
338   StringRef Name;
339   CV_DESERIALIZE(Data, L, Value, Name);
340   return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
341 }
342
343 ErrorOr<VFPtrRecord> VFPtrRecord::deserialize(TypeRecordKind Kind,
344                                               ArrayRef<uint8_t> &Data) {
345   const Layout *L = nullptr;
346   if (auto EC = consumeObject(Data, L))
347     return EC;
348   return VFPtrRecord(L->Type);
349 }
350
351 ErrorOr<BaseClassRecord> BaseClassRecord::deserialize(TypeRecordKind Kind,
352                                                       ArrayRef<uint8_t> &Data) {
353   const Layout *L = nullptr;
354   uint64_t Offset;
355   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset));
356   return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset);
357 }
358
359 ErrorOr<VirtualBaseClassRecord>
360 VirtualBaseClassRecord::deserialize(TypeRecordKind Kind,
361                                     ArrayRef<uint8_t> &Data) {
362   const Layout *L = nullptr;
363   uint64_t Offset;
364   uint64_t Index;
365   CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index));
366   return VirtualBaseClassRecord(L->Attrs.getAccess(), L->BaseType, L->VBPtrType,
367                                 Offset, Index);
368 }
369
370 ErrorOr<ListContinuationRecord>
371 ListContinuationRecord::deserialize(TypeRecordKind Kind,
372                                     ArrayRef<uint8_t> &Data) {
373   const Layout *L = nullptr;
374   CV_DESERIALIZE(Data, L);
375   return ListContinuationRecord(L->ContinuationIndex);
376 }
377
378 //===----------------------------------------------------------------------===//
379 // Type index remapping
380 //===----------------------------------------------------------------------===//
381
382 static bool remapIndex(ArrayRef<TypeIndex> IndexMap, TypeIndex &Idx) {
383   // Simple types are unchanged.
384   if (Idx.isSimple())
385     return true;
386   unsigned MapPos = Idx.getIndex() - TypeIndex::FirstNonSimpleIndex;
387   if (MapPos < IndexMap.size()) {
388     Idx = IndexMap[MapPos];
389     return true;
390   }
391
392   // This type index is invalid. Remap this to "not translated by cvpack",
393   // and return failure.
394   Idx = TypeIndex(SimpleTypeKind::NotTranslated, SimpleTypeMode::Direct);
395   return false;
396 }
397
398 bool ModifierRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
399   return remapIndex(IndexMap, ModifiedType);
400 }
401
402 bool ProcedureRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
403   bool Success = true;
404   Success &= remapIndex(IndexMap, ReturnType);
405   Success &= remapIndex(IndexMap, ArgumentList);
406   return Success;
407 }
408
409 bool MemberFunctionRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
410   bool Success = true;
411   Success &= remapIndex(IndexMap, ReturnType);
412   Success &= remapIndex(IndexMap, ClassType);
413   Success &= remapIndex(IndexMap, ThisType);
414   Success &= remapIndex(IndexMap, ArgumentList);
415   return Success;
416 }
417
418 bool MemberFuncIdRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
419   bool Success = true;
420   Success &= remapIndex(IndexMap, ClassType);
421   Success &= remapIndex(IndexMap, FunctionType);
422   return Success;
423 }
424
425 bool ArgListRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
426   bool Success = true;
427   for (TypeIndex &Str : StringIndices)
428     Success &= remapIndex(IndexMap, Str);
429   return Success;
430 }
431
432 bool MemberPointerInfo::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
433   return remapIndex(IndexMap, ContainingType);
434 }
435
436 bool PointerRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
437   bool Success = true;
438   Success &= remapIndex(IndexMap, ReferentType);
439   if (isPointerToMember())
440     Success &= MemberInfo.remapTypeIndices(IndexMap);
441   return Success;
442 }
443
444 bool NestedTypeRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
445   return remapIndex(IndexMap, Type);
446 }
447
448 bool ArrayRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
449   bool Success = true;
450   Success &= remapIndex(IndexMap, ElementType);
451   Success &= remapIndex(IndexMap, IndexType);
452   return Success;
453 }
454
455 bool TagRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
456   return remapIndex(IndexMap, FieldList);
457 }
458
459 bool ClassRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
460   bool Success = true;
461   Success &= TagRecord::remapTypeIndices(IndexMap);
462   Success &= remapIndex(IndexMap, DerivationList);
463   Success &= remapIndex(IndexMap, VTableShape);
464   return Success;
465 }
466
467 bool EnumRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
468   bool Success = true;
469   Success &= TagRecord::remapTypeIndices(IndexMap);
470   Success &= remapIndex(IndexMap, UnderlyingType);
471   return Success;
472 }
473
474 bool BitFieldRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
475   return remapIndex(IndexMap, Type);
476 }
477
478 bool VFTableShapeRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
479   return true;
480 }
481
482 bool TypeServer2Record::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
483   return true;
484 }
485
486 bool StringIdRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
487   return remapIndex(IndexMap, Id);
488 }
489
490 bool FuncIdRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
491   bool Success = true;
492   Success &= remapIndex(IndexMap, ParentScope);
493   Success &= remapIndex(IndexMap, FunctionType);
494   return Success;
495 }
496
497 bool UdtSourceLineRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
498   bool Success = true;
499   Success &= remapIndex(IndexMap, UDT);
500   Success &= remapIndex(IndexMap, SourceFile);
501   return Success;
502 }
503
504 bool UdtModSourceLineRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
505   bool Success = true;
506   Success &= remapIndex(IndexMap, UDT);
507   Success &= remapIndex(IndexMap, SourceFile);
508   return Success;
509 }
510
511 bool BuildInfoRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
512   bool Success = true;
513   for (TypeIndex &Arg : ArgIndices)
514     Success &= remapIndex(IndexMap, Arg);
515   return Success;
516 }
517
518 bool VFTableRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
519   bool Success = true;
520   Success &= remapIndex(IndexMap, CompleteClass);
521   Success &= remapIndex(IndexMap, OverriddenVFTable);
522   return Success;
523 }
524
525 bool OneMethodRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
526   bool Success = true;
527   Success &= remapIndex(IndexMap, Type);
528   return Success;
529 }
530
531 bool MethodOverloadListRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
532   bool Success = true;
533   for (OneMethodRecord &Meth : Methods)
534     if ((Success = Meth.remapTypeIndices(IndexMap)))
535       return Success;
536   return Success;
537 }
538
539 bool OverloadedMethodRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
540   return remapIndex(IndexMap, MethodList);
541 }
542
543 bool DataMemberRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
544   return remapIndex(IndexMap, Type);
545 }
546
547 bool StaticDataMemberRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
548   return remapIndex(IndexMap, Type);
549 }
550
551 bool EnumeratorRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
552   return true;
553 }
554
555 bool VFPtrRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
556   return remapIndex(IndexMap, Type);
557 }
558
559 bool BaseClassRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
560   return remapIndex(IndexMap, Type);
561 }
562
563 bool VirtualBaseClassRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
564   bool Success = true;
565   Success &= remapIndex(IndexMap, BaseType);
566   Success &= remapIndex(IndexMap, VBPtrType);
567   return Success;
568 }
569
570 bool ListContinuationRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
571   return remapIndex(IndexMap, ContinuationIndex);
572 }