LLVM: lib/CodeGen/AsmPrinter/DwarfUnit.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

31#include

32#include

33#include

34#include

35#include

36

37using namespace llvm;

38

39#define DEBUG_TYPE "dwarfdebug"

40

44

45void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {

46 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op);

47}

48

49void DIEDwarfExpression::emitSigned(int64_t Value) {

50 CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value);

51}

52

53void DIEDwarfExpression::emitUnsigned(uint64_t Value) {

54 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value);

55}

56

57void DIEDwarfExpression::emitData1(uint8_t Value) {

58 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value);

59}

60

61void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {

62 CU.addBaseTypeRef(getActiveDIE(), Idx);

63}

64

65void DIEDwarfExpression::enableTemporaryBuffer() {

66 assert(!IsBuffering && "Already buffering?");

67 IsBuffering = true;

68}

69

70void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }

71

72unsigned DIEDwarfExpression::getTemporaryBufferSize() {

74}

75

76void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }

77

80 return MachineReg == TRI.getFrameRegister(*AP.MF);

81}

82

85 unsigned UniqueID)

86 : DIEUnit(UnitTag), UniqueID(UniqueID), CUNode(Node), Asm(A), DD(DW),

87 DU(DWU) {}

88

92 : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU, UniqueID),

93 CU(CU), SplitLineTable(SplitLineTable) {}

94

97 B->~DIEBlock();

99 L->~DIELoc();

100}

101

102int64_t DwarfUnit::getDefaultLowerBound() const {

104 default:

105 break;

106

107

108 case dwarf::DW_LANG_C:

109 case dwarf::DW_LANG_C89:

110 case dwarf::DW_LANG_C_plus_plus:

111 return 0;

112

113 case dwarf::DW_LANG_Fortran77:

114 case dwarf::DW_LANG_Fortran90:

115 return 1;

116

117

118 case dwarf::DW_LANG_C99:

119 case dwarf::DW_LANG_ObjC:

120 case dwarf::DW_LANG_ObjC_plus_plus:

122 return 0;

123 break;

124

125 case dwarf::DW_LANG_Fortran95:

127 return 1;

128 break;

129

130

131 case dwarf::DW_LANG_D:

132 case dwarf::DW_LANG_Java:

133 case dwarf::DW_LANG_Python:

134 case dwarf::DW_LANG_UPC:

136 return 0;

137 break;

138

139 case dwarf::DW_LANG_Ada83:

140 case dwarf::DW_LANG_Ada95:

141 case dwarf::DW_LANG_Cobol74:

142 case dwarf::DW_LANG_Cobol85:

143 case dwarf::DW_LANG_Modula2:

144 case dwarf::DW_LANG_Pascal83:

145 case dwarf::DW_LANG_PLI:

147 return 1;

148 break;

149

150

151 case dwarf::DW_LANG_BLISS:

152 case dwarf::DW_LANG_C11:

153 case dwarf::DW_LANG_C_plus_plus_03:

154 case dwarf::DW_LANG_C_plus_plus_11:

155 case dwarf::DW_LANG_C_plus_plus_14:

156 case dwarf::DW_LANG_Dylan:

157 case dwarf::DW_LANG_Go:

158 case dwarf::DW_LANG_Haskell:

159 case dwarf::DW_LANG_OCaml:

160 case dwarf::DW_LANG_OpenCL:

161 case dwarf::DW_LANG_RenderScript:

162 case dwarf::DW_LANG_Rust:

163 case dwarf::DW_LANG_Swift:

165 return 0;

166 break;

167

168 case dwarf::DW_LANG_Fortran03:

169 case dwarf::DW_LANG_Fortran08:

170 case dwarf::DW_LANG_Julia:

171 case dwarf::DW_LANG_Modula3:

173 return 1;

174 break;

175 }

176

177 return -1;

178}

179

180

182

183

184

185

186

187

188

190 return false;

191 return (isa(D) ||

192 (isa(D) && !cast(D)->isDefinition())) &&

194}

195

200}

201

205 return;

206 }

208}

209

212}

213

217 else

219}

220

223 if (!Form)

225 assert(Form != dwarf::DW_FORM_implicit_const &&

226 "DW_FORM_implicit_const is used only for signed integers");

228}

229

233}

234

236 std::optionaldwarf::Form Form, int64_t Integer) {

237 if (!Form)

240}

241

245}

246

250 return;

251

256 return;

257 }

259 isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;

260

261 auto StringPoolEntry =

265

266

268 IxForm = dwarf::DW_FORM_strx1;

269 unsigned Index = StringPoolEntry.getIndex();

270 if (Index > 0xffffff)

271 IxForm = dwarf::DW_FORM_strx4;

272 else if (Index > 0xffff)

273 IxForm = dwarf::DW_FORM_strx3;

274 else if (Index > 0xff)

275 IxForm = dwarf::DW_FORM_strx2;

276 }

278}

279

283}

284

287}

288

292}

293

294unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {

295 if (!SplitLineTable)

297 if (!UsedLineTable) {

298 UsedLineTable = true;

299

301 }

302 return SplitLineTable->getFile(

303 File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),

305}

306

308 bool UseAddrOffsetFormOrExpressions =

310

312 if (Label->isInSection() && UseAddrOffsetFormOrExpressions)

314

316

318 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);

319 addUInt(Die, dwarf::DW_FORM_addrx, Index);

320 } else {

321 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);

322 addUInt(Die, dwarf::DW_FORM_GNU_addr_index, Index);

323 }

324

326 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_const4u);

328 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

329 }

330}

331

335 return;

336 }

337

340 return;

341 }

342

343 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);

345}

346

351}

352

355}

356

358

359

360

361

362 addFlag(Die, dwarf::DW_AT_declaration);

363

364 addAttribute(Die, dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,

366}

367

371 const DIEUnit *EntryCU = Entry.getEntry().getUnit();

372 if (CU)

373

375 if (!EntryCU)

378 !static_cast<const DwarfUnit*>(CU)->isDwoUnit());

380 EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,

381 Entry);

382}

383

386 if (N)

388 return Die;

389}

390

393 DIELocs.push_back(Loc);

395}

396

400 DIEBlocks.push_back(Block);

402}

403

407}

408

410 if (Line == 0)

411 return;

412

414 addUInt(Die, dwarf::DW_AT_decl_file, std::nullopt, FileID);

415 addUInt(Die, dwarf::DW_AT_decl_line, std::nullopt, Line);

416}

417

420

422}

423

426

428}

429

432

434}

435

438

440}

441

444

446}

447

450

452}

453

455

457}

458

462}

463

466}

467

469

470

471 addUInt(Die, dwarf::DW_AT_const_value,

472 Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);

473}

474

477}

478

481 if (CIBitWidth <= 64) {

484 return;

485 }

486

488

489

491

492 int NumBytes = Val.getBitWidth() / 8;

494

495

496 for (int i = 0; i < NumBytes; i++) {

498 if (LittleEndian)

499 c = Ptr64[i / 8] >> (8 * (i & 7));

500 else

501 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));

503 }

504

506}

507

512 : dwarf::DW_AT_MIPS_linkage_name,

514}

515

517

518 for (const auto *Element : TParams) {

519 if (auto *TTP = dyn_cast(Element))

520 constructTemplateTypeParameterDIE(Buffer, TTP);

521 else if (auto *TVP = dyn_cast(Element))

522 constructTemplateValueParameterDIE(Buffer, TVP);

523 }

524}

525

526

528 for (const auto *Ty : ThrownTypes) {

530 addType(TT, cast(Ty));

531 }

532}

533

536 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,

539 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,

542 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,

544}

545

547 if (!Context || isa(Context) || isa(Context))

549 if (auto *T = dyn_cast(Context))

551 if (auto *NS = dyn_cast(Context))

553 if (auto *SP = dyn_cast(Context))

555 if (auto *M = dyn_cast(Context))

557 return getDIE(Context);

558}

559

561 auto *Context = Ty->getScope();

563

565 return TyDIE;

566

567

569

571

573 return &TyDIE;

574}

575

578

580

581 auto construct = [&](const auto *Ty) {

584 };

585

586 if (auto *CTy = dyn_cast(Ty)) {

588 (Ty->getRawName() || CTy->getRawIdentifier())) {

589

590 if (MDString *TypeId = CTy->getRawIdentifier()) {

593 } else {

595 finishNonUnitTypeDIE(TyDIE, CTy);

596 }

597 return &TyDIE;

598 }

599 construct(CTy);

600 } else if (auto *BT = dyn_cast(Ty))

601 construct(BT);

602 else if (auto *ST = dyn_cast(Ty))

603 construct(ST);

604 else if (auto *STy = dyn_cast(Ty))

605 construct(STy);

606 else

607 construct(cast(Ty));

608

609 return &TyDIE;

610}

611

613 if (!TyNode)

614 return nullptr;

615

616 auto *Ty = cast(TyNode);

617

618

619 if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)

621

622

623 if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5)

625

626

627

628 auto *Context = Ty->getScope();

631

633 return TyDIE;

634

637}

638

640 const DIType *Ty, const DIE &TyDIE) {

642 return;

644 return;

645

646

647

648 unsigned Flags = 0;

649 if (auto *CT = dyn_cast(Ty)) {

650

651

652 if (CT->getRuntimeLang() == 0 || CT->isObjcClassComplete())

654 }

655

657 Flags);

658

659 if (auto *CT = dyn_cast(Ty))

660 if (Ty->getName() != CT->getIdentifier() &&

661 CT->getRuntimeLang() == dwarf::DW_LANG_Swift)

663 TyDIE, Flags);

664

666}

667

669 const DIScope *Context) {

670 if (!Context || isa(Context) || isa(Context) ||

671 isa(Context) || isa(Context))

673}

674

677 assert(Ty && "Trying to add a type that doesn't exist?");

679}

680

682 if (!Context)

683 return "";

684

685

687 return "";

688

689 std::string CS;

691 while (!isa(Context)) {

692 Parents.push_back(Context);

694 Context = S;

695 else

696

697

698 break;

699 }

700

701

702

705 if (Name.empty() && isa(Ctx))

706 Name = "(anonymous namespace)";

707 if (Name.empty()) {

709 CS += "::";

710 }

711 }

712 return CS;

713}

714

716

718

719 if (Name.empty())

721

722

723 if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)

724 return;

725

726 if (BTy->getTag() != dwarf::DW_TAG_string_type)

727 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,

729

731 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);

732

734 addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big);

736 addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little);

737

739 addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,

740 NumExtraInhabitants);

741}

742

744

746

747 if (Name.empty())

749

751 if (auto *VarDIE = getDIE(Var))

752 addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);

756

757

758

759 DwarfExpr.setMemoryLocationKind();

760 DwarfExpr.addExpression(Expr);

761 addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());

762 } else {

764 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);

765 }

766

770

771

772 DwarfExpr.setMemoryLocationKind();

773 DwarfExpr.addExpression(Expr);

774 addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());

775 }

776

778

779 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,

781 }

782}

783

785

789

790

791 const DIType *FromTy = DTy->getBaseType();

792 if (FromTy)

794

795

796 if (Name.empty())

798

800

801

802

805 if (AlignInBytes > 0)

806 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

807 AlignInBytes);

808 }

809

810

811 if (Size && Tag != dwarf::DW_TAG_pointer_type

812 && Tag != dwarf::DW_TAG_ptr_to_member_type

813 && Tag != dwarf::DW_TAG_reference_type

814 && Tag != dwarf::DW_TAG_rvalue_reference_type)

815 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);

816

817 if (Tag == dwarf::DW_TAG_ptr_to_member_type)

818 addDIEEntry(Buffer, dwarf::DW_AT_containing_type,

820

822

823

826

827

828

829

830 if (DTy->getDWARFAddressSpace())

831 addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,

832 *DTy->getDWARFAddressSpace());

833

834

835 if (Tag == dwarf::DW_TAG_template_alias)

837

838 if (auto PtrAuthData = DTy->getPtrAuthData()) {

839 addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1,

840 PtrAuthData->key());

841 if (PtrAuthData->isAddressDiscriminated())

842 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated);

843 addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator,

844 dwarf::DW_FORM_data2, PtrAuthData->extraDiscriminator());

845 if (PtrAuthData->isaPointer())

846 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer);

847 if (PtrAuthData->authenticatesNullValues())

848 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values);

849 }

850}

851

853

854 DIE *ObjectPointer = nullptr;

855 for (unsigned i = 1, N = Args.size(); i < N; ++i) {

856 const DIType *Ty = Args[i];

857 if (!Ty) {

858 assert(i == N-1 && "Unspecified parameter must be the last argument");

859 createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);

860 } else {

864 addFlag(Arg, dwarf::DW_AT_artificial);

866 assert(!ObjectPointer && "Can't have more than one object pointer");

867 ObjectPointer = &Arg;

868 }

869 }

870 }

871

872 return ObjectPointer;

873}

874

876

877 auto Elements = cast(CTy)->getTypeArray();

878 if (Elements.size())

879 if (auto RTy = Elements[0])

881

882 bool isPrototyped = true;

883 if (Elements.size() == 2 && !Elements[1])

884 isPrototyped = false;

885

887

888

889

891 addFlag(Buffer, dwarf::DW_AT_prototyped);

892

893

894 if (CTy->getCC() && CTy->getCC() != dwarf::DW_CC_normal)

895 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,

897

899 addFlag(Buffer, dwarf::DW_AT_reference);

900

902 addFlag(Buffer, dwarf::DW_AT_rvalue_reference);

903}

904

907 return;

908

910 const MDNode *MD = cast(Annotation);

913

914 DIE &AnnotationDie = createAndAddDIE(dwarf::DW_TAG_LLVM_annotation, Buffer);

915 addString(AnnotationDie, dwarf::DW_AT_name, Name->getString());

916 if (const auto *Data = dyn_cast(Value))

917 addString(AnnotationDie, dwarf::DW_AT_const_value, Data->getString());

918 else if (const auto *Data = dyn_cast(Value))

920 true);

921 else

922 assert(false && "Unsupported annotation value type");

923 }

924}

925

927

929

932

933 switch (Tag) {

934 case dwarf::DW_TAG_array_type:

935 constructArrayTypeDIE(Buffer, CTy);

936 break;

937 case dwarf::DW_TAG_enumeration_type:

938 constructEnumTypeDIE(Buffer, CTy);

939 break;

940 case dwarf::DW_TAG_variant_part:

941 case dwarf::DW_TAG_structure_type:

942 case dwarf::DW_TAG_union_type:

943 case dwarf::DW_TAG_class_type:

944 case dwarf::DW_TAG_namelist: {

945

947 if (Tag == dwarf::DW_TAG_variant_part) {

949 if (Discriminator) {

950

951

952

953

954 DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);

955 addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);

956 }

957 }

958

959

960 if (Tag == dwarf::DW_TAG_class_type ||

961 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)

963

964

965 DINodeArray Elements = CTy->getElements();

966 for (const auto *Element : Elements) {

967 if (!Element)

968 continue;

969 if (auto *SP = dyn_cast(Element))

971 else if (auto *DDTy = dyn_cast(Element)) {

972 if (DDTy->getTag() == dwarf::DW_TAG_friend) {

974 addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend);

975 } else if (DDTy->isStaticMember()) {

977 } else if (Tag == dwarf::DW_TAG_variant_part) {

978

979

982 dyn_cast_or_null(DDTy->getDiscriminantValue())) {

984 addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,

985 CI->getZExtValue());

986 else

987 addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,

988 CI->getSExtValue());

989 }

990 constructMemberDIE(Variant, DDTy);

991 } else {

992 constructMemberDIE(Buffer, DDTy);

993 }

994 } else if (auto *Property = dyn_cast(Element)) {

996 StringRef PropertyName = Property->getName();

997 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);

998 if (Property->getType())

999 addType(ElemDie, Property->getType());

1001 StringRef GetterName = Property->getGetterName();

1002 if (!GetterName.empty())

1003 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);

1004 StringRef SetterName = Property->getSetterName();

1005 if (!SetterName.empty())

1006 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);

1007 if (unsigned PropertyAttributes = Property->getAttributes())

1008 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, std::nullopt,

1009 PropertyAttributes);

1010 } else if (auto *Composite = dyn_cast(Element)) {

1011 if (Composite->getTag() == dwarf::DW_TAG_variant_part) {

1014 }

1015 } else if (Tag == dwarf::DW_TAG_namelist) {

1016 auto *Var = dyn_cast(Element);

1017 auto *VarDIE = getDIE(Var);

1018 if (VarDIE) {

1019 DIE &ItemDie = createAndAddDIE(dwarf::DW_TAG_namelist_item, Buffer);

1020 addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE);

1021 }

1022 }

1023 }

1024

1026 addFlag(Buffer, dwarf::DW_AT_APPLE_block);

1027

1029 addFlag(Buffer, dwarf::DW_AT_export_symbols);

1030

1031

1032

1033

1034

1036 addDIEEntry(Buffer, dwarf::DW_AT_containing_type,

1038

1040 addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);

1041

1042

1043

1047 CC = dwarf::DW_CC_pass_by_value;

1049 CC = dwarf::DW_CC_pass_by_reference;

1050 if (CC)

1051 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,

1052 CC);

1053 }

1054

1056 addDIEEntry(Buffer, dwarf::DW_AT_specification,

1058

1059 break;

1060 }

1061 default:

1062 break;

1063 }

1064

1065

1066 if (Name.empty())

1068

1069

1072

1074

1075 if (Tag == dwarf::DW_TAG_enumeration_type ||

1076 Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||

1077 Tag == dwarf::DW_TAG_union_type) {

1078

1079

1080

1082 (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))

1083 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);

1085

1086 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0);

1087

1088

1090 addFlag(Buffer, dwarf::DW_AT_declaration);

1091

1092

1094

1095

1098

1099

1101 if (RLang)

1102 addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,

1103 RLang);

1104

1105

1107 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

1108 AlignInBytes);

1109

1111 addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,

1112 NumExtraInhabitants);

1113 }

1114}

1115

1116void DwarfUnit::constructTemplateTypeParameterDIE(

1118 DIE &ParamDIE =

1119 createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer);

1120

1125 if (TP->isDefault() && isCompatibleWithVersion(5))

1126 addFlag(ParamDIE, dwarf::DW_AT_default_value);

1127}

1128

1129void DwarfUnit::constructTemplateValueParameterDIE(

1132

1133

1134

1135 if (VP->getTag() == dwarf::DW_TAG_template_value_parameter)

1139 if (VP->isDefault() && isCompatibleWithVersion(5))

1140 addFlag(ParamDIE, dwarf::DW_AT_default_value);

1142 if (ConstantInt *CI = mdconst::dyn_extract(Val))

1144 else if (GlobalValue *GV = mdconst::dyn_extract(Val)) {

1145

1146

1147 if (!GV->hasDLLImportStorageClass()) {

1148

1149

1152

1153

1154 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);

1155 addBlock(ParamDIE, dwarf::DW_AT_location, Loc);

1156 }

1157 } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) {

1158 assert(isa(Val));

1159 addString(ParamDIE, dwarf::DW_AT_GNU_template_name,

1160 cast(Val)->getString());

1161 } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {

1163 }

1164 }

1165}

1166

1168

1169

1171

1173 return NDie;

1174 DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);

1175

1177 if (Name.empty())

1179 else

1180 Name = "(anonymous namespace)";

1184 addFlag(NDie, dwarf::DW_AT_export_symbols);

1185 return &NDie;

1186}

1187

1189

1190

1192

1194 return MDie;

1196

1197 if (!M->getName().empty()) {

1198 addString(MDie, dwarf::DW_AT_name, M->getName());

1199 addGlobalName(M->getName(), MDie, M->getScope());

1200 }

1201 if (!M->getConfigurationMacros().empty())

1202 addString(MDie, dwarf::DW_AT_LLVM_config_macros,

1203 M->getConfigurationMacros());

1204 if (!M->getIncludePath().empty())

1205 addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());

1206 if (!M->getAPINotesFile().empty())

1207 addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile());

1208 if (M->getFile())

1209 addUInt(MDie, dwarf::DW_AT_decl_file, std::nullopt,

1211 if (M->getLineNo())

1212 addUInt(MDie, dwarf::DW_AT_decl_line, std::nullopt, M->getLineNo());

1213 if (M->getIsDecl())

1214 addFlag(MDie, dwarf::DW_AT_declaration);

1215

1216 return &MDie;

1217}

1218

1220

1221

1222

1223 DIE *ContextDIE =

1225

1227 return SPDie;

1228

1229 if (auto *SPDecl = SP->getDeclaration()) {

1230 if (!Minimal) {

1231

1233

1235 }

1236 }

1237

1238

1239 DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);

1240

1241

1242

1243 if (SP->isDefinition())

1244 return &SPDie;

1245

1248 return &SPDie;

1249}

1250

1252 DIE &SPDie, bool Minimal) {

1253 DIE *DeclDie = nullptr;

1255 if (auto *SPDecl = SP->getDeclaration()) {

1256 if (!Minimal) {

1258 DeclArgs = SPDecl->getType()->getTypeArray();

1259 DefinitionArgs = SP->getType()->getTypeArray();

1260

1261 if (DeclArgs.size() && DefinitionArgs.size())

1262 if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0])

1263 addType(SPDie, DefinitionArgs[0]);

1264

1265 DeclDie = getDIE(SPDecl);

1266 assert(DeclDie && "This DIE should've already been constructed when the "

1267 "definition DIE was created in "

1268 "getOrCreateSubprogramDIE");

1269

1271 DeclLinkageName = SPDecl->getLinkageName();

1274 if (DeclID != DefID)

1275 addUInt(SPDie, dwarf::DW_AT_decl_file, std::nullopt, DefID);

1276

1277 if (SP->getLine() != SPDecl->getLine())

1278 addUInt(SPDie, dwarf::DW_AT_decl_line, std::nullopt, SP->getLine());

1279 }

1280 }

1281

1282

1284

1285

1289 "decl has a linkage name and it is different");

1290 if (DeclLinkageName.empty() &&

1291

1294

1295 if (!DeclDie)

1296 return false;

1297

1298

1299

1300 addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);

1301 return true;

1302}

1303

1305 bool SkipSPAttributes) {

1306

1307

1308 bool SkipSPSourceLocation = SkipSPAttributes &&

1310 if (!SkipSPSourceLocation)

1312 return;

1313

1314

1317

1319

1320 if (!SkipSPSourceLocation)

1322

1323

1324 if (SkipSPAttributes)

1325 return;

1326

1327

1328

1330 addFlag(SPDie, dwarf::DW_AT_prototyped);

1331

1332 if (SP->isObjCDirect())

1333 addFlag(SPDie, dwarf::DW_AT_APPLE_objc_direct);

1334

1335 unsigned CC = 0;

1338 Args = SPTy->getTypeArray();

1339 CC = SPTy->getCC();

1340 }

1341

1342

1343 if (CC && CC != dwarf::DW_CC_normal)

1344 addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);

1345

1346

1347

1348 if (Args.size())

1349 if (auto Ty = Args[0])

1351

1352 unsigned VK = SP->getVirtuality();

1353 if (VK) {

1354 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);

1355 if (SP->getVirtualIndex() != -1u) {

1357 addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);

1358 addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());

1359 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);

1360 }

1361 ContainingTypeMap.insert(std::make_pair(&SPDie, SP->getContainingType()));

1362 }

1363

1364 if (!SP->isDefinition()) {

1365 addFlag(SPDie, dwarf::DW_AT_declaration);

1366

1367

1368

1370 addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, *ObjectPointer);

1371 }

1372

1374

1375 if (SP->isArtificial())

1376 addFlag(SPDie, dwarf::DW_AT_artificial);

1377

1378 if (!SP->isLocalToUnit())

1379 addFlag(SPDie, dwarf::DW_AT_external);

1380

1382 if (SP->isOptimized())

1383 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);

1384

1386 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);

1387 }

1388

1389 if (SP->isLValueReference())

1390 addFlag(SPDie, dwarf::DW_AT_reference);

1391

1392 if (SP->isRValueReference())

1393 addFlag(SPDie, dwarf::DW_AT_rvalue_reference);

1394

1395 if (SP->isNoReturn())

1396 addFlag(SPDie, dwarf::DW_AT_noreturn);

1397

1398 addAccess(SPDie, SP->getFlags());

1399

1400 if (SP->isExplicit())

1401 addFlag(SPDie, dwarf::DW_AT_explicit);

1402

1403 if (SP->isMainSubprogram())

1404 addFlag(SPDie, dwarf::DW_AT_main_subprogram);

1405 if (SP->isPure())

1406 addFlag(SPDie, dwarf::DW_AT_pure);

1407 if (SP->isElemental())

1408 addFlag(SPDie, dwarf::DW_AT_elemental);

1409 if (SP->isRecursive())

1410 addFlag(SPDie, dwarf::DW_AT_recursive);

1411

1412 if (!SP->getTargetFuncName().empty())

1413 addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName());

1414

1416 addFlag(SPDie, dwarf::DW_AT_deleted);

1417}

1418

1419void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,

1420 DIE *IndexTy) {

1421 DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer);

1422 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);

1423

1424

1425

1426

1427

1428 int64_t DefaultLowerBound = getDefaultLowerBound();

1429

1431 DISubrange::BoundType Bound) -> void {

1432 if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {

1433 if (auto *VarDIE = getDIE(BV))

1434 addDIEEntry(DW_Subrange, Attr, *VarDIE);

1435 } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {

1438 DwarfExpr.setMemoryLocationKind();

1439 DwarfExpr.addExpression(BE);

1440 addBlock(DW_Subrange, Attr, DwarfExpr.finalize());

1441 } else if (auto *BI = dyn_cast_if_present<ConstantInt *>(Bound)) {

1442 if (Attr == dwarf::DW_AT_count) {

1443 if (BI->getSExtValue() != -1)

1444 addUInt(DW_Subrange, Attr, std::nullopt, BI->getSExtValue());

1445 } else if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||

1446 BI->getSExtValue() != DefaultLowerBound)

1447 addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue());

1448 }

1449 };

1450

1451 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound());

1452

1453 AddBoundTypeEntry(dwarf::DW_AT_count, SR->getCount());

1454

1455 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());

1456

1457 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());

1458}

1459

1460void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer,

1462 DIE *IndexTy) {

1463 DIE &DwGenericSubrange =

1464 createAndAddDIE(dwarf::DW_TAG_generic_subrange, Buffer);

1465 addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);

1466

1467 int64_t DefaultLowerBound = getDefaultLowerBound();

1468

1471 if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {

1472 if (auto *VarDIE = getDIE(BV))

1473 addDIEEntry(DwGenericSubrange, Attr, *VarDIE);

1474 } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {

1475 if (BE->isConstant() &&

1477 *BE->isConstant()) {

1478 if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||

1479 static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound)

1480 addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,

1481 BE->getElement(1));

1482 } else {

1485 DwarfExpr.setMemoryLocationKind();

1486 DwarfExpr.addExpression(BE);

1487 addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());

1488 }

1489 }

1490 };

1491

1492 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->getLowerBound());

1493 AddBoundTypeEntry(dwarf::DW_AT_count, GSR->getCount());

1494 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->getUpperBound());

1495 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->getStride());

1496}

1497

1498DIE *DwarfUnit::getIndexTyDie() {

1501

1505 addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, std::nullopt, sizeof(int64_t));

1506 addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,

1510 0);

1512}

1513

1514

1515

1516

1518 assert(CTy && CTy->isVector() && "Composite type is not a vector");

1520

1521

1523 assert(BaseTy && "Unknown vector element type.");

1524 const uint64_t ElementSize = BaseTy->getSizeInBits();

1525

1526

1527 const DINodeArray Elements = CTy->getElements();

1528 assert(Elements.size() == 1 &&

1529 Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&

1530 "Invalid vector element array, expected one element of type subrange");

1531 const auto Subrange = cast(Elements[0]);

1532 const auto NumVecElements =

1533 Subrange->getCount()

1534 ? cast<ConstantInt *>(Subrange->getCount())->getSExtValue()

1535 : 0;

1536

1537

1538

1539 assert(ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size");

1540 return ActualSize != (NumVecElements * ElementSize);

1541}

1542

1543void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {

1545 addFlag(Buffer, dwarf::DW_AT_GNU_vector);

1547 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,

1549 }

1550

1552 if (auto *VarDIE = getDIE(Var))

1553 addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);

1557 DwarfExpr.setMemoryLocationKind();

1558 DwarfExpr.addExpression(Expr);

1559 addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());

1560 }

1561

1563 if (auto *VarDIE = getDIE(Var))

1564 addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);

1568 DwarfExpr.setMemoryLocationKind();

1569 DwarfExpr.addExpression(Expr);

1570 addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());

1571 }

1572

1574 if (auto *VarDIE = getDIE(Var))

1575 addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);

1579 DwarfExpr.setMemoryLocationKind();

1580 DwarfExpr.addExpression(Expr);

1581 addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());

1582 }

1583

1584 if (auto *RankConst = CTy->getRankConst()) {

1585 addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,

1586 RankConst->getSExtValue());

1587 } else if (auto *RankExpr = CTy->getRankExp()) {

1590 DwarfExpr.setMemoryLocationKind();

1591 DwarfExpr.addExpression(RankExpr);

1592 addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());

1593 }

1594

1595

1597

1598

1599

1600

1601 DIE *IdxTy = getIndexTyDie();

1602

1603

1605 for (DINode *E : Elements) {

1606

1607 if (auto *Element = dyn_cast_or_null(E)) {

1608 if (Element->getTag() == dwarf::DW_TAG_subrange_type)

1609 constructSubrangeDIE(Buffer, cast(Element), IdxTy);

1610 else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)

1611 constructGenericSubrangeDIE(Buffer, cast(Element),

1612 IdxTy);

1613 }

1614 }

1615}

1616

1617void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {

1620 if (DTy) {

1624 addFlag(Buffer, dwarf::DW_AT_enum_class);

1625 }

1626

1627 auto *Context = CTy->getScope();

1628 bool IndexEnumerators = !Context || isa(Context) || isa(Context) ||

1629 isa(Context) || isa(Context);

1631

1632

1633 for (const DINode *E : Elements) {

1634 auto *Enum = dyn_cast_or_null(E);

1635 if (Enum) {

1640 if (IndexEnumerators)

1642 }

1643 }

1644}

1645

1648 DIE &SPDie = *P.first;

1650 if (D)

1651 continue;

1653 if (!NDie)

1654 continue;

1655 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);

1656 }

1657}

1658

1659DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {

1662 if (Name.empty())

1664

1666

1667 if (DIType *Resolved = DT->getBaseType())

1668 addType(MemberDie, Resolved);

1669

1671

1672 if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) {

1673

1674

1675

1676

1677

1679 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);

1680 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);

1681 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);

1682 addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits());

1683 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);

1684 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);

1685 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

1686

1687 addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);

1688 } else {

1691 uint32_t AlignInBytes = DT->getAlignInBytes();

1693

1694 bool IsBitfield = DT->isBitField();

1695 if (IsBitfield) {

1696

1698 addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8);

1699 addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);

1700

1701 assert(DT->getOffsetInBits() <=

1702 (uint64_t)std::numeric_limits<int64_t>::max());

1703 int64_t Offset = DT->getOffsetInBits();

1704

1705

1706

1707 uint32_t AlignInBits = FieldSize;

1708 uint32_t AlignMask = ~(AlignInBits - 1);

1709

1710 uint64_t StartBitOffset = Offset - (Offset & AlignMask);

1711

1712 OffsetInBytes = (Offset - StartBitOffset) / 8;

1713

1715 uint64_t HiMark = (Offset + FieldSize) & AlignMask;

1716 uint64_t FieldOffset = (HiMark - FieldSize);

1717 Offset -= FieldOffset;

1718

1719

1721 Offset = FieldSize - (Offset + Size);

1722

1723 if (Offset < 0)

1724 addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,

1725 Offset);

1726 else

1727 addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,

1729 OffsetInBytes = FieldOffset >> 3;

1730 } else {

1731 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset);

1732 }

1733 } else {

1734

1735 OffsetInBytes = DT->getOffsetInBits() / 8;

1736 if (AlignInBytes)

1737 addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

1738 AlignInBytes);

1739 }

1740

1743 addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);

1744 addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);

1745 addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);

1747

1748

1749

1750

1752 addUInt(MemberDie, dwarf::DW_AT_data_member_location,

1753 dwarf::DW_FORM_udata, OffsetInBytes);

1754 else

1755 addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,

1756 OffsetInBytes);

1757 }

1758 }

1759

1760 addAccess(MemberDie, DT->getFlags());

1761

1762 if (DT->isVirtual())

1763 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,

1764 dwarf::DW_VIRTUALITY_virtual);

1765

1766

1767 if (DINode *PNode = DT->getObjCProperty())

1769 addAttribute(MemberDie, dwarf::DW_AT_APPLE_property,

1770 dwarf::DW_FORM_ref4, DIEEntry(*PDie));

1771

1772 if (DT->isArtificial())

1773 addFlag(MemberDie, dwarf::DW_AT_artificial);

1774

1775 return MemberDie;

1776}

1777

1779 if (!DT)

1780 return nullptr;

1781

1782

1783

1786 "Static member should belong to a type.");

1787

1788 if (DIE *StaticMemberDIE = getDIE(DT))

1789 return StaticMemberDIE;

1790

1791 DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT);

1792

1793 const DIType *Ty = DT->getBaseType();

1794

1795 addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName());

1796 addType(StaticMemberDIE, Ty);

1798 addFlag(StaticMemberDIE, dwarf::DW_AT_external);

1799 addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);

1800

1801

1802 if (DT->isArtificial())

1803 addFlag(StaticMemberDIE, dwarf::DW_AT_artificial);

1804

1805

1806

1807 addAccess(StaticMemberDIE, DT->getFlags());

1808

1809 if (const ConstantInt *CI = dyn_cast_or_null(DT->getConstant()))

1811 if (const ConstantFP *CFP = dyn_cast_or_null(DT->getConstant()))

1813

1814 if (uint32_t AlignInBytes = DT->getAlignInBytes())

1815 addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

1816 AlignInBytes);

1817

1818 return &StaticMemberDIE;

1819}

1820

1822

1825 isDwoUnit() ? "debug_info_dwo" : "debug_info", "Length of Unit");

1826 else

1828 "Length of Unit");

1829

1830 Asm->OutStreamer->AddComment("DWARF version number");

1833

1834

1838 Asm->OutStreamer->AddComment("Address Size (in bytes)");

1840 }

1841

1842

1843

1844

1845 Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");

1847 if (UseOffsets)

1849 else

1852

1854 Asm->OutStreamer->AddComment("Address Size (in bytes)");

1856 }

1857}

1858

1863 }

1866 : dwarf::DW_UT_type);

1868 Asm->OutStreamer->emitIntValue(TypeSignature, sizeof(TypeSignature));

1870

1872}

1873

1878}

1879

1884 else

1886}

1887

1888bool DwarfTypeUnit::isDwoUnit() const {

1889

1890

1892}

1893

1895 const DIScope *Context) {

1897}

1898

1900 const DIScope *Context) {

1902}

1903

1904const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const {

1906 return nullptr;

1907 if (isDwoUnit())

1908 return nullptr;

1910}

1911

1917}

1918

1921 "DW_AT_rnglists_base requires DWARF version 5 or later");

1926}

1927

1928void DwarfTypeUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {

1930}

1931

1932bool DwarfUnit::isCompatibleWithVersion(uint16_t Version) const {

1934}

This file declares a class to represent arbitrary precision floating point values and provide a varie...

This file implements a class to represent arbitrary precision integral constant values and operations...

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static bool hasVectorBeenPadded(const DICompositeType *CTy)

Returns true if the vector's size differs from the sum of sizes of elements the user specified.

unsigned const TargetRegisterInfo * TRI

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

static enum BaseType getBaseType(const Value *Val)

Return the baseType for Val which states whether Val is exclusively derived from constant/null,...

static unsigned getSize(unsigned Kind)

APInt bitcastToAPInt() const

Class for arbitrary precision integers.

uint64_t getZExtValue() const

Get zero extended value.

unsigned getBitWidth() const

Return the number of bits in the APInt.

const uint64_t * getRawData() const

This function returns a pointer to the internal storage of the APInt.

int64_t getSExtValue() const

Get sign extended value.

unsigned getIndex(const MCSymbol *Sym, bool TLS=false)

Returns the index into the address pool with the given label/symbol.

void resetUsedFlag(bool HasBeenUsed=false)

Annotations lets you mark points and ranges inside source code, for tests:

This class is intended to be used as a driving class for all asm writers.

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

MCSymbol * getSymbol(const GlobalValue *GV) const

void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const

Emit a reference to a symbol for use in dwarf.

void emitDwarfLengthOrOffset(uint64_t Value) const

Emit 32- or 64-bit value depending on the DWARF format.

TargetMachine & TM

Target machine description.

const MCAsmInfo * MAI

Target Asm Printer information.

MachineFunction * MF

The current machine function.

void emitInt8(int Value) const

Emit a byte directive and value.

void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const

Emit a unit length field.

MCContext & OutContext

This is the context for the output file that we are streaming.

MCSymbol * createTempSymbol(const Twine &Name) const

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

virtual unsigned getISAEncoding()

Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.

void emitInt16(int Value) const

Emit a short directive and value.

const DataLayout & getDataLayout() const

Return information about data layout.

dwarf::FormParams getDwarfFormParams() const

Returns information about the byte size of DW_FORM values.

bool doesDwarfUseRelocationsAcrossSections() const

ConstantFP - Floating Point Values [float, double].

const APFloat & getValueAPF() const

This is the shared class of boolean and integer constants.

const APInt & getValue() const

Return the constant as an APInt value reference.

Basic type, like 'int' or 'float'.

unsigned getEncoding() const

bool getDebugInfoForProfiling() const

bool isDebugDirectivesOnly() const

static std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)

DIExpression * getRankExp() const

DIExpression * getAssociatedExp() const

DIVariable * getAllocated() const

DIExpression * getDataLocationExp() const

DIVariable * getAssociated() const

DIDerivedType * getDiscriminator() const

DIVariable * getDataLocation() const

unsigned getRuntimeLang() const

DIType * getSpecification() const

StringRef getIdentifier() const

DINodeArray getElements() const

DITemplateParameterArray getTemplateParams() const

DIExpression * getAllocatedExp() const

DIType * getVTableHolder() const

DINodeArray getAnnotations() const

ConstantInt * getRankConst() const

MDString * getRawIdentifier() const

DIType * getBaseType() const

DINodeArray getAnnotations() const

Get annotations associated with this derived type.

DITemplateParameterArray getTemplateParams() const

Get the template parameters from a template alias.

DIEBlock - Represents a block of values.

A simple label difference DIE.

DwarfExpression implementation for singular DW_AT_location.

DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE)

A pointer to another debug information entry.

A container for inline string values.

static dwarf::Form BestForm(bool IsSigned, uint64_t Int)

Choose the best form for integer.

DIELoc - Represents an expression location.

unsigned computeSize(const dwarf::FormParams &FormParams) const

Calculate the size of the location expression.

dwarf::Form BestForm(unsigned DwarfVersion) const

BestForm - Choose the best form for data.

A container for string pool string values.

Represents a compile or type unit.

MCSection * getSection() const

Return the section that this DIEUnit will be emitted into.

void takeValues(DIEValueList &Other)

Take ownership of the nodes in Other, and append them to the back of the list.

A structured debug information entry.

DIE & addChild(DIE *Child)

Add a child to the DIE.

static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)

DIEUnit * getUnit() const

Climb up the parent chain to get the compile unit or type unit that this DIE belongs to.

unsigned getOffset() const

Get the compile/type unit relative offset of this DIE.

dwarf::Tag getTag() const

BoundType getLowerBound() const

BoundType getCount() const

BoundType getUpperBound() const

BoundType getStride() const

Represents a module in the programming language, for example, a Clang module, or a Fortran module.

DIScope * getScope() const

StringRef getName() const

bool getExportSymbols() const

Tagged DWARF-like metadata node.

dwarf::Tag getTag() const

Base class for scope-like contexts.

StringRef getName() const

DIScope * getScope() const

String type, Fortran CHARACTER(n)

unsigned getEncoding() const

DIExpression * getStringLengthExp() const

DIVariable * getStringLength() const

DIExpression * getStringLocationExp() const

BoundType getUpperBound() const

BoundType getStride() const

BoundType getLowerBound() const

BoundType getCount() const

Type array for a subprogram.

StringRef getName() const

Metadata * getValue() const

bool isLittleEndian() const

uint32_t getNumExtraInhabitants() const

bool isLValueReference() const

bool isObjcClassComplete() const

MDString * getRawName() const

bool isAppleBlockExtension() const

bool isObjectPointer() const

StringRef getName() const

bool isForwardDecl() const

bool isTypePassByValue() const

uint64_t getSizeInBits() const

uint32_t getAlignInBytes() const

bool isRValueReference() const

bool isArtificial() const

bool getExportSymbols() const

DIScope * getScope() const

bool isTypePassByReference() const

Base class for variables.

This class represents an Operation in the Expression.

bool isLittleEndian() const

Layout endianness...

static bool isUnsignedDIType(const DIType *Ty)

Return true if type encoding is unsigned.

static uint64_t getBaseTypeSize(const DIType *Ty)

If this type is derived from a base type then return base type size.

void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context)

Add a new global name present in a type unit to this compile unit.

unsigned getOrCreateSourceID(const DIFile *File) override

Look up the source ID for the given file.

void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context)

Add a new global type present in a type unit to this compile unit.

Collects and handles dwarf debug information.

std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const

If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.

bool useAddrOffsetForm() const

uint16_t getDwarfVersion() const

Returns the Dwarf Version.

void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

bool useAllLinkageNames() const

Returns whether we should emit all DW_AT_[MIPS_]linkage_name.

dwarf::Form getDwarfSectionOffsetForm() const

Returns a suitable DWARF form to represent a section offset, i.e.

bool useAppleExtensionAttributes() const

bool useInlineStrings() const

Returns whether to use inline strings.

bool generateTypeUnits() const

Returns whether to generate DWARF v4 type units.

AddressPool & getAddressPool()

bool useSectionsAsReferences() const

Returns whether to use sections as labels rather than temp symbols.

bool shareAcrossDWOCUs() const

const MCSymbol * getSectionLabel(const MCSection *S)

bool useSplitDwarf() const

Returns whether or not to change the current debug info for the split dwarf proposal support.

bool useDWARF2Bitfields() const

Returns whether to use the DWARF2 format for bitfields instyead of the DWARF4 format.

bool useAddrOffsetExpressions() const

void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)

Add a DIE to the set of types that we're going to pull into type units.

void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)

Base class containing the logic for constructing DWARF expressions independently of whether they are ...

MCSymbol * getStringOffsetsStartSym() const

MCSymbol * getRnglistsTableBaseSym() const

DwarfStringPool & getStringPool()

Returns the string pool.

DenseMap< const DILocalScope *, DIE * > & getAbstractScopeDIEs()

void insertDIE(const MDNode *TypeMD, DIE *Die)

DIE * getDIE(const MDNode *TypeMD)

EntryRef getEntry(AsmPrinter &Asm, StringRef Str)

Get a reference to an entry in the string pool.

EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)

Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....

DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID, MCDwarfDwoLineTable *SplitLineTable=nullptr)

void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context) override

Add a new global type to the compile unit.

DwarfCompileUnit & getCU() override

void emitHeader(bool UseOffsets) override

Emit the header for this unit, not including the initial length field.

void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override

Add a new global name to the compile unit.

This dwarf writer support class manages information associated with a source file.

virtual DIE * getOrCreateTypeDIE(const MDNode *TyNode)

Find existing DIE or create new DIE for the given type.

void addThrownTypes(DIE &Die, DINodeArray ThrownTypes)

Add thrown types.

void addStringOffsetsStart()

Add the DW_AT_str_offsets_base attribute to the unit DIE.

void addAnnotation(DIE &Buffer, DINodeArray Annotations)

Add DW_TAG_LLVM_annotation.

std::vector< DIEBlock * > DIEBlocks

A list of all the DIEBlocks in use.

std::vector< DIELoc * > DIELocs

A list of all the DIELocs in use.

uint16_t getLanguage() const

void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc)

Add block data.

void addTemplateParams(DIE &Buffer, DINodeArray TParams)

Add template parameters in buffer.

virtual DIE * getOrCreateContextDIE(const DIScope *Context)

Get context owner's DIE.

bool useSegmentedStringOffsetsTable() const

bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie, bool Minimal)

DIELoc * getDIELoc()

Returns a fresh newly allocated DIELoc.

void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, const DIE &TyDIE)

If this is a named finished type then include it in the list of types for the accelerator tables.

void addAttribute(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, T &&Value)

void addOpAddress(DIELoc &Die, const MCSymbol *Sym)

Add a dwarf op address data and value using the form given and an op of either DW_FORM_addr or DW_FOR...

void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)

Add an unsigned integer attribute data and value.

void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)

Add a string attribute data and value.

void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty)

Add constant value entry in variable DIE.

DIE * getOrCreateNameSpace(const DINamespace *NS)

void insertDIE(const DINode *Desc, DIE *D)

Insert DIE into the map.

void addAccess(DIE &Die, DINode::DIFlags Flags)

Add the accessibility attribute.

void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)

addSectionDelta - Add a label delta attribute data and value.

void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context)

DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)

Creates type DIE with specific context.

DenseMap< DIE *, const DINode * > ContainingTypeMap

This map is used to keep track of subprogram DIEs that need DW_AT_containing_type attribute.

const DICompileUnit * CUNode

MDNode for the compile unit.

virtual unsigned getOrCreateSourceID(const DIFile *File)=0

Look up the source ID for the given file.

virtual void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context)=0

Add a new global type to the compile unit.

void addDIETypeSignature(DIE &Die, uint64_t Signature)

Add a type's DW_AT_signature and set the declaration flag.

virtual DwarfCompileUnit & getCU()=0

DIE * getDIE(const DINode *D) const

Returns the DIE map slot for the specified debug variable.

virtual unsigned getHeaderSize() const

Compute the size of a header for this unit, not including the initial length field.

MCSymbol * LabelBegin

The start of the unit within its section.

void addSInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, int64_t Integer)

Add an signed integer attribute data and value.

DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID=0)

void addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)

Add a label delta attribute data and value.

void addLinkageName(DIE &Die, StringRef LinkageName)

Add a linkage name, if it isn't empty.

std::string getParentContextString(const DIScope *Context) const

Get string containing language specific context for a global name.

void addSourceLine(DIE &Die, unsigned Line, const DIFile *File)

Add location information to specified debug information entry.

void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT)

Emit the common part of the header for this unit.

BumpPtrAllocator DIEValueAllocator

DIE * IndexTyDie

An anonymous type for index type. Owned by DIEUnit.

void addRnglistsBase()

Add the DW_AT_rnglists_base attribute to the unit DIE.

DIE * constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args)

Construct function argument DIEs.

DIE * getOrCreateModule(const DIModule *M)

DIE & createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N=nullptr)

Create a DIE with the given Tag, add the DIE to its parent, and call insertDIE if MD is not null.

void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer)

Add an offset into a section attribute data and value.

DIE * getOrCreateStaticMemberDIE(const DIDerivedType *DT)

Create new static data member DIE.

void addLabel(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label)

Add a Dwarf label attribute data and value.

void addConstantFPValue(DIE &Die, const ConstantFP *CFP)

Add constant value entry in variable DIE.

void constructContainingTypeDIEs()

Construct DIEs for types that contain vtables.

DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal=false)

void addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)

Add a Dwarf section label attribute data and value.

bool isShareableAcrossCUs(const DINode *D) const

Check whether the DIE for this MDNode can be shared across CUs.

void addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label)

DenseMap< const MDNode *, DIE * > MDNodeToDieMap

Tracks the mapping of unit level debug information variables to debug information entries.

void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)

virtual void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context)=0

Add a new global name to the compile unit.

MCSymbol * EndLabel

Emitted at the end of the CU and used to compute the CU Length field.

void addFlag(DIE &Die, dwarf::Attribute Attribute)

Add a flag that is true to the DIE.

AsmPrinter * Asm

Target of Dwarf emission.

void addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute=dwarf::DW_AT_type)

Add a new type attribute to the specified entity.

void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, bool SkipSPAttributes=false)

void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)

Add a DIE attribute data and value.

static StringRef dropLLVMManglingEscape(StringRef Name)

If the given string begins with the GlobalValue name mangling escape character '\1',...

unsigned getCodePointerSize() const

Get the code pointer size in bytes.

uint16_t getDwarfVersion() const

unsigned getFile(StringRef Directory, StringRef FileName, std::optional< MD5::MD5Result > Checksum, uint16_t DwarfVersion, std::optional< StringRef > Source)

MCSection * getDwarfStrOffSection() const

MCSection * getDwarfRnglistsSection() const

MCSection * getDwarfAbbrevSection() const

MCSymbol * getBeginSymbol()

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

const MDOperand & getOperand(unsigned I) const

A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...

Wrapper class representing virtual and physical registers.

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 bool empty() const

empty - Check if the string is empty.

unsigned DebugStrictDwarf

When set to true, don't use DWARF extensions in later DWARF versions.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

LLVM Value Representation.

UnitType

Constants for unit types in DWARF v5.

bool isCPlusPlus(SourceLanguage S)

TypeKind getArrayIndexTypeEncoding(SourceLanguage S)

@ DW_FLAG_type_implementation

bool isC(SourceLanguage S)

This is an optimization pass for GlobalISel generic memory operations.

auto reverse(ContainerTy &&C)

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

Description of the encoding of one expression Op.