LLVM  14.0.0git
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"
11 #include "llvm/ADT/Twine.h"
13 #include "llvm/Support/MD5.h"
14 
15 using namespace llvm;
16 using namespace llvm::codeview;
17 
18 namespace {
19 
20 #define error(X) \
21  if (auto EC = X) \
22  return EC;
23 
24 static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
25 #define CV_TYPE(enum, val) {#enum, enum},
26 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
27 };
28 
30  switch (LT) {
31 #define TYPE_RECORD(ename, value, name) \
32  case ename: \
33  return #name;
34 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
35  default:
36  break;
37  }
38  return "UnknownLeaf";
39 }
40 
41 template <typename T>
42 static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
43  return lhs.Name < rhs.Name;
44 }
45 
46 template <typename T, typename TFlag>
47 static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
48  ArrayRef<EnumEntry<TFlag>> Flags) {
49  if (!IO.isStreaming())
50  return std::string("");
51  typedef EnumEntry<TFlag> FlagEntry;
52  typedef SmallVector<FlagEntry, 10> FlagVector;
53  FlagVector SetFlags;
54  for (const auto &Flag : Flags) {
55  if (Flag.Value == 0)
56  continue;
57  if ((Value & Flag.Value) == Flag.Value) {
58  SetFlags.push_back(Flag);
59  }
60  }
61 
62  llvm::sort(SetFlags, &compEnumNames<TFlag>);
63 
64  std::string FlagLabel;
65  bool FirstOcc = true;
66  for (const auto &Flag : SetFlags) {
67  if (FirstOcc)
68  FirstOcc = false;
69  else
70  FlagLabel += (" | ");
71 
72  FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
73  }
74 
75  if (!FlagLabel.empty()) {
76  std::string LabelWithBraces(" ( ");
77  LabelWithBraces += FlagLabel + " )";
78  return LabelWithBraces;
79  } else
80  return FlagLabel;
81 }
82 
83 template <typename T, typename TEnum>
84 static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
85  ArrayRef<EnumEntry<TEnum>> EnumValues) {
86  if (!IO.isStreaming())
87  return "";
89  for (const auto &EnumItem : EnumValues) {
90  if (EnumItem.Value == Value) {
91  Name = EnumItem.Name;
92  break;
93  }
94  }
95 
96  return Name;
97 }
98 
99 static std::string getMemberAttributes(CodeViewRecordIO &IO,
100  MemberAccess Access, MethodKind Kind,
102  if (!IO.isStreaming())
103  return "";
104  std::string AccessSpecifier = std::string(
105  getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())));
106  std::string MemberAttrs(AccessSpecifier);
107  if (Kind != MethodKind::Vanilla) {
108  std::string MethodKind = std::string(
109  getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())));
110  MemberAttrs += ", " + MethodKind;
111  }
112  if (Options != MethodOptions::None) {
113  std::string MethodOptions = getFlagNames(
114  IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
115  MemberAttrs += ", " + MethodOptions;
116  }
117  return MemberAttrs;
118 }
119 
120 struct MapOneMethodRecord {
121  explicit MapOneMethodRecord(bool IsFromOverloadList)
122  : IsFromOverloadList(IsFromOverloadList) {}
123 
124  Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
125  std::string Attrs = getMemberAttributes(
126  IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
127  error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
128  if (IsFromOverloadList) {
129  uint16_t Padding = 0;
130  error(IO.mapInteger(Padding));
131  }
132  error(IO.mapInteger(Method.Type, "Type"));
133  if (Method.isIntroducingVirtual()) {
134  error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
135  } else if (IO.isReading())
136  Method.VFTableOffset = -1;
137 
138  if (!IsFromOverloadList)
139  error(IO.mapStringZ(Method.Name, "Name"));
140 
141  return Error::success();
142  }
143 
144 private:
145  bool IsFromOverloadList;
146 };
147 } // namespace
148 
149 // Computes a string representation of a hash of the specified name, suitable
150 // for use when emitting CodeView type names.
152  SmallString<32> &StringifiedHash) {
153  llvm::MD5 Hash;
154  llvm::MD5::MD5Result Result;
155  Hash.update(Name);
156  Hash.final(Result);
157  Hash.stringifyResult(Result, StringifiedHash);
158 }
159 
161  StringRef &UniqueName, bool HasUniqueName) {
162  if (IO.isWriting()) {
163  // Try to be smart about what we write here. We can't write anything too
164  // large, so if we're going to go over the limit, replace lengthy names with
165  // a stringified hash value.
166  size_t BytesLeft = IO.maxFieldLength();
167  if (HasUniqueName) {
168  size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
169  if (BytesNeeded > BytesLeft) {
170  // The minimum space required for emitting hashes of both names.
171  assert(BytesLeft >= 70);
172 
173  // Replace the entire unique name with a hash of the unique name.
174  SmallString<32> Hash;
175  computeHashString(UniqueName, Hash);
176  std::string UniqueB = Twine("??@" + Hash + "@").str();
177  assert(UniqueB.size() == 36);
178 
179  // Truncate the name if necessary and append a hash of the name.
180  // The name length, hash included, is limited to 4096 bytes.
181  const size_t MaxTakeN = 4096;
182  size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;
183  computeHashString(Name, Hash);
184  std::string NameB = (Name.take_front(TakeN) + Hash).str();
185 
186  StringRef N = NameB;
187  StringRef U = UniqueB;
188  error(IO.mapStringZ(N));
189  error(IO.mapStringZ(U));
190  } else {
191  error(IO.mapStringZ(Name));
192  error(IO.mapStringZ(UniqueName));
193  }
194  } else {
195  // Cap the length of the string at however many bytes we have available,
196  // plus one for the required null terminator.
197  auto N = StringRef(Name).take_front(BytesLeft - 1);
198  error(IO.mapStringZ(N));
199  }
200  } else {
201  // Reading & Streaming mode come after writing mode is executed for each
202  // record. Truncating large names are done during writing, so its not
203  // necessary to do it while reading or streaming.
204  error(IO.mapStringZ(Name, "Name"));
205  if (HasUniqueName)
206  error(IO.mapStringZ(UniqueName, "LinkageName"));
207  }
208 
209  return Error::success();
210 }
211 
213  assert(!TypeKind.hasValue() && "Already in a type mapping!");
214  assert(!MemberKind.hasValue() && "Already in a member mapping!");
215 
216  // FieldList and MethodList records can be any length because they can be
217  // split with continuation records. All other record types cannot be
218  // longer than the maximum record length.
219  Optional<uint32_t> MaxLen;
220  if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
221  CVR.kind() != TypeLeafKind::LF_METHODLIST)
222  MaxLen = MaxRecordLength - sizeof(RecordPrefix);
223  error(IO.beginRecord(MaxLen));
224  TypeKind = CVR.kind();
225 
226  if (IO.isStreaming()) {
227  auto RecordKind = CVR.kind();
228  uint16_t RecordLen = CVR.length() - 2;
229  std::string RecordKindName = std::string(
230  getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)));
231  error(IO.mapInteger(RecordLen, "Record length"));
232  error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
233  }
234  return Error::success();
235 }
236 
238  if (IO.isStreaming())
239  IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
240  utohexstr(Index.getIndex()) + ")");
241  return visitTypeBegin(CVR);
242 }
243 
245  assert(TypeKind.hasValue() && "Not in a type mapping!");
246  assert(!MemberKind.hasValue() && "Still in a member mapping!");
247 
248  error(IO.endRecord());
249 
250  TypeKind.reset();
251  return Error::success();
252 }
253 
255  assert(TypeKind.hasValue() && "Not in a type mapping!");
256  assert(!MemberKind.hasValue() && "Already in a member mapping!");
257 
258  // The largest possible subrecord is one in which there is a record prefix,
259  // followed by the subrecord, followed by a continuation, and that entire
260  // sequence spawns `MaxRecordLength` bytes. So the record's length is
261  // calculated as follows.
262 
263  constexpr uint32_t ContinuationLength = 8;
266 
267  MemberKind = Record.Kind;
268  if (IO.isStreaming()) {
269  std::string MemberKindName = std::string(getLeafTypeName(Record.Kind));
270  MemberKindName +=
271  " ( " +
272  (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
273  .str() +
274  " )";
275  error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
276  }
277  return Error::success();
278 }
279 
281  assert(TypeKind.hasValue() && "Not in a type mapping!");
282  assert(MemberKind.hasValue() && "Not in a member mapping!");
283 
284  if (IO.isReading()) {
285  if (auto EC = IO.skipPadding())
286  return EC;
287  }
288 
289  MemberKind.reset();
290  error(IO.endRecord());
291  return Error::success();
292 }
293 
295  std::string ModifierNames =
296  getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
298  error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
299  error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
300  return Error::success();
301 }
302 
305  std::string CallingConvName = std::string(getEnumName(
306  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
307  std::string FuncOptionNames =
308  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
310  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
311  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
312  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
313  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
314  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
315 
316  return Error::success();
317 }
318 
321  std::string CallingConvName = std::string(getEnumName(
322  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
323  std::string FuncOptionNames =
324  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
326  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
327  error(IO.mapInteger(Record.ClassType, "ClassType"));
328  error(IO.mapInteger(Record.ThisType, "ThisType"));
329  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
330  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
331  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
332  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
333  error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
334 
335  return Error::success();
336 }
337 
340  Record.ArgIndices,
341  [](CodeViewRecordIO &IO, TypeIndex &N) {
342  return IO.mapInteger(N, "Argument");
343  },
344  "NumArgs"));
345  return Error::success();
346 }
347 
351  Record.StringIndices,
352  [](CodeViewRecordIO &IO, TypeIndex &N) {
353  return IO.mapInteger(N, "Strings");
354  },
355  "NumStrings"));
356 
357  return Error::success();
358 }
359 
361 
362  SmallString<128> Attr("Attrs: ");
363 
364  if (IO.isStreaming()) {
365  std::string PtrType =
366  std::string(getEnumName(IO, unsigned(Record.getPointerKind()),
368  Attr += "[ Type: " + PtrType;
369 
370  std::string PtrMode = std::string(getEnumName(
371  IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames())));
372  Attr += ", Mode: " + PtrMode;
373 
374  auto PtrSizeOf = Record.getSize();
375  Attr += ", SizeOf: " + itostr(PtrSizeOf);
376 
377  if (Record.isFlat())
378  Attr += ", isFlat";
379  if (Record.isConst())
380  Attr += ", isConst";
381  if (Record.isVolatile())
382  Attr += ", isVolatile";
383  if (Record.isUnaligned())
384  Attr += ", isUnaligned";
385  if (Record.isRestrict())
386  Attr += ", isRestricted";
387  if (Record.isLValueReferenceThisPtr())
388  Attr += ", isThisPtr&";
389  if (Record.isRValueReferenceThisPtr())
390  Attr += ", isThisPtr&&";
391  Attr += " ]";
392  }
393 
394  error(IO.mapInteger(Record.ReferentType, "PointeeType"));
395  error(IO.mapInteger(Record.Attrs, Attr));
396 
397  if (Record.isPointerToMember()) {
398  if (IO.isReading())
399  Record.MemberInfo.emplace();
400 
401  MemberPointerInfo &M = *Record.MemberInfo;
402  error(IO.mapInteger(M.ContainingType, "ClassType"));
403  std::string PtrMemberGetRepresentation = std::string(getEnumName(
404  IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())));
405  error(IO.mapEnum(M.Representation,
406  "Representation: " + PtrMemberGetRepresentation));
407  }
408 
409  return Error::success();
410 }
411 
413  error(IO.mapInteger(Record.ElementType, "ElementType"));
414  error(IO.mapInteger(Record.IndexType, "IndexType"));
415  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
416  error(IO.mapStringZ(Record.Name, "Name"));
417 
418  return Error::success();
419 }
420 
422  assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
423  (CVR.kind() == TypeLeafKind::LF_CLASS) ||
424  (CVR.kind() == TypeLeafKind::LF_INTERFACE));
425 
426  std::string PropertiesNames =
427  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
429  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
430  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
431  error(IO.mapInteger(Record.FieldList, "FieldList"));
432  error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
433  error(IO.mapInteger(Record.VTableShape, "VShape"));
434  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
435  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
436  Record.hasUniqueName()));
437 
438  return Error::success();
439 }
440 
442  std::string PropertiesNames =
443  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
445  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
446  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
447  error(IO.mapInteger(Record.FieldList, "FieldList"));
448  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
449  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
450  Record.hasUniqueName()));
451 
452  return Error::success();
453 }
454 
456  std::string PropertiesNames =
457  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
459  error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
460  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
461  error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
462  error(IO.mapInteger(Record.FieldList, "FieldListType"));
463  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
464  Record.hasUniqueName()));
465 
466  return Error::success();
467 }
468 
470  error(IO.mapInteger(Record.Type, "Type"));
471  error(IO.mapInteger(Record.BitSize, "BitSize"));
472  error(IO.mapInteger(Record.BitOffset, "BitOffset"));
473 
474  return Error::success();
475 }
476 
479  uint16_t Size;
480  if (!IO.isReading()) {
481  ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
482  Size = Slots.size();
483  error(IO.mapInteger(Size, "VFEntryCount"));
484 
485  for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
486  uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
487  if ((SlotIndex + 1) < Slots.size()) {
488  Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
489  }
490  error(IO.mapInteger(Byte));
491  }
492  } else {
493  error(IO.mapInteger(Size));
494  for (uint16_t I = 0; I < Size; I += 2) {
495  uint8_t Byte;
496  error(IO.mapInteger(Byte));
497  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
498  if ((I + 1) < Size)
499  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
500  }
501  }
502 
503  return Error::success();
504 }
505 
507  error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
508  error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
509  error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
510  uint32_t NamesLen = 0;
511  if (!IO.isReading()) {
512  for (auto Name : Record.MethodNames)
513  NamesLen += Name.size() + 1;
514  }
515  error(IO.mapInteger(NamesLen));
516  error(IO.mapVectorTail(
517  Record.MethodNames,
518  [](CodeViewRecordIO &IO, StringRef &S) {
519  return IO.mapStringZ(S, "MethodName");
520  },
521  "VFTableName"));
522 
523  return Error::success();
524 }
525 
527  error(IO.mapInteger(Record.Id, "Id"));
528  error(IO.mapStringZ(Record.String, "StringData"));
529 
530  return Error::success();
531 }
532 
535  error(IO.mapInteger(Record.UDT, "UDT"));
536  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
537  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
538 
539  return Error::success();
540 }
541 
544  error(IO.mapInteger(Record.UDT, "UDT"));
545  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
546  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
547  error(IO.mapInteger(Record.Module, "Module"));
548 
549  return Error::success();
550 }
551 
553  error(IO.mapInteger(Record.ParentScope, "ParentScope"));
554  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
555  error(IO.mapStringZ(Record.Name, "Name"));
556 
557  return Error::success();
558 }
559 
562  error(IO.mapInteger(Record.ClassType, "ClassType"));
563  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
564  error(IO.mapStringZ(Record.Name, "Name"));
565 
566  return Error::success();
567 }
568 
572  Record.ArgIndices,
573  [](CodeViewRecordIO &IO, TypeIndex &N) {
574  return IO.mapInteger(N, "Argument");
575  },
576  "NumArgs"));
577 
578  return Error::success();
579 }
580 
583  // TODO: Split the list into multiple records if it's longer than 64KB, using
584  // a subrecord of TypeRecordKind::Index to chain the records together.
585  error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true), "Method"));
586 
587  return Error::success();
588 }
589 
592  if (IO.isStreaming()) {
593  if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
594  return EC;
595  } else
596  error(IO.mapByteVectorTail(Record.Data));
597 
598  return Error::success();
599 }
600 
603  error(IO.mapGuid(Record.Guid, "Guid"));
604  error(IO.mapInteger(Record.Age, "Age"));
605  error(IO.mapStringZ(Record.Name, "Name"));
606  return Error::success();
607 }
608 
610  std::string ModeName = std::string(
611  getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())));
612  error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
613  return Error::success();
614 }
615 
618  std::string Attrs = getMemberAttributes(
620  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
621  error(IO.mapInteger(Record.Type, "BaseType"));
622  error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
623 
624  return Error::success();
625 }
626 
629  std::string Attrs = getMemberAttributes(
631  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
632 
633  // FIXME: Handle full APInt such as __int128.
634  error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
635  error(IO.mapStringZ(Record.Name, "Name"));
636 
637  return Error::success();
638 }
639 
642  std::string Attrs = getMemberAttributes(
644  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
645  error(IO.mapInteger(Record.Type, "Type"));
646  error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
647  error(IO.mapStringZ(Record.Name, "Name"));
648 
649  return Error::success();
650 }
651 
654  error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
655  error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
656  error(IO.mapStringZ(Record.Name, "Name"));
657 
658  return Error::success();
659 }
660 
663  const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
664  MapOneMethodRecord Mapper(IsFromOverloadList);
665  return Mapper(IO, Record);
666 }
667 
670  uint16_t Padding = 0;
671  error(IO.mapInteger(Padding, "Padding"));
672  error(IO.mapInteger(Record.Type, "Type"));
673  error(IO.mapStringZ(Record.Name, "Name"));
674 
675  return Error::success();
676 }
677 
680 
681  std::string Attrs = getMemberAttributes(
683  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
684  error(IO.mapInteger(Record.Type, "Type"));
685  error(IO.mapStringZ(Record.Name, "Name"));
686 
687  return Error::success();
688 }
689 
692 
693  std::string Attrs = getMemberAttributes(
695  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
696  error(IO.mapInteger(Record.BaseType, "BaseType"));
697  error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
698  error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
699  error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));
700 
701  return Error::success();
702 }
703 
705  VFPtrRecord &Record) {
706  uint16_t Padding = 0;
707  error(IO.mapInteger(Padding, "Padding"));
708  error(IO.mapInteger(Record.Type, "Type"));
709 
710  return Error::success();
711 }
712 
715  uint16_t Padding = 0;
716  error(IO.mapInteger(Padding, "Padding"));
717  error(IO.mapInteger(Record.ContinuationIndex, "ContinuationIndex"));
718 
719  return Error::success();
720 }
721 
723  PrecompRecord &Precomp) {
724  error(IO.mapInteger(Precomp.StartTypeIndex, "StartIndex"));
725  error(IO.mapInteger(Precomp.TypesCount, "Count"));
726  error(IO.mapInteger(Precomp.Signature, "Signature"));
727  error(IO.mapStringZ(Precomp.PrecompFilePath, "PrecompFile"));
728  return Error::success();
729 }
730 
732  EndPrecompRecord &EndPrecomp) {
733  error(IO.mapInteger(EndPrecomp.Signature, "Signature"));
734  return Error::success();
735 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::codeview::SimpleTypeKind::Byte
@ Byte
llvm::codeview::OneMethodRecord::Type
TypeIndex Type
Definition: TypeRecord.h:744
Attrs
Function Attrs
Definition: README_ALTIVEC.txt:215
llvm::codeview::MemberAccess
MemberAccess
Source-level access specifier. (CV_access_e)
Definition: CodeView.h:263
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::codeview::getMemberKindNames
ArrayRef< EnumEntry< uint16_t > > getMemberKindNames()
Definition: EnumTables.cpp:529
llvm::MD5::update
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:190
llvm::codeview::CodeViewRecordIO::isWriting
bool isWriting() const
Definition: CodeViewRecordIO.h:75
llvm::codeview::StringIdRecord
Definition: TypeRecord.h:594
llvm::MD5::stringifyResult
static void stringifyResult(MD5Result &Result, SmallString< 32 > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
Definition: MD5.cpp:290
llvm::codeview::NestedTypeRecord
Definition: TypeRecord.h:369
ContinuationLength
static constexpr uint32_t ContinuationLength
Definition: ContinuationRecordBuilder.cpp:37
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::codeview::CodeViewRecordIO::mapByteVectorTail
Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:100
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::codeview::PrecompRecord::TypesCount
uint32_t TypesCount
Definition: TypeRecord.h:939
llvm::codeview::CodeViewRecordIO::mapStringZ
Error mapStringZ(StringRef &Value, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:207
llvm::codeview::PrecompRecord::Signature
uint32_t Signature
Definition: TypeRecord.h:940
llvm::codeview::PrecompRecord
Definition: TypeRecord.h:928
llvm::codeview::VFTableShapeRecord
Definition: TypeRecord.h:552
llvm::codeview::MethodKind::Vanilla
@ Vanilla
llvm::codeview::BaseClassRecord
Definition: TypeRecord.h:863
llvm::codeview::getTypeModifierNames
ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()
Definition: EnumTables.cpp:545
llvm::Optional< uint32_t >
llvm::codeview::CodeViewRecordIO::mapEnum
Error mapEnum(T &Value, const Twine &Comment="")
Definition: CodeViewRecordIO.h:114
llvm::codeview::TypeRecordMapping::visitTypeEnd
Error visitTypeEnd(CVType &Record) override
Definition: TypeRecordMapping.cpp:244
visitKnownRecord
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
Definition: CVSymbolVisitor.cpp:21
llvm::codeview::PointerRecord
Definition: TypeRecord.h:263
llvm::codeview::RecordPrefix
Definition: RecordSerialization.h:33
llvm::codeview::DataMemberRecord
Definition: TypeRecord.h:783
llvm::codeview::OneMethodRecord::Attrs
MemberAttributes Attrs
Definition: TypeRecord.h:745
EnumTables.h
llvm::EnumEntry
Definition: ScopedPrinter.h:24
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:288
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::codeview::CodeViewRecordIO::beginRecord
Error beginRecord(Optional< uint32_t > MaxLength)
Definition: CodeViewRecordIO.cpp:18
llvm::codeview::visitMemberRecordStream
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
Definition: CVTypeVisitor.cpp:270
llvm::codeview::ArgListRecord
Definition: TypeRecord.h:235
llvm::codeview::getMethodOptionNames
ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
Definition: EnumTables.cpp:525
llvm::codeview::EnumRecord
Definition: TypeRecord.h:518
llvm::codeview::TypeRecordMapping::visitMemberEnd
Error visitMemberEnd(CVMemberRecord &Record) override
Definition: TypeRecordMapping.cpp:280
llvm::codeview::CVMemberRecord
Definition: TypeRecord.h:34
llvm::MD5::final
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:235
llvm::StringRef::take_front
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:620
MD5.h
llvm::codeview::CodeViewRecordIO
Definition: CodeViewRecordIO.h:43
Twine.h
llvm::codeview::BitFieldRecord
Definition: TypeRecord.h:534
llvm::codeview::MethodOverloadListRecord
Definition: TypeRecord.h:751
llvm::codeview::MethodKind
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition: CodeView.h:271
llvm::codeview::UdtModSourceLineRecord
Definition: TypeRecord.h:645
llvm::codeview::EndPrecompRecord::Signature
uint32_t Signature
Definition: TypeRecord.h:952
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:146
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::codeview::ListContinuationRecord
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
Definition: TypeRecord.h:914
llvm::codeview::getFunctionOptionEnum
ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
Definition: EnumTables.cpp:553
llvm::codeview::CodeViewRecordIO::emitRawComment
void emitRawComment(const Twine &T)
Definition: CodeViewRecordIO.h:213
llvm::EnumEntry::Name
StringRef Name
Definition: ScopedPrinter.h:25
llvm::codeview::ModifierRecord
Definition: TypeRecord.h:129
llvm::codeview::OverloadedMethodRecord
For method overload sets. LF_METHOD.
Definition: TypeRecord.h:764
llvm::SlotIndex
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:83
llvm::codeview::MethodOptions::None
@ None
llvm::codeview::CodeViewRecordIO::mapVectorN
Error mapVectorN(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Definition: CodeViewRecordIO.h:143
llvm::codeview::MemberFunctionRecord
Definition: TypeRecord.h:170
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::codeview::getPtrKindNames
ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()
Definition: EnumTables.cpp:533
llvm::codeview::getLabelTypeEnum
ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()
Definition: EnumTables.cpp:557
llvm::codeview::OneMethodRecord::isIntroducingVirtual
bool isIntroducingVirtual() const
Definition: TypeRecord.h:739
llvm::SmallString< 32 >
llvm::codeview::TypeRecordMapping::visitTypeBegin
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Definition: TypeRecordMapping.cpp:212
llvm::Twine::str
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
llvm::codeview::TypeRecordMapping::visitMemberBegin
Error visitMemberBegin(CVMemberRecord &Record) override
Definition: TypeRecordMapping.cpp:254
llvm::codeview::CodeViewRecordIO::skipPadding
Error skipPadding()
Definition: CodeViewRecordIO.cpp:85
llvm::codeview::TypeServer2Record
Definition: TypeRecord.h:574
llvm::codeview::MaxRecordLength
@ MaxRecordLength
Definition: RecordSerialization.h:31
llvm::codeview::EnumeratorRecord
Definition: TypeRecord.h:829
llvm::codeview::OneMethodRecord
Definition: TypeRecord.h:719
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::Optional::reset
void reset()
Definition: Optional.h:278
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:43
llvm::codeview::VirtualBaseClassRecord
Definition: TypeRecord.h:884
llvm::MD5
Definition: MD5.h:41
I
#define I(x, y, z)
Definition: MD5.cpp:59
TypeRecordMapping.h
StringExtras.h
llvm::codeview::getPtrModeNames
ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
Definition: EnumTables.cpp:537
llvm::codeview::PrecompRecord::PrecompFilePath
StringRef PrecompFilePath
Definition: TypeRecord.h:941
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::codeview::StaticDataMemberRecord
Definition: TypeRecord.h:808
llvm::codeview::CompileSym2Flags::EC
@ EC
getLeafTypeName
static StringRef getLeafTypeName(TypeLeafKind LT)
Definition: TypeDumpVisitor.cpp:149
llvm::codeview::getPtrMemberRepNames
ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
Definition: EnumTables.cpp:541
llvm::Record
Definition: Record.h:1472
llvm::codeview::getMemberAccessNames
ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
Definition: EnumTables.cpp:521
llvm::codeview::FuncIdRecord
Definition: TypeRecord.h:609
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::codeview::FieldListRecord
Definition: TypeRecord.h:384
llvm::codeview::OneMethodRecord::getMethodKind
MethodKind getMethodKind() const
Definition: TypeRecord.h:733
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::codeview::CodeViewRecordIO::isStreaming
bool isStreaming() const
Definition: CodeViewRecordIO.h:69
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::codeview::CVRecord< TypeLeafKind >
llvm::codeview::OneMethodRecord::getAccess
MemberAccess getAccess() const
Definition: TypeRecord.h:735
llvm::codeview::VFTableSlotKind
VFTableSlotKind
Definition: CodeView.h:386
llvm::codeview::UdtSourceLineRecord
Definition: TypeRecord.h:627
uint32_t
llvm::codeview::VFTableRecord
Definition: TypeRecord.h:690
llvm::codeview::CodeViewRecordIO::mapInteger
Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:127
llvm::codeview::CodeViewRecordIO::maxFieldLength
uint32_t maxFieldLength() const
Definition: CodeViewRecordIO.cpp:57
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::codeview::ProcedureRecord
Definition: TypeRecord.h:145
llvm::MD5::MD5Result
Definition: MD5.h:43
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::codeview::CodeViewRecordIO::mapEncodedInteger
Error mapEncodedInteger(int64_t &Value, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:148
uint16_t
LeafTypeNames
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
Definition: TypeDumpVisitor.cpp:23
llvm::codeview::CodeViewRecordIO::endRecord
Error endRecord()
Definition: CodeViewRecordIO.cpp:26
llvm::codeview::UnionRecord
Definition: TypeRecord.h:497
computeHashString
static void computeHashString(StringRef Name, SmallString< 32 > &StringifiedHash)
Definition: TypeRecordMapping.cpp:151
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::codeview::OneMethodRecord::VFTableOffset
int32_t VFTableOffset
Definition: TypeRecord.h:746
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1488
visitKnownMember
static Error visitKnownMember(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks)
Definition: CVTypeVisitor.cpp:33
mapNameAndUniqueName
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)
Definition: TypeRecordMapping.cpp:160
llvm::codeview::MemberAttributes::Attrs
uint16_t Attrs
Definition: TypeRecord.h:41
llvm::codeview::VFPtrRecord
Definition: TypeRecord.h:850
llvm::codeview::BuildInfoRecord
Definition: TypeRecord.h:666
llvm::codeview::MemberFuncIdRecord
Definition: TypeRecord.h:216
llvm::codeview::TypeLeafKind
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:33
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:476
llvm::codeview::CodeViewRecordIO::isReading
bool isReading() const
Definition: CodeViewRecordIO.h:72
llvm::codeview::StringListRecord
Definition: TypeRecord.h:249
llvm::codeview::ArrayRecord
Definition: TypeRecord.h:395
N
#define N
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::codeview::LabelRecord
Definition: TypeRecord.h:205
llvm::codeview::ClassOptions::HasUniqueName
@ HasUniqueName
llvm::codeview::OneMethodRecord::getOptions
MethodOptions getOptions() const
Definition: TypeRecord.h:734
llvm::codeview::getCallingConventions
ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
Definition: EnumTables.cpp:549
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:95
llvm::codeview::CodeViewRecordIO::mapGuid
Error mapGuid(GUID &Guid, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:225
llvm::codeview::ClassRecord
Definition: TypeRecord.h:464
llvm::codeview::getClassOptionNames
ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
Definition: EnumTables.cpp:517
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::codeview::MemberPointerInfo
Definition: TypeRecord.h:100
llvm::codeview::EndPrecompRecord
Definition: TypeRecord.h:945
llvm::codeview::CodeViewRecordIO::mapVectorTail
Error mapVectorTail(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Definition: CodeViewRecordIO.h:180
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::codeview::OneMethodRecord::Name
StringRef Name
Definition: TypeRecord.h:747
error
#define error(X)
Definition: TypeRecordMapping.cpp:20
llvm::codeview::PrecompRecord::StartTypeIndex
uint32_t StartTypeIndex
Definition: TypeRecord.h:938
llvm::codeview::MethodOptions
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition: CodeView.h:282
llvm::codeview::CVRecord::length
uint32_t length() const
Definition: CVRecord.h:41