LLVM: lib/DebugInfo/CodeView/TypeRecordMapping.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
25
26#include
27#include
28#include
29#include
30#include
31#include
32
33using namespace llvm;
35
36namespace {
37
38#define error(X) \
39 do { \
40 if (auto EC = X) \
41 return EC; \
42 } while (false)
43
45#define CV_TYPE(enum, val) {#enum, enum},
46#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
47};
48
50 switch (LT) {
51#define TYPE_RECORD(ename, value, name) \
52 case ename: \
53 return #name;
54#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
55 default:
56 break;
57 }
58 return "UnknownLeaf";
59}
60
61template
64}
65
66template <typename T, typename TFlag>
70 return std::string("");
73 FlagVector SetFlags;
74 for (const auto &Flag : Flags) {
75 if (Flag.Value == 0)
76 continue;
79 }
80 }
81
82 llvm::sort(SetFlags, &compEnumNames);
83
84 std::string FlagLabel;
85 bool FirstOcc = true;
86 for (const auto &Flag : SetFlags) {
87 if (FirstOcc)
88 FirstOcc = false;
89 else
90 FlagLabel += (" | ");
91
92 FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
93 }
94
95 if (!FlagLabel.empty()) {
96 std::string LabelWithBraces(" ( ");
97 LabelWithBraces += FlagLabel + " )";
98 return LabelWithBraces;
99 } else
100 return FlagLabel;
101}
102
103template <typename T, typename TEnum>
107 return "";
109 for (const auto &EnumItem : EnumValues) {
110 if (EnumItem.Value == Value) {
111 Name = EnumItem.Name;
112 break;
113 }
114 }
115
117}
118
123 return "";
124 std::string AccessSpecifier = std::string(
126 std::string MemberAttrs(AccessSpecifier);
127 if (Kind != MethodKind::Vanilla) {
128 std::string MethodKind = std::string(
131 }
132 if (Options != MethodOptions::None) {
136 }
137 return MemberAttrs;
138}
139
140struct MapOneMethodRecord {
141 explicit MapOneMethodRecord(bool IsFromOverloadList)
142 : IsFromOverloadList(IsFromOverloadList) {}
143
145 std::string Attrs = getMemberAttributes(
148 if (IsFromOverloadList) {
151 }
157
158 if (!IsFromOverloadList)
160
162 }
163
164private:
165 bool IsFromOverloadList;
166};
167}
168
169
170
176 Hash.final(Result);
178}
179
183
184
185
188 size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
189 if (BytesNeeded > BytesLeft) {
190
191 assert(BytesLeft >= 70);
192
193
196 std::string UniqueB = Twine("??@" + Hash + "@").str();
197 assert(UniqueB.size() == 36);
198
199
200
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();
205
210 } else {
213 }
214 } else {
215
216
219 }
220 } else {
221
222
223
227 }
228
230}
231
233 assert(!TypeKind && "Already in a type mapping!");
234 assert(!MemberKind && "Already in a member mapping!");
235
236
237
238
239 std::optional<uint32_t> MaxLen;
240 if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
241 CVR.kind() != TypeLeafKind::LF_METHODLIST)
244 TypeKind = CVR.kind();
245
247 auto RecordKind = CVR.kind();
249 std::string RecordKindName = std::string(
252 error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
253 }
255}
256
260 utohexstr(Index.getIndex()) + ")");
262}
263
265 assert(TypeKind && "Not in a type mapping!");
266 assert(!MemberKind && "Still in a member mapping!");
267
269
270 TypeKind.reset();
272}
273
275 assert(TypeKind && "Not in a type mapping!");
276 assert(!MemberKind && "Already in a member mapping!");
277
278
279
280
281
282
286
287 MemberKind = Record.Kind;
290 MemberKindName +=
291 " ( " +
293 .str() +
294 " )";
296 }
298}
299
301 assert(TypeKind && "Not in a type mapping!");
302 assert(MemberKind && "Not in a member mapping!");
303
306 return EC;
307 }
308
309 MemberKind.reset();
312}
313
315 std::string ModifierNames =
316 getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
321}
322
323Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
325 std::string CallingConvName = std::string(getEnumName(
327 std::string FuncOptionNames =
328 getFlagNames(IO, static_cast<uint16_t>(Record.Options),
331 error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
332 error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
335
337}
338
339Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
341 std::string CallingConvName = std::string(getEnumName(
343 std::string FuncOptionNames =
344 getFlagNames(IO, static_cast<uint16_t>(Record.Options),
349 error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
350 error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
354
356}
357
362 return IO.mapInteger(N, "Argument");
363 },
364 "NumArgs"));
366}
367
368Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
371 Record.StringIndices,
373 return IO.mapInteger(N, "Strings");
374 },
375 "NumStrings"));
376
378}
379
381
383
385 std::string PtrType = std::string(getEnumName(
387 Attr += "[ Type: " + PtrType;
388
389 std::string PtrMode = std::string(getEnumName(
391 Attr += ", Mode: " + PtrMode;
392
393 auto PtrSizeOf = Record.getSize();
394 Attr += ", SizeOf: " + itostr(PtrSizeOf);
395
397 Attr += ", isFlat";
398 if (Record.isConst())
399 Attr += ", isConst";
400 if (Record.isVolatile())
401 Attr += ", isVolatile";
402 if (Record.isUnaligned())
403 Attr += ", isUnaligned";
404 if (Record.isRestrict())
405 Attr += ", isRestricted";
406 if (Record.isLValueReferenceThisPtr())
407 Attr += ", isThisPtr&";
408 if (Record.isRValueReferenceThisPtr())
409 Attr += ", isThisPtr&&";
410 Attr += " ]";
411 }
412
415
416 if (Record.isPointerToMember()) {
418 Record.MemberInfo.emplace();
419
422 std::string PtrMemberGetRepresentation = std::string(getEnumName(
425 "Representation: " + PtrMemberGetRepresentation));
426 }
427
429}
430
436
438}
439
441 assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
442 (CVR.kind() == TypeLeafKind::LF_CLASS) ||
443 (CVR.kind() == TypeLeafKind::LF_INTERFACE));
444
445 std::string PropertiesNames =
446 getFlagNames(IO, static_cast<uint16_t>(Record.Options),
455 Record.hasUniqueName()));
456
458}
459
461 std::string PropertiesNames =
462 getFlagNames(IO, static_cast<uint16_t>(Record.Options),
469 Record.hasUniqueName()));
470
472}
473
475 std::string PropertiesNames =
476 getFlagNames(IO, static_cast<uint16_t>(Record.Options),
483 Record.hasUniqueName()));
484
486}
487
492
494}
495
496Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
503
508 }
510 }
511 } else {
519 }
520 }
521
523}
524
532 NamesLen += Name.size() + 1;
533 }
538 return IO.mapStringZ(S, "MethodName");
539 },
540 "VFTableName"));
541
543}
544
548
550}
551
552Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
557
559}
560
561Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
567
569}
570
575
577}
578
579Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
584
586}
587
588Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
593 return IO.mapInteger(N, "Argument");
594 },
595 "NumArgs"));
596
598}
599
600Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
602
603
605
607}
608
609Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
613 return EC;
614 } else
616
618}
619
620Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
626}
627
629 std::string ModeName = std::string(
633}
634
637 std::string Attrs = getMemberAttributes(
642
644}
645
648 std::string Attrs = getMemberAttributes(
651
652
655
657}
658
661 std::string Attrs = getMemberAttributes(
667
669}
670
676
678}
679
682 const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
683 MapOneMethodRecord Mapper(IsFromOverloadList);
684 return Mapper(IO, Record);
685}
686
693
695}
696
699
700 std::string Attrs = getMemberAttributes(
705
707}
708
711
712 std::string Attrs = getMemberAttributes(
719
721}
722
728
730}
731
737
739}
740
741Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
748}
749
750Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
754}
static constexpr uint32_t ContinuationLength
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
SlotIndex - An opaque wrapper around machine indexes.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
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...
std::string str() const
Return the twine contents as a std::string.
LLVM Value Representation.
Error mapVectorTail(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Error mapVectorN(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
Error mapGuid(GUID &Guid, const Twine &Comment="")
Error mapStringZ(StringRef &Value, const Twine &Comment="")
Error mapEnum(T &Value, const Twine &Comment="")
Error mapEncodedInteger(int64_t &Value, const Twine &Comment="")
Error beginRecord(std::optional< uint32_t > MaxLength)
Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes, const Twine &Comment="")
uint32_t maxFieldLength() const
void emitRawComment(const Twine &T)
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
bool isIntroducingVirtual() const
MemberAccess getAccess() const
MethodOptions getOptions() const
MethodKind getMethodKind() const
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.
ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
MethodKind
Part of member attribute flags. (CV_methodprop_e)
ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()
ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()
MethodOptions
Equivalent to CV_fldattr_t bitfield.
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.
ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
This is an optimization pass for GlobalISel generic memory operations.
void sort(IteratorTy Start, IteratorTy End)