diff options
Diffstat (limited to 'lib/DebugInfo/CodeView')
-rw-r--r-- | lib/DebugInfo/CodeView/CVTypeVisitor.cpp | 15 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/CodeViewRecordIO.cpp | 8 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/EnumTables.cpp | 166 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/SymbolDumper.cpp | 2 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/SymbolRecordMapping.cpp | 2 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/TypeRecordMapping.cpp | 238 |
6 files changed, 391 insertions, 40 deletions
diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp index ec4773d571c8..dd6f75f97a4a 100644 --- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -209,14 +209,6 @@ struct VisitHelper { } } - VisitHelper(TypeVisitorCallbackPipeline &Callbacks, VisitorDataSource Source) - : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) { - if (Source == VDS_BytesPresent) { - Pipeline = Callbacks; - Pipeline.addCallbackToPipelineFront(Deserializer); - } - } - TypeDeserializer Deserializer; TypeVisitorCallbackPipeline Pipeline; CVTypeVisitor Visitor; @@ -230,13 +222,6 @@ Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index, return V.Visitor.visitTypeRecord(Record, Index); } -Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index, - TypeVisitorCallbackPipeline &Callbacks, - VisitorDataSource Source) { - VisitHelper V(Callbacks, Source); - return V.Visitor.visitTypeRecord(Record, Index); -} - Error llvm::codeview::visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source) { diff --git a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp index 2f49474115a1..36a384baa13d 100644 --- a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp +++ b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp @@ -20,7 +20,6 @@ Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) { Limit.MaxLength = MaxLength; Limit.BeginOffset = getCurrentOffset(); Limits.push_back(Limit); - resetStreamedLen(); return Error::success(); } @@ -50,6 +49,7 @@ Error CodeViewRecordIO::endRecord() { Streamer->EmitBytes(BytesSR); --PaddingBytes; } + resetStreamedLen(); } return Error::success(); } @@ -126,7 +126,11 @@ Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes, Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) { if (isStreaming()) { - emitComment(Comment); + std::string TypeNameStr = Streamer->getTypeName(TypeInd); + if (!TypeNameStr.empty()) + emitComment(Comment + ": " + TypeNameStr); + else + emitComment(Comment); Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex())); incrStreamedLen(sizeof(TypeInd.getIndex())); } else if (isWriting()) { diff --git a/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp index 54e68ae4ea9f..82f6713a88f5 100644 --- a/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/lib/DebugInfo/CodeView/EnumTables.cpp @@ -300,6 +300,128 @@ static const EnumEntry<COFF::SectionCharacteristics> CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ), CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)}; +static const EnumEntry<uint16_t> ClassOptionNames[] = { + CV_ENUM_CLASS_ENT(ClassOptions, Packed), + CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor), + CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator), + CV_ENUM_CLASS_ENT(ClassOptions, Nested), + CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass), + CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator), + CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator), + CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference), + CV_ENUM_CLASS_ENT(ClassOptions, Scoped), + CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName), + CV_ENUM_CLASS_ENT(ClassOptions, Sealed), + CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic), +}; + +static const EnumEntry<uint8_t> MemberAccessNames[] = { + CV_ENUM_CLASS_ENT(MemberAccess, None), + CV_ENUM_CLASS_ENT(MemberAccess, Private), + CV_ENUM_CLASS_ENT(MemberAccess, Protected), + CV_ENUM_CLASS_ENT(MemberAccess, Public), +}; + +static const EnumEntry<uint16_t> MethodOptionNames[] = { + CV_ENUM_CLASS_ENT(MethodOptions, Pseudo), + CV_ENUM_CLASS_ENT(MethodOptions, NoInherit), + CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct), + CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated), + CV_ENUM_CLASS_ENT(MethodOptions, Sealed), +}; + +static const EnumEntry<uint16_t> MemberKindNames[] = { + CV_ENUM_CLASS_ENT(MethodKind, Vanilla), + CV_ENUM_CLASS_ENT(MethodKind, Virtual), + CV_ENUM_CLASS_ENT(MethodKind, Static), + CV_ENUM_CLASS_ENT(MethodKind, Friend), + CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual), + CV_ENUM_CLASS_ENT(MethodKind, PureVirtual), + CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual), +}; + +static const EnumEntry<uint8_t> PtrKindNames[] = { + CV_ENUM_CLASS_ENT(PointerKind, Near16), + CV_ENUM_CLASS_ENT(PointerKind, Far16), + CV_ENUM_CLASS_ENT(PointerKind, Huge16), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnType), + CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf), + CV_ENUM_CLASS_ENT(PointerKind, Near32), + CV_ENUM_CLASS_ENT(PointerKind, Far32), + CV_ENUM_CLASS_ENT(PointerKind, Near64), +}; + +static const EnumEntry<uint8_t> PtrModeNames[] = { + CV_ENUM_CLASS_ENT(PointerMode, Pointer), + CV_ENUM_CLASS_ENT(PointerMode, LValueReference), + CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember), + CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction), + CV_ENUM_CLASS_ENT(PointerMode, RValueReference), +}; + +static const EnumEntry<uint16_t> PtrMemberRepNames[] = { + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceFunction), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, + MultipleInheritanceFunction), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, + VirtualInheritanceFunction), + CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction), +}; + +static const EnumEntry<uint16_t> TypeModifierNames[] = { + CV_ENUM_CLASS_ENT(ModifierOptions, Const), + CV_ENUM_CLASS_ENT(ModifierOptions, Volatile), + CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned), +}; + +static const EnumEntry<uint8_t> CallingConventions[] = { + CV_ENUM_CLASS_ENT(CallingConvention, NearC), + CV_ENUM_CLASS_ENT(CallingConvention, FarC), + CV_ENUM_CLASS_ENT(CallingConvention, NearPascal), + CV_ENUM_CLASS_ENT(CallingConvention, FarPascal), + CV_ENUM_CLASS_ENT(CallingConvention, NearFast), + CV_ENUM_CLASS_ENT(CallingConvention, FarFast), + CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall), + CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall), + CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall), + CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall), + CV_ENUM_CLASS_ENT(CallingConvention, ThisCall), + CV_ENUM_CLASS_ENT(CallingConvention, MipsCall), + CV_ENUM_CLASS_ENT(CallingConvention, Generic), + CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall), + CV_ENUM_CLASS_ENT(CallingConvention, PpcCall), + CV_ENUM_CLASS_ENT(CallingConvention, SHCall), + CV_ENUM_CLASS_ENT(CallingConvention, ArmCall), + CV_ENUM_CLASS_ENT(CallingConvention, AM33Call), + CV_ENUM_CLASS_ENT(CallingConvention, TriCall), + CV_ENUM_CLASS_ENT(CallingConvention, SH5Call), + CV_ENUM_CLASS_ENT(CallingConvention, M32RCall), + CV_ENUM_CLASS_ENT(CallingConvention, ClrCall), + CV_ENUM_CLASS_ENT(CallingConvention, Inline), + CV_ENUM_CLASS_ENT(CallingConvention, NearVector), +}; + +static const EnumEntry<uint8_t> FunctionOptionEnum[] = { + CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt), + CV_ENUM_CLASS_ENT(FunctionOptions, Constructor), + CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases), +}; + +static const EnumEntry<uint16_t> LabelTypeEnum[] = { + CV_ENUM_CLASS_ENT(LabelType, Near), + CV_ENUM_CLASS_ENT(LabelType, Far), +}; + namespace llvm { namespace codeview { @@ -379,5 +501,49 @@ getImageSectionCharacteristicNames() { return makeArrayRef(ImageSectionCharacteristicNames); } +ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() { + return makeArrayRef(ClassOptionNames); +} + +ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() { + return makeArrayRef(MemberAccessNames); +} + +ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() { + return makeArrayRef(MethodOptionNames); +} + +ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() { + return makeArrayRef(MemberKindNames); +} + +ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() { + return makeArrayRef(PtrKindNames); +} + +ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() { + return makeArrayRef(PtrModeNames); +} + +ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() { + return makeArrayRef(PtrMemberRepNames); +} + +ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() { + return makeArrayRef(TypeModifierNames); +} + +ArrayRef<EnumEntry<uint8_t>> getCallingConventions() { + return makeArrayRef(CallingConventions); +} + +ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() { + return makeArrayRef(FunctionOptionEnum); +} + +ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() { + return makeArrayRef(LabelTypeEnum); +} + } // end namespace codeview } // end namespace llvm diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 27cb7e35234b..45b63983beb4 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -315,7 +315,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { - W.printNumber("Offset", DefRangeFramePointerRel.Offset); + W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset); printLocalVariableAddrRange(DefRangeFramePointerRel.Range, DefRangeFramePointerRel.getRelocationOffset()); printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps); diff --git a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp index 70889839ef48..3b627930e271 100644 --- a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp +++ b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp @@ -229,7 +229,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { Error SymbolRecordMapping::visitKnownRecord( CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { - error(IO.mapInteger(DefRangeFramePointerRel.Offset)); + error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset)); error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range)); error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap())); diff --git a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp index 47928c2eef64..1aded589e565 100644 --- a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp +++ b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -7,24 +7,125 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/CodeView/EnumTables.h" using namespace llvm; using namespace llvm::codeview; +namespace { + #define error(X) \ if (auto EC = X) \ return EC; -namespace { +static const EnumEntry<TypeLeafKind> LeafTypeNames[] = { +#define CV_TYPE(enum, val) {#enum, enum}, +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +}; + +static StringRef getLeafTypeName(TypeLeafKind LT) { + switch (LT) { +#define TYPE_RECORD(ename, value, name) \ + case ename: \ + return #name; +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: + break; + } + return "UnknownLeaf"; +} + +template <typename T> +static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) { + return lhs.Name < rhs.Name; +} + +template <typename T, typename TFlag> +static std::string getFlagNames(CodeViewRecordIO &IO, T Value, + ArrayRef<EnumEntry<TFlag>> Flags) { + if (!IO.isStreaming()) + return std::string(""); + typedef EnumEntry<TFlag> FlagEntry; + typedef SmallVector<FlagEntry, 10> FlagVector; + FlagVector SetFlags; + for (const auto &Flag : Flags) { + if (Flag.Value == 0) + continue; + if ((Value & Flag.Value) == Flag.Value) { + SetFlags.push_back(Flag); + } + } + + llvm::sort(SetFlags, &compEnumNames<TFlag>); + + std::string FlagLabel; + bool FirstOcc = true; + for (const auto &Flag : SetFlags) { + if (FirstOcc) + FirstOcc = false; + else + FlagLabel += (" | "); + + FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")"); + } + + if (!FlagLabel.empty()) { + std::string LabelWithBraces(" ( "); + LabelWithBraces += FlagLabel + " )"; + return LabelWithBraces; + } else + return FlagLabel; +} + +template <typename T, typename TEnum> +static StringRef getEnumName(CodeViewRecordIO &IO, T Value, + ArrayRef<EnumEntry<TEnum>> EnumValues) { + if (!IO.isStreaming()) + return ""; + StringRef Name; + for (const auto &EnumItem : EnumValues) { + if (EnumItem.Value == Value) { + Name = EnumItem.Name; + break; + } + } + + return Name; +} + +static std::string getMemberAttributes(CodeViewRecordIO &IO, + MemberAccess Access, MethodKind Kind, + MethodOptions Options) { + if (!IO.isStreaming()) + return ""; + std::string AccessSpecifier = + getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())); + std::string MemberAttrs(AccessSpecifier); + if (Kind != MethodKind::Vanilla) { + std::string MethodKind = + getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())); + MemberAttrs += ", " + MethodKind; + } + if (Options != MethodOptions::None) { + std::string MethodOptions = getFlagNames( + IO, unsigned(Options), makeArrayRef(getMethodOptionNames())); + MemberAttrs += ", " + MethodOptions; + } + return MemberAttrs; +} + struct MapOneMethodRecord { explicit MapOneMethodRecord(bool IsFromOverloadList) : IsFromOverloadList(IsFromOverloadList) {} Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const { - error(IO.mapInteger(Method.Attrs.Attrs, "AccessSpecifier")); + std::string Attrs = getMemberAttributes( + IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions()); + error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs)); if (IsFromOverloadList) { uint16_t Padding = 0; - error(IO.mapInteger(Padding, "Padding")); + error(IO.mapInteger(Padding)); } error(IO.mapInteger(Method.Type, "Type")); if (Method.isIntroducingVirtual()) { @@ -41,7 +142,7 @@ struct MapOneMethodRecord { private: bool IsFromOverloadList; }; -} +} // namespace static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName) { @@ -96,10 +197,22 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR) { MaxLen = MaxRecordLength - sizeof(RecordPrefix); error(IO.beginRecord(MaxLen)); TypeKind = CVR.kind(); + + if (IO.isStreaming()) { + auto RecordKind = CVR.kind(); + uint16_t RecordLen = CVR.length() - 2; + std::string RecordKindName = + getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)); + error(IO.mapInteger(RecordLen, "Record length")); + error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName)); + } return Error::success(); } Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) { + if (IO.isStreaming()) + IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" + + utohexstr(Index.getIndex()) + ")"); return visitTypeBegin(CVR); } @@ -121,11 +234,21 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) { // followed by the subrecord, followed by a continuation, and that entire // sequence spaws `MaxRecordLength` bytes. So the record's length is // calculated as follows. + constexpr uint32_t ContinuationLength = 8; error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) - ContinuationLength)); MemberKind = Record.Kind; + if (IO.isStreaming()) { + std::string MemberKindName = getLeafTypeName(Record.Kind); + MemberKindName += + " ( " + + (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames))) + .str() + + " )"; + error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName)); + } return Error::success(); } @@ -144,16 +267,24 @@ Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) { + std::string ModifierNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers), + makeArrayRef(getTypeModifierNames())); error(IO.mapInteger(Record.ModifiedType, "ModifiedType")); - error(IO.mapEnum(Record.Modifiers, "Modifiers")); + error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames)); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ProcedureRecord &Record) { + std::string CallingConvName = getEnumName( + IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())); + std::string FuncOptionNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Options), + makeArrayRef(getFunctionOptionEnum())); error(IO.mapInteger(Record.ReturnType, "ReturnType")); - error(IO.mapEnum(Record.CallConv, "CallingConvention")); - error(IO.mapEnum(Record.Options, "FunctionOptions")); + error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName)); + error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames)); error(IO.mapInteger(Record.ParameterCount, "NumParameters")); error(IO.mapInteger(Record.ArgumentList, "ArgListType")); @@ -162,11 +293,16 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Error TypeRecordMapping::visitKnownRecord(CVType &CVR, MemberFunctionRecord &Record) { + std::string CallingConvName = getEnumName( + IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())); + std::string FuncOptionNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Options), + makeArrayRef(getFunctionOptionEnum())); error(IO.mapInteger(Record.ReturnType, "ReturnType")); error(IO.mapInteger(Record.ClassType, "ClassType")); error(IO.mapInteger(Record.ThisType, "ThisType")); - error(IO.mapEnum(Record.CallConv, "CallingConvention")); - error(IO.mapEnum(Record.Options, "FunctionOptions")); + error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName)); + error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames)); error(IO.mapInteger(Record.ParameterCount, "NumParameters")); error(IO.mapInteger(Record.ArgumentList, "ArgListType")); error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment")); @@ -197,8 +333,40 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { + + SmallString<128> Attr("Attrs: "); + + if (IO.isStreaming()) { + std::string PtrType = getEnumName(IO, unsigned(Record.getPointerKind()), + makeArrayRef(getPtrKindNames())); + Attr += "[ Type: " + PtrType; + + std::string PtrMode = getEnumName(IO, unsigned(Record.getMode()), + makeArrayRef(getPtrModeNames())); + Attr += ", Mode: " + PtrMode; + + auto PtrSizeOf = Record.getSize(); + Attr += ", SizeOf: " + itostr(PtrSizeOf); + + if (Record.isFlat()) + Attr += ", isFlat"; + if (Record.isConst()) + Attr += ", isConst"; + if (Record.isVolatile()) + Attr += ", isVolatile"; + if (Record.isUnaligned()) + Attr += ", isUnaligned"; + if (Record.isRestrict()) + Attr += ", isRestricted"; + if (Record.isLValueReferenceThisPtr()) + Attr += ", isThisPtr&"; + if (Record.isRValueReferenceThisPtr()) + Attr += ", isThisPtr&&"; + Attr += " ]"; + } + error(IO.mapInteger(Record.ReferentType, "PointeeType")); - error(IO.mapInteger(Record.Attrs, "Attributes")); + error(IO.mapInteger(Record.Attrs, Attr)); if (Record.isPointerToMember()) { if (IO.isReading()) @@ -206,7 +374,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { MemberPointerInfo &M = *Record.MemberInfo; error(IO.mapInteger(M.ContainingType, "ClassType")); - error(IO.mapEnum(M.Representation, "Representation")); + std::string PtrMemberGetRepresentation = getEnumName( + IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())); + error(IO.mapEnum(M.Representation, + "Representation: " + PtrMemberGetRepresentation)); } return Error::success(); @@ -226,8 +397,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) { (CVR.kind() == TypeLeafKind::LF_CLASS) || (CVR.kind() == TypeLeafKind::LF_INTERFACE)); + std::string PropertiesNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Options), + makeArrayRef(getClassOptionNames())); error(IO.mapInteger(Record.MemberCount, "MemberCount")); - error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames)); error(IO.mapInteger(Record.FieldList, "FieldList")); error(IO.mapInteger(Record.DerivationList, "DerivedFrom")); error(IO.mapInteger(Record.VTableShape, "VShape")); @@ -239,8 +413,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) { + std::string PropertiesNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Options), + makeArrayRef(getClassOptionNames())); error(IO.mapInteger(Record.MemberCount, "MemberCount")); - error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames)); error(IO.mapInteger(Record.FieldList, "FieldList")); error(IO.mapEncodedInteger(Record.Size, "SizeOf")); error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, @@ -250,8 +427,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) { + std::string PropertiesNames = + getFlagNames(IO, static_cast<uint16_t>(Record.Options), + makeArrayRef(getClassOptionNames())); error(IO.mapInteger(Record.MemberCount, "NumEnumerators")); - error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames)); error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType")); error(IO.mapInteger(Record.FieldList, "FieldListType")); error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, @@ -383,7 +563,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Error TypeRecordMapping::visitKnownRecord(CVType &CVR, FieldListRecord &Record) { - error(IO.mapByteVectorTail(Record.Data)); + if (IO.isStreaming()) { + if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this)) + return EC; + } else + error(IO.mapByteVectorTail(Record.Data)); return Error::success(); } @@ -397,13 +581,17 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) { - error(IO.mapEnum(Record.Mode, "Mode")); + std::string ModeName = + getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())); + error(IO.mapEnum(Record.Mode, "Mode: " + ModeName)); return Error::success(); } Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, BaseClassRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + std::string Attrs = getMemberAttributes( + IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None); + error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs)); error(IO.mapInteger(Record.Type, "BaseType")); error(IO.mapEncodedInteger(Record.Offset, "BaseOffset")); @@ -412,7 +600,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, EnumeratorRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs)); + std::string Attrs = getMemberAttributes( + IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None); + error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs)); // FIXME: Handle full APInt such as __int128. error(IO.mapEncodedInteger(Record.Value, "EnumValue")); @@ -423,7 +613,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, DataMemberRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + std::string Attrs = getMemberAttributes( + IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None); + error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs)); error(IO.mapInteger(Record.Type, "Type")); error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset")); error(IO.mapStringZ(Record.Name, "Name")); @@ -460,7 +652,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, StaticDataMemberRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + std::string Attrs = getMemberAttributes( + IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None); + error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs)); error(IO.mapInteger(Record.Type, "Type")); error(IO.mapStringZ(Record.Name, "Name")); @@ -470,7 +664,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, VirtualBaseClassRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + std::string Attrs = getMemberAttributes( + IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None); + error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs)); error(IO.mapInteger(Record.BaseType, "BaseType")); error(IO.mapInteger(Record.VBPtrType, "VBPtrType")); error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset")); |