LLVM: lib/DebugInfo/CodeView/TypeRecordMapping.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

25

26#include

27#include

28#include

29#include

30#include

31#include

32

33using namespace llvm;

35

36namespace {

37

38#define error(X) \

39 do { \

40 if (auto EC = X) \

41 return EC; \

42 } while (false)

43

45#define CV_TYPE(enum, val) {#enum, enum},

46#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"

47};

48

50 switch (LT) {

51#define TYPE_RECORD(ename, value, name) \

52 case ename: \

53 return #name;

54#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"

55 default:

56 break;

57 }

58 return "UnknownLeaf";

59}

60

61template

64}

65

66template <typename T, typename TFlag>

70 return std::string("");

73 FlagVector SetFlags;

74 for (const auto &Flag : Flags) {

75 if (Flag.Value == 0)

76 continue;

79 }

80 }

81

82 llvm::sort(SetFlags, &compEnumNames);

83

84 std::string FlagLabel;

85 bool FirstOcc = true;

86 for (const auto &Flag : SetFlags) {

87 if (FirstOcc)

88 FirstOcc = false;

89 else

90 FlagLabel += (" | ");

91

92 FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");

93 }

94

95 if (!FlagLabel.empty()) {

96 std::string LabelWithBraces(" ( ");

97 LabelWithBraces += FlagLabel + " )";

98 return LabelWithBraces;

99 } else

100 return FlagLabel;

101}

102

103template <typename T, typename TEnum>

107 return "";

109 for (const auto &EnumItem : EnumValues) {

110 if (EnumItem.Value == Value) {

111 Name = EnumItem.Name;

112 break;

113 }

114 }

115

117}

118

123 return "";

124 std::string AccessSpecifier = std::string(

126 std::string MemberAttrs(AccessSpecifier);

127 if (Kind != MethodKind::Vanilla) {

128 std::string MethodKind = std::string(

131 }

132 if (Options != MethodOptions::None) {

136 }

137 return MemberAttrs;

138}

139

140struct MapOneMethodRecord {

141 explicit MapOneMethodRecord(bool IsFromOverloadList)

142 : IsFromOverloadList(IsFromOverloadList) {}

143

145 std::string Attrs = getMemberAttributes(

148 if (IsFromOverloadList) {

151 }

157

158 if (!IsFromOverloadList)

160

162 }

163

164private:

165 bool IsFromOverloadList;

166};

167}

168

169

170

176 Hash.final(Result);

178}

179

183

184

185

188 size_t BytesNeeded = Name.size() + UniqueName.size() + 2;

189 if (BytesNeeded > BytesLeft) {

190

191 assert(BytesLeft >= 70);

192

193

196 std::string UniqueB = Twine("??@" + Hash + "@").str();

197 assert(UniqueB.size() == 36);

198

199

200

201 const size_t MaxTakeN = 4096;

202 size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;

204 std::string NameB = (Name.take_front(TakeN) + Hash).str();

205

210 } else {

213 }

214 } else {

215

216

219 }

220 } else {

221

222

223

227 }

228

230}

231

233 assert(!TypeKind && "Already in a type mapping!");

234 assert(!MemberKind && "Already in a member mapping!");

235

236

237

238

239 std::optional<uint32_t> MaxLen;

240 if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&

241 CVR.kind() != TypeLeafKind::LF_METHODLIST)

244 TypeKind = CVR.kind();

245

247 auto RecordKind = CVR.kind();

249 std::string RecordKindName = std::string(

252 error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));

253 }

255}

256

260 utohexstr(Index.getIndex()) + ")");

262}

263

265 assert(TypeKind && "Not in a type mapping!");

266 assert(!MemberKind && "Still in a member mapping!");

267

269

270 TypeKind.reset();

272}

273

275 assert(TypeKind && "Not in a type mapping!");

276 assert(!MemberKind && "Already in a member mapping!");

277

278

279

280

281

282

286

287 MemberKind = Record.Kind;

290 MemberKindName +=

291 " ( " +

293 .str() +

294 " )";

296 }

298}

299

301 assert(TypeKind && "Not in a type mapping!");

302 assert(MemberKind && "Not in a member mapping!");

303

306 return EC;

307 }

308

309 MemberKind.reset();

312}

313

315 std::string ModifierNames =

316 getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),

321}

322

323Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

325 std::string CallingConvName = std::string(getEnumName(

327 std::string FuncOptionNames =

328 getFlagNames(IO, static_cast<uint16_t>(Record.Options),

331 error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));

332 error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));

335

337}

338

339Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

341 std::string CallingConvName = std::string(getEnumName(

343 std::string FuncOptionNames =

344 getFlagNames(IO, static_cast<uint16_t>(Record.Options),

349 error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));

350 error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));

354

356}

357

362 return IO.mapInteger(N, "Argument");

363 },

364 "NumArgs"));

366}

367

368Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

371 Record.StringIndices,

373 return IO.mapInteger(N, "Strings");

374 },

375 "NumStrings"));

376

378}

379

381

383

385 std::string PtrType = std::string(getEnumName(

387 Attr += "[ Type: " + PtrType;

388

389 std::string PtrMode = std::string(getEnumName(

391 Attr += ", Mode: " + PtrMode;

392

393 auto PtrSizeOf = Record.getSize();

394 Attr += ", SizeOf: " + itostr(PtrSizeOf);

395

397 Attr += ", isFlat";

398 if (Record.isConst())

399 Attr += ", isConst";

400 if (Record.isVolatile())

401 Attr += ", isVolatile";

402 if (Record.isUnaligned())

403 Attr += ", isUnaligned";

404 if (Record.isRestrict())

405 Attr += ", isRestricted";

406 if (Record.isLValueReferenceThisPtr())

407 Attr += ", isThisPtr&";

408 if (Record.isRValueReferenceThisPtr())

409 Attr += ", isThisPtr&&";

410 Attr += " ]";

411 }

412

415

416 if (Record.isPointerToMember()) {

418 Record.MemberInfo.emplace();

419

422 std::string PtrMemberGetRepresentation = std::string(getEnumName(

425 "Representation: " + PtrMemberGetRepresentation));

426 }

427

429}

430

436

438}

439

441 assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||

442 (CVR.kind() == TypeLeafKind::LF_CLASS) ||

443 (CVR.kind() == TypeLeafKind::LF_INTERFACE));

444

445 std::string PropertiesNames =

446 getFlagNames(IO, static_cast<uint16_t>(Record.Options),

455 Record.hasUniqueName()));

456

458}

459

461 std::string PropertiesNames =

462 getFlagNames(IO, static_cast<uint16_t>(Record.Options),

469 Record.hasUniqueName()));

470

472}

473

475 std::string PropertiesNames =

476 getFlagNames(IO, static_cast<uint16_t>(Record.Options),

483 Record.hasUniqueName()));

484

486}

487

492

494}

495

496Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

503

508 }

510 }

511 } else {

517 if ((I + 1) < Size)

519 }

520 }

521

523}

524

532 NamesLen += Name.size() + 1;

533 }

538 return IO.mapStringZ(S, "MethodName");

539 },

540 "VFTableName"));

541

543}

544

548

550}

551

552Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

557

559}

560

561Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

567

569}

570

575

577}

578

579Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

584

586}

587

588Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

593 return IO.mapInteger(N, "Argument");

594 },

595 "NumArgs"));

596

598}

599

600Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

602

603

605

607}

608

609Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

613 return EC;

614 } else

616

618}

619

620Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

626}

627

629 std::string ModeName = std::string(

633}

634

637 std::string Attrs = getMemberAttributes(

642

644}

645

648 std::string Attrs = getMemberAttributes(

651

652

655

657}

658

661 std::string Attrs = getMemberAttributes(

667

669}

670

676

678}

679

682 const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);

683 MapOneMethodRecord Mapper(IsFromOverloadList);

684 return Mapper(IO, Record);

685}

686

693

695}

696

699

700 std::string Attrs = getMemberAttributes(

705

707}

708

711

712 std::string Attrs = getMemberAttributes(

719

721}

722

728

730}

731

737

739}

740

741Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

748}

749

750Error TypeRecordMapping::visitKnownRecord(CVType &CVR,

754}

static constexpr uint32_t ContinuationLength

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

This file defines the SmallVector class.

static StringRef getLeafTypeName(TypeLeafKind LT)

static const EnumEntry< TypeLeafKind > LeafTypeNames[]

static void computeHashString(StringRef Name, SmallString< 32 > &StringifiedHash)

static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, StringRef &UniqueName, bool HasUniqueName)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

void update(ArrayRef< uint8_t > Data)

Updates the hash for the byte stream provided.

static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)

Translates the bytes in Res to a hex string that is deposited into Str.

void final(MD5Result &Result)

Finishes off the hash and puts the result in result.

SlotIndex - An opaque wrapper around machine indexes.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

StringRef take_front(size_t N=1) const

Return a StringRef equal to 'this' but with only the first N elements remaining.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

std::string str() const

Return the twine contents as a std::string.

LLVM Value Representation.

Error mapVectorTail(T &Items, const ElementMapper &Mapper, const Twine &Comment="")

Error mapVectorN(T &Items, const ElementMapper &Mapper, const Twine &Comment="")

Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")

Error mapGuid(GUID &Guid, const Twine &Comment="")

Error mapStringZ(StringRef &Value, const Twine &Comment="")

Error mapEnum(T &Value, const Twine &Comment="")

Error mapEncodedInteger(int64_t &Value, const Twine &Comment="")

Error beginRecord(std::optional< uint32_t > MaxLength)

Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes, const Twine &Comment="")

uint32_t maxFieldLength() const

void emitRawComment(const Twine &T)

LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.

bool isIntroducingVirtual() const

MemberAccess getAccess() const

MethodOptions getOptions() const

MethodKind getMethodKind() const

For method overload sets. LF_METHOD.

StringRef PrecompFilePath

Error visitTypeBegin(CVType &Record) override

Paired begin/end actions for all types.

Error visitMemberBegin(CVMemberRecord &Record) override

Error visitTypeEnd(CVType &Record) override

Error visitMemberEnd(CVMemberRecord &Record) override

constexpr char Attrs[]

Key for Kernel::Metadata::mAttrs.

Flag

These should be considered private to the implementation of the MCInstrDesc class.

ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()

MethodKind

Part of member attribute flags. (CV_methodprop_e)

ArrayRef< EnumEntry< uint8_t > > getCallingConventions()

ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()

ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()

ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()

ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()

Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)

ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()

MethodOptions

Equivalent to CV_fldattr_t bitfield.

ArrayRef< EnumEntry< uint16_t > > getMemberKindNames()

MemberAccess

Source-level access specifier. (CV_access_e)

TypeLeafKind

Duplicate copy of the above enum, but using the official CV names.

ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()

ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()

ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()

This is an optimization pass for GlobalISel generic memory operations.

void sort(IteratorTy Start, IteratorTy End)