diff options
author | Zachary Turner <zturner@google.com> | 2016-08-18 16:49:29 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-08-18 16:49:29 +0000 |
commit | ac5763eca45d20466eb180928ec5afe231c11d4e (patch) | |
tree | d8e836c16af8b15a167ec7bab10e42bd4e615aa3 /llvm/tools/llvm-pdbdump/CodeViewYaml.cpp | |
parent | c6bf547564088ad0ba0b2f281ffa813974f66bda (diff) | |
download | bcm5719-llvm-ac5763eca45d20466eb180928ec5afe231c11d4e.tar.gz bcm5719-llvm-ac5763eca45d20466eb180928ec5afe231c11d4e.zip |
Resubmit "Write the TPI stream from a PDB to Yaml."
The original patch was breaking some buildbots due to an
incorrect ordering of function definitions which caused some
compilers to recognize a definition but others to not.
llvm-svn: 279089
Diffstat (limited to 'llvm/tools/llvm-pdbdump/CodeViewYaml.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbdump/CodeViewYaml.cpp | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/llvm/tools/llvm-pdbdump/CodeViewYaml.cpp b/llvm/tools/llvm-pdbdump/CodeViewYaml.cpp new file mode 100644 index 00000000000..690e46fb041 --- /dev/null +++ b/llvm/tools/llvm-pdbdump/CodeViewYaml.cpp @@ -0,0 +1,506 @@ +//===- PdbYAML.cpp -------------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CodeViewYaml.h" + +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::codeview::yaml; + +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) +LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) +LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) +LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) +LLVM_YAML_IS_SEQUENCE_VECTOR(CVType) + +namespace llvm { +namespace yaml { +template <> struct ScalarEnumerationTraits<PointerToMemberRepresentation> { + static void enumeration(IO &IO, PointerToMemberRepresentation &Value) { + IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown); + IO.enumCase(Value, "SingleInheritanceData", + PointerToMemberRepresentation::SingleInheritanceData); + IO.enumCase(Value, "MultipleInheritanceData", + PointerToMemberRepresentation::MultipleInheritanceData); + IO.enumCase(Value, "VirtualInheritanceData", + PointerToMemberRepresentation::VirtualInheritanceData); + IO.enumCase(Value, "GeneralData", + PointerToMemberRepresentation::GeneralData); + IO.enumCase(Value, "SingleInheritanceFunction", + PointerToMemberRepresentation::SingleInheritanceFunction); + IO.enumCase(Value, "MultipleInheritanceFunction", + PointerToMemberRepresentation::MultipleInheritanceFunction); + IO.enumCase(Value, "VirtualInheritanceFunction", + PointerToMemberRepresentation::VirtualInheritanceFunction); + IO.enumCase(Value, "GeneralFunction", + PointerToMemberRepresentation::GeneralFunction); + } +}; + +template <> struct ScalarEnumerationTraits<VFTableSlotKind> { + static void enumeration(IO &IO, VFTableSlotKind &Kind) { + IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16); + IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16); + IO.enumCase(Kind, "This", VFTableSlotKind::This); + IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer); + IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta); + IO.enumCase(Kind, "Near", VFTableSlotKind::Near); + IO.enumCase(Kind, "Far", VFTableSlotKind::Far); + } +}; + +template <> struct ScalarEnumerationTraits<CallingConvention> { + static void enumeration(IO &IO, CallingConvention &Value) { + IO.enumCase(Value, "NearC", CallingConvention::NearC); + IO.enumCase(Value, "FarC", CallingConvention::FarC); + IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal); + IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal); + IO.enumCase(Value, "NearFast", CallingConvention::NearFast); + IO.enumCase(Value, "FarFast", CallingConvention::FarFast); + IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall); + IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall); + IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall); + IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall); + IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall); + IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall); + IO.enumCase(Value, "Generic", CallingConvention::Generic); + IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall); + IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall); + IO.enumCase(Value, "SHCall", CallingConvention::SHCall); + IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall); + IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call); + IO.enumCase(Value, "TriCall", CallingConvention::TriCall); + IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call); + IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall); + IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall); + IO.enumCase(Value, "Inline", CallingConvention::Inline); + IO.enumCase(Value, "NearVector", CallingConvention::NearVector); + } +}; + +template <> struct ScalarEnumerationTraits<PointerKind> { + static void enumeration(IO &IO, PointerKind &Kind) { + IO.enumCase(Kind, "Near16", PointerKind::Near16); + IO.enumCase(Kind, "Far16", PointerKind::Far16); + IO.enumCase(Kind, "Huge16", PointerKind::Huge16); + IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment); + IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue); + IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue); + IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress); + IO.enumCase(Kind, "BasedOnSegmentAddress", + PointerKind::BasedOnSegmentAddress); + IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType); + IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf); + IO.enumCase(Kind, "Near32", PointerKind::Near32); + IO.enumCase(Kind, "Far32", PointerKind::Far32); + IO.enumCase(Kind, "Near64", PointerKind::Near64); + } +}; + +template <> struct ScalarEnumerationTraits<PointerMode> { + static void enumeration(IO &IO, PointerMode &Mode) { + IO.enumCase(Mode, "Pointer", PointerMode::Pointer); + IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference); + IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember); + IO.enumCase(Mode, "PointerToMemberFunction", + PointerMode::PointerToMemberFunction); + IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference); + } +}; + +template <> struct ScalarEnumerationTraits<HfaKind> { + static void enumeration(IO &IO, HfaKind &Value) { + IO.enumCase(Value, "None", HfaKind::None); + IO.enumCase(Value, "Float", HfaKind::Float); + IO.enumCase(Value, "Double", HfaKind::Double); + IO.enumCase(Value, "Other", HfaKind::Other); + } +}; + +template <> struct ScalarEnumerationTraits<MemberAccess> { + static void enumeration(IO &IO, MemberAccess &Access) { + IO.enumCase(Access, "None", MemberAccess::None); + IO.enumCase(Access, "Private", MemberAccess::Private); + IO.enumCase(Access, "Protected", MemberAccess::Protected); + IO.enumCase(Access, "Public", MemberAccess::Public); + } +}; + +template <> struct ScalarEnumerationTraits<MethodKind> { + static void enumeration(IO &IO, MethodKind &Kind) { + IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla); + IO.enumCase(Kind, "Virtual", MethodKind::Virtual); + IO.enumCase(Kind, "Static", MethodKind::Static); + IO.enumCase(Kind, "Friend", MethodKind::Friend); + IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual); + IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual); + IO.enumCase(Kind, "PureIntroducingVirtual", + MethodKind::PureIntroducingVirtual); + } +}; + +template <> struct ScalarEnumerationTraits<WindowsRTClassKind> { + static void enumeration(IO &IO, WindowsRTClassKind &Value) { + IO.enumCase(Value, "None", WindowsRTClassKind::None); + IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass); + IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass); + IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface); + } +}; + +template <> struct ScalarBitSetTraits<PointerOptions> { + static void bitset(IO &IO, PointerOptions &Options) { + IO.bitSetCase(Options, "None", PointerOptions::None); + IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32); + IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile); + IO.bitSetCase(Options, "Const", PointerOptions::Const); + IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); + IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); + IO.bitSetCase(Options, "WinRTSmartPointer", + PointerOptions::WinRTSmartPointer); + } +}; + +template <> struct ScalarBitSetTraits<ModifierOptions> { + static void bitset(IO &IO, ModifierOptions &Options) { + IO.bitSetCase(Options, "None", ModifierOptions::None); + IO.bitSetCase(Options, "Const", ModifierOptions::Const); + IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile); + IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned); + } +}; + +template <> struct ScalarBitSetTraits<FunctionOptions> { + static void bitset(IO &IO, FunctionOptions &Options) { + IO.bitSetCase(Options, "None", FunctionOptions::None); + IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt); + IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor); + IO.bitSetCase(Options, "ConstructorWithVirtualBases", + FunctionOptions::ConstructorWithVirtualBases); + } +}; + +template <> struct ScalarBitSetTraits<ClassOptions> { + static void bitset(IO &IO, ClassOptions &Options) { + IO.bitSetCase(Options, "None", ClassOptions::None); + IO.bitSetCase(Options, "HasConstructorOrDestructor", + ClassOptions::HasConstructorOrDestructor); + IO.bitSetCase(Options, "HasOverloadedOperator", + ClassOptions::HasOverloadedOperator); + IO.bitSetCase(Options, "Nested", ClassOptions::Nested); + IO.bitSetCase(Options, "ContainsNestedClass", + ClassOptions::ContainsNestedClass); + IO.bitSetCase(Options, "HasOverloadedAssignmentOperator", + ClassOptions::HasOverloadedAssignmentOperator); + IO.bitSetCase(Options, "HasConversionOperator", + ClassOptions::HasConversionOperator); + IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference); + IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped); + IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName); + IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed); + IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic); + } +}; + +template <> struct ScalarBitSetTraits<MethodOptions> { + static void bitset(IO &IO, MethodOptions &Options) { + IO.bitSetCase(Options, "None", MethodOptions::None); + IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo); + IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit); + IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct); + IO.bitSetCase(Options, "CompilerGenerated", + MethodOptions::CompilerGenerated); + IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed); + } +}; + +template <> struct ScalarTraits<APSInt> { + static void output(const APSInt &S, void *, llvm::raw_ostream &OS) { + S.print(OS, true); + } + static StringRef input(StringRef Scalar, void *Ctx, APSInt &S) { + S = APSInt(Scalar); + return ""; + } + + static bool mustQuote(StringRef Scalar) { return false; } +}; + +void MappingTraits<CVType>::mapping(IO &IO, CVType &Record) { + if (IO.outputting()) { + codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO); + codeview::TypeDeserializer Deserializer(Callbacks); + + codeview::CVTypeVisitor Visitor(Deserializer); + consumeError(Visitor.visitTypeRecord(Record)); + } +} + +void MappingTraits<FieldListRecord>::mapping(IO &IO, + FieldListRecord &FieldList) { + if (IO.outputting()) { + codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO); + codeview::TypeDeserializer Deserializer(Callbacks); + codeview::CVTypeVisitor Visitor(Deserializer); + consumeError(Visitor.visitFieldListMemberStream(FieldList.Data)); + } +} + +void MappingTraits<StringIdRecord>::mapping(IO &IO, StringIdRecord &String) { + IO.mapRequired("Id", String.Id); + IO.mapRequired("String", String.String); +} + +void MappingTraits<ArgListRecord>::mapping(IO &IO, ArgListRecord &Args) { + IO.mapRequired("ArgIndices", Args.StringIndices); +} + +void MappingTraits<ClassRecord>::mapping(IO &IO, ClassRecord &Class) { + IO.mapRequired("MemberCount", Class.MemberCount); + IO.mapRequired("Options", Class.Options); + IO.mapRequired("FieldList", Class.FieldList); + IO.mapRequired("Name", Class.Name); + IO.mapRequired("UniqueName", Class.UniqueName); + IO.mapRequired("Hfa", Class.Hfa); + IO.mapRequired("WinRTKind", Class.WinRTKind); + IO.mapRequired("DerivationList", Class.DerivationList); + IO.mapRequired("VTableShape", Class.VTableShape); + IO.mapRequired("Size", Class.Size); +} + +void MappingTraits<UnionRecord>::mapping(IO &IO, UnionRecord &Union) { + IO.mapRequired("MemberCount", Union.MemberCount); + IO.mapRequired("Options", Union.Options); + IO.mapRequired("FieldList", Union.FieldList); + IO.mapRequired("Name", Union.Name); + IO.mapRequired("UniqueName", Union.UniqueName); + IO.mapRequired("Hfa", Union.Hfa); + IO.mapRequired("Size", Union.Size); +} + +void MappingTraits<EnumRecord>::mapping(IO &IO, EnumRecord &Enum) { + IO.mapRequired("NumEnumerators", Enum.MemberCount); + IO.mapRequired("Options", Enum.Options); + IO.mapRequired("FieldList", Enum.FieldList); + IO.mapRequired("Name", Enum.Name); + IO.mapRequired("UniqueName", Enum.UniqueName); + IO.mapRequired("UnderlyingType", Enum.UnderlyingType); +} + +void MappingTraits<ArrayRecord>::mapping(IO &IO, ArrayRecord &AT) { + IO.mapRequired("ElementType", AT.ElementType); + IO.mapRequired("IndexType", AT.IndexType); + IO.mapRequired("Size", AT.Size); + IO.mapRequired("Name", AT.Name); +} + +void MappingTraits<VFTableRecord>::mapping(IO &IO, VFTableRecord &VFT) { + IO.mapRequired("CompleteClass", VFT.CompleteClass); + IO.mapRequired("OverriddenVFTable", VFT.OverriddenVFTable); + IO.mapRequired("VFPtrOffset", VFT.VFPtrOffset); + IO.mapRequired("Name", VFT.Name); + IO.mapRequired("MethodNames", VFT.MethodNames); +} + +void MappingTraits<MemberFuncIdRecord>::mapping(IO &IO, + MemberFuncIdRecord &Id) { + IO.mapRequired("ClassType", Id.ClassType); + IO.mapRequired("FunctionType", Id.FunctionType); + IO.mapRequired("Name", Id.Name); +} + +void MappingTraits<ProcedureRecord>::mapping(IO &IO, ProcedureRecord &Proc) { + IO.mapRequired("ReturnType", Proc.ReturnType); + IO.mapRequired("CallConv", Proc.CallConv); + IO.mapRequired("Options", Proc.Options); + IO.mapRequired("ParameterCount", Proc.ParameterCount); + IO.mapRequired("ArgumentList", Proc.ArgumentList); +} + +void MappingTraits<MemberFunctionRecord>::mapping(IO &IO, + MemberFunctionRecord &MF) { + IO.mapRequired("ReturnType", MF.ReturnType); + IO.mapRequired("ClassType", MF.ClassType); + IO.mapRequired("ThisType", MF.ThisType); + IO.mapRequired("CallConv", MF.CallConv); + IO.mapRequired("Options", MF.Options); + IO.mapRequired("ParameterCount", MF.ParameterCount); + IO.mapRequired("ArgumentList", MF.ArgumentList); + IO.mapRequired("ThisPointerAdjustment", MF.ThisPointerAdjustment); +} + +void MappingTraits<MethodOverloadListRecord>::mapping( + IO &IO, MethodOverloadListRecord &MethodList) { + IO.mapRequired("Methods", MethodList.Methods); +} + +void MappingTraits<FuncIdRecord>::mapping(IO &IO, FuncIdRecord &Func) { + IO.mapRequired("ParentScope", Func.ParentScope); + IO.mapRequired("FunctionType", Func.FunctionType); + IO.mapRequired("Name", Func.Name); +} + +void MappingTraits<TypeServer2Record>::mapping(IO &IO, TypeServer2Record &TS) { + IO.mapRequired("Guid", TS.Guid); + IO.mapRequired("Age", TS.Age); + IO.mapRequired("Name", TS.Name); +} + +void MappingTraits<PointerRecord>::mapping(IO &IO, PointerRecord &Ptr) { + IO.mapRequired("ReferentType", Ptr.ReferentType); + IO.mapRequired("PtrKind", Ptr.PtrKind); + IO.mapRequired("Mode", Ptr.Mode); + IO.mapRequired("Options", Ptr.Options); + IO.mapRequired("Size", Ptr.Size); + IO.mapOptional("MemberInfo", Ptr.MemberInfo); +} + +void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) { + IO.mapRequired("ContainingType", MPI.ContainingType); + IO.mapRequired("Representation", MPI.Representation); +} + +void MappingTraits<ModifierRecord>::mapping(IO &IO, ModifierRecord &Mod) { + IO.mapRequired("ModifiedType", Mod.ModifiedType); + IO.mapRequired("Modifiers", Mod.Modifiers); +} + +void MappingTraits<BitFieldRecord>::mapping(IO &IO, BitFieldRecord &BitField) { + IO.mapRequired("Type", BitField.Type); + IO.mapRequired("BitSize", BitField.BitSize); + IO.mapRequired("BitOffset", BitField.BitOffset); +} + +void MappingTraits<VFTableShapeRecord>::mapping(IO &IO, + VFTableShapeRecord &Shape) { + IO.mapRequired("Slots", Shape.Slots); +} + +void MappingTraits<UdtSourceLineRecord>::mapping(IO &IO, + UdtSourceLineRecord &Line) { + IO.mapRequired("UDT", Line.UDT); + IO.mapRequired("SourceFile", Line.SourceFile); + IO.mapRequired("LineNumber", Line.LineNumber); +} + +void MappingTraits<UdtModSourceLineRecord>::mapping( + IO &IO, UdtModSourceLineRecord &Line) { + IO.mapRequired("UDT", Line.UDT); + IO.mapRequired("SourceFile", Line.SourceFile); + IO.mapRequired("LineNumber", Line.LineNumber); + IO.mapRequired("Module", Line.Module); +} + +void MappingTraits<BuildInfoRecord>::mapping(IO &IO, BuildInfoRecord &Args) { + IO.mapRequired("ArgIndices", Args.ArgIndices); +} + +void MappingTraits<NestedTypeRecord>::mapping(IO &IO, + NestedTypeRecord &Nested) { + IO.mapRequired("Type", Nested.Type); + IO.mapRequired("Name", Nested.Name); +} + +void MappingTraits<OneMethodRecord>::mapping(IO &IO, OneMethodRecord &Method) { + IO.mapRequired("Type", Method.Type); + IO.mapRequired("Kind", Method.Kind); + IO.mapRequired("Options", Method.Options); + IO.mapRequired("Access", Method.Access); + IO.mapRequired("VFTableOffset", Method.VFTableOffset); + IO.mapRequired("Name", Method.Name); +} + +void MappingTraits<OverloadedMethodRecord>::mapping( + IO &IO, OverloadedMethodRecord &Method) { + IO.mapRequired("NumOverloads", Method.NumOverloads); + IO.mapRequired("MethodList", Method.MethodList); + IO.mapRequired("Name", Method.Name); +} + +void MappingTraits<DataMemberRecord>::mapping(IO &IO, DataMemberRecord &Field) { + IO.mapRequired("Access", Field.Access); + IO.mapRequired("Type", Field.Type); + IO.mapRequired("FieldOffset", Field.FieldOffset); + IO.mapRequired("Name", Field.Name); +} + +void MappingTraits<StaticDataMemberRecord>::mapping( + IO &IO, StaticDataMemberRecord &Field) { + IO.mapRequired("Access", Field.Access); + IO.mapRequired("Type", Field.Type); + IO.mapRequired("Name", Field.Name); +} + +void MappingTraits<VFPtrRecord>::mapping(IO &IO, VFPtrRecord &VFTable) { + IO.mapRequired("Type", VFTable.Type); +} + +void MappingTraits<EnumeratorRecord>::mapping(IO &IO, EnumeratorRecord &Enum) { + IO.mapRequired("Access", Enum.Access); + IO.mapRequired("Value", Enum.Value); + IO.mapRequired("Name", Enum.Name); +} + +void MappingTraits<BaseClassRecord>::mapping(IO &IO, BaseClassRecord &Base) { + IO.mapRequired("Access", Base.Access); + IO.mapRequired("Type", Base.Type); + IO.mapRequired("Offset", Base.Offset); +} + +void MappingTraits<VirtualBaseClassRecord>::mapping( + IO &IO, VirtualBaseClassRecord &Base) { + IO.mapRequired("Access", Base.Access); + IO.mapRequired("BaseType", Base.BaseType); + IO.mapRequired("VBPtrType", Base.VBPtrType); + IO.mapRequired("VBPtrOffset", Base.VBPtrOffset); + IO.mapRequired("VTableIndex", Base.VTableIndex); +} + +void MappingTraits<ListContinuationRecord>::mapping( + IO &IO, ListContinuationRecord &Cont) { + IO.mapRequired("ContinuationIndex", Cont.ContinuationIndex); +} + +template <> struct ScalarTraits<codeview::TypeIndex> { + static void output(const codeview::TypeIndex &S, void *, + llvm::raw_ostream &OS) { + OS << S.getIndex(); + } + static StringRef input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S) { + uint32_t I; + StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I); + if (!Result.empty()) + return Result; + S = TypeIndex(I); + return ""; + } + static bool mustQuote(StringRef Scalar) { return false; } +}; + +void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io, + TypeLeafKind &Value) { + auto TypeLeafNames = getTypeLeafNames(); + for (const auto &E : TypeLeafNames) + io.enumCase(Value, E.Name.str().c_str(), E.Value); +} +} +} + +Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin( + const CVRecord<TypeLeafKind> &CVR) { + TypeLeafKind K = CVR.Type; + YamlIO.mapRequired("Kind", K); + return Error::success(); +} |