void CVTypeDumperImpl::visitMethodOverloadList( TypeLeafKind Leaf, MethodOverloadListRecord &MethodList) { for (auto &M : MethodList.getMethods()) { ListScope S(W, "Method"); printMemberAttributes(M.getAccess(), M.getKind(), M.getOptions()); printTypeIndex("Type", M.getType()); if (M.isIntroducingVirtual()) W.printHex("VFTableOffset", M.getVFTableOffset()); } }
Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MethodOverloadListRecord &MethodList) { for (auto &M : MethodList.getMethods()) { ListScope S(*W, "Method"); printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions()); printTypeIndex("Type", M.getType()); if (M.isIntroducingVirtual()) W->printHex("VFTableOffset", M.getVFTableOffset()); } return Error::success(); }
TypeIndex TypeTableBuilder::writeKnownType(const MethodOverloadListRecord &Record) { TypeRecordBuilder Builder(Record.getKind()); for (const OneMethodRecord &Method : Record.getMethods()) { uint16_t Flags = static_cast<uint16_t>(Method.getAccess()); Flags |= static_cast<uint16_t>(Method.getKind()) << MemberAttributes::MethodKindShift; Flags |= static_cast<uint16_t>(Method.getOptions()); Builder.writeUInt16(Flags); Builder.writeUInt16(0); // padding Builder.writeTypeIndex(Method.getType()); if (Method.isIntroducingVirtual()) { assert(Method.getVFTableOffset() >= 0); Builder.writeInt32(Method.getVFTableOffset()); } else { assert(Method.getVFTableOffset() == -1); } } // TODO: Split the list into multiple records if it's longer than 64KB, using // a subrecord of TypeRecordKind::Index to chain the records together. return writeRecord(Builder); }