49 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(
TypeIndex)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(
HfaKind)
76 namespace CodeViewYAML {
85 virtual void map(yaml::IO &io) = 0;
94 void map(yaml::IO &io)
override;
97 return TypeDeserializer::deserializeAs<T>(Type,
Record);
111 void map(yaml::IO &io)
override;
124 virtual void map(yaml::IO &io) = 0;
132 void map(yaml::IO &io)
override;
150 if (Scalar.
size() != 38)
151 return "GUID strings are 38 characters long";
152 if (Scalar[0] !=
'{' || Scalar[37] !=
'}')
153 return "GUID is not enclosed in {}";
154 if (Scalar[9] !=
'-' || Scalar[14] !=
'-' || Scalar[19] !=
'-' ||
156 return "GUID sections are not properly delineated with dashes";
158 uint8_t *OutBuffer = S.
Guid;
159 for (
auto Iter = Scalar.
begin(); Iter != Scalar.
end();) {
160 if (*Iter ==
'-' || *Iter ==
'{' || *Iter ==
'}') {
166 *OutBuffer++ = Value;
172 void ScalarTraits<TypeIndex>::output(
const TypeIndex &S,
void *,
180 StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
194 void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
196 #define CV_TYPE(name, val) io.enumCase(Value, #name, name); 197 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 201 void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration(
204 IO.enumCase(Value,
"SingleInheritanceData",
206 IO.enumCase(Value,
"MultipleInheritanceData",
208 IO.enumCase(Value,
"VirtualInheritanceData",
211 IO.enumCase(Value,
"SingleInheritanceFunction",
213 IO.enumCase(Value,
"MultipleInheritanceFunction",
215 IO.enumCase(Value,
"VirtualInheritanceFunction",
217 IO.enumCase(Value,
"GeneralFunction",
221 void ScalarEnumerationTraits<VFTableSlotKind>::enumeration(
232 void ScalarEnumerationTraits<CallingConvention>::enumeration(
260 void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO,
269 IO.enumCase(Kind,
"BasedOnSegmentAddress",
278 void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO,
283 IO.enumCase(Mode,
"PointerToMemberFunction",
288 void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO,
HfaKind &
Value) {
295 void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO,
303 void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO,
311 IO.enumCase(Kind,
"PureIntroducingVirtual",
315 void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration(
323 void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO,
LabelType &
Value) {
328 void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO,
336 IO.bitSetCase(Options,
"WinRTSmartPointer",
340 void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO,
348 void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO,
353 IO.bitSetCase(Options,
"ConstructorWithVirtualBases",
357 void ScalarBitSetTraits<ClassOptions>::bitset(IO &IO,
ClassOptions &Options) {
359 IO.bitSetCase(Options,
"HasConstructorOrDestructor",
361 IO.bitSetCase(Options,
"HasOverloadedOperator",
364 IO.bitSetCase(Options,
"ContainsNestedClass",
366 IO.bitSetCase(Options,
"HasOverloadedAssignmentOperator",
368 IO.bitSetCase(Options,
"HasConversionOperator",
377 void ScalarBitSetTraits<MethodOptions>::bitset(IO &IO,
MethodOptions &Options) {
392 namespace CodeViewYAML {
396 IO.mapRequired(
"ModifiedType",
Record.ModifiedType);
397 IO.mapRequired(
"Modifiers",
Record.Modifiers);
401 IO.mapRequired(
"ReturnType",
Record.ReturnType);
402 IO.mapRequired(
"CallConv",
Record.CallConv);
403 IO.mapRequired(
"Options",
Record.Options);
404 IO.mapRequired(
"ParameterCount",
Record.ParameterCount);
405 IO.mapRequired(
"ArgumentList",
Record.ArgumentList);
409 IO.mapRequired(
"ReturnType",
Record.ReturnType);
410 IO.mapRequired(
"ClassType",
Record.ClassType);
411 IO.mapRequired(
"ThisType",
Record.ThisType);
412 IO.mapRequired(
"CallConv",
Record.CallConv);
413 IO.mapRequired(
"Options",
Record.Options);
414 IO.mapRequired(
"ParameterCount",
Record.ParameterCount);
415 IO.mapRequired(
"ArgumentList",
Record.ArgumentList);
416 IO.mapRequired(
"ThisPointerAdjustment",
Record.ThisPointerAdjustment);
420 IO.mapRequired(
"Mode",
Record.Mode);
424 IO.mapRequired(
"ClassType",
Record.ClassType);
425 IO.mapRequired(
"FunctionType",
Record.FunctionType);
426 IO.mapRequired(
"Name",
Record.Name);
430 IO.mapRequired(
"ArgIndices",
Record.ArgIndices);
434 IO.mapRequired(
"StringIndices",
Record.StringIndices);
438 IO.mapRequired(
"ReferentType",
Record.ReferentType);
439 IO.mapRequired(
"Attrs",
Record.Attrs);
440 IO.mapOptional(
"MemberInfo",
Record.MemberInfo);
444 IO.mapRequired(
"ElementType",
Record.ElementType);
445 IO.mapRequired(
"IndexType",
Record.IndexType);
446 IO.mapRequired(
"Size",
Record.Size);
447 IO.mapRequired(
"Name",
Record.Name);
451 IO.mapRequired(
"FieldList", Members);
462 explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records)
463 : Records(Records) {}
465 #define TYPE_RECORD(EnumName, EnumVal, Name) 466 #define MEMBER_RECORD(EnumName, EnumVal, Name) \ 467 Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ 468 return visitKnownMemberImpl(Record); \ 470 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 471 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 472 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 474 template <
typename T>
Error visitKnownMemberImpl(
T &
Record) {
476 auto Impl = std::make_shared<MemberRecordImpl<T>>(K);
477 Impl->Record = Record;
482 std::vector<MemberRecord> &Records;
488 MemberRecordConversionVisitor V(Members);
496 for (
const auto &Member : Members) {
497 Member.Member->writeTo(CRB);
504 io.mapRequired(
"Type", Record.
Type);
507 io.mapRequired(
"Name", Record.
Name);
511 namespace CodeViewYAML {
515 IO.mapRequired(
"MemberCount", Record.MemberCount);
516 IO.mapRequired(
"Options", Record.Options);
517 IO.mapRequired(
"FieldList", Record.FieldList);
518 IO.mapRequired(
"Name", Record.
Name);
519 IO.mapRequired(
"UniqueName", Record.UniqueName);
520 IO.mapRequired(
"DerivationList", Record.DerivationList);
521 IO.mapRequired(
"VTableShape", Record.VTableShape);
522 IO.mapRequired(
"Size", Record.Size);
526 IO.mapRequired(
"MemberCount", Record.MemberCount);
527 IO.mapRequired(
"Options", Record.Options);
528 IO.mapRequired(
"FieldList", Record.FieldList);
529 IO.mapRequired(
"Name", Record.
Name);
530 IO.mapRequired(
"UniqueName", Record.UniqueName);
531 IO.mapRequired(
"Size", Record.Size);
535 IO.mapRequired(
"NumEnumerators", Record.MemberCount);
536 IO.mapRequired(
"Options", Record.Options);
537 IO.mapRequired(
"FieldList", Record.FieldList);
538 IO.mapRequired(
"Name", Record.
Name);
539 IO.mapRequired(
"UniqueName", Record.UniqueName);
540 IO.mapRequired(
"UnderlyingType", Record.UnderlyingType);
544 IO.mapRequired(
"Type", Record.
Type);
545 IO.mapRequired(
"BitSize", Record.BitSize);
546 IO.mapRequired(
"BitOffset", Record.BitOffset);
550 IO.mapRequired(
"Slots", Record.Slots);
554 IO.mapRequired(
"Guid", Record.Guid);
555 IO.mapRequired(
"Age", Record.Age);
556 IO.mapRequired(
"Name", Record.
Name);
560 IO.mapRequired(
"Id", Record.Id);
561 IO.mapRequired(
"String", Record.String);
565 IO.mapRequired(
"ParentScope", Record.ParentScope);
566 IO.mapRequired(
"FunctionType", Record.FunctionType);
567 IO.mapRequired(
"Name", Record.
Name);
571 IO.mapRequired(
"UDT", Record.UDT);
572 IO.mapRequired(
"SourceFile", Record.SourceFile);
573 IO.mapRequired(
"LineNumber", Record.LineNumber);
577 IO.mapRequired(
"UDT", Record.UDT);
578 IO.mapRequired(
"SourceFile", Record.SourceFile);
579 IO.mapRequired(
"LineNumber", Record.LineNumber);
580 IO.mapRequired(
"Module", Record.Module);
584 IO.mapRequired(
"ArgIndices", Record.ArgIndices);
588 IO.mapRequired(
"CompleteClass", Record.CompleteClass);
589 IO.mapRequired(
"OverriddenVFTable", Record.OverriddenVFTable);
590 IO.mapRequired(
"VFPtrOffset", Record.VFPtrOffset);
591 IO.mapRequired(
"MethodNames", Record.MethodNames);
595 IO.mapRequired(
"Methods", Record.Methods);
599 IO.mapRequired(
"StartTypeIndex", Record.StartTypeIndex);
600 IO.mapRequired(
"TypesCount", Record.TypesCount);
601 IO.mapRequired(
"Signature", Record.Signature);
602 IO.mapRequired(
"PrecompFilePath", Record.PrecompFilePath);
606 IO.mapRequired(
"Signature", Record.Signature);
614 IO.mapRequired(
"NumOverloads", Record.NumOverloads);
615 IO.mapRequired(
"MethodList", Record.MethodList);
616 IO.mapRequired(
"Name", Record.
Name);
620 IO.mapRequired(
"Type", Record.
Type);
621 IO.mapRequired(
"Name", Record.
Name);
626 IO.mapRequired(
"Type", Record.
Type);
627 IO.mapRequired(
"FieldOffset", Record.FieldOffset);
628 IO.mapRequired(
"Name", Record.
Name);
633 IO.mapRequired(
"Type", Record.
Type);
634 IO.mapRequired(
"Name", Record.
Name);
639 IO.mapRequired(
"Value", Record.Value);
640 IO.mapRequired(
"Name", Record.
Name);
644 IO.mapRequired(
"Type", Record.
Type);
649 IO.mapRequired(
"Type", Record.
Type);
650 IO.mapRequired(
"Offset", Record.Offset);
655 IO.mapRequired(
"BaseType", Record.BaseType);
656 IO.mapRequired(
"VBPtrType", Record.VBPtrType);
657 IO.mapRequired(
"VBPtrOffset", Record.VBPtrOffset);
658 IO.mapRequired(
"VTableIndex", Record.VTableIndex);
662 IO.mapRequired(
"ContinuationIndex", Record.ContinuationIndex);
669 template <
typename T>
673 auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.
kind());
674 if (
auto EC = Impl->fromCodeViewRecord(Type))
675 return std::move(
EC);
681 #define TYPE_RECORD(EnumName, EnumVal, ClassName) \ 683 return fromCodeViewRecordImpl<ClassName##Record>(Type); 684 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 685 TYPE_RECORD(EnumName, EnumVal, ClassName) 686 #define MEMBER_RECORD(EnumName, EnumVal, ClassName) 687 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) 688 switch (Type.
kind()) {
689 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 698 return Leaf->toCodeViewRecord(Serializer);
715 template <
typename ConcreteType>
718 if (!IO.outputting())
721 if (Kind == LF_FIELDLIST)
724 IO.mapRequired(Class, *Obj.
Leaf);
730 Kind = Obj.
Leaf->Kind;
731 IO.mapRequired(
"Kind", Kind);
733 #define TYPE_RECORD(EnumName, EnumVal, ClassName) \ 735 mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ 737 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 738 TYPE_RECORD(EnumName, EnumVal, ClassName) 739 #define MEMBER_RECORD(EnumName, EnumVal, ClassName) 740 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) 742 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 747 template <
typename ConcreteType>
750 if (!IO.outputting())
753 IO.mapRequired(Class, *Obj.
Member);
760 IO.mapRequired(
"Kind", Kind);
762 #define MEMBER_RECORD(EnumName, EnumVal, ClassName) \ 764 mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ 766 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 767 MEMBER_RECORD(EnumName, EnumVal, ClassName) 768 #define TYPE_RECORD(EnumName, EnumVal, ClassName) 769 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) 771 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 776 std::vector<LeafRecord>
779 ExitOnError Err(
"Invalid " + std::string(SectionName) +
" section!");
786 "Invalid .debug$T or .debug$P section!");
788 std::vector<LeafRecord> Result;
790 for (
const auto &
T : Types) {
791 auto CVT = Err(LeafRecord::fromCodeViewRecord(
T));
792 Result.push_back(CVT);
802 for (
const auto &Leaf : Leafs) {
803 CVType T = Leaf.Leaf->toCodeViewRecord(TS);
805 assert(T.
length() % 4 == 0 &&
"Improper type record alignment!");
810 ExitOnError Err(
"Error writing type record to " + std::string(SectionName) +
813 for (
const auto &R : TS.
records()) {
PointerKind
Equivalent to CV_ptrtype_e.
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
virtual void map(yaml::IO &io)=0
This class represents lattice values for constants.
ArrayRef< ArrayRef< uint8_t > > records() const
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
void writeMemberType(RecordType &Record)
Helper for check-and-exit error handling.
TypeIndex writeLeafType(T &Record)
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
LeafRecordImpl(TypeLeafKind K)
CVRecord< TypeLeafKind > CVType
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
void setIndex(uint32_t I)
virtual void map(yaml::IO &io)=0
ArrayRef< uint8_t > content() const
This represents the 'GUID' type from windows.h.
Tagged union holding either a T or a Error.
ModifierOptions
Equivalent to CV_modifier_t.
LabelType
Equivalent to CV_LABEL_TYPE_e.
Error fromCodeViewRecord(CVType Type) override
MethodKind
Part of member attribute flags. (CV_methodprop_e)
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
static void mapping(IO &io, LeafRecordBase &Record)
The instances of the Type class are immutable: once they are created, they are never changed...
Allocate memory in an ever growing pool, as if by bump-pointer.
std::vector< LeafRecord > fromDebugT(ArrayRef< uint8_t > DebugTorP, StringRef SectionName)
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
static Expected< LeafRecord > fromCodeViewRecordImpl(CVType Type)
Provides write only access to a subclass of WritableBinaryStream.
MemberRecordImpl(TypeLeafKind K)
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
TypeIndex insertRecord(ContinuationRecordBuilder &Builder)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, MemberRecord &Obj)
uint32_t getIndex() const
uint32_t bytesRemaining() const
static const char *const Magic
PointerOptions
Equivalent to misc lfPointerAttr bitfields.
static ErrorSuccess success()
Create a success value.
LeafRecordBase(TypeLeafKind K)
std::vector< MemberRecord > Members
static void mapping(IO &io, MemberRecordBase &Record)
LeafRecordImpl(TypeLeafKind K)
void print(raw_ostream &OS, bool isSigned) const
PointerMode
Equivalent to CV_ptrmode_e.
std::shared_ptr< detail::MemberRecordBase > Member
unsigned hexDigitValue(char C)
Interpret the given character C as a hexadecimal digit and return its value.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, LeafRecord &Obj)
ArrayRef< uint8_t > toDebugT(ArrayRef< LeafRecord >, BumpPtrAllocator &Alloc, StringRef SectionName)
CVType toCodeViewRecord(AppendingTypeTableBuilder &TS) const override
uint32_t bytesRemaining() const
PointerToMemberRepresentation
Equivalent to CV_pmtype_e.
MemberAccess
Source-level access specifier. (CV_access_e)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Lightweight error class with error context and mandatory checking.
CallingConvention
These values correspond to the CV_call_e enumeration, and are documented at the following locations: ...
MemberRecordBase(TypeLeafKind K)
This class implements an extremely fast bulk output stream that can only output to a stream...
void writeTo(ContinuationRecordBuilder &CRB) override
Provides read only access to a subclass of BinaryStream.
StringRef - Represent a constant reference to a string, i.e.
std::shared_ptr< detail::LeafRecordBase > Leaf
void begin(ContinuationRecordKind RecordKind)
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 ...
PointerToMemberRepresentation Representation