45#define CV_TYPE(enum, val) {#enum, enum},
46#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
51#define TYPE_RECORD(ename, value, name) \
54#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
66template <
typename T,
typename TFlag>
70 return std::string(
"");
74 for (
const auto &Flag : Flags) {
78 SetFlags.push_back(Flag);
84 std::string FlagLabel;
86 for (
const auto &Flag : SetFlags) {
95 if (!FlagLabel.empty()) {
96 std::string LabelWithBraces(
" ( ");
97 LabelWithBraces += FlagLabel +
" )";
98 return LabelWithBraces;
103template <
typename T,
typename TEnum>
109 for (
const auto &EnumItem : EnumValues) {
110 if (EnumItem.Value ==
Value) {
111 Name = EnumItem.Name;
124 std::string AccessSpecifier = std::string(
126 std::string MemberAttrs(AccessSpecifier);
140struct MapOneMethodRecord {
141 explicit MapOneMethodRecord(
bool IsFromOverloadList)
142 : IsFromOverloadList(IsFromOverloadList) {}
144 Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method)
const {
145 std::string
Attrs = getMemberAttributes(
148 if (IsFromOverloadList) {
153 if (
Method.isIntroducingVirtual()) {
156 Method.VFTableOffset = -1;
158 if (!IsFromOverloadList)
165 bool IsFromOverloadList;
188 size_t BytesNeeded = Name.size() + UniqueName.
size() + 2;
189 if (BytesNeeded > BytesLeft) {
196 std::string UniqueB =
Twine(
"??@" + Hash +
"@").
str();
197 assert(UniqueB.size() == 36);
201 const size_t MaxTakeN = 4096;
202 size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;
204 std::string NameB = (Name.take_front(TakeN) + Hash).str();
233 assert(!TypeKind &&
"Already in a type mapping!");
234 assert(!MemberKind &&
"Already in a member mapping!");
239 std::optional<uint32_t> MaxLen;
240 if (CVR.
kind() != TypeLeafKind::LF_FIELDLIST &&
241 CVR.
kind() != TypeLeafKind::LF_METHODLIST)
243 error(IO.beginRecord(MaxLen));
244 TypeKind = CVR.
kind();
246 if (IO.isStreaming()) {
247 auto RecordKind = CVR.
kind();
249 std::string RecordKindName = std::string(
251 error(IO.mapInteger(RecordLen,
"Record length"));
252 error(IO.mapEnum(RecordKind,
"Record kind: " + RecordKindName));
258 if (IO.isStreaming())
265 assert(TypeKind &&
"Not in a type mapping!");
266 assert(!MemberKind &&
"Still in a member mapping!");
268 error(IO.endRecord());
275 assert(TypeKind &&
"Not in a type mapping!");
276 assert(!MemberKind &&
"Already in a member mapping!");
288 if (IO.isStreaming()) {
295 error(IO.mapEnum(
Record.Kind,
"Member kind: " + MemberKindName));
301 assert(TypeKind &&
"Not in a type mapping!");
302 assert(MemberKind &&
"Not in a member mapping!");
304 if (IO.isReading()) {
305 if (
auto EC = IO.skipPadding())
310 error(IO.endRecord());
315 std::string ModifierNames =
323Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
325 std::string CallingConvName = std::string(getEnumName(
327 std::string FuncOptionNames =
339Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
341 std::string CallingConvName = std::string(getEnumName(
343 std::string FuncOptionNames =
359 error(IO.mapVectorN<uint32_t>(
361 [](CodeViewRecordIO &IO, TypeIndex &
N) {
362 return IO.mapInteger(N,
"Argument");
368Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
370 error(IO.mapVectorN<uint32_t>(
372 [](CodeViewRecordIO &IO, TypeIndex &
N) {
373 return IO.mapInteger(N,
"Strings");
382 SmallString<128> Attr(
"Attrs: ");
384 if (IO.isStreaming()) {
385 std::string PtrType = std::string(getEnumName(
387 Attr +=
"[ Type: " + PtrType;
389 std::string PtrMode = std::string(getEnumName(
391 Attr +=
", Mode: " + PtrMode;
393 auto PtrSizeOf = Record.
getSize();
394 Attr +=
", SizeOf: " +
itostr(PtrSizeOf);
401 Attr +=
", isVolatile";
403 Attr +=
", isUnaligned";
405 Attr +=
", isRestricted";
407 Attr +=
", isThisPtr&";
409 Attr +=
", isThisPtr&&";
421 error(IO.mapInteger(
M.ContainingType,
"ClassType"));
422 std::string PtrMemberGetRepresentation = std::string(getEnumName(
424 error(IO.mapEnum(
M.Representation,
425 "Representation: " + PtrMemberGetRepresentation));
434 error(IO.mapEncodedInteger(Record.
Size,
"SizeOf"));
435 error(IO.mapStringZ(Record.
Name,
"Name"));
441 assert((CVR.
kind() == TypeLeafKind::LF_STRUCTURE) ||
442 (CVR.
kind() == TypeLeafKind::LF_CLASS) ||
443 (CVR.
kind() == TypeLeafKind::LF_INTERFACE));
445 std::string PropertiesNames =
446 getFlagNames(IO,
static_cast<uint16_t
>(Record.
Options),
449 error(IO.mapEnum(Record.
Options,
"Properties" + PropertiesNames));
453 error(IO.mapEncodedInteger(Record.
Size,
"SizeOf"));
461 std::string PropertiesNames =
462 getFlagNames(IO,
static_cast<uint16_t
>(Record.
Options),
465 error(IO.mapEnum(Record.
Options,
"Properties" + PropertiesNames));
467 error(IO.mapEncodedInteger(Record.
Size,
"SizeOf"));
475 std::string PropertiesNames =
476 getFlagNames(IO,
static_cast<uint16_t
>(Record.
Options),
479 error(IO.mapEnum(Record.
Options,
"Properties" + PropertiesNames));
489 error(IO.mapInteger(Record.
Type,
"Type"));
496Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
499 if (!IO.isReading()) {
500 ArrayRef<VFTableSlotKind> Slots = Record.
getSlots();
502 error(IO.mapInteger(
Size,
"VFEntryCount"));
504 for (
size_t SlotIndex = 0; SlotIndex < Slots.
size(); SlotIndex += 2) {
505 uint8_t
Byte =
static_cast<uint8_t
>(Slots[SlotIndex]) << 4;
506 if ((SlotIndex + 1) < Slots.
size()) {
507 Byte |=
static_cast<uint8_t
>(Slots[SlotIndex + 1]);
513 for (uint16_t
I = 0;
I <
Size;
I += 2) {
529 uint32_t NamesLen = 0;
530 if (!IO.isReading()) {
532 NamesLen +=
Name.size() + 1;
534 error(IO.mapInteger(NamesLen));
535 error(IO.mapVectorTail(
537 [](CodeViewRecordIO &IO, StringRef &S) {
538 return IO.mapStringZ(S,
"MethodName");
546 error(IO.mapInteger(Record.
Id,
"Id"));
552Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
554 error(IO.mapInteger(Record.
UDT,
"UDT"));
561Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
563 error(IO.mapInteger(Record.
UDT,
"UDT"));
574 error(IO.mapStringZ(Record.
Name,
"Name"));
579Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
583 error(IO.mapStringZ(Record.
Name,
"Name"));
588Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
590 error(IO.mapVectorN<uint16_t>(
592 [](CodeViewRecordIO &IO, TypeIndex &
N) {
593 return IO.mapInteger(N,
"Argument");
600Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
604 error(IO.mapVectorTail(Record.
Methods, MapOneMethodRecord(
true),
"Method"));
609Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
611 if (IO.isStreaming()) {
615 error(IO.mapByteVectorTail(Record.
Data));
620Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
623 error(IO.mapInteger(Record.
Age,
"Age"));
624 error(IO.mapStringZ(Record.
Name,
"Name"));
629 std::string ModeName = std::string(
631 error(IO.mapEnum(Record.
Mode,
"Mode: " + ModeName));
637 std::string
Attrs = getMemberAttributes(
640 error(IO.mapInteger(Record.
Type,
"BaseType"));
641 error(IO.mapEncodedInteger(Record.
Offset,
"BaseOffset"));
648 std::string
Attrs = getMemberAttributes(
653 error(IO.mapEncodedInteger(Record.
Value,
"EnumValue"));
654 error(IO.mapStringZ(Record.
Name,
"Name"));
661 std::string
Attrs = getMemberAttributes(
664 error(IO.mapInteger(Record.
Type,
"Type"));
666 error(IO.mapStringZ(Record.
Name,
"Name"));
675 error(IO.mapStringZ(Record.
Name,
"Name"));
682 const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
683 MapOneMethodRecord Mapper(IsFromOverloadList);
684 return Mapper(IO, Record);
690 error(IO.mapInteger(Padding,
"Padding"));
691 error(IO.mapInteger(Record.
Type,
"Type"));
692 error(IO.mapStringZ(Record.
Name,
"Name"));
700 std::string
Attrs = getMemberAttributes(
703 error(IO.mapInteger(Record.
Type,
"Type"));
704 error(IO.mapStringZ(Record.
Name,
"Name"));
712 std::string
Attrs = getMemberAttributes(
726 error(IO.mapInteger(Padding,
"Padding"));
727 error(IO.mapInteger(Record.
Type,
"Type"));
735 error(IO.mapInteger(Padding,
"Padding"));
741Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
750Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr uint32_t ContinuationLength
This file defines the SmallString class.
This file defines the SmallVector class.
static StringRef getLeafTypeName(TypeLeafKind LT)
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
static void computeHashString(StringRef Name, SmallString< 32 > &StringifiedHash)
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
static LLVM_ABI void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
LLVM Value Representation.
std::vector< TypeIndex > ArgIndices
MemberAccess getAccess() const
SmallVector< TypeIndex, MaxArgs > ArgIndices
LLVM_ABI Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
LLVM_ABI Error mapStringZ(StringRef &Value, const Twine &Comment="")
Error mapEnum(T &Value, const Twine &Comment="")
LLVM_ABI uint32_t maxFieldLength() const
MemberAccess getAccess() const
MemberAccess getAccess() const
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex ContinuationIndex
std::vector< OneMethodRecord > Methods
For method overload sets. LF_METHOD.
bool isRValueReferenceThisPtr() const
std::optional< MemberPointerInfo > MemberInfo
bool isPointerToMember() const
bool isLValueReferenceThisPtr() const
PointerMode getMode() const
PointerKind getPointerKind() const
StringRef PrecompFilePath
MemberAccess getAccess() const
std::vector< TypeIndex > StringIndices
bool hasUniqueName() const
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitTypeEnd(CVType &Record) override
Error visitMemberEnd(CVMemberRecord &Record) override
TypeIndex OverriddenVFTable
std::vector< StringRef > MethodNames
ArrayRef< VFTableSlotKind > getSlots() const
std::vector< VFTableSlotKind > Slots
MemberAccess getAccess() const
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
MethodKind
Part of member attribute flags. (CV_methodprop_e)
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
CVRecord< TypeLeafKind > CVType
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()
LLVM_ABI Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()
MethodOptions
Equivalent to CV_fldattr_t bitfield.
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getMemberKindNames()
MemberAccess
Source-level access specifier. (CV_access_e)
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
This is an optimization pass for GlobalISel generic memory operations.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
void sort(IteratorTy Start, IteratorTy End)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string itostr(int64_t X)