LLVM  10.0.0svn
TypeRecordMapping.cpp
Go to the documentation of this file.
1 //===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/StringExtras.h"
12 
13 using namespace llvm;
14 using namespace llvm::codeview;
15 
16 namespace {
17 
18 #define error(X) \
19  if (auto EC = X) \
20  return EC;
21 
22 static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
23 #define CV_TYPE(enum, val) {#enum, enum},
24 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
25 };
26 
28  switch (LT) {
29 #define TYPE_RECORD(ename, value, name) \
30  case ename: \
31  return #name;
32 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
33  default:
34  break;
35  }
36  return "UnknownLeaf";
37 }
38 
39 template <typename T>
40 static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
41  return lhs.Name < rhs.Name;
42 }
43 
44 template <typename T, typename TFlag>
45 static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
46  ArrayRef<EnumEntry<TFlag>> Flags) {
47  if (!IO.isStreaming())
48  return std::string("");
49  typedef EnumEntry<TFlag> FlagEntry;
50  typedef SmallVector<FlagEntry, 10> FlagVector;
51  FlagVector SetFlags;
52  for (const auto &Flag : Flags) {
53  if (Flag.Value == 0)
54  continue;
55  if ((Value & Flag.Value) == Flag.Value) {
56  SetFlags.push_back(Flag);
57  }
58  }
59 
60  llvm::sort(SetFlags, &compEnumNames<TFlag>);
61 
62  std::string FlagLabel;
63  bool FirstOcc = true;
64  for (const auto &Flag : SetFlags) {
65  if (FirstOcc)
66  FirstOcc = false;
67  else
68  FlagLabel += (" | ");
69 
70  FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
71  }
72 
73  if (!FlagLabel.empty()) {
74  std::string LabelWithBraces(" ( ");
75  LabelWithBraces += FlagLabel + " )";
76  return LabelWithBraces;
77  } else
78  return FlagLabel;
79 }
80 
81 template <typename T, typename TEnum>
82 static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
83  ArrayRef<EnumEntry<TEnum>> EnumValues) {
84  if (!IO.isStreaming())
85  return "";
87  for (const auto &EnumItem : EnumValues) {
88  if (EnumItem.Value == Value) {
89  Name = EnumItem.Name;
90  break;
91  }
92  }
93 
94  return Name;
95 }
96 
97 static std::string getMemberAttributes(CodeViewRecordIO &IO,
99  MethodOptions Options) {
100  if (!IO.isStreaming())
101  return "";
102  std::string AccessSpecifier =
103  getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames()));
104  std::string MemberAttrs(AccessSpecifier);
105  if (Kind != MethodKind::Vanilla) {
106  std::string MethodKind =
107  getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames()));
108  MemberAttrs += ", " + MethodKind;
109  }
110  if (Options != MethodOptions::None) {
111  std::string MethodOptions = getFlagNames(
112  IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
113  MemberAttrs += ", " + MethodOptions;
114  }
115  return MemberAttrs;
116 }
117 
118 struct MapOneMethodRecord {
119  explicit MapOneMethodRecord(bool IsFromOverloadList)
120  : IsFromOverloadList(IsFromOverloadList) {}
121 
122  Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
123  std::string Attrs = getMemberAttributes(
124  IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
125  error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
126  if (IsFromOverloadList) {
127  uint16_t Padding = 0;
128  error(IO.mapInteger(Padding));
129  }
130  error(IO.mapInteger(Method.Type, "Type"));
131  if (Method.isIntroducingVirtual()) {
132  error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
133  } else if (IO.isReading())
134  Method.VFTableOffset = -1;
135 
136  if (!IsFromOverloadList)
137  error(IO.mapStringZ(Method.Name, "Name"));
138 
139  return Error::success();
140  }
141 
142 private:
143  bool IsFromOverloadList;
144 };
145 } // namespace
146 
148  StringRef &UniqueName, bool HasUniqueName) {
149  if (IO.isWriting()) {
150  // Try to be smart about what we write here. We can't write anything too
151  // large, so if we're going to go over the limit, truncate both the name
152  // and unique name by the same amount.
153  size_t BytesLeft = IO.maxFieldLength();
154  if (HasUniqueName) {
155  size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
156  StringRef N = Name;
157  StringRef U = UniqueName;
158  if (BytesNeeded > BytesLeft) {
159  size_t BytesToDrop = (BytesNeeded - BytesLeft);
160  size_t DropN = std::min(N.size(), BytesToDrop / 2);
161  size_t DropU = std::min(U.size(), BytesToDrop - DropN);
162 
163  N = N.drop_back(DropN);
164  U = U.drop_back(DropU);
165  }
166 
167  error(IO.mapStringZ(N));
168  error(IO.mapStringZ(U));
169  } else {
170  // Cap the length of the string at however many bytes we have available,
171  // plus one for the required null terminator.
172  auto N = StringRef(Name).take_front(BytesLeft - 1);
173  error(IO.mapStringZ(N));
174  }
175  } else {
176  // Reading & Streaming mode come after writing mode is executed for each
177  // record. Truncating large names are done during writing, so its not
178  // necessary to do it while reading or streaming.
179  error(IO.mapStringZ(Name, "Name"));
180  if (HasUniqueName)
181  error(IO.mapStringZ(UniqueName, "LinkageName"));
182  }
183 
184  return Error::success();
185 }
186 
188  assert(!TypeKind.hasValue() && "Already in a type mapping!");
189  assert(!MemberKind.hasValue() && "Already in a member mapping!");
190 
191  // FieldList and MethodList records can be any length because they can be
192  // split with continuation records. All other record types cannot be
193  // longer than the maximum record length.
194  Optional<uint32_t> MaxLen;
195  if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
196  CVR.kind() != TypeLeafKind::LF_METHODLIST)
197  MaxLen = MaxRecordLength - sizeof(RecordPrefix);
198  error(IO.beginRecord(MaxLen));
199  TypeKind = CVR.kind();
200 
201  if (IO.isStreaming()) {
202  auto RecordKind = CVR.kind();
203  uint16_t RecordLen = CVR.length() - 2;
204  std::string RecordKindName =
205  getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames));
206  error(IO.mapInteger(RecordLen, "Record length"));
207  error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
208  }
209  return Error::success();
210 }
211 
213  if (IO.isStreaming())
214  IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
215  utohexstr(Index.getIndex()) + ")");
216  return visitTypeBegin(CVR);
217 }
218 
220  assert(TypeKind.hasValue() && "Not in a type mapping!");
221  assert(!MemberKind.hasValue() && "Still in a member mapping!");
222 
223  error(IO.endRecord());
224 
225  TypeKind.reset();
226  return Error::success();
227 }
228 
230  assert(TypeKind.hasValue() && "Not in a type mapping!");
231  assert(!MemberKind.hasValue() && "Already in a member mapping!");
232 
233  // The largest possible subrecord is one in which there is a record prefix,
234  // followed by the subrecord, followed by a continuation, and that entire
235  // sequence spaws `MaxRecordLength` bytes. So the record's length is
236  // calculated as follows.
237 
238  constexpr uint32_t ContinuationLength = 8;
239  error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
240  ContinuationLength));
241 
242  MemberKind = Record.Kind;
243  if (IO.isStreaming()) {
244  std::string MemberKindName = getLeafTypeName(Record.Kind);
245  MemberKindName +=
246  " ( " +
247  (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
248  .str() +
249  " )";
250  error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
251  }
252  return Error::success();
253 }
254 
256  assert(TypeKind.hasValue() && "Not in a type mapping!");
257  assert(MemberKind.hasValue() && "Not in a member mapping!");
258 
259  if (IO.isReading()) {
260  if (auto EC = IO.skipPadding())
261  return EC;
262  }
263 
264  MemberKind.reset();
265  error(IO.endRecord());
266  return Error::success();
267 }
268 
270  std::string ModifierNames =
271  getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
273  error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
274  error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
275  return Error::success();
276 }
277 
279  ProcedureRecord &Record) {
280  std::string CallingConvName = getEnumName(
281  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
282  std::string FuncOptionNames =
283  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
285  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
286  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
287  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
288  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
289  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
290 
291  return Error::success();
292 }
293 
295  MemberFunctionRecord &Record) {
296  std::string CallingConvName = getEnumName(
297  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
298  std::string FuncOptionNames =
299  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
301  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
302  error(IO.mapInteger(Record.ClassType, "ClassType"));
303  error(IO.mapInteger(Record.ThisType, "ThisType"));
304  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
305  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
306  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
307  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
308  error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
309 
310  return Error::success();
311 }
312 
314  error(IO.mapVectorN<uint32_t>(
315  Record.ArgIndices,
316  [](CodeViewRecordIO &IO, TypeIndex &N) {
317  return IO.mapInteger(N, "Argument");
318  },
319  "NumArgs"));
320  return Error::success();
321 }
322 
324  StringListRecord &Record) {
325  error(IO.mapVectorN<uint32_t>(
326  Record.StringIndices,
327  [](CodeViewRecordIO &IO, TypeIndex &N) {
328  return IO.mapInteger(N, "Strings");
329  },
330  "NumStrings"));
331 
332  return Error::success();
333 }
334 
336 
337  SmallString<128> Attr("Attrs: ");
338 
339  if (IO.isStreaming()) {
340  std::string PtrType = getEnumName(IO, unsigned(Record.getPointerKind()),
342  Attr += "[ Type: " + PtrType;
343 
344  std::string PtrMode = getEnumName(IO, unsigned(Record.getMode()),
346  Attr += ", Mode: " + PtrMode;
347 
348  auto PtrSizeOf = Record.getSize();
349  Attr += ", SizeOf: " + itostr(PtrSizeOf);
350 
351  if (Record.isFlat())
352  Attr += ", isFlat";
353  if (Record.isConst())
354  Attr += ", isConst";
355  if (Record.isVolatile())
356  Attr += ", isVolatile";
357  if (Record.isUnaligned())
358  Attr += ", isUnaligned";
359  if (Record.isRestrict())
360  Attr += ", isRestricted";
361  if (Record.isLValueReferenceThisPtr())
362  Attr += ", isThisPtr&";
363  if (Record.isRValueReferenceThisPtr())
364  Attr += ", isThisPtr&&";
365  Attr += " ]";
366  }
367 
368  error(IO.mapInteger(Record.ReferentType, "PointeeType"));
369  error(IO.mapInteger(Record.Attrs, Attr));
370 
371  if (Record.isPointerToMember()) {
372  if (IO.isReading())
373  Record.MemberInfo.emplace();
374 
375  MemberPointerInfo &M = *Record.MemberInfo;
376  error(IO.mapInteger(M.ContainingType, "ClassType"));
377  std::string PtrMemberGetRepresentation = getEnumName(
378  IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames()));
379  error(IO.mapEnum(M.Representation,
380  "Representation: " + PtrMemberGetRepresentation));
381  }
382 
383  return Error::success();
384 }
385 
387  error(IO.mapInteger(Record.ElementType, "ElementType"));
388  error(IO.mapInteger(Record.IndexType, "IndexType"));
389  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
390  error(IO.mapStringZ(Record.Name, "Name"));
391 
392  return Error::success();
393 }
394 
396  assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
397  (CVR.kind() == TypeLeafKind::LF_CLASS) ||
398  (CVR.kind() == TypeLeafKind::LF_INTERFACE));
399 
400  std::string PropertiesNames =
401  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
403  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
404  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
405  error(IO.mapInteger(Record.FieldList, "FieldList"));
406  error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
407  error(IO.mapInteger(Record.VTableShape, "VShape"));
408  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
409  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
410  Record.hasUniqueName()));
411 
412  return Error::success();
413 }
414 
416  std::string PropertiesNames =
417  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
419  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
420  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
421  error(IO.mapInteger(Record.FieldList, "FieldList"));
422  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
423  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
424  Record.hasUniqueName()));
425 
426  return Error::success();
427 }
428 
430  std::string PropertiesNames =
431  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
433  error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
434  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
435  error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
436  error(IO.mapInteger(Record.FieldList, "FieldListType"));
437  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
438  Record.hasUniqueName()));
439 
440  return Error::success();
441 }
442 
444  error(IO.mapInteger(Record.Type, "Type"));
445  error(IO.mapInteger(Record.BitSize, "BitSize"));
446  error(IO.mapInteger(Record.BitOffset, "BitOffset"));
447 
448  return Error::success();
449 }
450 
452  VFTableShapeRecord &Record) {
453  uint16_t Size;
454  if (!IO.isReading()) {
455  ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
456  Size = Slots.size();
457  error(IO.mapInteger(Size, "VFEntryCount"));
458 
459  for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
460  uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
461  if ((SlotIndex + 1) < Slots.size()) {
462  Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
463  }
464  error(IO.mapInteger(Byte));
465  }
466  } else {
467  error(IO.mapInteger(Size));
468  for (uint16_t I = 0; I < Size; I += 2) {
469  uint8_t Byte;
470  error(IO.mapInteger(Byte));
471  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
472  if ((I + 1) < Size)
473  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
474  }
475  }
476 
477  return Error::success();
478 }
479 
481  error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
482  error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
483  error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
484  uint32_t NamesLen = 0;
485  if (!IO.isReading()) {
486  for (auto Name : Record.MethodNames)
487  NamesLen += Name.size() + 1;
488  }
489  error(IO.mapInteger(NamesLen));
490  error(IO.mapVectorTail(
491  Record.MethodNames,
492  [](CodeViewRecordIO &IO, StringRef &S) {
493  return IO.mapStringZ(S, "MethodName");
494  },
495  "VFTableName"));
496 
497  return Error::success();
498 }
499 
501  error(IO.mapInteger(Record.Id, "Id"));
502  error(IO.mapStringZ(Record.String, "StringData"));
503 
504  return Error::success();
505 }
506 
508  UdtSourceLineRecord &Record) {
509  error(IO.mapInteger(Record.UDT, "UDT"));
510  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
511  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
512 
513  return Error::success();
514 }
515 
517  UdtModSourceLineRecord &Record) {
518  error(IO.mapInteger(Record.UDT, "UDT"));
519  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
520  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
521  error(IO.mapInteger(Record.Module, "Module"));
522 
523  return Error::success();
524 }
525 
527  error(IO.mapInteger(Record.ParentScope, "ParentScope"));
528  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
529  error(IO.mapStringZ(Record.Name, "Name"));
530 
531  return Error::success();
532 }
533 
535  MemberFuncIdRecord &Record) {
536  error(IO.mapInteger(Record.ClassType, "ClassType"));
537  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
538  error(IO.mapStringZ(Record.Name, "Name"));
539 
540  return Error::success();
541 }
542 
544  BuildInfoRecord &Record) {
545  error(IO.mapVectorN<uint16_t>(
546  Record.ArgIndices,
547  [](CodeViewRecordIO &IO, TypeIndex &N) {
548  return IO.mapInteger(N, "Argument");
549  },
550  "NumArgs"));
551 
552  return Error::success();
553 }
554 
556  MethodOverloadListRecord &Record) {
557  // TODO: Split the list into multiple records if it's longer than 64KB, using
558  // a subrecord of TypeRecordKind::Index to chain the records together.
559  error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true), "Method"));
560 
561  return Error::success();
562 }
563 
565  FieldListRecord &Record) {
566  if (IO.isStreaming()) {
567  if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
568  return EC;
569  } else
570  error(IO.mapByteVectorTail(Record.Data));
571 
572  return Error::success();
573 }
574 
576  TypeServer2Record &Record) {
577  error(IO.mapGuid(Record.Guid, "Guid"));
578  error(IO.mapInteger(Record.Age, "Age"));
579  error(IO.mapStringZ(Record.Name, "Name"));
580  return Error::success();
581 }
582 
584  std::string ModeName =
585  getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum()));
586  error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
587  return Error::success();
588 }
589 
591  BaseClassRecord &Record) {
592  std::string Attrs = getMemberAttributes(
594  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
595  error(IO.mapInteger(Record.Type, "BaseType"));
596  error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
597 
598  return Error::success();
599 }
600 
602  EnumeratorRecord &Record) {
603  std::string Attrs = getMemberAttributes(
605  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
606 
607  // FIXME: Handle full APInt such as __int128.
608  error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
609  error(IO.mapStringZ(Record.Name, "Name"));
610 
611  return Error::success();
612 }
613 
615  DataMemberRecord &Record) {
616  std::string Attrs = getMemberAttributes(
618  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
619  error(IO.mapInteger(Record.Type, "Type"));
620  error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
621  error(IO.mapStringZ(Record.Name, "Name"));
622 
623  return Error::success();
624 }
625 
627  OverloadedMethodRecord &Record) {
628  error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
629  error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
630  error(IO.mapStringZ(Record.Name, "Name"));
631 
632  return Error::success();
633 }
634 
636  OneMethodRecord &Record) {
637  const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
638  MapOneMethodRecord Mapper(IsFromOverloadList);
639  return Mapper(IO, Record);
640 }
641 
643  NestedTypeRecord &Record) {
644  uint16_t Padding = 0;
645  error(IO.mapInteger(Padding, "Padding"));
646  error(IO.mapInteger(Record.Type, "Type"));
647  error(IO.mapStringZ(Record.Name, "Name"));
648 
649  return Error::success();
650 }
651 
653  StaticDataMemberRecord &Record) {
654 
655  std::string Attrs = getMemberAttributes(
657  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
658  error(IO.mapInteger(Record.Type, "Type"));
659  error(IO.mapStringZ(Record.Name, "Name"));
660 
661  return Error::success();
662 }
663 
665  VirtualBaseClassRecord &Record) {
666 
667  std::string Attrs = getMemberAttributes(
669  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
670  error(IO.mapInteger(Record.BaseType, "BaseType"));
671  error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
672  error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
673  error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));
674 
675  return Error::success();
676 }
677 
679  VFPtrRecord &Record) {
680  uint16_t Padding = 0;
681  error(IO.mapInteger(Padding, "Padding"));
682  error(IO.mapInteger(Record.Type, "Type"));
683 
684  return Error::success();
685 }
686 
688  ListContinuationRecord &Record) {
689  uint16_t Padding = 0;
690  error(IO.mapInteger(Padding, "Padding"));
691  error(IO.mapInteger(Record.ContinuationIndex, "ContinuationIndex"));
692 
693  return Error::success();
694 }
695 
697  PrecompRecord &Precomp) {
698  error(IO.mapInteger(Precomp.StartTypeIndex, "StartIndex"));
699  error(IO.mapInteger(Precomp.TypesCount, "Count"));
700  error(IO.mapInteger(Precomp.Signature, "Signature"));
701  error(IO.mapStringZ(Precomp.PrecompFilePath, "PrecompFile"));
702  return Error::success();
703 }
704 
706  EndPrecompRecord &EndPrecomp) {
707  error(IO.mapInteger(EndPrecomp.Signature, "Signature"));
708  return Error::success();
709 }
MemberAccess getAccess() const
Definition: TypeRecord.h:846
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with only the first N elements remaining.
Definition: StringRef.h:601
Kind kind() const
Definition: CVRecord.h:43
This class represents lattice values for constants.
Definition: AllocatorList.h:23
ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()
Definition: EnumTables.cpp:532
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:33
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
bool isRValueReferenceThisPtr() const
Definition: TypeRecord.h:349
void push_back(const T &Elt)
Definition: SmallVector.h:211
StringRef Name
Definition: ScopedPrinter.h:24
MemberAccess getAccess() const
Definition: TypeRecord.h:741
#define error(X)
ArrayRef< uint8_t > Data
Definition: TypeRecord.h:397
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
Definition: EnumTables.cpp:504
MethodKind getMethodKind() const
Definition: TypeRecord.h:739
Error visitMemberEnd(CVMemberRecord &Record) override
bool isLValueReferenceThisPtr() const
Definition: TypeRecord.h:345
bool hasUniqueName() const
Definition: TypeRecord.h:436
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:450
Error visitTypeEnd(CVType &Record) override
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()
Definition: EnumTables.cpp:520
std::string itostr(int64_t X)
Definition: StringExtras.h:238
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
PointerMode getMode() const
Definition: TypeRecord.h:310
A 32-bit type reference.
Definition: TypeIndex.h:95
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
uint32_t length() const
Definition: CVRecord.h:41
std::vector< TypeIndex > StringIndices
Definition: TypeRecord.h:265
MemberAccess getAccess() const
Definition: TypeRecord.h:802
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition: CodeView.h:268
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:131
ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()
Definition: EnumTables.cpp:544
static StringRef getLeafTypeName(TypeLeafKind LT)
ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
Definition: EnumTables.cpp:528
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
static Error visitKnownMember(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
Optional< MemberPointerInfo > MemberInfo
Definition: TypeRecord.h:355
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
Definition: TypeRecord.h:920
std::vector< TypeIndex > ArgIndices
Definition: TypeRecord.h:251
For method overload sets. LF_METHOD.
Definition: TypeRecord.h:770
MethodOptions getOptions() const
Definition: TypeRecord.h:740
PointerKind getPointerKind() const
Definition: TypeRecord.h:305
std::vector< StringRef > MethodNames
Definition: TypeRecord.h:721
ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
Definition: EnumTables.cpp:512
ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
Definition: EnumTables.cpp:540
ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
Definition: EnumTables.cpp:524
static constexpr uint32_t ContinuationLength
Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
uint32_t getIndex() const
Definition: TypeIndex.h:110
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1095
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)
CallingConvention CallConv
Definition: TypeRecord.h:169
MemberAccess getAccess() const
Definition: TypeRecord.h:880
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition: CodeView.h:279
Error mapStringZ(StringRef &Value, const Twine &Comment="")
std::vector< OneMethodRecord > Methods
Definition: TypeRecord.h:766
ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
Definition: EnumTables.cpp:508
ArrayRef< EnumEntry< uint16_t > > getMemberKindNames()
Definition: EnumTables.cpp:516
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
uint32_t Size
Definition: Profile.cpp:46
MemberAccess
Source-level access specifier. (CV_access_e)
Definition: CodeView.h:260
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< VFTableSlotKind > Slots
Definition: TypeRecord.h:576
ArrayRef< VFTableSlotKind > getSlots() const
Definition: TypeRecord.h:567
LLVM Value Representation.
Definition: Value.h:74
LLVM_NODISCARD StringRef drop_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the last N elements dropped.
Definition: StringRef.h:642
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
Definition: EnumTables.cpp:536
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:83
SmallVector< TypeIndex, MaxArgs > ArgIndices
Definition: TypeRecord.h:692
Error visitMemberBegin(CVMemberRecord &Record) override
PointerToMemberRepresentation Representation
Definition: TypeRecord.h:120
std::string utohexstr(uint64_t X, bool LowerCase=false)
Definition: StringExtras.h:124