Home | History | Annotate | Download | only in CodeView
      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 }
    573