LLVM  16.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 
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/MD5.h"
25 
26 #include <algorithm>
27 #include <cassert>
28 #include <cstddef>
29 #include <cstdint>
30 #include <string>
31 #include <vector>
32 
33 using namespace llvm;
34 using namespace llvm::codeview;
35 
36 namespace {
37 
38 #define error(X) \
39  do { \
40  if (auto EC = X) \
41  return EC; \
42  } while (false)
43 
44 static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
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 
61 template <typename T>
62 static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
63  return lhs.Name < rhs.Name;
64 }
65 
66 template <typename T, typename TFlag>
67 static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
68  ArrayRef<EnumEntry<TFlag>> Flags) {
69  if (!IO.isStreaming())
70  return std::string("");
72  typedef SmallVector<FlagEntry, 10> FlagVector;
73  FlagVector SetFlags;
74  for (const auto &Flag : Flags) {
75  if (Flag.Value == 0)
76  continue;
77  if ((Value & Flag.Value) == Flag.Value) {
78  SetFlags.push_back(Flag);
79  }
80  }
81 
82  llvm::sort(SetFlags, &compEnumNames<TFlag>);
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 
103 template <typename T, typename TEnum>
104 static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
105  ArrayRef<EnumEntry<TEnum>> EnumValues) {
106  if (!IO.isStreaming())
107  return "";
108  StringRef Name;
109  for (const auto &EnumItem : EnumValues) {
110  if (EnumItem.Value == Value) {
111  Name = EnumItem.Name;
112  break;
113  }
114  }
115 
116  return Name;
117 }
118 
119 static std::string getMemberAttributes(CodeViewRecordIO &IO,
120  MemberAccess Access, MethodKind Kind,
122  if (!IO.isStreaming())
123  return "";
124  std::string AccessSpecifier = std::string(
125  getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())));
126  std::string MemberAttrs(AccessSpecifier);
127  if (Kind != MethodKind::Vanilla) {
128  std::string MethodKind = std::string(
129  getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())));
130  MemberAttrs += ", " + MethodKind;
131  }
132  if (Options != MethodOptions::None) {
133  std::string MethodOptions = getFlagNames(
134  IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
135  MemberAttrs += ", " + MethodOptions;
136  }
137  return MemberAttrs;
138 }
139 
140 struct MapOneMethodRecord {
141  explicit MapOneMethodRecord(bool IsFromOverloadList)
142  : IsFromOverloadList(IsFromOverloadList) {}
143 
144  Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
145  std::string Attrs = getMemberAttributes(
146  IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
147  error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
148  if (IsFromOverloadList) {
149  uint16_t Padding = 0;
150  error(IO.mapInteger(Padding));
151  }
152  error(IO.mapInteger(Method.Type, "Type"));
153  if (Method.isIntroducingVirtual()) {
154  error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
155  } else if (IO.isReading())
156  Method.VFTableOffset = -1;
157 
158  if (!IsFromOverloadList)
159  error(IO.mapStringZ(Method.Name, "Name"));
160 
161  return Error::success();
162  }
163 
164 private:
165  bool IsFromOverloadList;
166 };
167 } // namespace
168 
169 // Computes a string representation of a hash of the specified name, suitable
170 // for use when emitting CodeView type names.
172  SmallString<32> &StringifiedHash) {
173  llvm::MD5 Hash;
174  llvm::MD5::MD5Result Result;
175  Hash.update(Name);
176  Hash.final(Result);
177  Hash.stringifyResult(Result, StringifiedHash);
178 }
179 
181  StringRef &UniqueName, bool HasUniqueName) {
182  if (IO.isWriting()) {
183  // Try to be smart about what we write here. We can't write anything too
184  // large, so if we're going to go over the limit, replace lengthy names with
185  // a stringified hash value.
186  size_t BytesLeft = IO.maxFieldLength();
187  if (HasUniqueName) {
188  size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
189  if (BytesNeeded > BytesLeft) {
190  // The minimum space required for emitting hashes of both names.
191  assert(BytesLeft >= 70);
192 
193  // Replace the entire unique name with a hash of the unique name.
194  SmallString<32> Hash;
195  computeHashString(UniqueName, Hash);
196  std::string UniqueB = Twine("??@" + Hash + "@").str();
197  assert(UniqueB.size() == 36);
198 
199  // Truncate the name if necessary and append a hash of the name.
200  // The name length, hash included, is limited to 4096 bytes.
201  const size_t MaxTakeN = 4096;
202  size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;
203  computeHashString(Name, Hash);
204  std::string NameB = (Name.take_front(TakeN) + Hash).str();
205 
206  StringRef N = NameB;
207  StringRef U = UniqueB;
208  error(IO.mapStringZ(N));
209  error(IO.mapStringZ(U));
210  } else {
211  error(IO.mapStringZ(Name));
212  error(IO.mapStringZ(UniqueName));
213  }
214  } else {
215  // Cap the length of the string at however many bytes we have available,
216  // plus one for the required null terminator.
217  auto N = StringRef(Name).take_front(BytesLeft - 1);
218  error(IO.mapStringZ(N));
219  }
220  } else {
221  // Reading & Streaming mode come after writing mode is executed for each
222  // record. Truncating large names are done during writing, so its not
223  // necessary to do it while reading or streaming.
224  error(IO.mapStringZ(Name, "Name"));
225  if (HasUniqueName)
226  error(IO.mapStringZ(UniqueName, "LinkageName"));
227  }
228 
229  return Error::success();
230 }
231 
233  assert(!TypeKind && "Already in a type mapping!");
234  assert(!MemberKind && "Already in a member mapping!");
235 
236  // FieldList and MethodList records can be any length because they can be
237  // split with continuation records. All other record types cannot be
238  // longer than the maximum record length.
239  Optional<uint32_t> MaxLen;
240  if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
241  CVR.kind() != TypeLeafKind::LF_METHODLIST)
242  MaxLen = MaxRecordLength - sizeof(RecordPrefix);
243  error(IO.beginRecord(MaxLen));
244  TypeKind = CVR.kind();
245 
246  if (IO.isStreaming()) {
247  auto RecordKind = CVR.kind();
248  uint16_t RecordLen = CVR.length() - 2;
249  std::string RecordKindName = std::string(
250  getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)));
251  error(IO.mapInteger(RecordLen, "Record length"));
252  error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
253  }
254  return Error::success();
255 }
256 
258  if (IO.isStreaming())
259  IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
260  utohexstr(Index.getIndex()) + ")");
261  return visitTypeBegin(CVR);
262 }
263 
265  assert(TypeKind && "Not in a type mapping!");
266  assert(!MemberKind && "Still in a member mapping!");
267 
268  error(IO.endRecord());
269 
270  TypeKind.reset();
271  return Error::success();
272 }
273 
275  assert(TypeKind && "Not in a type mapping!");
276  assert(!MemberKind && "Already in a member mapping!");
277 
278  // The largest possible subrecord is one in which there is a record prefix,
279  // followed by the subrecord, followed by a continuation, and that entire
280  // sequence spawns `MaxRecordLength` bytes. So the record's length is
281  // calculated as follows.
282 
283  constexpr uint32_t ContinuationLength = 8;
286 
287  MemberKind = Record.Kind;
288  if (IO.isStreaming()) {
289  std::string MemberKindName = std::string(getLeafTypeName(Record.Kind));
290  MemberKindName +=
291  " ( " +
292  (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
293  .str() +
294  " )";
295  error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
296  }
297  return Error::success();
298 }
299 
301  assert(TypeKind && "Not in a type mapping!");
302  assert(MemberKind && "Not in a member mapping!");
303 
304  if (IO.isReading()) {
305  if (auto EC = IO.skipPadding())
306  return EC;
307  }
308 
309  MemberKind.reset();
310  error(IO.endRecord());
311  return Error::success();
312 }
313 
315  std::string ModifierNames =
316  getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
318  error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
319  error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
320  return Error::success();
321 }
322 
325  std::string CallingConvName = std::string(getEnumName(
326  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
327  std::string FuncOptionNames =
328  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
330  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
331  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
332  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
333  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
334  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
335 
336  return Error::success();
337 }
338 
341  std::string CallingConvName = std::string(getEnumName(
342  IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
343  std::string FuncOptionNames =
344  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
346  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
347  error(IO.mapInteger(Record.ClassType, "ClassType"));
348  error(IO.mapInteger(Record.ThisType, "ThisType"));
349  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
350  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
351  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
352  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
353  error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
354 
355  return Error::success();
356 }
357 
360  Record.ArgIndices,
361  [](CodeViewRecordIO &IO, TypeIndex &N) {
362  return IO.mapInteger(N, "Argument");
363  },
364  "NumArgs"));
365  return Error::success();
366 }
367 
371  Record.StringIndices,
372  [](CodeViewRecordIO &IO, TypeIndex &N) {
373  return IO.mapInteger(N, "Strings");
374  },
375  "NumStrings"));
376 
377  return Error::success();
378 }
379 
381 
382  SmallString<128> Attr("Attrs: ");
383 
384  if (IO.isStreaming()) {
385  std::string PtrType =
386  std::string(getEnumName(IO, unsigned(Record.getPointerKind()),
388  Attr += "[ Type: " + PtrType;
389 
390  std::string PtrMode = std::string(getEnumName(
391  IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames())));
392  Attr += ", Mode: " + PtrMode;
393 
394  auto PtrSizeOf = Record.getSize();
395  Attr += ", SizeOf: " + itostr(PtrSizeOf);
396 
397  if (Record.isFlat())
398  Attr += ", isFlat";
399  if (Record.isConst())
400  Attr += ", isConst";
401  if (Record.isVolatile())
402  Attr += ", isVolatile";
403  if (Record.isUnaligned())
404  Attr += ", isUnaligned";
405  if (Record.isRestrict())
406  Attr += ", isRestricted";
407  if (Record.isLValueReferenceThisPtr())
408  Attr += ", isThisPtr&";
409  if (Record.isRValueReferenceThisPtr())
410  Attr += ", isThisPtr&&";
411  Attr += " ]";
412  }
413 
414  error(IO.mapInteger(Record.ReferentType, "PointeeType"));
415  error(IO.mapInteger(Record.Attrs, Attr));
416 
417  if (Record.isPointerToMember()) {
418  if (IO.isReading())
419  Record.MemberInfo.emplace();
420 
421  MemberPointerInfo &M = *Record.MemberInfo;
422  error(IO.mapInteger(M.ContainingType, "ClassType"));
423  std::string PtrMemberGetRepresentation = std::string(getEnumName(
424  IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())));
425  error(IO.mapEnum(M.Representation,
426  "Representation: " + PtrMemberGetRepresentation));
427  }
428 
429  return Error::success();
430 }
431 
433  error(IO.mapInteger(Record.ElementType, "ElementType"));
434  error(IO.mapInteger(Record.IndexType, "IndexType"));
435  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
436  error(IO.mapStringZ(Record.Name, "Name"));
437 
438  return Error::success();
439 }
440 
442  assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
443  (CVR.kind() == TypeLeafKind::LF_CLASS) ||
444  (CVR.kind() == TypeLeafKind::LF_INTERFACE));
445 
446  std::string PropertiesNames =
447  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
449  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
450  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
451  error(IO.mapInteger(Record.FieldList, "FieldList"));
452  error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
453  error(IO.mapInteger(Record.VTableShape, "VShape"));
454  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
455  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
456  Record.hasUniqueName()));
457 
458  return Error::success();
459 }
460 
462  std::string PropertiesNames =
463  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
465  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
466  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
467  error(IO.mapInteger(Record.FieldList, "FieldList"));
468  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
469  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
470  Record.hasUniqueName()));
471 
472  return Error::success();
473 }
474 
476  std::string PropertiesNames =
477  getFlagNames(IO, static_cast<uint16_t>(Record.Options),
479  error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
480  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
481  error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
482  error(IO.mapInteger(Record.FieldList, "FieldListType"));
483  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
484  Record.hasUniqueName()));
485 
486  return Error::success();
487 }
488 
490  error(IO.mapInteger(Record.Type, "Type"));
491  error(IO.mapInteger(Record.BitSize, "BitSize"));
492  error(IO.mapInteger(Record.BitOffset, "BitOffset"));
493 
494  return Error::success();
495 }
496 
499  uint16_t Size;
500  if (!IO.isReading()) {
501  ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
502  Size = Slots.size();
503  error(IO.mapInteger(Size, "VFEntryCount"));
504 
505  for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
506  uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
507  if ((SlotIndex + 1) < Slots.size()) {
508  Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
509  }
510  error(IO.mapInteger(Byte));
511  }
512  } else {
513  error(IO.mapInteger(Size));
514  for (uint16_t I = 0; I < Size; I += 2) {
515  uint8_t Byte;
516  error(IO.mapInteger(Byte));
517  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
518  if ((I + 1) < Size)
519  Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
520  }
521  }
522 
523  return Error::success();
524 }
525 
527  error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
528  error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
529  error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
530  uint32_t NamesLen = 0;
531  if (!IO.isReading()) {
532  for (auto Name : Record.MethodNames)
533  NamesLen += Name.size() + 1;
534  }
535  error(IO.mapInteger(NamesLen));
536  error(IO.mapVectorTail(
537  Record.MethodNames,
538  [](CodeViewRecordIO &IO, StringRef &S) {
539  return IO.mapStringZ(S, "MethodName");
540  },
541  "VFTableName"));
542 
543  return Error::success();
544 }
545 
547  error(IO.mapInteger(Record.Id, "Id"));
548  error(IO.mapStringZ(Record.String, "StringData"));
549 
550  return Error::success();
551 }
552 
555  error(IO.mapInteger(Record.UDT, "UDT"));
556  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
557  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
558 
559  return Error::success();
560 }
561 
564  error(IO.mapInteger(Record.UDT, "UDT"));
565  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
566  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
567  error(IO.mapInteger(Record.Module, "Module"));
568 
569  return Error::success();
570 }
571 
573  error(IO.mapInteger(Record.ParentScope, "ParentScope"));
574  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
575  error(IO.mapStringZ(Record.Name, "Name"));
576 
577  return Error::success();
578 }
579 
582  error(IO.mapInteger(Record.ClassType, "ClassType"));
583  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
584  error(IO.mapStringZ(Record.Name, "Name"));
585 
586  return Error::success();
587 }
588 
592  Record.ArgIndices,
593  [](CodeViewRecordIO &IO, TypeIndex &N) {
594  return IO.mapInteger(N, "Argument");
595  },
596  "NumArgs"));
597 
598  return Error::success();
599 }
600 
603  // TODO: Split the list into multiple records if it's longer than 64KB, using
604  // a subrecord of TypeRecordKind::Index to chain the records together.
605  error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true), "Method"));
606 
607  return Error::success();
608 }
609 
612  if (IO.isStreaming()) {
613  if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
614  return EC;
615  } else
616  error(IO.mapByteVectorTail(Record.Data));
617 
618  return Error::success();
619 }
620 
623  error(IO.mapGuid(Record.Guid, "Guid"));
624  error(IO.mapInteger(Record.Age, "Age"));
625  error(IO.mapStringZ(Record.Name, "Name"));
626  return Error::success();
627 }
628 
630  std::string ModeName = std::string(
631  getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())));
632  error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
633  return Error::success();
634 }
635 
638  std::string Attrs = getMemberAttributes(
640  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
641  error(IO.mapInteger(Record.Type, "BaseType"));
642  error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
643 
644  return Error::success();
645 }
646 
649  std::string Attrs = getMemberAttributes(
651  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
652 
653  // FIXME: Handle full APInt such as __int128.
654  error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
655  error(IO.mapStringZ(Record.Name, "Name"));
656 
657  return Error::success();
658 }
659 
662  std::string Attrs = getMemberAttributes(
664  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
665  error(IO.mapInteger(Record.Type, "Type"));
666  error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
667  error(IO.mapStringZ(Record.Name, "Name"));
668 
669  return Error::success();
670 }
671 
674  error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
675  error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
676  error(IO.mapStringZ(Record.Name, "Name"));
677 
678  return Error::success();
679 }
680 
683  const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
684  MapOneMethodRecord Mapper(IsFromOverloadList);
685  return Mapper(IO, Record);
686 }
687 
690  uint16_t Padding = 0;
691  error(IO.mapInteger(Padding, "Padding"));
692  error(IO.mapInteger(Record.Type, "Type"));
693  error(IO.mapStringZ(Record.Name, "Name"));
694 
695  return Error::success();
696 }
697 
700 
701  std::string Attrs = getMemberAttributes(
703  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
704  error(IO.mapInteger(Record.Type, "Type"));
705  error(IO.mapStringZ(Record.Name, "Name"));
706 
707  return Error::success();
708 }
709 
712 
713  std::string Attrs = getMemberAttributes(
715  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
716  error(IO.mapInteger(Record.BaseType, "BaseType"));
717  error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
718  error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
719  error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));
720 
721  return Error::success();
722 }
723 
725  VFPtrRecord &Record) {
726  uint16_t Padding = 0;
727  error(IO.mapInteger(Padding, "Padding"));
728  error(IO.mapInteger(Record.Type, "Type"));
729 
730  return Error::success();
731 }
732 
735  uint16_t Padding = 0;
736  error(IO.mapInteger(Padding, "Padding"));
737  error(IO.mapInteger(Record.ContinuationIndex, "ContinuationIndex"));
738 
739  return Error::success();
740 }
741 
743  PrecompRecord &Precomp) {
744  error(IO.mapInteger(Precomp.StartTypeIndex, "StartIndex"));
745  error(IO.mapInteger(Precomp.TypesCount, "Count"));
746  error(IO.mapInteger(Precomp.Signature, "Signature"));
747  error(IO.mapStringZ(Precomp.PrecompFilePath, "PrecompFile"));
748  return Error::success();
749 }
750 
752  EndPrecompRecord &EndPrecomp) {
753  error(IO.mapInteger(EndPrecomp.Signature, "Signature"));
754  return Error::success();
755 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::codeview::SimpleTypeKind::Byte
@ Byte
llvm::codeview::OneMethodRecord::Type
TypeIndex Type
Definition: TypeRecord.h:745
Attrs
Function Attrs
Definition: README_ALTIVEC.txt:215
llvm::codeview::MemberAccess
MemberAccess
Source-level access specifier. (CV_access_e)
Definition: CodeView.h:265
llvm::FlagEntry
Definition: ScopedPrinter.h:60
llvm::StringRef::take_front
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:561
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:189
RecordSerialization.h
llvm::MD5::stringifyResult
static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
Definition: MD5.cpp:287
llvm::codeview::CodeViewRecordIO::isWriting
bool isWriting() const
Definition: CodeViewRecordIO.h:77
llvm::codeview::StringIdRecord
Definition: TypeRecord.h:595
StringRef.h
llvm::codeview::NestedTypeRecord
Definition: TypeRecord.h:370
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:1183
llvm::codeview::CodeViewRecordIO::mapByteVectorTail
Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:102
ErrorHandling.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::codeview::PrecompRecord::TypesCount
uint32_t TypesCount
Definition: TypeRecord.h:940
llvm::codeview::CodeViewRecordIO::mapStringZ
Error mapStringZ(StringRef &Value, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:209
llvm::codeview::PrecompRecord::Signature
uint32_t Signature
Definition: TypeRecord.h:941
llvm::codeview::PrecompRecord
Definition: TypeRecord.h:929
llvm::codeview::VFTableShapeRecord
Definition: TypeRecord.h:553
llvm::codeview::MethodKind::Vanilla
@ Vanilla
llvm::codeview::BaseClassRecord
Definition: TypeRecord.h:864
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:116
llvm::codeview::TypeRecordMapping::visitTypeEnd
Error visitTypeEnd(CVType &Record) override
Definition: TypeRecordMapping.cpp:264
STLExtras.h
visitKnownRecord
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
Definition: CVSymbolVisitor.cpp:25
llvm::codeview::PointerRecord
Definition: TypeRecord.h:264
llvm::codeview::RecordPrefix
Definition: RecordSerialization.h:32
llvm::codeview::DataMemberRecord
Definition: TypeRecord.h:784
llvm::codeview::OneMethodRecord::Attrs
MemberAttributes Attrs
Definition: TypeRecord.h:746
EnumTables.h
llvm::EnumEntry
Definition: EnumTables.h:18
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::codeview::CodeViewRecordIO::beginRecord
Error beginRecord(Optional< uint32_t > MaxLength)
Definition: CodeViewRecordIO.cpp:20
llvm::codeview::visitMemberRecordStream
Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
Definition: CVTypeVisitor.cpp:271
llvm::codeview::ArgListRecord
Definition: TypeRecord.h:236
llvm::codeview::getMethodOptionNames
ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
Definition: EnumTables.cpp:525
llvm::codeview::EnumRecord
Definition: TypeRecord.h:519
llvm::codeview::TypeRecordMapping::visitMemberEnd
Error visitMemberEnd(CVMemberRecord &Record) override
Definition: TypeRecordMapping.cpp:300
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:234
MD5.h
SmallString.h
llvm::codeview::CodeViewRecordIO
Definition: CodeViewRecordIO.h:45
llvm::codeview::BitFieldRecord
Definition: TypeRecord.h:535
llvm::codeview::MethodOverloadListRecord
Definition: TypeRecord.h:752
llvm::codeview::MaxRecordLength
@ MaxRecordLength
Definition: RecordSerialization.h:30
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::codeview::MethodKind
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition: CodeView.h:273
llvm::codeview::UdtModSourceLineRecord
Definition: TypeRecord.h:646
llvm::codeview::EndPrecompRecord::Signature
uint32_t Signature
Definition: TypeRecord.h:953
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
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:915
llvm::codeview::getFunctionOptionEnum
ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
Definition: EnumTables.cpp:553
llvm::codeview::CodeViewRecordIO::emitRawComment
void emitRawComment(const Twine &T)
Definition: CodeViewRecordIO.h:215
llvm::EnumEntry::Name
StringRef Name
Definition: ScopedPrinter.h:25
llvm::codeview::ModifierRecord
Definition: TypeRecord.h:130
llvm::codeview::OverloadedMethodRecord
For method overload sets. LF_METHOD.
Definition: TypeRecord.h:765
llvm::SlotIndex
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:82
llvm::codeview::MethodOptions::None
@ None
llvm::codeview::CodeViewRecordIO::mapVectorN
Error mapVectorN(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Definition: CodeViewRecordIO.h:145
llvm::codeview::MemberFunctionRecord
Definition: TypeRecord.h:171
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:740
llvm::SmallString< 32 >
llvm::codeview::TypeRecordMapping::visitTypeBegin
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Definition: TypeRecordMapping.cpp:232
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:274
llvm::codeview::CodeViewRecordIO::skipPadding
Error skipPadding()
Definition: CodeViewRecordIO.cpp:87
llvm::codeview::TypeServer2Record
Definition: TypeRecord.h:575
llvm::codeview::EnumeratorRecord
Definition: TypeRecord.h:830
llvm::codeview::OneMethodRecord
Definition: TypeRecord.h:720
llvm::Optional::reset
void reset()
Definition: Optional.h:309
TypeRecord.h
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:42
llvm::codeview::VirtualBaseClassRecord
Definition: TypeRecord.h:885
llvm::MD5
Definition: MD5.h:41
I
#define I(x, y, z)
Definition: MD5.cpp:58
TypeRecordMapping.h
llvm::codeview::getPtrModeNames
ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
Definition: EnumTables.cpp:537
CodeViewRecordIO.h
ArrayRef.h
llvm::codeview::PrecompRecord::PrecompFilePath
StringRef PrecompFilePath
Definition: TypeRecord.h:942
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::codeview::StaticDataMemberRecord
Definition: TypeRecord.h:809
llvm::codeview::CompileSym2Flags::EC
@ EC
getLeafTypeName
static StringRef getLeafTypeName(TypeLeafKind LT)
Definition: TypeDumpVisitor.cpp:150
llvm::codeview::getPtrMemberRepNames
ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
Definition: EnumTables.cpp:541
llvm::Record
Definition: Record.h:1543
llvm::codeview::getMemberAccessNames
ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
Definition: EnumTables.cpp:521
llvm::codeview::FuncIdRecord
Definition: TypeRecord.h:610
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:385
llvm::codeview::OneMethodRecord::getMethodKind
MethodKind getMethodKind() const
Definition: TypeRecord.h:734
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:71
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::codeview::CVRecord< TypeLeafKind >
llvm::codeview::OneMethodRecord::getAccess
MemberAccess getAccess() const
Definition: TypeRecord.h:736
llvm::codeview::VFTableSlotKind
VFTableSlotKind
Definition: CodeView.h:391
llvm::codeview::UdtSourceLineRecord
Definition: TypeRecord.h:628
uint32_t
llvm::codeview::VFTableRecord
Definition: TypeRecord.h:691
llvm::codeview::CodeViewRecordIO::mapInteger
Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:129
llvm::codeview::CodeViewRecordIO::maxFieldLength
uint32_t maxFieldLength() const
Definition: CodeViewRecordIO.cpp:59
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::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:129
llvm::codeview::ProcedureRecord
Definition: TypeRecord.h:146
llvm::MD5::MD5Result
Definition: MD5.h:43
llvm::dwarf::TypeKind
TypeKind
Definition: Dwarf.h:151
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::codeview::CodeViewRecordIO::mapEncodedInteger
Error mapEncodedInteger(int64_t &Value, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:150
uint16_t
LeafTypeNames
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
Definition: TypeDumpVisitor.cpp:24
llvm::codeview::CodeViewRecordIO::endRecord
Error endRecord()
Definition: CodeViewRecordIO.cpp:28
llvm::codeview::UnionRecord
Definition: TypeRecord.h:498
computeHashString
static void computeHashString(StringRef Name, SmallString< 32 > &StringifiedHash)
Definition: TypeRecordMapping.cpp:171
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
CVTypeVisitor.h
llvm::codeview::OneMethodRecord::VFTableOffset
int32_t VFTableOffset
Definition: TypeRecord.h:747
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1563
visitKnownMember
static Error visitKnownMember(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks)
Definition: CVTypeVisitor.cpp:34
TypeIndex.h
mapNameAndUniqueName
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)
Definition: TypeRecordMapping.cpp:180
llvm::codeview::MemberAttributes::Attrs
uint16_t Attrs
Definition: TypeRecord.h:41
llvm::codeview::VFPtrRecord
Definition: TypeRecord.h:851
llvm::codeview::BuildInfoRecord
Definition: TypeRecord.h:667
llvm::codeview::MemberFuncIdRecord
Definition: TypeRecord.h:217
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::pdb::PDB_ColorItem::Padding
@ Padding
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
llvm::codeview::CodeViewRecordIO::isReading
bool isReading() const
Definition: CodeViewRecordIO.h:74
SmallVector.h
llvm::codeview::StringListRecord
Definition: TypeRecord.h:250
llvm::codeview::ArrayRecord
Definition: TypeRecord.h:396
N
#define N
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::codeview::LabelRecord
Definition: TypeRecord.h:206
llvm::codeview::ClassOptions::HasUniqueName
@ HasUniqueName
llvm::codeview::OneMethodRecord::getOptions
MethodOptions getOptions() const
Definition: TypeRecord.h:735
llvm::codeview::getCallingConventions
ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
Definition: EnumTables.cpp:549
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:96
llvm::codeview::CodeViewRecordIO::mapGuid
Error mapGuid(GUID &Guid, const Twine &Comment="")
Definition: CodeViewRecordIO.cpp:227
llvm::codeview::ClassRecord
Definition: TypeRecord.h:465
llvm::codeview::getClassOptionNames
ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
Definition: EnumTables.cpp:517
llvm::codeview::MemberPointerInfo
Definition: TypeRecord.h:100
llvm::codeview::EndPrecompRecord
Definition: TypeRecord.h:946
llvm::codeview::CodeViewRecordIO::mapVectorTail
Error mapVectorTail(T &Items, const ElementMapper &Mapper, const Twine &Comment="")
Definition: CodeViewRecordIO.h:182
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::codeview::OneMethodRecord::Name
StringRef Name
Definition: TypeRecord.h:748
error
#define error(X)
Definition: TypeRecordMapping.cpp:38
llvm::codeview::PrecompRecord::StartTypeIndex
uint32_t StartTypeIndex
Definition: TypeRecord.h:939
llvm::codeview::MethodOptions
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition: CodeView.h:284
ScopedPrinter.h
llvm::codeview::CVRecord::length
uint32_t length() const
Definition: CVRecord.h:40