45#define TYPE_RECORD(ename, value, name) \
48#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
60template <
typename T,
typename TFlag>
64 return std::string(
"");
68 for (
const auto &Flag : Flags) {
72 SetFlags.push_back(Flag);
78 std::string FlagLabel;
80 for (
const auto &Flag : SetFlags) {
89 if (!FlagLabel.empty()) {
90 std::string LabelWithBraces(
" ( ");
91 LabelWithBraces += FlagLabel +
" )";
92 return LabelWithBraces;
97template <
typename T,
typename TEnum>
103 for (
const auto &EnumItem : EnumValues) {
104 if (EnumItem.Value ==
Value) {
105 Name = EnumItem.Name;
118 std::string AccessSpecifier = std::string(
120 std::string MemberAttrs(AccessSpecifier);
134struct MapOneMethodRecord {
135 explicit MapOneMethodRecord(
bool IsFromOverloadList)
136 : IsFromOverloadList(IsFromOverloadList) {}
138 Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method)
const {
139 std::string
Attrs = getMemberAttributes(
142 if (IsFromOverloadList) {
147 if (
Method.isIntroducingVirtual()) {
150 Method.VFTableOffset = -1;
152 if (!IsFromOverloadList)
159 bool IsFromOverloadList;
182 size_t BytesNeeded = Name.size() + UniqueName.
size() + 2;
183 if (BytesNeeded > BytesLeft) {
190 std::string UniqueB =
Twine(
"??@" + Hash +
"@").
str();
191 assert(UniqueB.size() == 36);
195 const size_t MaxTakeN = 4096;
196 size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;
198 std::string NameB = (Name.take_front(TakeN) + Hash).str();
227 assert(!TypeKind &&
"Already in a type mapping!");
228 assert(!MemberKind &&
"Already in a member mapping!");
233 std::optional<uint32_t> MaxLen;
234 if (CVR.
kind() != TypeLeafKind::LF_FIELDLIST &&
235 CVR.
kind() != TypeLeafKind::LF_METHODLIST)
237 error(IO.beginRecord(MaxLen));
238 TypeKind = CVR.
kind();
240 if (IO.isStreaming()) {
241 auto RecordKind = CVR.
kind();
243 std::string RecordKindName =
245 error(IO.mapInteger(RecordLen,
"Record length"));
246 error(IO.mapEnum(RecordKind,
"Record kind: " + RecordKindName));
252 if (IO.isStreaming())
259 assert(TypeKind &&
"Not in a type mapping!");
260 assert(!MemberKind &&
"Still in a member mapping!");
262 error(IO.endRecord());
269 assert(TypeKind &&
"Not in a type mapping!");
270 assert(!MemberKind &&
"Already in a member mapping!");
282 if (IO.isStreaming()) {
287 error(IO.mapEnum(
Record.Kind,
"Member kind: " + MemberKindName));
293 assert(TypeKind &&
"Not in a type mapping!");
294 assert(MemberKind &&
"Not in a member mapping!");
296 if (IO.isReading()) {
297 if (
auto EC = IO.skipPadding())
302 error(IO.endRecord());
307 std::string ModifierNames =
315Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
317 std::string CallingConvName = std::string(getEnumName(
319 std::string FuncOptionNames =
331Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
333 std::string CallingConvName = std::string(getEnumName(
335 std::string FuncOptionNames =
351 error(IO.mapVectorN<uint32_t>(
353 [](CodeViewRecordIO &IO, TypeIndex &
N) {
354 return IO.mapInteger(N,
"Argument");
360Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
362 error(IO.mapVectorN<uint32_t>(
364 [](CodeViewRecordIO &IO, TypeIndex &
N) {
365 return IO.mapInteger(N,
"Strings");
374 SmallString<128> Attr(
"Attrs: ");
376 if (IO.isStreaming()) {
377 std::string PtrType = std::string(getEnumName(
379 Attr +=
"[ Type: " + PtrType;
381 std::string PtrMode = std::string(getEnumName(
383 Attr +=
", Mode: " + PtrMode;
385 auto PtrSizeOf =
Record.getSize();
386 Attr +=
", SizeOf: " +
itostr(PtrSizeOf);
393 Attr +=
", isVolatile";
395 Attr +=
", isUnaligned";
397 Attr +=
", isRestricted";
398 if (
Record.isLValueReferenceThisPtr())
399 Attr +=
", isThisPtr&";
400 if (
Record.isRValueReferenceThisPtr())
401 Attr +=
", isThisPtr&&";
405 error(IO.mapInteger(
Record.ReferentType,
"PointeeType"));
408 if (
Record.isPointerToMember()) {
410 Record.MemberInfo.emplace();
412 MemberPointerInfo &
M = *
Record.MemberInfo;
413 error(IO.mapInteger(
M.ContainingType,
"ClassType"));
414 std::string PtrMemberGetRepresentation = std::string(getEnumName(
416 error(IO.mapEnum(
M.Representation,
417 "Representation: " + PtrMemberGetRepresentation));
424 error(IO.mapInteger(
Record.ElementType,
"ElementType"));
425 error(IO.mapInteger(
Record.IndexType,
"IndexType"));
426 error(IO.mapEncodedInteger(
Record.Size,
"SizeOf"));
433 assert((CVR.
kind() == TypeLeafKind::LF_STRUCTURE) ||
434 (CVR.
kind() == TypeLeafKind::LF_CLASS) ||
435 (CVR.
kind() == TypeLeafKind::LF_INTERFACE));
437 std::string PropertiesNames =
438 getFlagNames(IO,
static_cast<uint16_t
>(
Record.Options),
440 error(IO.mapInteger(
Record.MemberCount,
"MemberCount"));
441 error(IO.mapEnum(
Record.Options,
"Properties" + PropertiesNames));
442 error(IO.mapInteger(
Record.FieldList,
"FieldList"));
443 error(IO.mapInteger(
Record.DerivationList,
"DerivedFrom"));
444 error(IO.mapInteger(
Record.VTableShape,
"VShape"));
445 error(IO.mapEncodedInteger(
Record.Size,
"SizeOf"));
453 std::string PropertiesNames =
454 getFlagNames(IO,
static_cast<uint16_t
>(
Record.Options),
456 error(IO.mapInteger(
Record.MemberCount,
"MemberCount"));
457 error(IO.mapEnum(
Record.Options,
"Properties" + PropertiesNames));
458 error(IO.mapInteger(
Record.FieldList,
"FieldList"));
459 error(IO.mapEncodedInteger(
Record.Size,
"SizeOf"));
467 std::string PropertiesNames =
468 getFlagNames(IO,
static_cast<uint16_t
>(
Record.Options),
470 error(IO.mapInteger(
Record.MemberCount,
"NumEnumerators"));
471 error(IO.mapEnum(
Record.Options,
"Properties" + PropertiesNames));
472 error(IO.mapInteger(
Record.UnderlyingType,
"UnderlyingType"));
473 error(IO.mapInteger(
Record.FieldList,
"FieldListType"));
483 error(IO.mapInteger(
Record.BitOffset,
"BitOffset"));
488Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
491 if (!IO.isReading()) {
492 ArrayRef<VFTableSlotKind> Slots =
Record.getSlots();
494 error(IO.mapInteger(
Size,
"VFEntryCount"));
496 for (
size_t SlotIndex = 0; SlotIndex < Slots.
size(); SlotIndex += 2) {
497 uint8_t
Byte =
static_cast<uint8_t
>(Slots[SlotIndex]) << 4;
498 if ((SlotIndex + 1) < Slots.
size()) {
499 Byte |=
static_cast<uint8_t
>(Slots[SlotIndex + 1]);
505 for (uint16_t
I = 0;
I <
Size;
I += 2) {
518 error(IO.mapInteger(
Record.CompleteClass,
"CompleteClass"));
519 error(IO.mapInteger(
Record.OverriddenVFTable,
"OverriddenVFTable"));
520 error(IO.mapInteger(
Record.VFPtrOffset,
"VFPtrOffset"));
521 uint32_t NamesLen = 0;
522 if (!IO.isReading()) {
523 for (
auto Name :
Record.MethodNames)
524 NamesLen +=
Name.size() + 1;
526 error(IO.mapInteger(NamesLen));
527 error(IO.mapVectorTail(
529 [](CodeViewRecordIO &IO, StringRef &S) {
530 return IO.mapStringZ(S,
"MethodName");
544Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
547 error(IO.mapInteger(
Record.SourceFile,
"SourceFile"));
548 error(IO.mapInteger(
Record.LineNumber,
"LineNumber"));
553Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
556 error(IO.mapInteger(
Record.SourceFile,
"SourceFile"));
557 error(IO.mapInteger(
Record.LineNumber,
"LineNumber"));
564 error(IO.mapInteger(
Record.ParentScope,
"ParentScope"));
565 error(IO.mapInteger(
Record.FunctionType,
"FunctionType"));
571Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
573 error(IO.mapInteger(
Record.ClassType,
"ClassType"));
574 error(IO.mapInteger(
Record.FunctionType,
"FunctionType"));
580Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
582 error(IO.mapVectorN<uint16_t>(
584 [](CodeViewRecordIO &IO, TypeIndex &
N) {
585 return IO.mapInteger(N,
"Argument");
592Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
596 error(IO.mapVectorTail(
Record.Methods, MapOneMethodRecord(
true),
"Method"));
601Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
603 if (IO.isStreaming()) {
612Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
621 std::string ModeName = std::string(
623 error(IO.mapEnum(
Record.Mode,
"Mode: " + ModeName));
629 std::string
Attrs = getMemberAttributes(
631 error(IO.mapInteger(
Record.Attrs.Attrs,
"Attrs: " + Attrs));
633 error(IO.mapEncodedInteger(
Record.Offset,
"BaseOffset"));
640 std::string
Attrs = getMemberAttributes(
642 error(IO.mapInteger(
Record.Attrs.Attrs,
"Attrs: " + Attrs));
645 error(IO.mapEncodedInteger(
Record.Value,
"EnumValue"));
653 std::string
Attrs = getMemberAttributes(
655 error(IO.mapInteger(
Record.Attrs.Attrs,
"Attrs: " + Attrs));
657 error(IO.mapEncodedInteger(
Record.FieldOffset,
"FieldOffset"));
665 error(IO.mapInteger(
Record.NumOverloads,
"MethodCount"));
666 error(IO.mapInteger(
Record.MethodList,
"MethodListIndex"));
674 const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
675 MapOneMethodRecord Mapper(IsFromOverloadList);
676 return Mapper(IO, Record);
682 error(IO.mapInteger(Padding,
"Padding"));
692 std::string
Attrs = getMemberAttributes(
694 error(IO.mapInteger(
Record.Attrs.Attrs,
"Attrs: " + Attrs));
704 std::string
Attrs = getMemberAttributes(
706 error(IO.mapInteger(
Record.Attrs.Attrs,
"Attrs: " + Attrs));
708 error(IO.mapInteger(
Record.VBPtrType,
"VBPtrType"));
709 error(IO.mapEncodedInteger(
Record.VBPtrOffset,
"VBPtrOffset"));
710 error(IO.mapEncodedInteger(
Record.VTableIndex,
"VBTableIndex"));
718 error(IO.mapInteger(Padding,
"Padding"));
727 error(IO.mapInteger(Padding,
"Padding"));
728 error(IO.mapInteger(
Record.ContinuationIndex,
"ContinuationIndex"));
733Error TypeRecordMapping::visitKnownRecord(
CVType &CVR,
742Error 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 void computeHashString(StringRef Name, SmallString< 32 > &StringifiedHash)
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
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.
Represent a constant reference to a string, i.e.
constexpr size_t size() const
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.
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
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
For method overload sets. LF_METHOD.
StringRef PrecompFilePath
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
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 ArrayRef< EnumEntry< TypeLeafKind > > getTypeLeafNames()
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)