Go to the documentation of this file.
75 namespace CodeViewYAML {
84 virtual void map(yaml::IO &io) = 0;
93 void map(yaml::IO &io)
override;
96 return TypeDeserializer::deserializeAs<T>(
Type,
Record);
110 void map(yaml::IO &io)
override;
123 virtual void map(yaml::IO &io) = 0;
131 void map(yaml::IO &io)
override;
150 return "GUID strings are 38 characters long";
152 return "GUID is not enclosed in {}";
156 if (
A.size() != 5 || Scalar[8] !=
'-' || Scalar[13] !=
'-' ||
157 Scalar[18] !=
'-' || Scalar[23] !=
'-')
158 return "GUID sections are not properly delineated with dashes";
167 if (!to_integer(A[0],
G.Data1, 16) || !to_integer(A[1],
G.Data2, 16) ||
168 !to_integer(A[2],
G.Data3, 16) || !to_integer(A[3], D41, 16) ||
169 !to_integer(A[4], D42, 16))
170 return "GUID contains non hex digits";
171 G.Data4 = (D41 << 48) | D42;
190 S.print(OS,
S.isSigned());
198 void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
200 #define CV_TYPE(name, val) io.enumCase(Value, #name, name);
201 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
205 void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration(
208 IO.enumCase(
Value,
"SingleInheritanceData",
210 IO.enumCase(
Value,
"MultipleInheritanceData",
212 IO.enumCase(
Value,
"VirtualInheritanceData",
215 IO.enumCase(
Value,
"SingleInheritanceFunction",
217 IO.enumCase(
Value,
"MultipleInheritanceFunction",
219 IO.enumCase(
Value,
"VirtualInheritanceFunction",
221 IO.enumCase(
Value,
"GeneralFunction",
225 void ScalarEnumerationTraits<VFTableSlotKind>::enumeration(
236 void ScalarEnumerationTraits<CallingConvention>::enumeration(
264 void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO,
273 IO.enumCase(
Kind,
"BasedOnSegmentAddress",
282 void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO,
287 IO.enumCase(
Mode,
"PointerToMemberFunction",
292 void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO,
HfaKind &
Value) {
299 void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO,
307 void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO,
315 IO.enumCase(
Kind,
"PureIntroducingVirtual",
319 void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration(
327 void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO,
LabelType &
Value) {
332 void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO,
340 IO.bitSetCase(
Options,
"WinRTSmartPointer",
344 void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO,
352 void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO,
357 IO.bitSetCase(
Options,
"ConstructorWithVirtualBases",
363 IO.bitSetCase(
Options,
"HasConstructorOrDestructor",
365 IO.bitSetCase(
Options,
"HasOverloadedOperator",
368 IO.bitSetCase(
Options,
"ContainsNestedClass",
370 IO.bitSetCase(
Options,
"HasOverloadedAssignmentOperator",
372 IO.bitSetCase(
Options,
"HasConversionOperator",
396 namespace CodeViewYAML {
400 IO.mapRequired(
"ModifiedType",
Record.ModifiedType);
401 IO.mapRequired(
"Modifiers",
Record.Modifiers);
405 IO.mapRequired(
"ReturnType",
Record.ReturnType);
406 IO.mapRequired(
"CallConv",
Record.CallConv);
407 IO.mapRequired(
"Options",
Record.Options);
408 IO.mapRequired(
"ParameterCount",
Record.ParameterCount);
409 IO.mapRequired(
"ArgumentList",
Record.ArgumentList);
413 IO.mapRequired(
"ReturnType",
Record.ReturnType);
414 IO.mapRequired(
"ClassType",
Record.ClassType);
415 IO.mapRequired(
"ThisType",
Record.ThisType);
416 IO.mapRequired(
"CallConv",
Record.CallConv);
417 IO.mapRequired(
"Options",
Record.Options);
418 IO.mapRequired(
"ParameterCount",
Record.ParameterCount);
419 IO.mapRequired(
"ArgumentList",
Record.ArgumentList);
420 IO.mapRequired(
"ThisPointerAdjustment",
Record.ThisPointerAdjustment);
424 IO.mapRequired(
"Mode",
Record.Mode);
428 IO.mapRequired(
"ClassType",
Record.ClassType);
429 IO.mapRequired(
"FunctionType",
Record.FunctionType);
430 IO.mapRequired(
"Name",
Record.Name);
434 IO.mapRequired(
"ArgIndices",
Record.ArgIndices);
438 IO.mapRequired(
"StringIndices",
Record.StringIndices);
442 IO.mapRequired(
"ReferentType",
Record.ReferentType);
443 IO.mapRequired(
"Attrs",
Record.Attrs);
444 IO.mapOptional(
"MemberInfo",
Record.MemberInfo);
448 IO.mapRequired(
"ElementType",
Record.ElementType);
449 IO.mapRequired(
"IndexType",
Record.IndexType);
450 IO.mapRequired(
"Size",
Record.Size);
451 IO.mapRequired(
"Name",
Record.Name);
455 IO.mapRequired(
"FieldList", Members);
466 explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records)
467 : Records(Records) {}
469 #define TYPE_RECORD(EnumName, EnumVal, Name)
470 #define MEMBER_RECORD(EnumName, EnumVal, Name) \
471 Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
472 return visitKnownMemberImpl(Record); \
474 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
475 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
476 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
478 template <
typename T>
Error visitKnownMemberImpl(T &
Record) {
480 auto Impl = std::make_shared<MemberRecordImpl<T>>(K);
486 std::vector<MemberRecord> &Records;
492 MemberRecordConversionVisitor V(Members);
500 for (
const auto &Member : Members) {
501 Member.Member->writeTo(CRB);
508 io.mapRequired(
"Type",
Record.Type);
509 io.mapRequired(
"Attrs",
Record.Attrs.Attrs);
510 io.mapRequired(
"VFTableOffset",
Record.VFTableOffset);
511 io.mapRequired(
"Name",
Record.Name);
515 namespace CodeViewYAML {
519 IO.mapRequired(
"MemberCount",
Record.MemberCount);
520 IO.mapRequired(
"Options",
Record.Options);
521 IO.mapRequired(
"FieldList",
Record.FieldList);
522 IO.mapRequired(
"Name",
Record.Name);
523 IO.mapRequired(
"UniqueName",
Record.UniqueName);
524 IO.mapRequired(
"DerivationList",
Record.DerivationList);
525 IO.mapRequired(
"VTableShape",
Record.VTableShape);
526 IO.mapRequired(
"Size",
Record.Size);
530 IO.mapRequired(
"MemberCount",
Record.MemberCount);
531 IO.mapRequired(
"Options",
Record.Options);
532 IO.mapRequired(
"FieldList",
Record.FieldList);
533 IO.mapRequired(
"Name",
Record.Name);
534 IO.mapRequired(
"UniqueName",
Record.UniqueName);
535 IO.mapRequired(
"Size",
Record.Size);
539 IO.mapRequired(
"NumEnumerators",
Record.MemberCount);
540 IO.mapRequired(
"Options",
Record.Options);
541 IO.mapRequired(
"FieldList",
Record.FieldList);
542 IO.mapRequired(
"Name",
Record.Name);
543 IO.mapRequired(
"UniqueName",
Record.UniqueName);
544 IO.mapRequired(
"UnderlyingType",
Record.UnderlyingType);
548 IO.mapRequired(
"Type",
Record.Type);
549 IO.mapRequired(
"BitSize",
Record.BitSize);
550 IO.mapRequired(
"BitOffset",
Record.BitOffset);
554 IO.mapRequired(
"Slots",
Record.Slots);
558 IO.mapRequired(
"Guid",
Record.Guid);
559 IO.mapRequired(
"Age",
Record.Age);
560 IO.mapRequired(
"Name",
Record.Name);
564 IO.mapRequired(
"Id",
Record.Id);
565 IO.mapRequired(
"String",
Record.String);
569 IO.mapRequired(
"ParentScope",
Record.ParentScope);
570 IO.mapRequired(
"FunctionType",
Record.FunctionType);
571 IO.mapRequired(
"Name",
Record.Name);
575 IO.mapRequired(
"UDT",
Record.UDT);
576 IO.mapRequired(
"SourceFile",
Record.SourceFile);
577 IO.mapRequired(
"LineNumber",
Record.LineNumber);
581 IO.mapRequired(
"UDT",
Record.UDT);
582 IO.mapRequired(
"SourceFile",
Record.SourceFile);
583 IO.mapRequired(
"LineNumber",
Record.LineNumber);
584 IO.mapRequired(
"Module",
Record.Module);
588 IO.mapRequired(
"ArgIndices",
Record.ArgIndices);
592 IO.mapRequired(
"CompleteClass",
Record.CompleteClass);
593 IO.mapRequired(
"OverriddenVFTable",
Record.OverriddenVFTable);
594 IO.mapRequired(
"VFPtrOffset",
Record.VFPtrOffset);
595 IO.mapRequired(
"MethodNames",
Record.MethodNames);
599 IO.mapRequired(
"Methods",
Record.Methods);
603 IO.mapRequired(
"StartTypeIndex",
Record.StartTypeIndex);
604 IO.mapRequired(
"TypesCount",
Record.TypesCount);
605 IO.mapRequired(
"Signature",
Record.Signature);
606 IO.mapRequired(
"PrecompFilePath",
Record.PrecompFilePath);
610 IO.mapRequired(
"Signature",
Record.Signature);
618 IO.mapRequired(
"NumOverloads",
Record.NumOverloads);
619 IO.mapRequired(
"MethodList",
Record.MethodList);
620 IO.mapRequired(
"Name",
Record.Name);
624 IO.mapRequired(
"Type",
Record.Type);
625 IO.mapRequired(
"Name",
Record.Name);
629 IO.mapRequired(
"Attrs",
Record.Attrs.Attrs);
630 IO.mapRequired(
"Type",
Record.Type);
631 IO.mapRequired(
"FieldOffset",
Record.FieldOffset);
632 IO.mapRequired(
"Name",
Record.Name);
636 IO.mapRequired(
"Attrs",
Record.Attrs.Attrs);
637 IO.mapRequired(
"Type",
Record.Type);
638 IO.mapRequired(
"Name",
Record.Name);
642 IO.mapRequired(
"Attrs",
Record.Attrs.Attrs);
643 IO.mapRequired(
"Value",
Record.Value);
644 IO.mapRequired(
"Name",
Record.Name);
648 IO.mapRequired(
"Type",
Record.Type);
652 IO.mapRequired(
"Attrs",
Record.Attrs.Attrs);
653 IO.mapRequired(
"Type",
Record.Type);
654 IO.mapRequired(
"Offset",
Record.Offset);
658 IO.mapRequired(
"Attrs",
Record.Attrs.Attrs);
659 IO.mapRequired(
"BaseType",
Record.BaseType);
660 IO.mapRequired(
"VBPtrType",
Record.VBPtrType);
661 IO.mapRequired(
"VBPtrOffset",
Record.VBPtrOffset);
662 IO.mapRequired(
"VTableIndex",
Record.VTableIndex);
666 IO.mapRequired(
"ContinuationIndex",
Record.ContinuationIndex);
673 template <
typename T>
677 auto Impl = std::make_shared<LeafRecordImpl<T>>(
Type.kind());
678 if (
auto EC = Impl->fromCodeViewRecord(
Type))
685 #define TYPE_RECORD(EnumName, EnumVal, ClassName) \
687 return fromCodeViewRecordImpl<ClassName##Record>(Type);
688 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
689 TYPE_RECORD(EnumName, EnumVal, ClassName)
690 #define MEMBER_RECORD(EnumName, EnumVal, ClassName)
691 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
692 switch (
Type.kind()) {
693 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
702 return Leaf->toCodeViewRecord(Serializer);
719 template <
typename ConcreteType>
722 if (!IO.outputting())
723 Obj.
Leaf = std::make_shared<LeafRecordImpl<ConcreteType>>(
Kind);
725 if (
Kind == LF_FIELDLIST)
728 IO.mapRequired(Class, *Obj.
Leaf);
735 IO.mapRequired(
"Kind",
Kind);
737 #define TYPE_RECORD(EnumName, EnumVal, ClassName) \
739 mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
741 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
742 TYPE_RECORD(EnumName, EnumVal, ClassName)
743 #define MEMBER_RECORD(EnumName, EnumVal, ClassName)
744 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
746 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
751 template <
typename ConcreteType>
754 if (!IO.outputting())
755 Obj.
Member = std::make_shared<MemberRecordImpl<ConcreteType>>(
Kind);
757 IO.mapRequired(Class, *Obj.
Member);
764 IO.mapRequired(
"Kind",
Kind);
766 #define MEMBER_RECORD(EnumName, EnumVal, ClassName) \
768 mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
770 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
771 MEMBER_RECORD(EnumName, EnumVal, ClassName)
772 #define TYPE_RECORD(EnumName, EnumVal, ClassName)
773 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
775 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
780 std::vector<LeafRecord>
790 "Invalid .debug$T or .debug$P section!");
792 std::vector<LeafRecord> Result;
794 for (
const auto &
T : Types) {
795 auto CVT = Err(LeafRecord::fromCodeViewRecord(
T));
796 Result.push_back(CVT);
806 for (
const auto &Leaf : Leafs) {
807 CVType T = Leaf.Leaf->toCodeViewRecord(TS);
809 assert(
T.length() % 4 == 0 &&
"Improper type record alignment!");
811 uint8_t *ResultBuffer = Alloc.
Allocate<uint8_t>(Size);
817 for (
const auto &R : TS.
records()) {
MemberAccess
Source-level access specifier. (CV_access_e)
#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)
static void mapping(IO &io, MemberRecordBase &Record)
This is an optimization pass for GlobalISel generic memory operations.
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)
MemberRecordImpl(TypeLeafKind K)
ModifierOptions
Equivalent to CV_modifier_t.
@ HasConstructorOrDestructor
std::vector< LeafRecord > fromDebugT(ArrayRef< uint8_t > DebugTorP, StringRef SectionName)
Provides write only access to a subclass of WritableBinaryStream.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static ErrorSuccess success()
Create a success value.
This represents the 'GUID' type from windows.h.
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
@ VirtualInheritanceFunction
The instances of the Type class are immutable: once they are created, they are never changed.
@ ConstructorWithVirtualBases
Helper for check-and-exit error handling.
uint64_t bytesRemaining() const
LeafRecordImpl(TypeLeafKind K)
ArrayRef< ArrayRef< uint8_t > > records() const
LeafRecordImpl(TypeLeafKind K)
Tagged union holding either a T or a Error.
LabelType
Equivalent to CV_LABEL_TYPE_e.
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
ArrayRef< uint8_t > toDebugT(ArrayRef< LeafRecord >, BumpPtrAllocator &Alloc, StringRef SectionName)
void writeMemberType(RecordType &Record)
@ SingleInheritanceFunction
void writeTo(ContinuationRecordBuilder &CRB) override
PointerOptions
Equivalent to misc lfPointerAttr bitfields.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
An arbitrary precision integer that knows its signedness.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
static void mapping(IO &io, LeafRecordBase &Record)
This class implements an extremely fast bulk output stream that can only output to a stream.
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
MemberRecordBase(TypeLeafKind K)
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 input
PointerMode
Equivalent to CV_ptrmode_e.
Provides read only access to a subclass of BinaryStream.
#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)
std::shared_ptr< detail::MemberRecordBase > Member
uint64_t bytesRemaining() const
void begin(ContinuationRecordKind RecordKind)
#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)
Allocate memory in an ever growing pool, as if by bump-pointer.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, MemberRecord &Obj)
static Expected< LeafRecord > fromCodeViewRecordImpl(CVType Type)
#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
StringRef - Represent a constant reference to a string, i.e.
static const char Magic[]
@ HasOverloadedAssignmentOperator
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
PointerToMemberRepresentation
Equivalent to CV_pmtype_e.
static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, LeafRecord &Obj)
CVType toCodeViewRecord(AppendingTypeTableBuilder &TS) const override
std::vector< MemberRecord > Members
Lightweight error class with error context and mandatory checking.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
@ PointerToMemberFunction
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
TypeIndex writeLeafType(T &Record)
LeafRecordBase(TypeLeafKind K)
PointerToMemberRepresentation Representation
CallingConvention
These values correspond to the CV_call_e enumeration, and are documented at the following locations: ...
Error fromCodeViewRecord(CVType Type) override
PointerKind
Equivalent to CV_ptrtype_e.
TypeIndex insertRecord(ContinuationRecordBuilder &Builder)
@ MultipleInheritanceData
@ MultipleInheritanceFunction
CVRecord< TypeLeafKind > CVType
LLVM Value Representation.
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...
std::shared_ptr< detail::LeafRecordBase > Leaf
MethodOptions
Equivalent to CV_fldattr_t bitfield.