clang: lib/CodeGen/CGDebugInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

40#include "llvm/ADT/DenseSet.h"

41#include "llvm/ADT/SmallVector.h"

42#include "llvm/ADT/StringExtras.h"

43#include "llvm/IR/Constants.h"

44#include "llvm/IR/DataLayout.h"

45#include "llvm/IR/DerivedTypes.h"

46#include "llvm/IR/Instructions.h"

47#include "llvm/IR/Intrinsics.h"

48#include "llvm/IR/Metadata.h"

49#include "llvm/IR/Module.h"

50#include "llvm/Support/MD5.h"

51#include "llvm/Support/Path.h"

52#include "llvm/Support/SHA1.h"

53#include "llvm/Support/SHA256.h"

54#include "llvm/Support/TimeProfiler.h"

55#include

56using namespace clang;

58

61 if (TI.isAlignRequired())

63

64

65

67 if (Decl->hasAttr())

68 return TI.Align;

69

70 return 0;

71}

72

75}

76

79}

80

81

82

86 return false;

87

88 auto const *RefExpr =

89 llvm::dyn_cast_or_null(Init->IgnoreUnlessSpelledInSource());

90 if (!RefExpr)

91 return false;

92

93 return llvm::dyn_cast_or_null(RefExpr->getDecl());

94}

95

96

97

98

100

101

102

104 return false;

105

108}

109

111 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),

112 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),

113 DBuilder(CGM.getModule()) {

114 CreateCompileUnit();

115}

116

118 assert(LexicalBlockStack.empty() &&

119 "Region stack mismatch, stack not empty!");

120}

121

124 : CGF(&CGF) {

125 init(TemporaryLocation);

126}

127

128ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,

129 bool DefaultToEmpty,

131 : CGF(&CGF) {

132 init(TemporaryLocation, DefaultToEmpty);

133}

134

135void ApplyDebugLocation::init(SourceLocation TemporaryLocation,

136 bool DefaultToEmpty) {

138 if (!DI) {

139 CGF = nullptr;

140 return;

141 }

142

143 OriginalLocation = CGF->Builder.getCurrentDebugLocation();

144

145 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())

146 return;

147

148 if (TemporaryLocation.isValid()) {

149 DI->EmitLocation(CGF->Builder, TemporaryLocation);

150 return;

151 }

152

153 if (DefaultToEmpty) {

154 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());

155 return;

156 }

157

158

159 assert(!DI->LexicalBlockStack.empty());

160 CGF->Builder.SetCurrentDebugLocation(

161 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,

162 DI->LexicalBlockStack.back(), DI->getInlinedAt()));

163}

164

166 : CGF(&CGF) {

168}

169

171 : CGF(&CGF) {

173 this->CGF = nullptr;

174 return;

175 }

176 OriginalLocation = CGF.Builder.getCurrentDebugLocation();

178 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));

179}

180

182

183

184 if (CGF)

185 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));

186}

187

190 : CGF(&CGF) {

192 this->CGF = nullptr;

193 return;

194 }

196 SavedLocation = DI.getLocation();

197 assert((DI.getInlinedAt() ==

198 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&

199 "CGDebugInfo and IRBuilder are out of sync");

200

201 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);

202}

203

205 if (!CGF)

206 return;

209 DI.EmitLocation(CGF->Builder, SavedLocation);

210}

211

213

215 return;

216

218

219

220

221

222 if (LexicalBlockStack.empty())

223 return;

224

226 auto *Scope = castllvm::DIScope(LexicalBlockStack.back());

228 if (PCLoc.isInvalid() || Scope->getFile() == getOrCreateFile(CurLoc))

229 return;

230

231 if (auto *LBF = dyn_castllvm::DILexicalBlockFile(Scope)) {

232 LexicalBlockStack.pop_back();

233 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(

234 LBF->getScope(), getOrCreateFile(CurLoc)));

235 } else if (isallvm::DILexicalBlock(Scope) ||

236 isallvm::DISubprogram(Scope)) {

237 LexicalBlockStack.pop_back();

238 LexicalBlockStack.emplace_back(

239 DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurLoc)));

240 }

241}

242

243llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(const Decl *D) {

244 llvm::DIScope *Mod = getParentModuleOrNull(D);

245 return getContextDescriptor(cast(D->getDeclContext()),

246 Mod ? Mod : TheCU);

247}

248

249llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,

250 llvm::DIScope *Default) {

251 if (!Context)

253

254 auto I = RegionMap.find(Context);

255 if (I != RegionMap.end()) {

256 llvm::Metadata *V = I->second;

257 return dyn_cast_or_nullllvm::DIScope(V);

258 }

259

260

261 if (const auto *NSDecl = dyn_cast(Context))

262 return getOrCreateNamespace(NSDecl);

263

264 if (const auto *RDecl = dyn_cast(Context))

265 if (!RDecl->isDependentType())

267 TheCU->getFile());

269}

270

271PrintingPolicy CGDebugInfo::getPrintingPolicy() const {

273

274

275

276

277

278

282 } else {

283

284

286 }

287

294

295

297 return PP;

298}

299

300StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {

301 return internString(GetName(FD));

302}

303

304StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {

306 llvm::raw_svector_ostream OS(MethodName);

309 if (const auto *OID = dyn_cast(DC)) {

310 OS << OID->getName();

311 } else if (const auto *OID = dyn_cast(DC)) {

312 OS << OID->getName();

313 } else if (const auto *OC = dyn_cast(DC)) {

314 if (OC->IsClassExtension()) {

315 OS << OC->getClassInterface()->getName();

316 } else {

317 OS << OC->getIdentifier()->getNameStart() << '('

318 << OC->getIdentifier()->getNameStart() << ')';

319 }

320 } else if (const auto *OCD = dyn_cast(DC)) {

321 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';

322 }

324

325 return internString(OS.str());

326}

327

328StringRef CGDebugInfo::getSelectorName(Selector S) {

329 return internString(S.getAsString());

330}

331

332StringRef CGDebugInfo::getClassName(const RecordDecl *RD) {

333 if (isa(RD)) {

334

335 return internString(GetName(RD));

336 }

337

338

339

341 return II->getName();

342

343

344

345

349 "Typedef should not be in another decl context!");

350 assert(D->getDeclName().getAsIdentifierInfo() &&

351 "Typedef was not named!");

352 return D->getDeclName().getAsIdentifierInfo()->getName();

353 }

354

356 StringRef Name;

357

360

361

362 Name = DD->getName();

365

366

367 Name = TND->getName();

368

369

370 if (const CXXRecordDecl *CXXRD = dyn_cast(RD))

371 if (CXXRD->isLambda())

372 return internString(

374

375 if (!Name.empty()) {

377 UnnamedType += Name;

378 UnnamedType += '>';

379 return internString(UnnamedType);

380 }

381 }

382 }

383

384 return StringRef();

385}

386

387std::optionalllvm::DIFile::ChecksumKind

389 Checksum.clear();

390

393 return std::nullopt;

394

396 std::optionalllvm::MemoryBufferRef MemBuffer = SM.getBufferOrNone(FID);

397 if (!MemBuffer)

398 return std::nullopt;

399

400 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());

403 llvm::toHex(llvm::MD5::hash(Data), true, Checksum);

404 return llvm::DIFile::CSK_MD5;

406 llvm::toHex(llvm::SHA1::hash(Data), true, Checksum);

407 return llvm::DIFile::CSK_SHA1;

409 llvm::toHex(llvm::SHA256::hash(Data), true, Checksum);

410 return llvm::DIFile::CSK_SHA256;

411 }

412 llvm_unreachable("Unhandled DebugSrcHashKind enum");

413}

414

415std::optional CGDebugInfo::getSource(const SourceManager &SM,

418 return std::nullopt;

419

420 bool SourceInvalid = false;

421 StringRef Source = SM.getBufferData(FID, &SourceInvalid);

422

423 if (SourceInvalid)

424 return std::nullopt;

425

426 return Source;

427}

428

433 std::optional<llvm::DIFile::ChecksumInfo> CSInfo;

434

436

437

438

439 FileName = TheCU->getFile()->getFilename();

440 CSInfo = TheCU->getFile()->getChecksum();

441 } else {

444

446 FileName = TheCU->getFile()->getFilename();

447 } else {

449 }

451 }

452

453

454 auto It = DIFileCache.find(FileName.data());

455 if (It != DIFileCache.end()) {

456

457 if (llvm::Metadata *V = It->second)

458 return castllvm::DIFile(V);

459 }

460

461

463 if (!CSInfo) {

464 std::optionalllvm::DIFile::ChecksumKind CSKind =

465 computeChecksum(FID, Checksum);

466 if (CSKind)

467 CSInfo.emplace(*CSKind, Checksum);

468 }

469 return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc)));

470}

471

472llvm::DIFile *CGDebugInfo::createFile(

474 std::optional<llvm::DIFile::ChecksumInfo> CSInfo,

475 std::optional Source) {

476 StringRef Dir;

477 StringRef File;

479 std::string CurDir = remapDIPath(getCurrentDirname());

482 if (llvm::sys::path::is_absolute(RemappedFile)) {

483

484

485 auto FileIt = llvm::sys::path::begin(RemappedFile);

486 auto FileE = llvm::sys::path::end(RemappedFile);

487 auto CurDirIt = llvm::sys::path::begin(CurDir);

488 auto CurDirE = llvm::sys::path::end(CurDir);

489 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)

490 llvm::sys::path::append(DirBuf, *CurDirIt);

491 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {

492

493

494 Dir = {};

495 File = RemappedFile;

496 } else {

497 for (; FileIt != FileE; ++FileIt)

498 llvm::sys::path::append(FileBuf, *FileIt);

499 Dir = DirBuf;

500 File = FileBuf;

501 }

502 } else {

503 if (!llvm::sys::path::is_absolute(FileName))

504 Dir = CurDir;

505 File = RemappedFile;

506 }

507 llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source);

508 DIFileCache[FileName.data()].reset(F);

509 return F;

510}

511

515 if (llvm::sys::path::replace_path_prefix(P, From, To))

516 break;

517 return P.str().str();

518}

519

522 return 0;

524 return SM.getPresumedLoc(Loc).getLine();

525}

526

527unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) {

528

530 return 0;

531

532

534 return 0;

538}

539

540StringRef CGDebugInfo::getCurrentDirname() {

543

544 if (!CWDName.empty())

545 return CWDName;

546 llvm::ErrorOrstd::string CWD =

547 CGM.getFileSystem()->getCurrentWorkingDirectory();

548 if (!CWD)

549 return StringRef();

550 return CWDName = internString(*CWD);

551}

552

553void CGDebugInfo::CreateCompileUnit() {

555 std::optionalllvm::DIFile::ChecksumKind CSKind;

556 std::optional<llvm::DIFile::ChecksumInfo> CSInfo;

557

558

559

560

561

562

563

564

565

569 std::string MainFileName = CGO.MainFileName;

570 if (MainFileName.empty())

571 MainFileName = "";

572

573

574

575

576

577 std::string MainFileDir;

579 SM.getFileEntryRefForID(SM.getMainFileID())) {

580 MainFileDir = std::string(MainFile->getDir().getName());

581 if (!llvm::sys::path::is_absolute(MainFileName)) {

583 llvm::sys::path::Style Style =

586 ? llvm::sys::path::Style::windows_backslash

587 : llvm::sys::path::Style::posix)

588 : llvm::sys::path::Style::native;

589 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);

590 MainFileName = std::string(

591 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));

592 }

593

594

595

596

597

598 if (MainFile->getName() == MainFileName &&

600 MainFile->getName().rsplit('.').second)

602 MainFileName = CGM.getModule().getName().str();

603 } else {

604 CSKind = computeChecksum(SM.getMainFileID(), Checksum);

605 }

606 }

607

608 llvm::dwarf::SourceLanguage LangTag;

609 if (LO.CPlusPlus) {

610 if (LO.ObjC)

611 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;

612 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)

613 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;

614 else if (LO.CPlusPlus14)

615 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;

616 else if (LO.CPlusPlus11)

617 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;

618 else

619 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;

620 } else if (LO.ObjC) {

621 LangTag = llvm::dwarf::DW_LANG_ObjC;

622 } else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf ||

624 LangTag = llvm::dwarf::DW_LANG_OpenCL;

625 } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {

626 LangTag = llvm::dwarf::DW_LANG_C11;

627 } else if (LO.C99) {

628 LangTag = llvm::dwarf::DW_LANG_C99;

629 } else {

630 LangTag = llvm::dwarf::DW_LANG_C89;

631 }

632

634

635

636 unsigned RuntimeVers = 0;

637 if (LO.ObjC)

639

640 llvm::DICompileUnit::DebugEmissionKind EmissionKind;

641 switch (DebugKind) {

642 case llvm::codegenoptions::NoDebugInfo:

643 case llvm::codegenoptions::LocTrackingOnly:

644 EmissionKind = llvm::DICompileUnit::NoDebug;

645 break;

646 case llvm::codegenoptions::DebugLineTablesOnly:

647 EmissionKind = llvm::DICompileUnit::LineTablesOnly;

648 break;

649 case llvm::codegenoptions::DebugDirectivesOnly:

650 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;

651 break;

652 case llvm::codegenoptions::DebugInfoConstructor:

653 case llvm::codegenoptions::LimitedDebugInfo:

654 case llvm::codegenoptions::FullDebugInfo:

655 case llvm::codegenoptions::UnusedTypeInfo:

656 EmissionKind = llvm::DICompileUnit::FullDebug;

657 break;

658 }

659

662

663

664

665

666 if (CSKind)

667 CSInfo.emplace(*CSKind, Checksum);

668 llvm::DIFile *CUFile = DBuilder.createFile(

670 getSource(SM, SM.getMainFileID()));

671

672 StringRef Sysroot, SDK;

673 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {

675 auto B = llvm::sys::path::rbegin(Sysroot);

676 auto E = llvm::sys::path::rend(Sysroot);

677 auto It =

678 std::find_if(B, E, [](auto SDK) { return SDK.ends_with(".sdk"); });

679 if (It != E)

680 SDK = *It;

681 }

682

683 llvm::DICompileUnit::DebugNameTableKind NameTableKind =

684 static_castllvm::DICompileUnit::DebugNameTableKind\(

685 CGOpts.DebugNameTable);

687 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;

688 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)

689 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;

690

691

692 TheCU = DBuilder.createCompileUnit(

693 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",

694 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,

695 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,

696 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,

697 NameTableKind, CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK);

698}

699

700llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {

701 llvm::dwarf::TypeKind Encoding;

702 StringRef BTName;

704#define BUILTIN_TYPE(Id, SingletonId)

705#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:

706#include "clang/AST/BuiltinTypes.def"

707 case BuiltinType::Dependent:

708 llvm_unreachable("Unexpected builtin type");

709 case BuiltinType::NullPtr:

710 return DBuilder.createNullPtrType();

711 case BuiltinType::Void:

712 return nullptr;

713 case BuiltinType::ObjCClass:

714 if (!ClassTy)

715 ClassTy =

716 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

717 "objc_class", TheCU, TheCU->getFile(), 0);

718 return ClassTy;

719 case BuiltinType::ObjCId: {

720

721

722

723

724

725 if (ObjTy)

726 return ObjTy;

727

728 if (!ClassTy)

729 ClassTy =

730 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

731 "objc_class", TheCU, TheCU->getFile(), 0);

732

734

735 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);

736

737 ObjTy = DBuilder.createStructType(TheCU, "objc_object", TheCU->getFile(), 0,

738 0, 0, llvm::DINode::FlagZero, nullptr,

739 llvm::DINodeArray());

740

741 DBuilder.replaceArrays(

742 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(

743 ObjTy, "isa", TheCU->getFile(), 0, Size, 0, 0,

744 llvm::DINode::FlagZero, ISATy)));

745 return ObjTy;

746 }

747 case BuiltinType::ObjCSel: {

748 if (!SelTy)

749 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

750 "objc_selector", TheCU,

751 TheCU->getFile(), 0);

752 return SelTy;

753 }

754

755#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \

756 case BuiltinType::Id: \

757 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \

758 SingletonId);

759#include "clang/Basic/OpenCLImageTypes.def"

760 case BuiltinType::OCLSampler:

761 return getOrCreateStructPtrType("opencl_sampler_t", OCLSamplerDITy);

762 case BuiltinType::OCLEvent:

763 return getOrCreateStructPtrType("opencl_event_t", OCLEventDITy);

764 case BuiltinType::OCLClkEvent:

765 return getOrCreateStructPtrType("opencl_clk_event_t", OCLClkEventDITy);

766 case BuiltinType::OCLQueue:

767 return getOrCreateStructPtrType("opencl_queue_t", OCLQueueDITy);

768 case BuiltinType::OCLReserveID:

769 return getOrCreateStructPtrType("opencl_reserve_id_t", OCLReserveIDDITy);

770#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \

771 case BuiltinType::Id: \

772 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);

773#include "clang/Basic/OpenCLExtensionTypes.def"

774#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \

775 case BuiltinType::Id: \

776 return getOrCreateStructPtrType(#Name, SingletonId);

777#include "clang/Basic/HLSLIntangibleTypes.def"

778

779#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:

780#include "clang/Basic/AArch64SVEACLETypes.def"

781 {

782 if (BT->getKind() == BuiltinType::MFloat8) {

783 Encoding = llvm::dwarf::DW_ATE_unsigned_char;

785

787 return DBuilder.createBasicType(BTName, Size, Encoding);

788 }

790

791 BT->getKind() == BuiltinType::SveCount

794 1)

795 : CGM.getContext().getBuiltinVectorTypeInfo(BT);

796

797

798

799

800

801 assert((BT->getKind() != BuiltinType::SveCount || Info.NumVectors == 1) &&

802 "Unsupported number of vectors for svcount_t");

803

804

805

806 unsigned NumElems = Info.EC.getKnownMinValue() * Info.NumVectors;

808 NumElems /= 8;

810 }

811

812 llvm::Metadata *LowerBound, *UpperBound;

813 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

815 if (Info.EC.isScalable()) {

816 unsigned NumElemsPerVG = NumElems / 2;

818 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,

819 46, 0, llvm::dwarf::DW_OP_mul,

820 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});

821 UpperBound = DBuilder.createExpression(Expr);

822 } else

823 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

824 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));

825

826 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(

827 nullptr, LowerBound, UpperBound, nullptr);

828 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

829 llvm::DIType *ElemTy =

830 getOrCreateType(Info.ElementType, TheCU->getFile());

832 return DBuilder.createVectorType( 0, Align, ElemTy,

833 SubscriptArray);

834 }

835

836

837#define PPC_VECTOR_TYPE(Name, Id, size) \

838 case BuiltinType::Id:

839#include "clang/Basic/PPCTypes.def"

840 return CreateType(cast(CGM.getContext().IntTy));

841

842#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:

843#include "clang/Basic/RISCVVTypes.def"

844 {

847

848 unsigned ElementCount = Info.EC.getKnownMinValue();

850

851 bool Fractional = false;

852 unsigned LMUL;

853 unsigned FixedSize = ElementCount * SEW;

855

856 LMUL = 1;

857 } else if (FixedSize < 64) {

858

859 Fractional = true;

860 LMUL = 64 / FixedSize;

861 } else {

862 LMUL = FixedSize / 64;

863 }

864

865

867

868

869

870 {llvm::dwarf::DW_OP_bregx,

871 4096 + 0xC22,

872 0,

873 llvm::dwarf::DW_OP_constu,

874 SEW / 8,

875 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});

876 if (Fractional)

877 Expr.push_back(llvm::dwarf::DW_OP_div);

878 else

879 Expr.push_back(llvm::dwarf::DW_OP_mul);

880

881 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});

882

883 auto *LowerBound =

884 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

886 auto *UpperBound = DBuilder.createExpression(Expr);

887 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(

888 nullptr, LowerBound, UpperBound, nullptr);

889 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

890 llvm::DIType *ElemTy =

891 getOrCreateType(Info.ElementType, TheCU->getFile());

892

894 return DBuilder.createVectorType(0, Align, ElemTy,

895 SubscriptArray);

896 }

897

898#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \

899 case BuiltinType::Id: { \

900 if (!SingletonId) \

901 SingletonId = \

902 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \

903 MangledName, TheCU, TheCU->getFile(), 0); \

904 return SingletonId; \

905 }

906#include "clang/Basic/WebAssemblyReferenceTypes.def"

907#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \

908 case BuiltinType::Id: { \

909 if (!SingletonId) \

910 SingletonId = \

911 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \

912 TheCU, TheCU->getFile(), 0); \

913 return SingletonId; \

914 }

915#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \

916 case BuiltinType::Id: { \

917 if (!SingletonId) \

918 SingletonId = \

919 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \

920 return SingletonId; \

921 }

922#include "clang/Basic/AMDGPUTypes.def"

923 case BuiltinType::UChar:

924 case BuiltinType::Char_U:

925 Encoding = llvm::dwarf::DW_ATE_unsigned_char;

926 break;

927 case BuiltinType::Char_S:

928 case BuiltinType::SChar:

929 Encoding = llvm::dwarf::DW_ATE_signed_char;

930 break;

931 case BuiltinType::Char8:

932 case BuiltinType::Char16:

933 case BuiltinType::Char32:

934 Encoding = llvm::dwarf::DW_ATE_UTF;

935 break;

936 case BuiltinType::UShort:

937 case BuiltinType::UInt:

938 case BuiltinType::UInt128:

939 case BuiltinType::ULong:

940 case BuiltinType::WChar_U:

941 case BuiltinType::ULongLong:

942 Encoding = llvm::dwarf::DW_ATE_unsigned;

943 break;

944 case BuiltinType::Short:

945 case BuiltinType::Int:

946 case BuiltinType::Int128:

947 case BuiltinType::Long:

948 case BuiltinType::WChar_S:

949 case BuiltinType::LongLong:

950 Encoding = llvm::dwarf::DW_ATE_signed;

951 break;

952 case BuiltinType::Bool:

953 Encoding = llvm::dwarf::DW_ATE_boolean;

954 break;

955 case BuiltinType::Half:

956 case BuiltinType::Float:

957 case BuiltinType::LongDouble:

958 case BuiltinType::Float16:

959 case BuiltinType::BFloat16:

960 case BuiltinType::Float128:

961 case BuiltinType::Double:

962 case BuiltinType::Ibm128:

963

964

965

966

967

968 Encoding = llvm::dwarf::DW_ATE_float;

969 break;

970 case BuiltinType::ShortAccum:

971 case BuiltinType::Accum:

972 case BuiltinType::LongAccum:

973 case BuiltinType::ShortFract:

974 case BuiltinType::Fract:

975 case BuiltinType::LongFract:

976 case BuiltinType::SatShortFract:

977 case BuiltinType::SatFract:

978 case BuiltinType::SatLongFract:

979 case BuiltinType::SatShortAccum:

980 case BuiltinType::SatAccum:

981 case BuiltinType::SatLongAccum:

982 Encoding = llvm::dwarf::DW_ATE_signed_fixed;

983 break;

984 case BuiltinType::UShortAccum:

985 case BuiltinType::UAccum:

986 case BuiltinType::ULongAccum:

987 case BuiltinType::UShortFract:

988 case BuiltinType::UFract:

989 case BuiltinType::ULongFract:

990 case BuiltinType::SatUShortAccum:

991 case BuiltinType::SatUAccum:

992 case BuiltinType::SatULongAccum:

993 case BuiltinType::SatUShortFract:

994 case BuiltinType::SatUFract:

995 case BuiltinType::SatULongFract:

996 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;

997 break;

998 }

999

1001

1003 return DBuilder.createBasicType(BTName, Size, Encoding);

1004}

1005

1006llvm::DIType *CGDebugInfo::CreateType(const BitIntType *Ty) {

1007

1008 StringRef Name = Ty->isUnsigned() ? "unsigned _BitInt" : "_BitInt";

1010 ? llvm::dwarf::DW_ATE_unsigned

1011 : llvm::dwarf::DW_ATE_signed;

1012

1014 Encoding);

1015}

1016

1017llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {

1018

1019 llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;

1021 Encoding = llvm::dwarf::DW_ATE_lo_user;

1022

1024 return DBuilder.createBasicType("complex", Size, Encoding);

1025}

1026

1028

1033}

1034

1038 return llvm::dwarf::DW_TAG_const_type;

1039 }

1042 return llvm::dwarf::DW_TAG_volatile_type;

1043 }

1046 return llvm::dwarf::DW_TAG_restrict_type;

1047 }

1048 return (llvm::dwarf::Tag)0;

1049}

1050

1051llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,

1052 llvm::DIFile *Unit) {

1055

1057

1058

1059

1061 if (!Tag) {

1062 assert(Qc.empty() && "Unknown type qualifier for debug info");

1063 return getOrCreateType(QualType(T, 0), Unit);

1064 }

1065

1066 auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);

1067

1068

1069

1070 return DBuilder.createQualifiedType(Tag, FromTy);

1071}

1072

1073llvm::DIType *CGDebugInfo::CreateQualifiedType(const FunctionProtoType *F,

1074 llvm::DIFile *Unit) {

1078

1079

1080

1082 if (!Tag) {

1083 assert(Q.empty() && "Unknown type qualifier for debug info");

1084 return nullptr;

1085 }

1086

1087 auto *FromTy =

1090 Unit);

1091

1092

1093

1094 return DBuilder.createQualifiedType(Tag, FromTy);

1095}

1096

1098 llvm::DIFile *Unit) {

1099

1100

1101

1102

1105

1106 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,

1108}

1109

1110llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,

1111 llvm::DIFile *Unit) {

1112 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,

1114}

1115

1116

1118 switch (TheCU->getSourceLanguage()) {

1119 case llvm::dwarf::DW_LANG_C_plus_plus:

1120 case llvm::dwarf::DW_LANG_C_plus_plus_11:

1121 case llvm::dwarf::DW_LANG_C_plus_plus_14:

1122 return true;

1123 case llvm::dwarf::DW_LANG_ObjC_plus_plus:

1124 return isa(TD) || isa(TD);

1125 default:

1126 return false;

1127 }

1128}

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1150

1152 llvm::DICompileUnit *TheCU) {

1153

1155 return false;

1156

1157

1159 return true;

1160

1161

1163 return true;

1164

1165 return false;

1166}

1167

1168

1170 llvm::DICompileUnit *TheCU) {

1173

1176 if (const auto *RD = dyn_cast(TD))

1178 if (RD->isDynamicClass() &&

1179 CGM.getVTableLinkage(RD) == llvm::GlobalValue::ExternalLinkage)

1181

1182

1183

1184 llvm::raw_svector_ostream Out(Identifier);

1187}

1188

1189

1191 llvm::dwarf::Tag Tag;

1193 Tag = llvm::dwarf::DW_TAG_structure_type;

1195 Tag = llvm::dwarf::DW_TAG_union_type;

1196 else {

1197

1198

1200 Tag = llvm::dwarf::DW_TAG_class_type;

1201 }

1202 return Tag;

1203}

1204

1205llvm::DICompositeType *

1206CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,

1207 llvm::DIScope *Ctx) {

1210 return castllvm::DICompositeType(T);

1211 llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());

1212 const unsigned Line =

1214 StringRef RDName = getClassName(RD);

1215

1218

1220 if (D && D->isCompleteDefinition())

1222

1223 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;

1224

1225

1226

1227

1228 if (const CXXRecordDecl *CXXRD = dyn_cast(RD))

1229 if (!CXXRD->hasDefinition() ||

1230 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))

1231 Flags |= llvm::DINode::FlagNonTrivial;

1232

1233

1235

1238 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(

1242 if (auto *TSpecial = dyn_cast(RD))

1243 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),

1244 CollectCXXTemplateParams(TSpecial, DefUnit));

1245 ReplaceMap.emplace_back(

1246 std::piecewise_construct, std::make_tuple(Ty),

1247 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));

1248 return RetTy;

1249}

1250

1251llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,

1252 const Type *Ty,

1254 llvm::DIFile *Unit) {

1255

1256

1259 std::optional DWARFAddressSpace =

1262

1265 BTFAttrTy = dyn_cast(Atomic->getValueType());

1266 else

1267 BTFAttrTy = dyn_cast(PointeeTy);

1269 while (BTFAttrTy) {

1270 StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();

1271 if (Tag.empty()) {

1272 llvm::Metadata *Ops[2] = {

1273 llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")),

1275 Annots.insert(Annots.begin(),

1277 }

1278 BTFAttrTy = dyn_cast(BTFAttrTy->getWrappedType());

1279 }

1280

1281 llvm::DINodeArray Annotations = nullptr;

1282 if (Annots.size() > 0)

1283 Annotations = DBuilder.getOrCreateArray(Annots);

1284

1285 if (Tag == llvm::dwarf::DW_TAG_reference_type ||

1286 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)

1287 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),

1288 Size, Align, DWARFAddressSpace);

1289 else

1290 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,

1291 Align, DWARFAddressSpace, StringRef(),

1292 Annotations);

1293}

1294

1295llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,

1296 llvm::DIType *&Cache) {

1299 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,

1300 TheCU, TheCU->getFile(), 0);

1302 Cache = DBuilder.createPointerType(Cache, Size);

1304}

1305

1306uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(

1307 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,

1310

1311

1312

1314

1315

1316

1317

1320 EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset));

1321 EltTys.push_back(CreateMemberType(Unit, FType, "__align", &FieldOffset));

1322 } else {

1324 EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));

1326 EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));

1327 EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset));

1329 EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset));

1333 EltTys.push_back(DBuilder.createMemberType(

1334 Unit, "__descriptor", nullptr, LineNo, FieldSize, FieldAlign,

1335 FieldOffset, llvm::DINode::FlagZero, DescTy));

1336 FieldOffset += FieldSize;

1337 }

1338

1339 return FieldOffset;

1340}

1341

1342llvm::DIType *CGDebugInfo::CreateType(const BlockPointerType *Ty,

1343 llvm::DIFile *Unit) {

1347 llvm::DINodeArray Elements;

1348

1349 FieldOffset = 0;

1351 EltTys.push_back(CreateMemberType(Unit, FType, "reserved", &FieldOffset));

1352 EltTys.push_back(CreateMemberType(Unit, FType, "Size", &FieldOffset));

1353

1354 Elements = DBuilder.getOrCreateArray(EltTys);

1355 EltTys.clear();

1356

1357 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;

1358

1359 auto *EltTy =

1360 DBuilder.createStructType(Unit, "__block_descriptor", nullptr, 0,

1361 FieldOffset, 0, Flags, nullptr, Elements);

1362

1363

1365

1366 auto *DescTy = DBuilder.createPointerType(EltTy, Size);

1367

1368 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,

1369 0, EltTys);

1370

1371 Elements = DBuilder.getOrCreateArray(EltTys);

1372

1373

1374

1375

1376

1377 EltTy = DBuilder.createStructType(Unit, "", nullptr, 0, FieldOffset, 0,

1378 Flags, nullptr, Elements);

1379

1380 return DBuilder.createPointerType(EltTy, Size);

1381}

1382

1386

1387

1388

1389

1390

1391

1392

1396

1397 if (Param->isParameterPack()) {

1399 break;

1400 }

1401

1402

1403

1404

1405

1406 if (SubstArgs.empty()) {

1407

1408

1409

1410

1411 break;

1412 }

1413

1414

1415 SpecArgs.push_back(SubstArgs.front());

1416 SubstArgs = SubstArgs.drop_front();

1417 }

1418 return SpecArgs;

1419}

1420

1422 llvm::DIFile *Unit) {

1424 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);

1425

1427 if (isa(TD))

1428 return Src;

1429

1430 const auto *AliasDecl = cast(TD)->getTemplatedDecl();

1431 if (AliasDecl->hasAttr())

1432 return Src;

1433

1435 llvm::raw_svector_ostream OS(NS);

1436

1437 auto PP = getPrintingPolicy();

1439

1441

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452

1453

1454

1455

1456

1457

1458

1459

1460

1461

1462

1464 auto ArgVector = ::GetTemplateArgs(TD, Ty);

1466

1467

1468

1469

1470

1471

1472 std::string Name;

1473 llvm::raw_string_ostream OS(Name);

1475 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=

1476 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||

1477 !HasReconstitutableArgs(Args.Args))

1479

1480 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(

1481 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),

1482 getDeclContextDescriptor(AliasDecl), CollectTemplateParams(Args, Unit));

1483 return AliasTy;

1484 }

1485

1488 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),

1489 getLineNumber(Loc),

1490 getDeclContextDescriptor(AliasDecl));

1491}

1492

1493

1494

1495

1499 if (RD && RD->isClass())

1503

1505 return llvm::DINode::FlagZero;

1506

1507 switch (Access) {

1509 return llvm::DINode::FlagPrivate;

1511 return llvm::DINode::FlagProtected;

1513 return llvm::DINode::FlagPublic;

1515 return llvm::DINode::FlagZero;

1516 }

1517 llvm_unreachable("unexpected access enumerator");

1518}

1519

1520llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,

1521 llvm::DIFile *Unit) {

1522 llvm::DIType *Underlying =

1524

1526 return Underlying;

1527

1528

1529

1531

1533

1534 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->getDecl());

1535

1536 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

1538 if (isa(DC))

1540

1541 return DBuilder.createTypedef(Underlying, Ty->getDecl()->getName(),

1542 getOrCreateFile(Loc), getLineNumber(Loc),

1543 getDeclContextDescriptor(Ty->getDecl()), Align,

1544 Flags, Annotations);

1545}

1546

1548 switch (CC) {

1550

1551 return 0;

1552

1554 return llvm::dwarf::DW_CC_BORLAND_stdcall;

1556 return llvm::dwarf::DW_CC_BORLAND_msfastcall;

1558 return llvm::dwarf::DW_CC_BORLAND_thiscall;

1560 return llvm::dwarf::DW_CC_LLVM_vectorcall;

1562 return llvm::dwarf::DW_CC_BORLAND_pascal;

1564 return llvm::dwarf::DW_CC_LLVM_Win64;

1566 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;

1570 return llvm::dwarf::DW_CC_LLVM_AAPCS;

1572 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;

1574 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;

1576 return llvm::dwarf::DW_CC_LLVM_SpirFunction;

1579 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;

1581 return llvm::dwarf::DW_CC_LLVM_Swift;

1583 return llvm::dwarf::DW_CC_LLVM_SwiftTail;

1585 return llvm::dwarf::DW_CC_LLVM_PreserveMost;

1587 return llvm::dwarf::DW_CC_LLVM_PreserveAll;

1589 return llvm::dwarf::DW_CC_LLVM_X86RegCall;

1591 return llvm::dwarf::DW_CC_LLVM_M68kRTD;

1593 return llvm::dwarf::DW_CC_LLVM_PreserveNone;

1595 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;

1596 }

1597 return 0;

1598}

1599

1601 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

1602 if (Func->getExtProtoInfo().RefQualifier == RQ_LValue)

1603 Flags |= llvm::DINode::FlagLValueReference;

1604 if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)

1605 Flags |= llvm::DINode::FlagRValueReference;

1606 return Flags;

1607}

1608

1609llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,

1610 llvm::DIFile *Unit) {

1611 const auto *FPT = dyn_cast(Ty);

1612 if (FPT) {

1613 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))

1614 return QTy;

1615 }

1616

1617

1618

1620

1621

1622 EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit));

1623

1624 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

1625

1626

1627 if (!FPT) {

1628 EltTys.push_back(DBuilder.createUnspecifiedParameter());

1629 } else {

1631 for (const QualType &ParamType : FPT->param_types())

1632 EltTys.push_back(getOrCreateType(ParamType, Unit));

1633 if (FPT->isVariadic())

1634 EltTys.push_back(DBuilder.createUnspecifiedParameter());

1635 }

1636

1637 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);

1638 llvm::DIType *F = DBuilder.createSubroutineType(

1640 return F;

1641}

1642

1643llvm::DIDerivedType *

1644CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,

1645 llvm::DIScope *RecordTy, const RecordDecl *RD) {

1646 StringRef Name = BitFieldDecl->getName();

1648 if (BitFieldDecl->hasAttr())

1649 Ty = BitFieldDecl->getAttr()->getType();

1651 llvm::DIFile *VUnit = getOrCreateFile(Loc);

1652 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);

1653

1654

1655 llvm::DIFile *File = getOrCreateFile(Loc);

1656 unsigned Line = getLineNumber(Loc);

1657

1661 assert(SizeInBits > 0 && "found named 0-width bitfield");

1662 uint64_t StorageOffsetInBits =

1665

1666

1667

1669 Offset = BitFieldInfo.StorageSize - BitFieldInfo.Size - Offset;

1670 uint64_t OffsetInBits = StorageOffsetInBits + Offset;

1672 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);

1673 return DBuilder.createBitFieldMemberType(

1674 RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits,

1675 Flags, DebugType, Annotations);

1676}

1677

1678llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(

1679 const FieldDecl *BitFieldDecl, const llvm::DIDerivedType *BitFieldDI,

1681

1683 return nullptr;

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700

1701

1702

1703

1704

1705

1706

1707 if (PreviousFieldsDI.empty())

1708 return nullptr;

1709

1710

1711 auto *PreviousMDEntry =

1712 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();

1713 auto *PreviousMDField =

1714 dyn_cast_or_nullllvm::DIDerivedType(PreviousMDEntry);

1715 if (!PreviousMDField || !PreviousMDField->isBitField() ||

1716 PreviousMDField->getSizeInBits() == 0)

1717 return nullptr;

1718

1719 auto PreviousBitfield = RD->field_begin();

1720 std::advance(PreviousBitfield, BitFieldDecl->getFieldIndex() - 1);

1721

1722 assert(PreviousBitfield->isBitField());

1723

1724 if (!PreviousBitfield->isZeroLengthBitField())

1725 return nullptr;

1726

1727 QualType Ty = PreviousBitfield->getType();

1729 llvm::DIFile *VUnit = getOrCreateFile(Loc);

1730 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);

1731 llvm::DIScope *RecordTy = BitFieldDI->getScope();

1732

1733 llvm::DIFile *File = getOrCreateFile(Loc);

1734 unsigned Line = getLineNumber(Loc);

1735

1736 uint64_t StorageOffsetInBits =

1737 castllvm::ConstantInt(BitFieldDI->getStorageOffsetInBits())

1738 ->getZExtValue();

1739

1740 llvm::DINode::DIFlags Flags =

1741 getAccessFlag(PreviousBitfield->getAccess(), RD);

1742 llvm::DINodeArray Annotations =

1743 CollectBTFDeclTagAnnotations(*PreviousBitfield);

1744 return DBuilder.createBitFieldMemberType(

1745 RecordTy, "", File, Line, 0, StorageOffsetInBits, StorageOffsetInBits,

1746 Flags, DebugType, Annotations);

1747}

1748

1749llvm::DIType *CGDebugInfo::createFieldType(

1751 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,

1752 llvm::DIScope *scope, const RecordDecl *RD, llvm::DINodeArray Annotations) {

1753 llvm::DIType *debugType = getOrCreateType(type, tunit);

1754

1755

1756 llvm::DIFile *file = getOrCreateFile(loc);

1757 const unsigned line = getLineNumber(loc.isValid() ? loc : CurLoc);

1758

1760 auto Align = AlignInBits;

1761 if (type->isIncompleteArrayType()) {

1763 SizeInBits = TI.Width;

1764 if (!Align)

1766 }

1767

1768 llvm::DINode::DIFlags flags = getAccessFlag(AS, RD);

1769 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,

1770 offsetInBits, flags, debugType, Annotations);

1771}

1772

1773llvm::DISubprogram *

1774CGDebugInfo::createInlinedTrapSubprogram(StringRef FuncName,

1775 llvm::DIFile *FileScope) {

1776

1777

1778

1779 llvm::DISubprogram *&SP = InlinedTrapFuncMap[FuncName];

1780

1781 if (!SP) {

1782 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(nullptr);

1783 SP = DBuilder.createFunction(

1784 FileScope, FuncName, StringRef(),

1785 FileScope, 0, DIFnTy,

1786 0,

1787 llvm::DINode::FlagArtificial,

1788 llvm::DISubprogram::SPFlagDefinition,

1789 nullptr, nullptr, nullptr);

1790 }

1791

1792 return SP;

1793}

1794

1795void CGDebugInfo::CollectRecordLambdaFields(

1797 llvm::DIType *RecordTy) {

1798

1799

1800

1803 unsigned fieldno = 0;

1806 I != E; ++I, ++Field, ++fieldno) {

1808 if (C.capturesVariable()) {

1810 assert(Field->isBitField() && "lambdas don't have bitfield members!");

1812 StringRef VName = V->getName();

1813 llvm::DIFile *VUnit = getOrCreateFile(Loc);

1815 llvm::DIType *FieldType = createFieldType(

1816 VName, Field->getType(), Loc, Field->getAccess(),

1817 layout.getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);

1818 elements.push_back(FieldType);

1819 } else if (C.capturesThis()) {

1820

1821

1822

1823

1825 llvm::DIFile *VUnit = getOrCreateFile(f->getLocation());

1827 StringRef ThisName =

1828 CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this";

1829 llvm::DIType *fieldType = createFieldType(

1831 layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl);

1832

1833 elements.push_back(fieldType);

1834 }

1835 }

1836}

1837

1838llvm::DIDerivedType *

1839CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,

1841

1842

1844 llvm::DIFile *VUnit = getOrCreateFile(Var->getLocation());

1845 llvm::DIType *VTy = getOrCreateType(Var->getType(), VUnit);

1846

1847 unsigned LineNumber = getLineNumber(Var->getLocation());

1848 StringRef VName = Var->getName();

1849

1850

1851

1852 llvm::Constant *C = nullptr;

1856 if (Value->isInt())

1858 if (Value->isFloat())

1860 }

1861 }

1862

1865 ? llvm::dwarf::DW_TAG_variable

1866 : llvm::dwarf::DW_TAG_member;

1868 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(

1869 RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Tag, Align);

1871 return GV;

1872}

1873

1874void CGDebugInfo::CollectRecordNormalField(

1875 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,

1880

1881

1882 if (name.empty() && type->isRecordType())

1883 return;

1884

1885 llvm::DIType *FieldType;

1887 llvm::DIDerivedType *BitFieldType;

1888 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);

1889 if (llvm::DIType *Separator =

1890 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))

1891 elements.push_back(Separator);

1892 } else {

1894 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);

1895 FieldType =

1897 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);

1898 }

1899

1900 elements.push_back(FieldType);

1901}

1902

1903void CGDebugInfo::CollectRecordNestedType(

1906

1907 if (isa(Ty))

1908 return;

1910 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))

1911 elements.push_back(nestedType);

1912}

1913

1914void CGDebugInfo::CollectRecordFields(

1915 const RecordDecl *record, llvm::DIFile *tunit,

1917 llvm::DICompositeType *RecordTy) {

1918 const auto *CXXDecl = dyn_cast(record);

1919

1920 if (CXXDecl && CXXDecl->isLambda())

1921 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);

1922 else {

1924

1925

1926 unsigned fieldNo = 0;

1927

1928

1929

1930 for (const auto *I : record->decls())

1931 if (const auto *V = dyn_cast(I)) {

1932 if (V->hasAttr())

1933 continue;

1934

1935

1936

1938 isa(V))

1939 continue;

1940

1941 if (isa(V))

1942 continue;

1943

1944

1945 auto MI = StaticDataMemberCache.find(V->getCanonicalDecl());

1946 if (MI != StaticDataMemberCache.end()) {

1947 assert(MI->second &&

1948 "Static data member declaration should still exist");

1949 elements.push_back(MI->second);

1950 } else {

1951 auto Field = CreateRecordStaticField(V, RecordTy, record);

1952 elements.push_back(Field);

1953 }

1954 } else if (const auto *field = dyn_cast(I)) {

1955 CollectRecordNormalField(field, layout.getFieldOffset(fieldNo), tunit,

1956 elements, RecordTy, record);

1957

1958

1959 ++fieldNo;

1961

1962

1963 if (const auto *nestedType = dyn_cast(I)) {

1964

1965 if (isa(I) &&

1966 cast(I)->isAnonymousStructOrUnion())

1967 continue;

1968 if (!nestedType->isImplicit() &&

1969 nestedType->getDeclContext() == record)

1970 CollectRecordNestedType(nestedType, elements);

1971 }

1972 }

1973 }

1974}

1975

1976llvm::DISubroutineType *

1977CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,

1978 llvm::DIFile *Unit) {

1981 return cast_or_nullllvm::DISubroutineType(

1983

1987

1988 return getOrCreateInstanceMethodType(ThisType, Func, Unit);

1989}

1990

1991llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(

1999

2000

2001

2002

2003

2004

2005

2006

2007 const auto *OriginalFunc = castllvm::DISubroutineType(

2009 Func->getReturnType(), Func->getParamTypes(), EPI),

2010 Unit));

2011 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();

2012 assert(Args.size() && "Invalid number of arguments!");

2013

2015

2016

2017 Elts.push_back(Args[0]);

2018

2019 const bool HasExplicitObjectParameter = ThisPtr.isNull();

2020

2021

2022

2023 if (!HasExplicitObjectParameter) {

2024 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);

2025 TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);

2026 ThisPtrType =

2027 DBuilder.createObjectPointerType(ThisPtrType, true);

2028 Elts.push_back(ThisPtrType);

2029 }

2030

2031

2032 for (unsigned i = 1, e = Args.size(); i != e; ++i)

2033 Elts.push_back(Args[i]);

2034

2035

2036 if (HasExplicitObjectParameter) {

2037 assert(Elts.size() >= 2 && Args.size() >= 2 &&

2038 "Expected at least return type and object parameter.");

2039 Elts[1] = DBuilder.createObjectPointerType(Args[1], false);

2040 }

2041

2042 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);

2043

2044 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),

2046}

2047

2048

2049

2051 if (const auto *NRD = dyn_cast(RD->getDeclContext()))

2054 return true;

2055 return false;

2056}

2057

2058llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(

2059 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {

2060 bool IsCtorOrDtor =

2061 isa(Method) || isa(Method);

2062

2063 StringRef MethodName = getFunctionName(Method);

2064 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);

2065

2066

2067

2068 StringRef MethodLinkageName;

2069

2070

2071

2072

2073

2076

2077

2078 llvm::DIFile *MethodDefUnit = nullptr;

2079 unsigned MethodLine = 0;

2081 MethodDefUnit = getOrCreateFile(Method->getLocation());

2082 MethodLine = getLineNumber(Method->getLocation());

2083 }

2084

2085

2086 llvm::DIType *ContainingType = nullptr;

2087 unsigned VIndex = 0;

2088 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

2089 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;

2091

2094 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;

2095 else

2096 SPFlags |= llvm::DISubprogram::SPFlagVirtual;

2097

2099

2100

2101 if (!isa(Method))

2103 } else {

2104

2105

2106 const auto *DD = dyn_cast(Method);

2110 VIndex = ML.Index;

2111

2112

2113

2114

2115

2116

2118 Flags |= llvm::DINode::FlagIntroducedVirtual;

2119

2120

2121

2122

2126 }

2127 ContainingType = RecordTy;

2128 }

2129

2131 SPFlags |= llvm::DISubprogram::SPFlagDeleted;

2132

2134 Flags |= llvm::DINode::FlagNoReturn;

2135

2137 Flags |= llvm::DINode::FlagStaticMember;

2139 Flags |= llvm::DINode::FlagArtificial;

2141 if (const auto *CXXC = dyn_cast(Method)) {

2142 if (CXXC->isExplicit())

2143 Flags |= llvm::DINode::FlagExplicit;

2144 } else if (const auto *CXXC = dyn_cast(Method)) {

2145 if (CXXC->isExplicit())

2146 Flags |= llvm::DINode::FlagExplicit;

2147 }

2149 Flags |= llvm::DINode::FlagPrototyped;

2151 Flags |= llvm::DINode::FlagLValueReference;

2153 Flags |= llvm::DINode::FlagRValueReference;

2155 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;

2157 SPFlags |= llvm::DISubprogram::SPFlagOptimized;

2158

2159

2160

2161 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)

2162 if (const CXXConstructorDecl *CD = dyn_cast(Method))

2164

2165 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);

2166 llvm::DISubprogram *SP = DBuilder.createMethod(

2167 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,

2168 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,

2169 TParamsArray.get());

2170

2172

2173 return SP;

2174}

2175

2176void CGDebugInfo::CollectCXXMemberFunctions(

2179

2180

2181

2182

2183 for (const auto *I : RD->decls()) {

2184 const auto *Method = dyn_cast(I);

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195 if (!Method || Method->isImplicit() || Method->hasAttr())

2196 continue;

2197

2199 continue;

2200

2201

2202

2203

2204

2205

2206

2208 EltTys.push_back(MI == SPCache.end()

2209 ? CreateCXXMemberFunction(Method, Unit, RecordTy)

2210 : static_cast<llvm::Metadata *>(MI->second));

2211 }

2212}

2213

2214void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit,

2216 llvm::DIType *RecordTy) {

2217 llvm::DenseSet<CanonicalDeclPtr> SeenTypes;

2218 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->bases(), SeenTypes,

2219 llvm::DINode::FlagZero);

2220

2221

2222

2224 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->vbases(), SeenTypes,

2225 llvm::DINode::FlagIndirectVirtualBase);

2226 }

2227}

2228

2229void CGDebugInfo::CollectCXXBasesAux(

2234 llvm::DINode::DIFlags StartingFlags) {

2236 for (const auto &BI : Bases) {

2237 const auto *Base =

2238 cast(BI.getType()->castAs<RecordType>()->getDecl());

2239 if (!SeenTypes.insert(Base).second)

2240 continue;

2241 auto *BaseTy = getOrCreateType(BI.getType(), Unit);

2242 llvm::DINode::DIFlags BFlags = StartingFlags;

2245

2246 if (BI.isVirtual()) {

2248

2249

2253 } else {

2254

2255

2256 BaseOffset =

2262 }

2263 BFlags |= llvm::DINode::FlagVirtual;

2264 } else

2266

2267

2268

2269 BFlags |= getAccessFlag(BI.getAccessSpecifier(), RD);

2270 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,

2271 VBPtrOffset, BFlags);

2272 EltTys.push_back(DTy);

2273 }

2274}

2275

2276llvm::DINodeArray

2277CGDebugInfo::CollectTemplateParams(std::optional OArgs,

2278 llvm::DIFile *Unit) {

2279 if (!OArgs)

2280 return llvm::DINodeArray();

2281 TemplateArgs &Args = *OArgs;

2283 for (unsigned i = 0, e = Args.Args.size(); i != e; ++i) {

2285 StringRef Name;

2287 if (Args.TList)

2288 Name = Args.TList->getParam(i)->getName();

2289

2292 llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit);

2293 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(

2294 TheCU, Name, TTy, defaultParameter));

2295

2296 } break;

2298 llvm::DIType *TTy = getOrCreateType(TA.getIntegralType(), Unit);

2299 TemplateParams.push_back(DBuilder.createTemplateValueParameter(

2300 TheCU, Name, TTy, defaultParameter,

2302 } break;

2306 llvm::DIType *TTy = getOrCreateType(T, Unit);

2307 llvm::Constant *V = nullptr;

2308

2309

2311 D->hasAttr()) {

2312

2313

2314 if (const auto *VD = dyn_cast(D))

2316

2317

2318 else if (const auto *MD = dyn_cast(D);

2319 MD && MD->isImplicitObjectMemberFunction())

2321 else if (const auto *FD = dyn_cast(D))

2323

2324

2325 else if (const auto *MPT =

2326 dyn_cast(T.getTypePtr())) {

2327

2328

2329

2334 } else if (const auto *GD = dyn_cast(D)) {

2336 } else if (const auto *TPO = dyn_cast(D)) {

2340 else

2342 }

2343 assert(V && "Failed to find template parameter pointer");

2344 V = V->stripPointerCasts();

2345 }

2346 TemplateParams.push_back(DBuilder.createTemplateValueParameter(

2347 TheCU, Name, TTy, defaultParameter, cast_or_nullllvm::Constant(V)));

2348 } break;

2351 llvm::DIType *TTy = getOrCreateType(T, Unit);

2352 llvm::Constant *V = nullptr;

2353

2354

2355 if (const auto *MPT = dyn_cast(T.getTypePtr()))

2356

2357

2358

2359

2360

2361 if (MPT->isMemberDataPointer())

2363 if (V)

2364 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);

2365 TemplateParams.push_back(DBuilder.createTemplateValueParameter(

2366 TheCU, Name, TTy, defaultParameter, V));

2367 } break;

2370 llvm::DIType *TTy = getOrCreateType(T, Unit);

2373 TemplateParams.push_back(DBuilder.createTemplateValueParameter(

2374 TheCU, Name, TTy, defaultParameter, V));

2375 } break;

2377 std::string QualName;

2378 llvm::raw_string_ostream OS(QualName);

2380 OS, getPrintingPolicy());

2381 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(

2382 TheCU, Name, nullptr, QualName, defaultParameter));

2383 break;

2384 }

2386 TemplateParams.push_back(DBuilder.createTemplateParameterPack(

2387 TheCU, Name, nullptr,

2388 CollectTemplateParams({{nullptr, TA.getPackAsArray()}}, Unit)));

2389 break;

2396 assert(V && "Expression in template argument isn't constant");

2397 llvm::DIType *TTy = getOrCreateType(T, Unit);

2398 TemplateParams.push_back(DBuilder.createTemplateValueParameter(

2399 TheCU, Name, TTy, defaultParameter, V->stripPointerCasts()));

2400 } break;

2401

2404 llvm_unreachable(

2405 "These argument types shouldn't exist in concrete types");

2406 }

2407 }

2408 return DBuilder.getOrCreateArray(TemplateParams);

2409}

2410

2411std::optionalCGDebugInfo::TemplateArgs

2412CGDebugInfo::GetTemplateArgs(const FunctionDecl *FD) const {

2419 }

2420 return std::nullopt;

2421}

2422std::optionalCGDebugInfo::TemplateArgs

2423CGDebugInfo::GetTemplateArgs(const VarDecl *VD) const {

2424

2425

2426

2427 auto *TS = dyn_cast(VD);

2428 if (!TS)

2429 return std::nullopt;

2432 auto TA = TS->getTemplateArgs().asArray();

2433 return {{TList, TA}};

2434}

2435std::optionalCGDebugInfo::TemplateArgs

2436CGDebugInfo::GetTemplateArgs(const RecordDecl *RD) const {

2437 if (auto *TSpecial = dyn_cast(RD)) {

2438

2439

2440

2442 TSpecial->getSpecializedTemplate()->getTemplateParameters();

2444 return {{TPList, TAList.asArray()}};

2445 }

2446 return std::nullopt;

2447}

2448

2449llvm::DINodeArray

2450CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD,

2451 llvm::DIFile *Unit) {

2452 return CollectTemplateParams(GetTemplateArgs(FD), Unit);

2453}

2454

2455llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL,

2456 llvm::DIFile *Unit) {

2457 return CollectTemplateParams(GetTemplateArgs(VL), Unit);

2458}

2459

2460llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(const RecordDecl *RD,

2461 llvm::DIFile *Unit) {

2462 return CollectTemplateParams(GetTemplateArgs(RD), Unit);

2463}

2464

2465llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(const Decl *D) {

2466 if (D->hasAttr())

2467 return nullptr;

2468

2470 for (const auto *I : D->specific_attrs()) {

2471 llvm::Metadata *Ops[2] = {

2472 llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_decl_tag")),

2473 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};

2474 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));

2475 }

2476 return DBuilder.getOrCreateArray(Annotations);

2477}

2478

2479llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {

2480 if (VTablePtrType)

2481 return VTablePtrType;

2482

2484

2485

2486 llvm::Metadata *STy = getOrCreateType(Context.IntTy, Unit);

2487 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);

2488 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);

2491 std::optional DWARFAddressSpace =

2493

2494 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(

2495 SubTy, Size, 0, DWARFAddressSpace, "__vtbl_ptr_type");

2496 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);

2497 return VTablePtrType;

2498}

2499

2500StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {

2501

2503}

2504

2505StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD,

2507 llvm::Function *InitFn) {

2508

2509

2512 return InitFn->getName();

2513

2514

2515

2516

2517

2519 StringRef Quals;

2520 StringRef GVName;

2521 {

2522 llvm::raw_svector_ostream OS(QualifiedGV);

2524 std::tie(Quals, GVName) = OS.str().rsplit("::");

2525 if (GVName.empty())

2526 std::swap(Quals, GVName);

2527 }

2528

2530 llvm::raw_svector_ostream OS(InitName);

2531 if (!Quals.empty())

2532 OS << Quals << "::";

2533

2534 switch (StubKind) {

2537 llvm_unreachable("not an initializer");

2539 OS << "`dynamic initializer for '";

2540 break;

2542 OS << "`dynamic atexit destructor for '";

2543 break;

2544 }

2545

2546 OS << GVName;

2547

2548

2549 if (const auto *VTpl = dyn_cast(VD)) {

2551 getPrintingPolicy());

2552 }

2553

2554 OS << '\'';

2555

2556 return internString(OS.str());

2557}

2558

2559void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,

2561

2563 return;

2564

2565

2566

2567

2568

2571 return;

2572

2573

2574

2575

2576 llvm::DIType *VPtrTy = nullptr;

2577 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&

2579 if (NeedVTableShape) {

2584 unsigned VSlotCount =

2586 unsigned VTableWidth = PtrWidth * VSlotCount;

2588 std::optional DWARFAddressSpace =

2590

2591

2592 llvm::DIType *VTableType = DBuilder.createPointerType(

2593 nullptr, VTableWidth, 0, DWARFAddressSpace, "__vtbl_ptr_type");

2594 EltTys.push_back(VTableType);

2595

2596

2597 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);

2598 }

2599

2600

2602 return;

2603

2604 if (!VPtrTy)

2605 VPtrTy = getOrCreateVTablePtrType(Unit);

2606

2608 llvm::DIType *VPtrMember =

2609 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,

2610 llvm::DINode::FlagArtificial, VPtrTy);

2611 EltTys.push_back(VPtrMember);

2612}

2613

2617 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));

2618 return T;

2619}

2620

2624}

2625

2629 assert(D.isNull() && "null type");

2630 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));

2631 assert(T && "could not create debug info for type");

2632

2633 RetainedTypes.push_back(D.getAsOpaquePtr());

2634 return T;

2635}

2636

2641 llvm::codegenoptions::DebugLineTablesOnly)

2642 return;

2643 llvm::MDNode *node;

2646 else

2647 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));

2648

2649 CI->setMetadata("heapallocsite", node);

2650}

2651

2653 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

2654 return;

2657 auto I = TypeCache.find(TyPtr);

2658 if (I == TypeCache.end() || !castllvm::DIType(I->second)->isForwardDecl())

2659 return;

2660 llvm::DIType *Res = CreateTypeDefinition(Ty->castAs<EnumType>());

2661 assert(!Res->isForwardDecl());

2662 TypeCache[TyPtr].reset(Res);

2663}

2664

2666 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||

2669}

2670

2671

2673 if (RD->hasAttr())

2674 return true;

2676 if (MD->hasAttr())

2677 return true;

2678 return false;

2679}

2680

2681

2683

2685 return false;

2686

2688 return false;

2689 if (auto *CXXDecl = dyn_cast(RD)) {

2691 return false;

2692

2695

2696

2697

2699 if (auto *TD = dyn_cast(CXXDecl))

2700 Explicit = TD->isExplicitInstantiationOrSpecialization();

2702 return false;

2703

2706 if (!CXXDecl->field_begin()->isFromASTFile())

2707 return false;

2708 }

2709 }

2710 return true;

2711}

2712

2714 if (auto *CXXRD = dyn_cast(RD))

2715 if (CXXRD->isDynamicClass() &&

2717 llvm::GlobalValue::AvailableExternallyLinkage &&

2719 return;

2720

2722 return;

2723

2725}

2726

2728 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

2729 return;

2732 auto I = TypeCache.find(TyPtr);

2733 if (I != TypeCache.end() && !castllvm::DIType(I->second)->isForwardDecl())

2734 return;

2735

2736

2737

2738

2739 auto [Res, PrefRes] = CreateTypeDefinition(Ty->castAs<RecordType>());

2740 assert(!Res->isForwardDecl());

2741 TypeCache[TyPtr].reset(Res);

2742}

2743

2746 for (CXXMethodDecl *MD : llvm::make_range(I, End))

2748 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&

2749 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())

2750 return true;

2751 return false;

2752}

2753

2755

2756

2757

2758

2759

2760

2761

2762

2764 return false;

2765

2769 return false;

2770

2772 if (Ctor->isCopyOrMoveConstructor())

2773 continue;

2774 if (!Ctor->isDeleted())

2775 return true;

2776 }

2777 return false;

2778}

2779

2781 bool DebugTypeExtRefs, const RecordDecl *RD,

2784 return true;

2785

2788 return true;

2789

2790

2791

2792

2793 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)

2794 return true;

2795

2796 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||

2797 RD->hasAttr())

2798 return false;

2799

2800 if (!LangOpts.CPlusPlus)

2801 return false;

2802

2804 return true;

2805

2806 const auto *CXXDecl = dyn_cast(RD);

2807

2808 if (!CXXDecl)

2809 return false;

2810

2811

2812

2813

2814

2815

2816

2819 return true;

2820

2822 if (const auto *SD = dyn_cast(RD))

2823 Spec = SD->getSpecializationKind();

2824

2828 return true;

2829

2830

2831

2832 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&

2834 return true;

2835

2836 return false;

2837}

2838

2841 return;

2842

2844 llvm::DIType *T = getTypeOrNull(Ty);

2845 if (T && T->isForwardDecl())

2847}

2848

2849llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {

2851 llvm::DIType *T = cast_or_nullllvm::DIType(getTypeOrNull(QualType(Ty, 0)));

2854 if (T)

2855 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));

2856 return T;

2857 }

2858

2859 auto [Def, Pref] = CreateTypeDefinition(Ty);

2860

2861 return Pref ? Pref : Def;

2862}

2863

2864llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD,

2865 llvm::DIFile *Unit) {

2866 if (!RD)

2867 return nullptr;

2868

2869 auto const *PNA = RD->getAttr();

2870 if (!PNA)

2871 return nullptr;

2872

2873 return getOrCreateType(PNA->getTypedefType(), Unit);

2874}

2875

2876std::pair<llvm::DIType *, llvm::DIType *>

2877CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {

2879

2880

2881 llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());

2882

2883

2884

2885

2886

2887

2888

2889 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);

2890

2892 if (D || D->isCompleteDefinition())

2893 return {FwdDecl, nullptr};

2894

2895 if (const auto *CXXDecl = dyn_cast(RD))

2896 CollectContainingType(CXXDecl, FwdDecl);

2897

2898

2899 LexicalBlockStack.emplace_back(&*FwdDecl);

2900 RegionMap[Ty->getDecl()].reset(FwdDecl);

2901

2902

2904

2905

2906

2907

2908

2909

2910 const auto *CXXDecl = dyn_cast(RD);

2911 if (CXXDecl) {

2912 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);

2913 CollectVTableInfo(CXXDecl, DefUnit, EltTys);

2914 }

2915

2916

2917 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);

2918 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)

2919 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);

2920

2921 LexicalBlockStack.pop_back();

2922 RegionMap.erase(Ty->getDecl());

2923

2924 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);

2925 DBuilder.replaceArrays(FwdDecl, Elements);

2926

2927 if (FwdDecl->isTemporary())

2928 FwdDecl =

2929 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));

2930

2931 RegionMap[Ty->getDecl()].reset(FwdDecl);

2932

2933 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)

2934 if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))

2935 return {FwdDecl, PrefDI};

2936

2937 return {FwdDecl, nullptr};

2938}

2939

2940llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty,

2941 llvm::DIFile *Unit) {

2942

2943 return getOrCreateType(Ty->getBaseType(), Unit);

2944}

2945

2946llvm::DIType *CGDebugInfo::CreateType(const ObjCTypeParamType *Ty,

2947 llvm::DIFile *Unit) {

2948

2950

2951

2952 return DBuilder.createTypedef(

2955 getDeclContextDescriptor(Ty->getDecl()));

2956}

2957

2958

2961 assert(PD);

2962 if (!Getter)

2963 return true;

2964

2968}

2969

2970

2973 assert(PD);

2974 if (!Setter)

2975 return true;

2976

2980}

2981

2982llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,

2983 llvm::DIFile *Unit) {

2985 if (!ID)

2986 return nullptr;

2987

2988 auto RuntimeLang =

2989 static_castllvm::dwarf::SourceLanguage\(TheCU->getSourceLanguage());

2990

2991

2992

2993

2994 if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition() &&

2995 ID->getImplementation())

2996 return DBuilder.createForwardDecl(

2997 llvm::dwarf::DW_TAG_structure_type, ID->getName(),

2998 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);

2999

3000

3001 llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());

3002 unsigned Line = getLineNumber(ID->getLocation());

3003

3004

3005

3008 llvm::DIScope *Mod = getParentModuleOrNull(ID);

3009 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(

3010 llvm::dwarf::DW_TAG_structure_type, ID->getName(), Mod ? Mod : TheCU,

3011 DefUnit, Line, RuntimeLang);

3012 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));

3013 return FwdDecl;

3014 }

3015

3016 return CreateTypeDefinition(Ty, Unit);

3017}

3018

3019llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,

3020 bool CreateSkeletonCU) {

3021

3022

3023

3025 auto ModRef = ModuleCache.find(M);

3026 if (ModRef != ModuleCache.end())

3027 return castllvm::DIModule(ModRef->second);

3028

3029

3031 {

3032 llvm::raw_svector_ostream OS(ConfigMacros);

3034 unsigned I = 0;

3035

3036 for (auto &M : PPOpts.Macros) {

3037 if (++I > 1)

3038 OS << " ";

3039 const std::string &Macro = M.first;

3040 bool Undef = M.second;

3041 OS << "\"-" << (Undef ? 'U' : 'D');

3042 for (char c : Macro)

3043 switch (c) {

3044 case '\\':

3045 OS << "\\\\";

3046 break;

3047 case '"':

3048 OS << "\\\"";

3049 break;

3050 default:

3051 OS << c;

3052 }

3053 OS << '\"';

3054 }

3055 }

3056

3057 bool IsRootModule = M ? !M->Parent : true;

3058

3059

3060

3061 if (CreateSkeletonCU && IsRootModule && Mod.getASTFile().empty() && M)

3063 "clang module without ASTFile must be specified by -fmodule-name");

3064

3065

3066 auto RemapPath = [this](StringRef Path) -> std::string {

3068 StringRef Relative(Remapped);

3069 StringRef CompDir = TheCU->getDirectory();

3070 if (Relative.consume_front(CompDir))

3071 Relative.consume_front(llvm::sys::path::get_separator());

3072

3073 return Relative.str();

3074 };

3075

3076 if (CreateSkeletonCU && IsRootModule && !Mod.getASTFile().empty()) {

3077

3078

3079

3080

3082 if (const auto &ModSig = Mod.getSignature())

3083 Signature = ModSig.truncatedValue();

3084 else

3085 Signature = ~1ULL;

3086

3087 llvm::DIBuilder DIB(CGM.getModule());

3089 if (!llvm::sys::path::is_absolute(Mod.getASTFile())) {

3091 PCM = getCurrentDirname();

3092 else

3094 }

3095 llvm::sys::path::append(PCM, Mod.getASTFile());

3096 DIB.createCompileUnit(

3097 TheCU->getSourceLanguage(),

3098

3099 DIB.createFile(Mod.getModuleName(), TheCU->getDirectory()),

3100 TheCU->getProducer(), false, StringRef(), 0, RemapPath(PCM),

3101 llvm::DICompileUnit::FullDebug, Signature);

3102 DIB.finalize();

3103 }

3104

3105 llvm::DIModule *Parent =

3106 IsRootModule ? nullptr

3108 CreateSkeletonCU);

3109 std::string IncludePath = Mod.getPath().str();

3110 llvm::DIModule *DIMod =

3112 RemapPath(IncludePath));

3113 ModuleCache[M].reset(DIMod);

3114 return DIMod;

3115}

3116

3117llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,

3118 llvm::DIFile *Unit) {

3120 llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());

3121 unsigned Line = getLineNumber(ID->getLocation());

3122 unsigned RuntimeLang = TheCU->getSourceLanguage();

3123

3124

3127

3128 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

3129 if (ID->getImplementation())

3130 Flags |= llvm::DINode::FlagObjcClassComplete;

3131

3132 llvm::DIScope *Mod = getParentModuleOrNull(ID);

3133 llvm::DICompositeType *RealDecl = DBuilder.createStructType(

3134 Mod ? Mod : Unit, ID->getName(), DefUnit, Line, Size, Align, Flags,

3135 nullptr, llvm::DINodeArray(), RuntimeLang);

3136

3138 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);

3139

3140

3141 LexicalBlockStack.emplace_back(RealDecl);

3142 RegionMap[Ty->getDecl()].reset(RealDecl);

3143

3144

3146

3148 if (SClass) {

3149 llvm::DIType *SClassTy =

3151 if (!SClassTy)

3152 return nullptr;

3153

3154 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,

3155 llvm::DINode::FlagZero);

3156 EltTys.push_back(InhTag);

3157 }

3158

3159

3162 llvm::DIFile *PUnit = getOrCreateFile(Loc);

3163 unsigned PLine = getLineNumber(Loc);

3166 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(

3167 PD->getName(), PUnit, PLine,

3169 : getSelectorName(PD->getGetterName()),

3171 : getSelectorName(PD->getSetterName()),

3172 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));

3173 EltTys.push_back(PropertyNode);

3174 };

3175 {

3176

3177

3178 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;

3179

3180

3181

3182 llvm::DenseSet PropertySet;

3183

3185 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());

3186 };

3188 for (auto *PD : ClassExt->properties()) {

3189 PropertySet.insert(GetIsClassAndIdent(PD));

3190 AddProperty(PD);

3191 }

3192 for (const auto *PD : ID->properties()) {

3193

3194

3195 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)

3196 continue;

3197 AddProperty(PD);

3198 }

3199 }

3200

3202 unsigned FieldNo = 0;

3203 for (ObjCIvarDecl *Field = ID->all_declared_ivar_begin(); Field;

3204 Field = Field->getNextIvar(), ++FieldNo) {

3205 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);

3206 if (!FieldTy)

3207 return nullptr;

3208

3209 StringRef FieldName = Field->getName();

3210

3211

3212 if (FieldName.empty())

3213 continue;

3214

3215

3216 llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation());

3217 unsigned FieldLine = getLineNumber(Field->getLocation());

3221

3223

3224

3225 FieldSize = Field->isBitField() ? Field->getBitWidthValue()

3228 }

3229

3232

3233

3234

3235 if (Field->isBitField()) {

3236 FieldOffset =

3239 } else {

3240 FieldOffset = 0;

3241 }

3242 } else {

3244 }

3245

3246 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

3248 Flags = llvm::DINode::FlagProtected;

3250 Flags = llvm::DINode::FlagPrivate;

3252 Flags = llvm::DINode::FlagPublic;

3253

3254 if (Field->isBitField())

3255 Flags |= llvm::DINode::FlagBitField;

3256

3257 llvm::MDNode *PropertyNode = nullptr;

3260 ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {

3263 llvm::DIFile *PUnit = getOrCreateFile(Loc);

3264 unsigned PLine = getLineNumber(Loc);

3265 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();

3266 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();

3267 PropertyNode = DBuilder.createObjCProperty(

3268 PD->getName(), PUnit, PLine,

3270 ? ""

3271 : getSelectorName(PD->getGetterName()),

3273 ? ""

3274 : getSelectorName(PD->getSetterName()),

3275 PD->getPropertyAttributes(),

3276 getOrCreateType(PD->getType(), PUnit));

3277 }

3278 }

3279 }

3280 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,

3281 FieldSize, FieldAlign, FieldOffset, Flags,

3282 FieldTy, PropertyNode);

3283 EltTys.push_back(FieldTy);

3284 }

3285

3286 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);

3287 DBuilder.replaceArrays(RealDecl, Elements);

3288

3289 LexicalBlockStack.pop_back();

3290 return RealDecl;

3291}

3292

3293llvm::DIType *CGDebugInfo::CreateType(const VectorType *Ty,

3294 llvm::DIFile *Unit) {

3296

3297

3298

3299

3300

3301

3305

3306

3309 return CreateType(CharVecTy->getAs<VectorType>(), Unit);

3310 }

3311

3312 llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit);

3314

3315 llvm::Metadata *Subscript;

3317 auto SizeExpr = SizeExprCache.find(QTy);

3318 if (SizeExpr != SizeExprCache.end())

3319 Subscript = DBuilder.getOrCreateSubrange(

3320 SizeExpr->getSecond() , nullptr ,

3321 nullptr , nullptr );

3322 else {

3323 auto *CountNode =

3324 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

3325 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));

3326 Subscript = DBuilder.getOrCreateSubrange(

3327 CountNode , nullptr , nullptr ,

3328 nullptr );

3329 }

3330 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

3331

3334

3335 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);

3336}

3337

3339 llvm::DIFile *Unit) {

3340

3341

3342

3343 llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit);

3346

3347

3349 auto *ColumnCountNode =

3350 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

3352 auto *RowCountNode =

3353 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

3355 Subscripts.push_back(DBuilder.getOrCreateSubrange(

3356 ColumnCountNode , nullptr , nullptr ,

3357 nullptr ));

3358 Subscripts.push_back(DBuilder.getOrCreateSubrange(

3359 RowCountNode , nullptr , nullptr ,

3360 nullptr ));

3361 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);

3362 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);

3363}

3364

3365llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) {

3368

3369

3370 if (const auto *VAT = dyn_cast(Ty)) {

3377 Align = 0;

3378 else

3382 Align = 0;

3383 } else {

3384

3387 }

3388

3389

3390

3391

3394 while ((Ty = dyn_cast(EltTy))) {

3395

3396

3397

3398

3399

3400

3401

3402 int64_t Count = -1;

3403 if (const auto *CAT = dyn_cast(Ty))

3404 Count = CAT->getZExtSize();

3405 else if (const auto *VAT = dyn_cast(Ty)) {

3406 if (Expr *Size = VAT->getSizeExpr()) {

3409 Count = Result.Val.getInt().getExtValue();

3410 }

3411 }

3412

3413 auto SizeNode = SizeExprCache.find(EltTy);

3414 if (SizeNode != SizeExprCache.end())

3415 Subscripts.push_back(DBuilder.getOrCreateSubrange(

3416 SizeNode->getSecond() , nullptr ,

3417 nullptr , nullptr ));

3418 else {

3419 auto *CountNode =

3420 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(

3421 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));

3422 Subscripts.push_back(DBuilder.getOrCreateSubrange(

3423 CountNode , nullptr , nullptr ,

3424 nullptr ));

3425 }

3427 }

3428

3429 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);

3430

3431 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),

3432 SubscriptArray);

3433}

3434

3436 llvm::DIFile *Unit) {

3437 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,

3439}

3440

3442 llvm::DIFile *Unit) {

3443 llvm::dwarf::Tag Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;

3444

3447 Tag = llvm::dwarf::DW_TAG_reference_type;

3448

3449 return CreatePointerLikeType(Tag, Ty, Ty->getPointeeType(), Unit);

3450}

3451

3452llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,

3453 llvm::DIFile *U) {

3454 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

3456

3459

3460

3464 Flags |= llvm::DINode::FlagSingleInheritance;

3465 break;

3467 Flags |= llvm::DINode::FlagMultipleInheritance;

3468 break;

3470 Flags |= llvm::DINode::FlagVirtualInheritance;

3471 break;

3473 break;

3474 }

3475 }

3476 }

3477

3478 llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);

3480 return DBuilder.createMemberPointerType(

3481 getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, 0,

3482 Flags);

3483

3486 return DBuilder.createMemberPointerType(

3487 getOrCreateInstanceMethodType(

3489 FPT, U),

3490 ClassType, Size, 0, Flags);

3491}

3492

3493llvm::DIType *CGDebugInfo::CreateType(const AtomicType *Ty, llvm::DIFile *U) {

3494 auto *FromTy = getOrCreateType(Ty->getValueType(), U);

3495 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);

3496}

3497

3498llvm::DIType *CGDebugInfo::CreateType(const PipeType *Ty, llvm::DIFile *U) {

3500}

3501

3503 llvm::DIFile *U) {

3505}

3506

3507llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {

3509

3515 }

3516

3518

3519 bool isImportedFromModule =

3521

3522

3523

3524 if (isImportedFromModule || !ED->getDefinition()) {

3525

3526

3527

3528

3529

3530

3531 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);

3532 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());

3533 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(

3534 llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));

3535

3537 StringRef EDName = ED->getName();

3538 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(

3539 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,

3540 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);

3541

3542 ReplaceMap.emplace_back(

3543 std::piecewise_construct, std::make_tuple(Ty),

3544 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));

3545 return RetTy;

3546 }

3547

3548 return CreateTypeDefinition(Ty);

3549}

3550

3551llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {

3558 }

3559

3561

3564 assert(ED && "An enumeration definition is required");

3566 Enumerators.push_back(

3567 DBuilder.createEnumerator(Enum->getName(), Enum->getInitVal()));

3568 }

3569

3570

3571 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);

3572

3573 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());

3575 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);

3576 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);

3577 return DBuilder.createEnumerationType(

3578 EnumContext, ED->getName(), DefUnit, Line, Size, Align, EltArray, ClassTy,

3580}

3581

3584 StringRef Name, StringRef Value) {

3585 unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);

3586 return DBuilder.createMacro(Parent, Line, MType, Name, Value);

3587}

3588

3592 llvm::DIFile *FName = getOrCreateFile(FileLoc);

3593 unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);

3594 return DBuilder.createTempMacroFile(Parent, Line, FName);

3595}

3596

3598 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {

3599

3600

3602

3603 FuncName += "$";

3605 FuncName += "$";

3606 FuncName += FailureMsg;

3607

3608 llvm::DISubprogram *TrapSP =

3609 createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());

3610 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,

3611 TrapSP, TrapLocation);

3612}

3613

3616 do {

3617 Qualifiers InnerQuals = T.getLocalQualifiers();

3618

3619

3621 Quals += InnerQuals;

3624 default:

3625 return C.getQualifiedType(T.getTypePtr(), Quals);

3626 case Type::TemplateSpecialization: {

3627 const auto *Spec = cast(T);

3628 if (Spec->isTypeAlias())

3629 return C.getQualifiedType(T.getTypePtr(), Quals);

3631 break;

3632 }

3633 case Type::TypeOfExpr:

3634 T = cast(T)->getUnderlyingExpr()->getType();

3635 break;

3636 case Type::TypeOf:

3637 T = cast(T)->getUnmodifiedType();

3638 break;

3639 case Type::Decltype:

3640 T = cast(T)->getUnderlyingType();

3641 break;

3642 case Type::UnaryTransform:

3643 T = cast(T)->getUnderlyingType();

3644 break;

3645 case Type::Attributed:

3646 T = cast(T)->getEquivalentType();

3647 break;

3648 case Type::BTFTagAttributed:

3649 T = cast(T)->getWrappedType();

3650 break;

3651 case Type::CountAttributed:

3652 T = cast(T)->desugar();

3653 break;

3654 case Type::Elaborated:

3655 T = cast(T)->getNamedType();

3656 break;

3657 case Type::Using:

3658 T = cast(T)->getUnderlyingType();

3659 break;

3660 case Type::Paren:

3661 T = cast(T)->getInnerType();

3662 break;

3663 case Type::MacroQualified:

3664 T = cast(T)->getUnderlyingType();

3665 break;

3666 case Type::SubstTemplateTypeParm:

3667 T = cast(T)->getReplacementType();

3668 break;

3669 case Type::Auto:

3670 case Type::DeducedTemplateSpecialization: {

3671 QualType DT = cast(T)->getDeducedType();

3672 assert(!DT.isNull() && "Undeduced types shouldn't reach here.");

3673 T = DT;

3674 break;

3675 }

3676 case Type::PackIndexing: {

3677 T = cast(T)->getSelectedType();

3678 break;

3679 }

3680 case Type::Adjusted:

3681 case Type::Decayed:

3682

3683 T = cast(T)->getAdjustedType();

3684 break;

3685 }

3686

3687 assert(T != LastT && "Type unwrapping failed to unwrap!");

3688 (void)LastT;

3689 } while (true);

3690}

3691

3692llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {

3695 if (It != TypeCache.end()) {

3696

3697 if (llvm::Metadata *V = It->second)

3698 return castllvm::DIType(V);

3699 }

3700

3701 return nullptr;

3702}

3703

3707}

3708

3710 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||

3711 D.isDynamicClass())

3712 return;

3713

3715

3716

3718}

3719

3720llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {

3722 return nullptr;

3723

3724 llvm::TimeTraceScope TimeScope("DebugType", [&]() {

3725 std::string Name;

3726 llvm::raw_string_ostream OS(Name);

3727 Ty.print(OS, getPrintingPolicy());

3728 return Name;

3729 });

3730

3731

3733

3734 if (auto *T = getTypeOrNull(Ty))

3735 return T;

3736

3737 llvm::DIType *Res = CreateTypeNode(Ty, Unit);

3738 void *TyPtr = Ty.getAsOpaquePtr();

3739

3740

3741 TypeCache[TyPtr].reset(Res);

3742

3743 return Res;

3744}

3745

3746llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {

3747

3748 if (isa(D) && !cast(D)->getDefinition())

3749 return nullptr;

3751

3754 auto Info = Reader->getSourceDescriptor(Idx);

3755 if (Info)

3756 return getOrCreateModuleRef(*Info, true);

3757 } else if (ClangModuleMap) {

3758

3759

3760

3761

3762

3763

3764

3765

3766

3767

3769

3771 return getOrCreateModuleRef(Info, false);

3772 } else {

3773

3774 return getOrCreateModuleRef(PCHDescriptor, false);

3775 }

3776 }

3777

3778 return nullptr;

3779}

3780

3781llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {

3782

3784 return CreateQualifiedType(Ty, Unit);

3785

3786

3788#define TYPE(Class, Base)

3789#define ABSTRACT_TYPE(Class, Base)

3790#define NON_CANONICAL_TYPE(Class, Base)

3791#define DEPENDENT_TYPE(Class, Base) case Type::Class:

3792#include "clang/AST/TypeNodes.inc"

3793 llvm_unreachable("Dependent types cannot show up in debug information");

3794

3795 case Type::ExtVector:

3796 case Type::Vector:

3797 return CreateType(cast(Ty), Unit);

3798 case Type::ConstantMatrix:

3799 return CreateType(cast(Ty), Unit);

3800 case Type::ObjCObjectPointer:

3801 return CreateType(cast(Ty), Unit);

3802 case Type::ObjCObject:

3803 return CreateType(cast(Ty), Unit);

3804 case Type::ObjCTypeParam:

3805 return CreateType(cast(Ty), Unit);

3806 case Type::ObjCInterface:

3807 return CreateType(cast(Ty), Unit);

3808 case Type::Builtin:

3809 return CreateType(cast(Ty));

3810 case Type::Complex:

3811 return CreateType(cast(Ty));

3812 case Type::Pointer:

3813 return CreateType(cast(Ty), Unit);

3814 case Type::BlockPointer:

3815 return CreateType(cast(Ty), Unit);

3816 case Type::Typedef:

3817 return CreateType(cast(Ty), Unit);

3818 case Type::Record:

3819 return CreateType(cast(Ty));

3820 case Type::Enum:

3821 return CreateEnumType(cast(Ty));

3822 case Type::FunctionProto:

3823 case Type::FunctionNoProto:

3824 return CreateType(cast(Ty), Unit);

3825 case Type::ConstantArray:

3826 case Type::VariableArray:

3827 case Type::IncompleteArray:

3828 case Type::ArrayParameter:

3829 return CreateType(cast(Ty), Unit);

3830

3831 case Type::LValueReference:

3832 return CreateType(cast(Ty), Unit);

3833 case Type::RValueReference:

3834 return CreateType(cast(Ty), Unit);

3835

3836 case Type::MemberPointer:

3837 return CreateType(cast(Ty), Unit);

3838

3839 case Type::Atomic:

3840 return CreateType(cast(Ty), Unit);

3841

3842 case Type::BitInt:

3843 return CreateType(cast(Ty));

3844 case Type::Pipe:

3845 return CreateType(cast(Ty), Unit);

3846

3847 case Type::TemplateSpecialization:

3848 return CreateType(cast(Ty), Unit);

3849 case Type::HLSLAttributedResource:

3850 return CreateType(cast(Ty), Unit);

3851

3852 case Type::CountAttributed:

3853 case Type::Auto:

3854 case Type::Attributed:

3855 case Type::BTFTagAttributed:

3856 case Type::Adjusted:

3857 case Type::Decayed:

3858 case Type::DeducedTemplateSpecialization:

3859 case Type::Elaborated:

3860 case Type::Using:

3861 case Type::Paren:

3862 case Type::MacroQualified:

3863 case Type::SubstTemplateTypeParm:

3864 case Type::TypeOfExpr:

3865 case Type::TypeOf:

3866 case Type::Decltype:

3867 case Type::PackIndexing:

3868 case Type::UnaryTransform:

3869 break;

3870 }

3871

3872 llvm_unreachable("type should have been unwrapped!");

3873}

3874

3875llvm::DICompositeType *

3876CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) {

3878

3879 auto *T = cast_or_nullllvm::DICompositeType(getTypeOrNull(QTy));

3880

3881

3882

3883

3884 if (T && T->isForwardDecl())

3885 return T;

3886

3887

3888 llvm::DICompositeType *Res = CreateLimitedType(Ty);

3889

3890

3891

3892

3893 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());

3894

3895

3896 TypeCache[QTy.getAsOpaquePtr()].reset(Res);

3897 return Res;

3898}

3899

3900

3901llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {

3903

3904

3905 StringRef RDName = getClassName(RD);

3907 llvm::DIFile *DefUnit = nullptr;

3908 unsigned Line = 0;

3910 DefUnit = getOrCreateFile(Loc);

3911 Line = getLineNumber(Loc);

3912 }

3913

3914 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);

3915

3916

3917

3918 auto *T = cast_or_nullllvm::DICompositeType(

3921 return T;

3922

3923

3924

3926 if (D || D->isCompleteDefinition())

3927 return getOrCreateRecordFwdDecl(Ty, RDContext);

3928

3930

3931

3932

3933

3935

3937

3938

3939

3940 auto Flags = llvm::DINode::FlagZero;

3941 if (auto CXXRD = dyn_cast(RD)) {

3943 Flags |= llvm::DINode::FlagTypePassByReference;

3944 else

3945 Flags |= llvm::DINode::FlagTypePassByValue;

3946

3947

3948 if (!CXXRD->isTrivial())

3949 Flags |= llvm::DINode::FlagNonTrivial;

3950

3951

3952 if (CXXRD->isAnonymousStructOrUnion())

3953 Flags |= llvm::DINode::FlagExportSymbols;

3954

3956 dyn_cast(CXXRD->getDeclContext()));

3957 }

3958

3959 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);

3960 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(

3963

3964

3965

3966 switch (RealDecl->getTag()) {

3967 default:

3968 llvm_unreachable("invalid composite type tag");

3969

3970 case llvm::dwarf::DW_TAG_array_type:

3971 case llvm::dwarf::DW_TAG_enumeration_type:

3972

3973

3974

3975

3977 break;

3978 [[fallthrough]];

3979

3980 case llvm::dwarf::DW_TAG_structure_type:

3981 case llvm::dwarf::DW_TAG_union_type:

3982 case llvm::dwarf::DW_TAG_class_type:

3983

3984 RealDecl =

3985 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));

3986 break;

3987 }

3988

3989 RegionMap[Ty->getDecl()].reset(RealDecl);

3991

3992 if (const auto *TSpecial = dyn_cast(RD))

3993 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),

3994 CollectCXXTemplateParams(TSpecial, DefUnit));

3995 return RealDecl;

3996}

3997

3998void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,

3999 llvm::DICompositeType *RealDecl) {

4000

4001 llvm::DIType *ContainingType = nullptr;

4004

4005 while (true) {

4009 PBase = PBT;

4010 else

4011 break;

4012 }

4013 ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0),

4016 ContainingType = RealDecl;

4017

4018 DBuilder.replaceVTableHolder(RealDecl, ContainingType);

4019}

4020

4021llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,

4022 StringRef Name, uint64_t *Offset) {

4023 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);

4026 llvm::DIType *Ty =

4027 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,

4028 *Offset, llvm::DINode::FlagZero, FieldTy);

4029 *Offset += FieldSize;

4030 return Ty;

4031}

4032

4033void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,

4034 StringRef &Name,

4035 StringRef &LinkageName,

4036 llvm::DIScope *&FDContext,

4037 llvm::DINodeArray &TParamsArray,

4038 llvm::DINode::DIFlags &Flags) {

4040 Name = getFunctionName(FD);

4041

4045 Flags |= llvm::DINode::FlagPrototyped;

4046

4047

4048

4049 if (LinkageName == Name ||

4054 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))

4055 LinkageName = StringRef();

4056

4057

4058

4060 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&

4063 dyn_cast_or_null(FD->getDeclContext()))

4064 FDContext = getOrCreateNamespace(NSDecl);

4066 dyn_cast_or_null(FD->getDeclContext())) {

4067 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);

4068 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);

4069 }

4070 }

4072

4074 Flags |= llvm::DINode::FlagNoReturn;

4075

4076 TParamsArray = CollectFunctionTemplateParams(FD, Unit);

4077 }

4078}

4079

4080void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit,

4082 StringRef &Name, StringRef &LinkageName,

4083 llvm::MDTuple *&TemplateParameters,

4084 llvm::DIScope *&VDContext) {

4085 Unit = getOrCreateFile(VD->getLocation());

4086 LineNo = getLineNumber(VD->getLocation());

4087

4089

4092

4093 llvm::APInt ConstVal(32, 1);

4095

4098 }

4099

4104 if (LinkageName == Name)

4105 LinkageName = StringRef();

4106

4107 if (isa(VD)) {

4108 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);

4109 TemplateParameters = parameterNodes.get();

4110 } else {

4111 TemplateParameters = nullptr;

4112 }

4113

4114

4115

4116

4117

4118

4119

4122

4123

4124

4125

4126

4127

4130

4131 llvm::DIScope *Mod = getParentModuleOrNull(VD);

4132 VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);

4133}

4134

4135llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,

4136 bool Stub) {

4137 llvm::DINodeArray TParamsArray;

4138 StringRef Name, LinkageName;

4139 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

4140 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;

4142 llvm::DIFile *Unit = getOrCreateFile(Loc);

4143 llvm::DIScope *DContext = Unit;

4144 unsigned Line = getLineNumber(Loc);

4145 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,

4146 Flags);

4147 auto *FD = cast(GD.getDecl());

4148

4149

4152 ArgTypes.push_back(Parm->getType());

4153

4158 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;

4160 SPFlags |= llvm::DISubprogram::SPFlagOptimized;

4161

4163 Flags |= getCallSiteRelatedAttrs();

4164 SPFlags |= llvm::DISubprogram::SPFlagDefinition;

4165 return DBuilder.createFunction(

4166 DContext, Name, LinkageName, Unit, Line,

4167 getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,

4168 TParamsArray.get(), getFunctionDeclaration(FD));

4169 }

4170

4171 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(

4172 DContext, Name, LinkageName, Unit, Line,

4173 getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,

4174 TParamsArray.get(), getFunctionDeclaration(FD));

4176 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,

4177 std::make_tuple(CanonDecl),

4178 std::make_tuple(SP));

4179 return SP;

4180}

4181

4182llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {

4183 return getFunctionFwdDeclOrStub(GD, false);

4184}

4185

4186llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {

4187 return getFunctionFwdDeclOrStub(GD, true);

4188}

4189

4190llvm::DIGlobalVariable *

4191CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) {

4193 StringRef Name, LinkageName;

4195 llvm::DIFile *Unit = getOrCreateFile(Loc);

4196 llvm::DIScope *DContext = Unit;

4197 unsigned Line = getLineNumber(Loc);

4198 llvm::MDTuple *TemplateParameters = nullptr;

4199

4200 collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, TemplateParameters,

4201 DContext);

4203 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(

4204 DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),

4206 FwdDeclReplaceMap.emplace_back(

4207 std::piecewise_construct,

4209 std::make_tuple(static_cast<llvm::Metadata *>(GV)));

4210 return GV;

4211}

4212

4213llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {

4214

4215

4216

4217

4218 if (const auto *TD = dyn_cast(D))

4222

4223 if (I != DeclCache.end()) {

4224 auto N = I->second;

4225 if (auto *GVE = dyn_cast_or_nullllvm::DIGlobalVariableExpression(N))

4226 return GVE->getVariable();

4227 return castllvm::DINode(N);

4228 }

4229

4230

4231

4233

4234 if (IE != ImportedDeclCache.end()) {

4235 auto N = IE->second;

4236 if (auto *GVE = dyn_cast_or_nullllvm::DIImportedEntity(N))

4237 return castllvm::DINode(GVE);

4238 return dyn_cast_or_nullllvm::DINode(N);

4239 }

4240

4241

4242

4243 if (const auto *FD = dyn_cast(D))

4244 return getFunctionForwardDeclaration(FD);

4245 else if (const auto *VD = dyn_cast(D))

4246 return getGlobalVariableForwardDeclaration(VD);

4247

4248 return nullptr;

4249}

4250

4251llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) {

4252 if (D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

4253 return nullptr;

4254

4255 const auto *FD = dyn_cast(D);

4256 if (!FD)

4257 return nullptr;

4258

4259

4260 auto *S = getDeclContextDescriptor(D);

4261

4263 if (MI == SPCache.end()) {

4264 if (const auto *MD = dyn_cast(FD->getCanonicalDecl())) {

4265 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),

4266 castllvm::DICompositeType(S));

4267 }

4268 }

4269 if (MI != SPCache.end()) {

4270 auto *SP = dyn_cast_or_nullllvm::DISubprogram(MI->second);

4271 if (SP && !SP->isDefinition())

4272 return SP;

4273 }

4274

4275 for (auto *NextFD : FD->redecls()) {

4276 auto MI = SPCache.find(NextFD->getCanonicalDecl());

4277 if (MI != SPCache.end()) {

4278 auto *SP = dyn_cast_or_nullllvm::DISubprogram(MI->second);

4279 if (SP && !SP->isDefinition())

4280 return SP;

4281 }

4282 }

4283 return nullptr;

4284}

4285

4286llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(

4287 const Decl *D, llvm::DISubroutineType *FnType, unsigned LineNo,

4288 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {

4289 if (D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

4290 return nullptr;

4291

4292 const auto *OMD = dyn_cast(D);

4293 if (!OMD)

4294 return nullptr;

4295

4297 return nullptr;

4298

4300 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;

4301

4302

4303

4304 auto *ID = dyn_cast_or_null(D->getDeclContext());

4305 if (!ID)

4307 if (!ID)

4308 return nullptr;

4309 QualType QTy(ID->getTypeForDecl(), 0);

4310 auto It = TypeCache.find(QTy.getAsOpaquePtr());

4311 if (It == TypeCache.end())

4312 return nullptr;

4313 auto *InterfaceType = castllvm::DICompositeType(It->second);

4314 llvm::DISubprogram *FD = DBuilder.createFunction(

4315 InterfaceType, getObjCMethodName(OMD), StringRef(),

4316 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);

4317 DBuilder.finalizeSubprogram(FD);

4319 return FD;

4320}

4321

4322

4323

4324llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,

4326 llvm::DIFile *F) {

4327

4328

4329 if (D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&

4331

4332

4333 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));

4334

4335 if (const auto *Method = dyn_cast(D))

4336 return getOrCreateMethodType(Method, F);

4337

4340

4341 if (const auto *OMethod = dyn_cast(D)) {

4342

4344

4345

4346 QualType ResultTy = OMethod->getReturnType();

4347

4348

4351 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));

4352

4353 Elts.push_back(getOrCreateType(ResultTy, F));

4354

4356 if (auto *SelfDecl = OMethod->getSelfDecl())

4357 SelfDeclTy = SelfDecl->getType();

4358 else if (auto *FPT = dyn_cast(FnType))

4361 if (!SelfDeclTy.isNull())

4362 Elts.push_back(

4363 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));

4364

4365 Elts.push_back(DBuilder.createArtificialType(

4367

4368 for (const auto *PI : OMethod->parameters())

4369 Elts.push_back(getOrCreateType(PI->getType(), F));

4370

4371 if (OMethod->isVariadic())

4372 Elts.push_back(DBuilder.createUnspecifiedParameter());

4373

4374 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);

4375 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,

4377 }

4378

4379

4380

4381 if (const auto *FD = dyn_cast(D))

4382 if (FD->isVariadic()) {

4384 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));

4385 if (const auto *FPT = dyn_cast(FnType))

4387 EltTys.push_back(getOrCreateType(ParamType, F));

4388 EltTys.push_back(DBuilder.createUnspecifiedParameter());

4389 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);

4390 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,

4392 }

4393

4394 return castllvm::DISubroutineType(getOrCreateType(FnType, F));

4395}

4396

4401 if (FD)

4403 CC = SrcFnTy->getCallConv();

4405 for (const VarDecl *VD : Args)

4406 ArgTypes.push_back(VD->getType());

4409}

4410

4413 llvm::Function *Fn, bool CurFuncIsThunk) {

4414 StringRef Name;

4415 StringRef LinkageName;

4416

4417 FnBeginRegionCount.push_back(LexicalBlockStack.size());

4418

4420 bool HasDecl = (D != nullptr);

4421

4422 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

4423 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;

4424 llvm::DIFile *Unit = getOrCreateFile(Loc);

4425 llvm::DIScope *FDContext = Unit;

4426 llvm::DINodeArray TParamsArray;

4427 if (!HasDecl) {

4428

4429 LinkageName = Fn->getName();

4430 } else if (const auto *FD = dyn_cast(D)) {

4431

4432 auto FI = SPCache.find(FD->getCanonicalDecl());

4433 if (FI != SPCache.end()) {

4434 auto *SP = dyn_cast_or_nullllvm::DISubprogram(FI->second);

4435 if (SP && SP->isDefinition()) {

4436 LexicalBlockStack.emplace_back(SP);

4437 RegionMap[D].reset(SP);

4438 return;

4439 }

4440 }

4441 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,

4442 TParamsArray, Flags);

4443 } else if (const auto *OMD = dyn_cast(D)) {

4444 Name = getObjCMethodName(OMD);

4445 Flags |= llvm::DINode::FlagPrototyped;

4446 } else if (isa(D) &&

4448

4449 Name = getDynamicInitializerName(cast(D), GD.getDynamicInitKind(),

4450 Fn);

4451 } else {

4452 Name = Fn->getName();

4453

4454 if (isa(D))

4455 LinkageName = Name;

4456

4457 Flags |= llvm::DINode::FlagPrototyped;

4458 }

4459 if (Name.starts_with("\01"))

4460 Name = Name.substr(1);

4461

4462 assert((D || !isa(D) ||

4464 "Unexpected DynamicInitKind !");

4465

4467 isa(D) || isa(D)) {

4468 Flags |= llvm::DINode::FlagArtificial;

4469

4471 }

4472

4473 if (CurFuncIsThunk)

4474 Flags |= llvm::DINode::FlagThunk;

4475

4476 if (Fn->hasLocalLinkage())

4477 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;

4479 SPFlags |= llvm::DISubprogram::SPFlagOptimized;

4480

4481 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();

4482 llvm::DISubprogram::DISPFlags SPFlagsForDef =

4483 SPFlags | llvm::DISubprogram::SPFlagDefinition;

4484

4485 const unsigned LineNo = getLineNumber(Loc.isValid() ? Loc : CurLoc);

4486 unsigned ScopeLine = getLineNumber(ScopeLoc);

4487 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);

4488 llvm::DISubprogram *Decl = nullptr;

4489 llvm::DINodeArray Annotations = nullptr;

4490 if (D) {

4491 Decl = isa(D)

4492 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)

4493 : getFunctionDeclaration(D);

4494 Annotations = CollectBTFDeclTagAnnotations(D);

4495 }

4496

4497

4498

4499

4500

4501

4502 llvm::DISubprogram *SP = DBuilder.createFunction(

4503 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,

4504 FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,

4505 Annotations);

4506 Fn->setSubprogram(SP);

4507

4508

4509

4510 if (HasDecl && isa(D))

4512

4513

4514 LexicalBlockStack.emplace_back(SP);

4515

4516 if (HasDecl)

4517 RegionMap[D].reset(SP);

4518}

4519

4521 QualType FnType, llvm::Function *Fn) {

4522 StringRef Name;

4523 StringRef LinkageName;

4524

4526 if (D)

4527 return;

4528

4529 llvm::TimeTraceScope TimeScope("DebugFunction", [&]() {

4530 return GetName(D, true);

4531 });

4532

4533 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

4534 llvm::DIFile *Unit = getOrCreateFile(Loc);

4535 bool IsDeclForCallSite = Fn ? true : false;

4536 llvm::DIScope *FDContext =

4537 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);

4538 llvm::DINodeArray TParamsArray;

4539 if (isa(D)) {

4540

4541 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,

4542 TParamsArray, Flags);

4543 } else if (const auto *OMD = dyn_cast(D)) {

4544 Name = getObjCMethodName(OMD);

4545 Flags |= llvm::DINode::FlagPrototyped;

4546 } else {

4547 llvm_unreachable("not a function or ObjC method");

4548 }

4549 if (!Name.empty() && Name[0] == '\01')

4550 Name = Name.substr(1);

4551

4553 Flags |= llvm::DINode::FlagArtificial;

4554

4557 }

4558 unsigned LineNo = getLineNumber(Loc);

4559 unsigned ScopeLine = 0;

4560 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;

4562 SPFlags |= llvm::DISubprogram::SPFlagOptimized;

4563

4564 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);

4565 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);

4566 llvm::DISubprogram *SP = DBuilder.createFunction(

4567 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,

4568 SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);

4569

4570

4571

4572

4574 if (auto *FD = dyn_cast(D)) {

4575 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();

4576 unsigned ArgNo = 1;

4577 for (ParmVarDecl *PD : FD->parameters()) {

4578 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);

4579 DBuilder.createParameterVariable(

4580 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo], true,

4581 llvm::DINode::FlagZero, ParamAnnotations);

4582 ++ArgNo;

4583 }

4584 }

4585 }

4586

4587 if (IsDeclForCallSite)

4588 Fn->setSubprogram(SP);

4589

4590 DBuilder.finalizeSubprogram(SP);

4591}

4592

4596 if (!CallOrInvoke)

4597 return;

4598 auto *Func = CallOrInvoke->getCalledFunction();

4600 return;

4601 if (Func->getSubprogram())

4602 return;

4603

4604

4605

4606 if (CalleeDecl->hasAttr() ||

4607 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)

4608 return;

4609

4610

4611

4612

4615}

4616

4618 const auto *FD = cast(GD.getDecl());

4619

4620 auto FI = SPCache.find(FD->getCanonicalDecl());

4621 llvm::DISubprogram *SP = nullptr;

4622 if (FI != SPCache.end())

4623 SP = dyn_cast_or_nullllvm::DISubprogram(FI->second);

4624 if (!SP || !SP->isDefinition())

4625 SP = getFunctionStub(GD);

4626 FnBeginRegionCount.push_back(LexicalBlockStack.size());

4627 LexicalBlockStack.emplace_back(SP);

4628 setInlinedAt(Builder.getCurrentDebugLocation());

4630}

4631

4633 assert(CurInlinedAt && "unbalanced inline scope stack");

4636}

4637

4639

4641

4642 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())

4643 return;

4644

4645 llvm::MDNode *Scope = LexicalBlockStack.back();

4646 Builder.SetCurrentDebugLocation(

4647 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),

4648 getColumnNumber(CurLoc), Scope, CurInlinedAt));

4649}

4650

4652 llvm::MDNode *Back = nullptr;

4653 if (!LexicalBlockStack.empty())

4654 Back = LexicalBlockStack.back().get();

4655 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(

4656 castllvm::DIScope(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),

4657 getColumnNumber(CurLoc)));

4658}

4659

4660void CGDebugInfo::AppendAddressSpaceXDeref(

4662 std::optional DWARFAddressSpace =

4664 if (!DWARFAddressSpace)

4665 return;

4666

4667 Expr.push_back(llvm::dwarf::DW_OP_constu);

4668 Expr.push_back(*DWARFAddressSpace);

4669 Expr.push_back(llvm::dwarf::DW_OP_swap);

4670 Expr.push_back(llvm::dwarf::DW_OP_xderef);

4671}

4672

4675

4677

4678

4679 Builder.SetCurrentDebugLocation(llvm::DILocation::get(

4681 LexicalBlockStack.back(), CurInlinedAt));

4682

4683 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

4684 return;

4685

4686

4687 CreateLexicalBlock(Loc);

4688}

4689

4692 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

4693

4694

4696

4697 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)

4698 return;

4699

4700 LexicalBlockStack.pop_back();

4701}

4702

4704 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

4705 unsigned RCount = FnBeginRegionCount.back();

4706 assert(RCount <= LexicalBlockStack.size() && "Region stack mismatch");

4707

4708

4709 while (LexicalBlockStack.size() != RCount) {

4710

4712 LexicalBlockStack.pop_back();

4713 }

4714 FnBeginRegionCount.pop_back();

4715

4716 if (Fn && Fn->getSubprogram())

4717 DBuilder.finalizeSubprogram(Fn->getSubprogram());

4718}

4719

4720CGDebugInfo::BlockByRefType

4721CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,

4722 uint64_t *XOffset) {

4725 uint64_t FieldSize, FieldOffset;

4726 uint32_t FieldAlign;

4727

4728 llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());

4730

4731 FieldOffset = 0;

4733 EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));

4734 EltTys.push_back(CreateMemberType(Unit, FType, "__forwarding", &FieldOffset));

4736 EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));

4737 EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset));

4738

4740 if (HasCopyAndDispose) {

4742 EltTys.push_back(

4743 CreateMemberType(Unit, FType, "__copy_helper", &FieldOffset));

4744 EltTys.push_back(

4745 CreateMemberType(Unit, FType, "__destroy_helper", &FieldOffset));

4746 }

4747 bool HasByrefExtendedLayout;

4750 HasByrefExtendedLayout) &&

4751 HasByrefExtendedLayout) {

4753 EltTys.push_back(

4754 CreateMemberType(Unit, FType, "__byref_variable_layout", &FieldOffset));

4755 }

4756

4762 CharUnits AlignedOffsetInBytes = FieldOffsetInBytes.alignTo(Align);

4763 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;

4764

4766 llvm::APInt pad(32, NumPaddingBytes.getQuantity());

4769 EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset));

4770 }

4771 }

4772

4773 FType = Type;

4774 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);

4777

4778 *XOffset = FieldOffset;

4779 llvm::DIType *FieldTy = DBuilder.createMemberType(

4780 Unit, VD->getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,

4781 llvm::DINode::FlagZero, WrappedTy);

4782 EltTys.push_back(FieldTy);

4783 FieldOffset += FieldSize;

4784

4785 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);

4786 return {DBuilder.createStructType(Unit, "", Unit, 0, FieldOffset, 0,

4787 llvm::DINode::FlagZero, nullptr, Elements),

4788 WrappedTy};

4789}

4790

4791llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,

4792 llvm::Value *Storage,

4793 std::optional ArgNo,

4795 const bool UsePointerValue) {

4797 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

4798 if (VD->hasAttr())

4799 return nullptr;

4800

4801 const bool VarIsArtificial = IsArtificial(VD);

4802

4803 llvm::DIFile *Unit = nullptr;

4804 if (!VarIsArtificial)

4805 Unit = getOrCreateFile(VD->getLocation());

4806 llvm::DIType *Ty;

4808 if (VD->hasAttr())

4809 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;

4810 else

4811 Ty = getOrCreateType(VD->getType(), Unit);

4812

4813

4814

4815 if (!Ty)

4816 return nullptr;

4817

4818

4819 unsigned Line = 0;

4820 unsigned Column = 0;

4821 if (!VarIsArtificial) {

4824 }

4826 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

4827 if (VarIsArtificial)

4828 Flags |= llvm::DINode::FlagArtificial;

4829

4831

4833 AppendAddressSpaceXDeref(AddressSpace, Expr);

4834

4835

4836

4837 if (const auto *IPD = dyn_cast(VD)) {

4840 Flags |= llvm::DINode::FlagObjectPointer;

4841 } else if (const auto *PVD = dyn_cast(VD)) {

4842 if (PVD->isExplicitObjectParameter())

4843 Flags |= llvm::DINode::FlagObjectPointer;

4844 }

4845

4846

4847

4848

4849

4850 auto *Scope = castllvm::DIScope(LexicalBlockStack.back());

4851 StringRef Name = VD->getName();

4852 if (!Name.empty()) {

4853

4854

4856

4858 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);

4859

4863 Expr.push_back(llvm::dwarf::DW_OP_deref);

4864 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);

4865

4868 }

4869 } else if (const auto *RT = dyn_cast(VD->getType())) {

4870

4871

4872 const RecordDecl *RD = RT->getDecl();

4874

4875

4876

4877

4878

4879

4880

4881 for (const auto *Field : RD->fields()) {

4882 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);

4883 StringRef FieldName = Field->getName();

4884

4885

4886 if (FieldName.empty() && !isa(Field->getType()))

4887 continue;

4888

4889

4891 auto *D = DBuilder.createAutoVariable(

4893 Flags | llvm::DINode::FlagArtificial, FieldAlign);

4894

4895

4896 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),

4899 CurInlinedAt),

4900 Builder.GetInsertBlock());

4901 }

4902 }

4903 }

4904

4905

4906

4907

4908 if (UsePointerValue) {

4909 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&

4910 "Debug info already contains DW_OP_deref.");

4911 Expr.push_back(llvm::dwarf::DW_OP_deref);

4912 }

4913

4914

4915 llvm::DILocalVariable *D = nullptr;

4916 if (ArgNo) {

4917 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);

4918 D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,

4920 Annotations);

4921 } else {

4922

4923

4924

4925

4926

4927

4928

4929 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {

4930

4931

4932 if (!isallvm::DISubprogram(Scope) || Scope->isDistinct())

4933 return nullptr;

4934

4935 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](auto &Pair) {

4936 Stmt *StmtPtr = const_cast<Stmt *>(Pair.second);

4937 if (DeclStmt *DeclStmtPtr = dyn_cast(StmtPtr)) {

4940 if (VD == dyn_cast_or_null(Decl))

4941 return true;

4942 }

4943 return false;

4944 });

4945

4946 if (Iter != CoroutineParameterMappings.end()) {

4948 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](auto &DbgPair) {

4949 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;

4950 });

4951 if (Iter2 != ParamDbgMappings.end())

4952 return const_cast<llvm::DILocalVariable *>(Iter2->second);

4953 }

4954 return nullptr;

4955 };

4956

4957

4958 D = RemapCoroArgToLocalVar();

4959

4960 if (D)

4961 D = DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty,

4962 CGM.getLangOpts().Optimize, Flags, Align);

4963 }

4964

4965 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),

4968 Builder.GetInsertBlock());

4969

4970 return D;

4971}

4972

4973llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,

4974 llvm::Value *Storage,

4975 std::optional ArgNo,

4977 const bool UsePointerValue) {

4979 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

4980 if (BD->hasAttr())

4981 return nullptr;

4982

4983

4984 if (isa(BD->getBinding()))

4985 return nullptr;

4986

4987 llvm::DIFile *Unit = getOrCreateFile(BD->getLocation());

4988 llvm::DIType *Ty = getOrCreateType(BD->getType(), Unit);

4989

4990

4991

4992 if (!Ty)

4993 return nullptr;

4994

4997

4999 AppendAddressSpaceXDeref(AddressSpace, Expr);

5000

5001

5002

5003

5004 if (UsePointerValue) {

5005 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&

5006 "Debug info already contains DW_OP_deref.");

5007 Expr.push_back(llvm::dwarf::DW_OP_deref);

5008 }

5009

5012 StringRef Name = BD->getName();

5013 auto *Scope = castllvm::DIScope(LexicalBlockStack.back());

5014

5015 llvm::DILocalVariable *D = DBuilder.createAutoVariable(

5017 llvm::DINode::FlagZero, Align);

5018

5020 if (const FieldDecl *FD = dyn_cast(ME->getMemberDecl())) {

5021 const unsigned fieldIndex = FD->getFieldIndex();

5027 if (FD->isBitField()) {

5031

5032

5034 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5036 }

5037

5038

5040 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext

5041 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);

5043

5044

5046 Expr.push_back(std::min((uint64_t)Info.Size, TypeSize));

5047 } else if (fieldOffset != 0) {

5049 "Unexpected non-bitfield with non-byte-aligned offset");

5050 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5051 Expr.push_back(

5053 }

5054 }

5056 dyn_cast(BD->getBinding())) {

5057 if (const IntegerLiteral *IL = dyn_cast(ASE->getIdx())) {

5058 const uint64_t value = IL->getValue().getZExtValue();

5060

5061 if (value != 0) {

5062 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5066 }

5067 }

5068 }

5069

5070

5071 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),

5074 Builder.GetInsertBlock());

5075

5076 return D;

5077}

5078

5079llvm::DILocalVariable *

5082 const bool UsePointerValue) {

5084

5085 if (auto *DD = dyn_cast(VD)) {

5086 for (auto *B : DD->bindings()) {

5087 EmitDeclare(B, Storage, std::nullopt, Builder,

5089 }

5090

5091

5092 return nullptr;

5093 }

5094

5095 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);

5096}

5097

5100 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

5101

5102 if (D->hasAttr())

5103 return;

5104

5105 auto *Scope = castllvm::DIScope(LexicalBlockStack.back());

5106 llvm::DIFile *Unit = getOrCreateFile(D->getLocation());

5107

5108

5111

5112 StringRef Name = D->getName();

5113

5114

5115 auto *L =

5117

5118

5119 DBuilder.insertLabel(L,

5121 Scope, CurInlinedAt),

5122 Builder.GetInsertBlock());

5123}

5124

5125llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,

5126 llvm::DIType *Ty) {

5127 llvm::DIType *CachedTy = getTypeOrNull(QualTy);

5128 if (CachedTy)

5129 Ty = CachedTy;

5130 return DBuilder.createObjectPointerType(Ty, true);

5131}

5132

5135 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {

5137 assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

5138

5139 if (Builder.GetInsertBlock() == nullptr)

5140 return;

5141 if (VD->hasAttr())

5142 return;

5143

5144 bool isByRef = VD->hasAttr();

5145

5146 uint64_t XOffset = 0;

5147 llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());

5148 llvm::DIType *Ty;

5149 if (isByRef)

5150 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;

5151 else

5152 Ty = getOrCreateType(VD->getType(), Unit);

5153

5154

5155

5156 if (const auto *IPD = dyn_cast(VD))

5158 Ty = CreateSelfType(VD->getType(), Ty);

5159

5160

5161 const unsigned Line =

5164

5165 const llvm::DataLayout &target = CGM.getDataLayout();

5166

5170

5172 addr.push_back(llvm::dwarf::DW_OP_deref);

5173 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5175 if (isByRef) {

5176 addr.push_back(llvm::dwarf::DW_OP_deref);

5177 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5178

5179 offset =

5182 addr.push_back(llvm::dwarf::DW_OP_deref);

5183 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);

5184

5187 }

5188

5189

5191 auto *D = DBuilder.createAutoVariable(

5192 castllvm::DILocalScope(LexicalBlockStack.back()), VD->getName(), Unit,

5193 Line, Ty, false, llvm::DINode::FlagZero, Align);

5194

5195

5197 LexicalBlockStack.back(), CurInlinedAt);

5198 auto *Expr = DBuilder.createExpression(addr);

5199 if (InsertPoint)

5200 DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);

5201 else

5202 DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());

5203}

5204

5205llvm::DILocalVariable *

5208 bool UsePointerValue) {

5210 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);

5211}

5212

5213namespace {

5214struct BlockLayoutChunk {

5215 uint64_t OffsetInBits;

5217};

5218bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {

5219 return l.OffsetInBits < r.OffsetInBits;

5220}

5221}

5222

5223void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(

5225 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,

5227

5228

5229

5231 Fields.push_back(createFieldType("__size", Context.IntTy, Loc, AS_public,

5232 BlockLayout.getElementOffsetInBits(0),

5233 Unit, Unit));

5234 Fields.push_back(createFieldType("__align", Context.IntTy, Loc, AS_public,

5235 BlockLayout.getElementOffsetInBits(1),

5236 Unit, Unit));

5237 } else {

5239 BlockLayout.getElementOffsetInBits(0),

5240 Unit, Unit));

5241 Fields.push_back(createFieldType("__flags", Context.IntTy, Loc, AS_public,

5242 BlockLayout.getElementOffsetInBits(1),

5243 Unit, Unit));

5244 Fields.push_back(

5246 BlockLayout.getElementOffsetInBits(2), Unit, Unit));

5247 auto *FnTy = Block.getBlockExpr()->getFunctionType();

5249 Fields.push_back(createFieldType("__FuncPtr", FnPtrType, Loc, AS_public,

5250 BlockLayout.getElementOffsetInBits(3),

5251 Unit, Unit));

5252 Fields.push_back(createFieldType(

5253 "__descriptor",

5257 Loc, AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));

5258 }

5259}

5260

5262 StringRef Name,

5263 unsigned ArgNo,

5264 llvm::AllocaInst *Alloca,

5269

5270

5272 llvm::DIFile *tunit = getOrCreateFile(loc);

5273 unsigned line = getLineNumber(loc);

5274 unsigned column = getColumnNumber(loc);

5275

5276

5277 getDeclContextDescriptor(blockDecl);

5278

5279 const llvm::StructLayout *blockLayout =

5281

5283 collectDefaultFieldsForBlockLiteralDeclare(block, C, loc, *blockLayout, tunit,

5284 fields);

5285

5286

5287

5289

5290

5291 if (blockDecl->capturesCXXThis()) {

5292 BlockLayoutChunk chunk;

5293 chunk.OffsetInBits =

5294 blockLayout->getElementOffsetInBits(block.CXXThisIndex);

5295 chunk.Capture = nullptr;

5296 chunks.push_back(chunk);

5297 }

5298

5299

5300 for (const auto &capture : blockDecl->captures()) {

5301 const VarDecl *variable = capture.getVariable();

5303

5304

5306 continue;

5307

5308 BlockLayoutChunk chunk;

5309 chunk.OffsetInBits =

5310 blockLayout->getElementOffsetInBits(captureInfo.getIndex());

5311 chunk.Capture = &capture;

5312 chunks.push_back(chunk);

5313 }

5314

5315

5316 llvm::array_pod_sort(chunks.begin(), chunks.end());

5317

5318 for (const BlockLayoutChunk &Chunk : chunks) {

5319 uint64_t offsetInBits = Chunk.OffsetInBits;

5321

5322

5323 if (!capture) {

5325 if (auto *Method =

5326 cast_or_null(blockDecl->getNonClosureContext()))

5328 else if (auto *RDecl = dyn_cast(blockDecl->getParent()))

5329 type = QualType(RDecl->getTypeForDecl(), 0);

5330 else

5331 llvm_unreachable("unexpected block declcontext");

5332

5333 fields.push_back(createFieldType("this", type, loc, AS_public,

5334 offsetInBits, tunit, tunit));

5335 continue;

5336 }

5337

5339 StringRef name = variable->getName();

5340

5341 llvm::DIType *fieldType;

5342 if (capture->isByRef()) {

5343 TypeInfo PtrInfo = C.getTypeInfo(C.VoidPtrTy);

5345

5346 uint64_t xoffset;

5347 fieldType =

5348 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;

5349 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.Width);

5350 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,

5351 PtrInfo.Width, Align, offsetInBits,

5352 llvm::DINode::FlagZero, fieldType);

5353 } else {

5355 fieldType = createFieldType(name, variable->getType(), loc, AS_public,

5356 offsetInBits, Align, tunit, tunit);

5357 }

5358 fields.push_back(fieldType);

5359 }

5360

5362 llvm::raw_svector_ostream(typeName)

5364

5365 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);

5366

5367 llvm::DIType *type =

5368 DBuilder.createStructType(tunit, typeName.str(), tunit, line,

5370 llvm::DINode::FlagZero, nullptr, fieldsArray);

5372

5373

5374 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;

5375 auto *scope = castllvm::DILocalScope(LexicalBlockStack.back());

5376

5377

5378 auto *debugVar = DBuilder.createParameterVariable(

5379 scope, Name, ArgNo, tunit, line, type, CGM.getLangOpts().Optimize, flags);

5380

5381

5382 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),

5384 column, scope, CurInlinedAt),

5385 Builder.GetInsertBlock());

5386}

5387

5388llvm::DIDerivedType *

5389CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {

5390 if (D || D->isStaticDataMember())

5391 return nullptr;

5392

5394 if (MI != StaticDataMemberCache.end()) {

5395 assert(MI->second && "Static data member declaration should still exist");

5396 return MI->second;

5397 }

5398

5399

5400

5402 auto *Ctxt = castllvm::DICompositeType(getDeclContextDescriptor(D));

5403 return CreateRecordStaticField(D, Ctxt, cast(DC));

5404}

5405

5406llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(

5407 const RecordDecl *RD, llvm::DIFile *Unit, unsigned LineNo,

5408 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {

5409 llvm::DIGlobalVariableExpression *GVE = nullptr;

5410

5411 for (const auto *Field : RD->fields()) {

5412 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);

5413 StringRef FieldName = Field->getName();

5414

5415

5416 if (FieldName.empty()) {

5417 if (const auto *RT = dyn_cast(Field->getType()))

5418 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,

5419 Var, DContext);

5420 continue;

5421 }

5422

5423 GVE = DBuilder.createGlobalVariableExpression(

5424 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,

5425 Var->hasLocalLinkage());

5426 Var->addDebugInfo(GVE);

5427 }

5428 return GVE;

5429}

5430

5433

5434

5435

5436

5437

5438 const auto *RD = dyn_cast(RT->getDecl());

5439 if (!RD)

5440 return false;

5442 return true;

5443 auto *TSpecial = dyn_cast(RD);

5444 if (!TSpecial)

5445 return false;

5447}

5451 case TemplateArgument::Pack:

5452 return ReferencesAnonymousEntity(TA.getPackAsArray());

5453 case TemplateArgument::Type: {

5454 struct ReferencesAnonymous

5455 : public RecursiveASTVisitor {

5456 bool RefAnon = false;

5457 bool VisitRecordType(RecordType *RT) {

5458 if (ReferencesAnonymousEntity(RT)) {

5459 RefAnon = true;

5460 return false;

5461 }

5462 return true;

5463 }

5464 };

5465 ReferencesAnonymous RT;

5466 RT.TraverseType(TA.getAsType());

5467 if (RT.RefAnon)

5468 return true;

5469 break;

5470 }

5471 default:

5472 break;

5473 }

5474 return false;

5475 });

5476}

5477namespace {

5478struct ReconstitutableType : public RecursiveASTVisitor {

5479 bool Reconstitutable = true;

5480 bool VisitVectorType(VectorType *FT) {

5481 Reconstitutable = false;

5482 return false;

5483 }

5484 bool VisitAtomicType(AtomicType *FT) {

5485 Reconstitutable = false;

5486 return false;

5487 }

5488 bool VisitType(Type *T) {

5489

5490

5492 Reconstitutable = false;

5493 return false;

5494 }

5495 return true;

5496 }

5497 bool TraverseEnumType(EnumType *ET) {

5498

5499

5500 if (const auto *ED = dyn_cast(ET->getDecl())) {

5502 Reconstitutable = false;

5503 return false;

5504 }

5506 Reconstitutable = false;

5507 return false;

5508 }

5509 }

5510 return true;

5511 }

5513

5516 return Reconstitutable;

5517 }

5518 bool VisitRecordType(RecordType *RT) {

5520 Reconstitutable = false;

5521 return false;

5522 }

5523 return true;

5524 }

5525};

5526}

5527

5528

5530 ReconstitutableType T;

5531 T.TraverseType(QT);

5532 return T.Reconstitutable;

5533}

5534

5535bool CGDebugInfo::HasReconstitutableArgs(

5539 case TemplateArgument::Template:

5540

5541

5542

5543

5544

5545 return true;

5546 case TemplateArgument::Declaration:

5547

5548

5549

5550

5551

5552

5553

5554 return false;

5555 case TemplateArgument::NullPtr:

5556

5557

5558 return false;

5559 case TemplateArgument::Pack:

5560

5561

5562 return HasReconstitutableArgs(TA.getPackAsArray());

5563 case TemplateArgument::Integral:

5564

5565

5566

5567

5568 return TA.getAsIntegral().getBitWidth() <= 64 &&

5569 IsReconstitutableType(TA.getIntegralType());

5570 case TemplateArgument::StructuralValue:

5571 return false;

5572 case TemplateArgument::Type:

5573 return IsReconstitutableType(TA.getAsType());

5574 case TemplateArgument::Expression:

5575 return IsReconstitutableType(TA.getAsExpr()->getType());

5576 default:

5577 llvm_unreachable("Other, unresolved, template arguments should "

5578 "not be seen here");

5579 }

5580 });

5581}

5582

5583std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const {

5584 std::string Name;

5585 llvm::raw_string_ostream OS(Name);

5586 const NamedDecl *ND = dyn_cast(D);

5587 if (!ND)

5588 return Name;

5589 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =

5591

5593 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;

5594

5595 std::optional Args;

5596

5597 bool IsOperatorOverload = false;

5598 if (auto *RD = dyn_cast(ND)) {

5599 Args = GetTemplateArgs(RD);

5600 } else if (auto *FD = dyn_cast(ND)) {

5601 Args = GetTemplateArgs(FD);

5603 IsOperatorOverload |=

5606 } else if (auto *VD = dyn_cast(ND)) {

5607 Args = GetTemplateArgs(VD);

5608 }

5609

5610

5611

5612

5613

5614

5615

5616

5617

5618

5619

5620

5621

5622

5623

5624

5625

5626

5627

5628

5629

5630

5631 bool Reconstitutable =

5632 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;

5633

5635

5636 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||

5637 !Reconstitutable) {

5639 } else {

5640 bool Mangled = TemplateNamesKind ==

5641 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;

5642

5643 if (Mangled)

5644 OS << "_STN|";

5645

5647 std::string EncodedOriginalName;

5648 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);

5649 EncodedOriginalNameOS << ND->getDeclName();

5650

5651 if (Mangled) {

5652 OS << "|";

5655#ifndef NDEBUG

5656 std::string CanonicalOriginalName;

5657 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);

5659 assert(EncodedOriginalName == CanonicalOriginalName);

5660#endif

5661 }

5662 }

5663 return Name;

5664}

5665

5669 if (D->hasAttr())

5670 return;

5671

5672 llvm::TimeTraceScope TimeScope("DebugGlobalVariable", [&]() {

5673 return GetName(D, true);

5674 });

5675

5676

5677

5679 if (Cached != DeclCache.end())

5680 return Var->addDebugInfo(

5681 castllvm::DIGlobalVariableExpression(Cached->second));

5682

5683

5684 llvm::DIFile *Unit = nullptr;

5685 llvm::DIScope *DContext = nullptr;

5686 unsigned LineNo;

5687 StringRef DeclName, LinkageName;

5689 llvm::MDTuple *TemplateParameters = nullptr;

5690 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,

5691 TemplateParameters, DContext);

5692

5693

5694

5695 llvm::DIGlobalVariableExpression *GVE = nullptr;

5696

5697

5698

5699

5703 "unnamed non-anonymous struct or union?");

5704 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);

5705 } else {

5707

5711 if (D->hasAttr())

5712 AddressSpace =

5714 else if (D->hasAttr())

5715 AddressSpace =

5717 }

5718 AppendAddressSpaceXDeref(AddressSpace, Expr);

5719

5720 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);

5721 GVE = DBuilder.createGlobalVariableExpression(

5722 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),

5723 Var->hasLocalLinkage(), true,

5724 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),

5725 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,

5726 Align, Annotations);

5727 Var->addDebugInfo(GVE);

5728 }

5730}

5731

5734 if (VD->hasAttr())

5735 return;

5736 llvm::TimeTraceScope TimeScope("DebugConstGlobalVariable", [&]() {

5737 return GetName(VD, true);

5738 });

5739

5741

5742 llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());

5743 StringRef Name = VD->getName();

5744 llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit);

5745

5746 if (const auto *ECD = dyn_cast(VD)) {

5747 const auto *ED = cast(ECD->getDeclContext());

5748 assert(isa(ED->getTypeForDecl()) && "Enum without EnumType?");

5749

5751

5752

5753

5754

5756 return;

5757 } else {

5758

5759

5760

5761 llvm::DIType *EDTy =

5763 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);

5764 (void)EDTy;

5765 return;

5766 }

5767 }

5768

5769

5771 return;

5772

5774 auto *VarD = dyn_cast(VD);

5775 if (VarD && VarD->isStaticDataMember()) {

5776 auto *RD = cast(VarD->getDeclContext());

5777 getDeclContextDescriptor(VarD);

5778

5779

5780

5781

5782 RetainedTypes.push_back(

5784

5785 return;

5786 }

5787 llvm::DIScope *DContext = getDeclContextDescriptor(VD);

5788

5789 auto &GV = DeclCache[VD];

5790 if (GV)

5791 return;

5792

5793 llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init);

5794 llvm::MDTuple *TemplateParameters = nullptr;

5795

5796 if (isa(VD))

5797 if (VarD) {

5798 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);

5799 TemplateParameters = parameterNodes.get();

5800 }

5801

5802 GV.reset(DBuilder.createGlobalVariableExpression(

5803 DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,

5804 true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),

5805 TemplateParameters, Align));

5806}

5807

5811 if (D->hasAttr())

5812 return;

5813

5815 llvm::DIFile *Unit = getOrCreateFile(D->getLocation());

5816 StringRef Name = D->getName();

5817 llvm::DIType *Ty = getOrCreateType(D->getType(), Unit);

5818

5819 llvm::DIScope *DContext = getDeclContextDescriptor(D);

5820 llvm::DIGlobalVariableExpression *GVE =

5821 DBuilder.createGlobalVariableExpression(

5822 DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()),

5823 Ty, false, false, nullptr, nullptr, nullptr, Align);

5824 Var->addDebugInfo(GVE);

5825}

5826

5829

5830

5832 llvm::codegenoptions::DebugLineTablesOnly)

5833 return;

5834

5835 llvm::DILocation *DIL = Value->getDebugLoc().get();

5836 if (!DIL)

5837 return;

5838

5839 llvm::DIFile *Unit = DIL->getFile();

5840 llvm::DIType *Type = getOrCreateType(Ty, Unit);

5841

5842

5843

5844

5845 if (llvm::LoadInst *Load = dyn_castllvm::LoadInst(Value)) {

5846 llvm::Value *Var = Load->getPointerOperand();

5847

5848

5849

5850

5851 auto DeclareTypeMatches = [&](auto *DbgDeclare) {

5852 return DbgDeclare->getVariable()->getType() == Type;

5853 };

5854 if (any_of(llvm::findDbgDeclares(Var), DeclareTypeMatches) ||

5855 any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))

5856 return;

5857 }

5858

5859 llvm::DILocalVariable *D =

5860 DBuilder.createAutoVariable(LexicalBlockStack.back(), "", nullptr, 0,

5861 Type, false, llvm::DINode::FlagArtificial);

5862

5863 if (auto InsertPoint = Value->getInsertionPointAfterDef()) {

5864 DBuilder.insertDbgValueIntrinsic(Value, D, DBuilder.createExpression(), DIL,

5865 &**InsertPoint);

5866 }

5867}

5868

5871

5872 assert(GV);

5873

5875 return;

5876

5877 const auto *D = cast(GD.getDecl());

5878 if (D->hasAttr())

5879 return;

5880

5882 llvm::DINode *DI;

5883

5884 if (!AliaseeDecl)

5885

5886

5887

5888

5889

5890

5891

5892

5893

5894

5895 return;

5896 if (!(DI = getDeclarationOrDefinition(

5897 AliaseeDecl.getCanonicalDecl().getDecl())))

5898 return;

5899

5900 llvm::DIScope *DContext = getDeclContextDescriptor(D);

5902

5903 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(

5904 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());

5905

5906

5908}

5909

5915 return;

5916

5917 llvm::DIFile *File = getOrCreateFile(Loc);

5918 llvm::DIGlobalVariableExpression *Debug =

5919 DBuilder.createGlobalVariableExpression(

5920 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),

5921 getLineNumber(Loc), getOrCreateType(S->getType(), File), true);

5922 GV->addDebugInfo(Debug);

5923}

5924

5925llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {

5926 if (!LexicalBlockStack.empty())

5927 return LexicalBlockStack.back();

5928 llvm::DIScope *Mod = getParentModuleOrNull(D);

5929 return getContextDescriptor(D, Mod ? Mod : TheCU);

5930}

5931

5934 return;

5940 Loc = CurLoc;

5941 DBuilder.createImportedModule(

5942 getCurrentContextDescriptor(cast(UD.getDeclContext())),

5943 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));

5944 }

5945}

5946

5948 if (llvm::DINode *Target =

5951 DBuilder.createImportedDeclaration(

5953 getOrCreateFile(Loc), getLineNumber(Loc));

5954 }

5955}

5956

5959 return;

5961 "We shouldn't be codegening an invalid UsingDecl containing no decls");

5962

5963 for (const auto *USD : UD.shadows()) {

5964

5965

5966

5967

5968 if (const auto *FD = dyn_cast(USD->getUnderlyingDecl()))

5969 if (const auto *AT = FD->getType()

5972 if (AT->getDeducedType().isNull())

5973 continue;

5974

5976

5977

5978 break;

5979 }

5980}

5981

5984 return;

5986 "We shouldn't be codegening an invalid UsingEnumDecl"

5987 " containing no decls");

5988

5989 for (const auto *USD : UD.shadows())

5991}

5992

5994 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)

5995 return;

5996 if (Module *M = ID.getImportedModule()) {

5998 auto Loc = ID.getLocation();

5999 DBuilder.createImportedDeclaration(

6000 getCurrentContextDescriptor(cast(ID.getDeclContext())),

6001 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),

6002 getLineNumber(Loc));

6003 }

6004}

6005

6006llvm::DIImportedEntity *

6009 return nullptr;

6010 auto &VH = NamespaceAliasCache[&NA];

6011 if (VH)

6012 return castllvm::DIImportedEntity(VH);

6013 llvm::DIImportedEntity *R;

6015 if (const auto *Underlying =

6017

6018 R = DBuilder.createImportedDeclaration(

6019 getCurrentContextDescriptor(cast(NA.getDeclContext())),

6022 else

6023 R = DBuilder.createImportedDeclaration(

6024 getCurrentContextDescriptor(cast(NA.getDeclContext())),

6026 getOrCreateFile(Loc), getLineNumber(Loc), NA.getName());

6027 VH.reset(R);

6028 return R;

6029}

6030

6031llvm::DINamespace *

6032CGDebugInfo::getOrCreateNamespace(const NamespaceDecl *NSDecl) {

6033

6034

6035

6036 auto I = NamespaceCache.find(NSDecl);

6037 if (I != NamespaceCache.end())

6038 return castllvm::DINamespace(I->second);

6039

6040 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);

6041

6042 llvm::DINamespace *NS =

6043 DBuilder.createNameSpace(Context, NSDecl->getName(), NSDecl->isInline());

6044 NamespaceCache[NSDecl].reset(NS);

6045 return NS;

6046}

6047

6049 assert(TheCU && "no main compile unit");

6050 TheCU->setDWOId(Signature);

6051}

6052

6054

6055

6056 for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {

6057 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];

6058 llvm::DIType *Ty = E.Type->getDecl()->getDefinition()

6059 ? CreateTypeDefinition(E.Type, E.Unit)

6060 : E.Decl;

6061 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);

6062 }

6063

6064

6065 for (const auto &P : ObjCMethodCache) {

6066 if (P.second.empty())

6067 continue;

6068

6069 QualType QTy(P.first->getTypeForDecl(), 0);

6071 assert(It != TypeCache.end());

6072

6073 llvm::DICompositeType *InterfaceDecl =

6074 castllvm::DICompositeType(It->second);

6075

6076 auto CurElts = InterfaceDecl->getElements();

6078

6079

6080 for (auto &SubprogramDirect : P.second)

6081 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())

6082 EltTys.push_back(SubprogramDirect.getPointer());

6083

6084 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);

6085 DBuilder.replaceArrays(InterfaceDecl, Elements);

6086 }

6087

6088 for (const auto &P : ReplaceMap) {

6089 assert(P.second);

6090 auto *Ty = castllvm::DIType(P.second);

6091 assert(Ty->isForwardDecl());

6092

6093 auto It = TypeCache.find(P.first);

6094 assert(It != TypeCache.end());

6095 assert(It->second);

6096

6097 DBuilder.replaceTemporary(llvm::TempDIType(Ty),

6098 castllvm::DIType(It->second));

6099 }

6100

6101 for (const auto &P : FwdDeclReplaceMap) {

6102 assert(P.second);

6103 llvm::TempMDNode FwdDecl(castllvm::MDNode(P.second));

6104 llvm::Metadata *Repl;

6105

6106 auto It = DeclCache.find(P.first);

6107

6108

6109

6110 if (It == DeclCache.end())

6111 Repl = P.second;

6112 else

6113 Repl = It->second;

6114

6115 if (auto *GVE = dyn_cast_or_nullllvm::DIGlobalVariableExpression(Repl))

6116 Repl = GVE->getVariable();

6117 DBuilder.replaceTemporary(std::move(FwdDecl), castllvm::MDNode(Repl));

6118 }

6119

6120

6121

6122 for (auto &RT : RetainedTypes)

6123 if (auto MD = TypeCache[RT])

6124 DBuilder.retainType(castllvm::DIType(MD));

6125

6126 DBuilder.finalize();

6127}

6128

6129

6132 if (auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))

6133 DBuilder.retainType(DieTy);

6134}

6135

6138 if (auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))

6139 DBuilder.retainType(DieTy);

6140}

6141

6143 if (LexicalBlockStack.empty())

6144 return llvm::DebugLoc();

6145

6146 llvm::MDNode *Scope = LexicalBlockStack.back();

6147 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),

6148 getColumnNumber(Loc), Scope);

6149}

6150

6151llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const {

6152

6153

6155 DebugKind == llvm::codegenoptions::NoDebugInfo ||

6156 DebugKind == llvm::codegenoptions::LocTrackingOnly)

6157 return llvm::DINode::FlagZero;

6158

6159

6160

6161

6162 bool SupportsDWARFv4Ext =

6164 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||

6165 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);

6166

6167 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)

6168 return llvm::DINode::FlagZero;

6169

6170 return llvm::DINode::FlagAllCallsDescribed;

6171}

6172

6173llvm::DIExpression *

6174CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD,

6176

6178 return nullptr;

6179

6181 return DBuilder.createConstantValueExpression(

6182 Val.getFloat().bitcastToAPInt().getZExtValue());

6183

6184 if (!Val.isInt())

6185 return nullptr;

6186

6187 llvm::APSInt const &ValInt = Val.getInt();

6188 std::optional<uint64_t> ValIntOpt;

6189 if (ValInt.isUnsigned())

6190 ValIntOpt = ValInt.tryZExtValue();

6191 else if (auto tmp = ValInt.trySExtValue())

6192

6193

6194 ValIntOpt = static_cast<uint64_t>(*tmp);

6195

6196 if (ValIntOpt)

6197 return DBuilder.createConstantValueExpression(ValIntOpt.value());

6198

6199 return nullptr;

6200}

Defines the clang::ASTContext interface.

static bool IsReconstitutableType(QualType QT)

static void stripUnusedQualifiers(Qualifiers &Q)

static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)

static bool IsArtificial(VarDecl const *VD)

Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...

static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)

static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)

static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)

Convert an AccessSpecifier into the corresponding DINode flag.

static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)

static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)

static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)

static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)

static bool isFunctionLocalClass(const CXXRecordDecl *RD)

isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.

static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)

static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)

static bool canUseCtorHoming(const CXXRecordDecl *RD)

static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)

static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)

Return true if the class or any of its methods are marked dllimport.

static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)

static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)

static bool isDefinedInClangModule(const RecordDecl *RD)

Does a type definition exist in an imported clang module?

static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)

static bool IsDecomposedVarDecl(VarDecl const *VD)

Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...

static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)

static unsigned getDwarfCC(CallingConv CC)

static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

llvm::MachO::Target Target

constexpr llvm::StringRef ClangTrapPrefix

static const NamedDecl * getDefinition(const Decl *D)

Defines the SourceManager interface.

Defines version macros and version-related utility functions for Clang.

__device__ __2f16 float c

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const

Returns true, if given type has a known lifetime.

BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const

Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...

SourceManager & getSourceManager()

TranslationUnitDecl * getTranslationUnitDecl() const

TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)

uint64_t getFieldOffset(const ValueDecl *FD) const

Get the offset of a FieldDecl or IndirectFieldDecl, in bits.

QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const

getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.

QualType getRecordType(const RecordDecl *Decl) const

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const

Return the unique reference to a vector type of the specified element type and size.

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

QualType getEnumType(const EnumDecl *Decl) const

QualType getBlockDescriptorExtendedType() const

Gets the struct used to keep track of the extended descriptor for pointer to blocks.

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

bool BlockRequiresCopying(QualType Ty, const VarDecl *D)

Returns true iff we need copy/dispose helpers for the given type.

QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const

Return the unique reference to the type for the specified type declaration.

QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const

Return the unique reference to the type for a constant array of the specified element type.

QualType getObjCInstanceType()

Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.

const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const

Get or compute information about the layout of the specified Objective-C interface.

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

QualType getObjCSelType() const

Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.

CanQualType UnsignedLongTy

TypeInfo getTypeInfo(const Type *T) const

Get the size and alignment of the specified complete type in bits.

QualType getBlockDescriptorType() const

Gets the struct used to keep track of the descriptor for pointer to blocks.

CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const

Return a conservative estimate of the alignment of the specified decl D.

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

const clang::PrintingPolicy & getPrintingPolicy() const

QualType getObjCIdType() const

Represents the Objective-CC id type.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CanQualType UnsignedCharTy

DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

ExternalASTSource * getExternalSource() const

Retrieve a pointer to the external AST source associated with this AST context, if any.

unsigned getTargetAddressSpace(LangAS AS) const

unsigned getTypeAlign(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in bits.

uint64_t getCharWidth() const

Return the size of the character type, in bits.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getVBPtrOffset() const

getVBPtrOffset - Get the offset for virtual base table pointer.

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

const CXXRecordDecl * getPrimaryBase() const

getPrimaryBase - Get the primary base for this record.

bool hasExtendableVFPtr() const

hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...

bool isPrimaryBaseVirtual() const

isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.

Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...

Module * getModuleOrNull() const

ASTFileSignature getSignature() const

StringRef getASTFile() const

StringRef getPath() const

std::string getModuleName() const

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

QualType getValueType() const

Gets the type contained by this atomic type, i.e.

const BTFTypeTagAttr * getAttr() const

QualType getWrappedType() const

unsigned shadow_size() const

Return the number of shadowed declarations associated with this using declaration.

shadow_range shadows() const

A binding in a decomposition declaration.

Expr * getBinding() const

Get the expression to which this declaration is bound.

A fixed int type of a specified bitwidth.

A class which contains all the information about a particular captured value.

bool isByRef() const

Whether this is a "by ref" capture, i.e.

Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)

VarDecl * getVariable() const

The variable being captured.

Represents a block literal declaration, which is like an unnamed FunctionDecl.

QualType getPointeeType() const

This class is used for builtin types like 'int'.

StringRef getName(const PrintingPolicy &Policy) const

Represents a C++ constructor within a class.

Represents a static or instance method of a struct/union/class.

unsigned size_overridden_methods() const

RefQualifierKind getRefQualifier() const

Retrieve the ref-qualifier associated with this method.

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

QualType getThisType() const

Return the type of the this pointer.

CXXMethodDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

Represents a C++ struct/union/class.

bool isAggregate() const

Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...

bool hasTrivialDefaultConstructor() const

Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).

bool isLambda() const

Determine whether this class describes a lambda function object.

capture_const_iterator captures_end() const

method_range methods() const

bool hasConstexprNonCopyMoveConstructor() const

Determine whether this class has at least one constexpr constructor other than the copy or move const...

method_iterator method_begin() const

Method begin iterator.

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine whether this particular class is a specialization or instantiation of a class template or m...

base_class_range vbases()

bool isDynamicClass() const

MSInheritanceModel getMSInheritanceModel() const

Returns the inheritance model used for this record.

bool hasDefinition() const

method_iterator method_end() const

Method past-the-end iterator.

capture_const_iterator captures_begin() const

llvm::iterator_range< base_class_const_iterator > base_class_const_range

A wrapper class around a pointer that always points to its canonical declaration.

CharUnits - This is an opaque type for sizes expressed in character units.

bool isPositive() const

isPositive - Test whether the quantity is greater than zero.

bool isZero() const

isZero - Test whether the quantity equals zero.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

CharUnits alignTo(const CharUnits &Align) const

alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

Represents a class template specialization, which refers to a class template with a given set of temp...

llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap

std::string CoverageNotesFile

The filename with path we use for coverage notes files.

std::string CoverageDataFile

The filename with path we use for coverage data files.

std::string DebugCompilationDir

The string to embed in debug information as the current working directory.

bool hasReducedDebugInfo() const

Check if type and variable info should be emitted.

bool hasMaybeUnusedDebugInfo() const

Check if maybe unused type info should be emitted.

ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)

Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.

~ApplyInlineDebugLocation()

Restore everything back to the original state.

unsigned getIndex() const

CGBlockInfo - Information to generate a block literal.

unsigned CXXThisIndex

The field index of 'this' within the block, if there is one.

const BlockDecl * getBlockDecl() const

llvm::StructType * StructureType

const Capture & getCapture(const VarDecl *var) const

virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)

Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.

@ RAA_Indirect

Pass it as a pointer to temporary memory.

virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)

Create a null member pointer of the given type.

virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0

Returns how an argument of the given record type should be passed.

virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)

Create a member pointer for the given field.

virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)

Create a member pointer for the given method.

MangleContext & getMangleContext()

Gets the mangle context.

llvm::MDNode * getInlinedAt() const

llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)

Emit standalone debug info for a type.

void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)

Emit metadata to indicate a change in line/column information in the source file.

void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl)

Emit information about global variable alias.

void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)

Emit call to llvm.dbg.label for an label.

void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)

Emit information about a global variable.

void setInlinedAt(llvm::MDNode *InlinedAt)

Update the current inline scope.

void completeUnusedClass(const CXXRecordDecl &D)

void EmitUsingShadowDecl(const UsingShadowDecl &USD)

Emit a shadow decl brought in by a using or using-enum.

void EmitUsingEnumDecl(const UsingEnumDecl &UD)

Emit C++ using-enum declaration.

void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)

Constructs the debug code for exiting a function.

void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, const FunctionDecl *CalleeDecl)

Emit debug info for an extern function being called.

void EmitUsingDecl(const UsingDecl &UD)

Emit C++ using declaration.

llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)

Create debug info for a file referenced by an #include directive.

void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)

void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)

Emit information about an external variable.

void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)

Emit a call to llvm.dbg.function.start to indicate start of a new function.

llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)

Emit call to llvm.dbg.declare for an argument variable declaration.

void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)

Emit metadata to indicate the end of a new lexical block and pop the current block.

void EmitUsingDirective(const UsingDirectiveDecl &UD)

Emit C++ using directive.

void completeRequiredType(const RecordDecl *RD)

void EmitAndRetainType(QualType Ty)

Emit the type even if it might not be used.

void EmitInlineFunctionEnd(CGBuilderTy &Builder)

End an inlined function scope.

void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)

Emit debug info for a function declaration.

void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)

DebugInfo isn't attached to string literals by default.

llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)

Emit call to llvm.dbg.declare for an automatic variable declaration.

void completeClassData(const RecordDecl *RD)

void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)

Start a new scope for an inlined function.

void EmitImportDecl(const ImportDecl &ID)

Emit an @import declaration.

void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)

Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.

llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)

CGDebugInfo(CodeGenModule &CGM)

void completeClass(const RecordDecl *RD)

void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)

Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.

void setLocation(SourceLocation Loc)

Update the current source location.

llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)

Create debug info for a macro defined by a #define directive or a macro undefined by a #undef directi...

llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)

Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...

llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)

Emit record type's standalone debug info.

void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)

Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...

std::string remapDIPath(StringRef) const

Remap a given path with the current debug prefix map.

void EmitExplicitCastType(QualType Ty)

Emit the type explicitly casted to.

void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)

Add heapallocsite metadata for MSAllocator calls.

void setDwoId(uint64_t Signature)

Module debugging: Support for building PCMs.

QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)

llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)

Emit an Objective-C interface type standalone debug info.

void completeType(const EnumDecl *ED)

void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)

Emit call to llvm.dbg.declare for an imported variable declaration in a block.

llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)

Emit C++ namespace alias.

unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar)

CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...

const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const

Return the BitFieldInfo that corresponds to the field FD.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

CGDebugInfo * getDebugInfo()

This class organizes the cross-function state that is used while generating LLVM code.

const PreprocessorOptions & getPreprocessorOpts() const

ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)

Get the address of a GUID.

llvm::Module & getModule() const

llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)

Return the address of the given function.

const IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const

const LangOptions & getLangOpts() const

int getUniqueBlockCount()

Fetches the global unique block count.

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

const llvm::DataLayout & getDataLayout() const

CGCXXABI & getCXXABI() const

ItaniumVTableContext & getItaniumVTableContext()

ASTContext & getContext() const

ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)

Get the address of a template parameter object.

llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)

Return the llvm::Constant for the address of the given global variable.

MicrosoftVTableContext & getMicrosoftVTableContext()

const HeaderSearchOptions & getHeaderSearchOpts() const

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

StringRef getMangledName(GlobalDecl GD)

llvm::LLVMContext & getLLVMContext()

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)

Return the appropriate linkage for the vtable, VTT, and type information of the given class.

const GlobalDecl getMangledNameDecl(StringRef)

const CGRecordLayout & getCGRecordLayout(const RecordDecl *)

getCGRecordLayout - Return record layout info for the given record decl.

unsigned getTargetAddressSpace(QualType T) const

llvm::Constant * getPointer() const

llvm::Constant * emitAbstract(const Expr *E, QualType T)

Emit the result of the given expression as an abstract constant, asserting that it succeeded.

virtual bool shouldEmitDWARFBitFieldSeparators() const

Complex values, per C99 6.2.5p11.

Represents a concrete matrix type with constant number of rows and columns.

unsigned getNumColumns() const

Returns the number of columns in the matrix.

unsigned getNumRows() const

Returns the number of rows in the matrix.

specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

DeclContext * getEnclosingNamespaceContext()

Retrieve the nearest enclosing namespace context.

decl_range decls() const

decls_begin/decls_end - Iterate over the declarations stored in this context.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

unsigned getMaxAlignment() const

getMaxAlignment - return the maximum alignment specified by attributes on this decl,...

Module * getOwningModule() const

Get the module that owns this declaration (for visibility purposes).

bool isFromASTFile() const

Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const

SourceLocation getLocation() const

DeclContext * getDeclContext()

AccessSpecifier getAccess() const

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

unsigned getOwningModuleID() const

Retrieve the global ID of the module that owns this particular declaration.

bool isObjCZeroArgSelector() const

@ CXXConversionFunctionName

Selector getObjCSelector() const

Get the Objective-C selector stored in this declaration name.

bool isObjCOneArgSelector() const

NameKind getNameKind() const

Determine what kind of name this is.

Represents a ValueDecl that came out of a declarator.

enumerator_range enumerators() const

bool isScoped() const

Returns true if this is a C++11 scoped enumeration.

QualType getIntegerType() const

Return the integer type this enum decl corresponds to.

EnumDecl * getDefinition() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.

EnumDecl * getDecl() const

This represents one expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getFieldIndex() const

Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

static InputKind getInputKindForExtension(StringRef Extension)

getInputKindForExtension - Return the appropriate input kind for a file extension.

Represents a function declaration or definition.

bool hasCXXExplicitFunctionObjectParameter() const

bool isInlined() const

Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...

bool isNoReturn() const

Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

bool hasPrototype() const

Whether this function has a prototype, either because one was explicitly written or because it was "i...

FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const

If this function is actually a function template specialization, retrieve information about this func...

FunctionDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isDeleted() const

Whether this function has been deleted.

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

@ TK_FunctionTemplateSpecialization

TemplatedKind getTemplatedKind() const

What kind of templated function this is.

bool isPureVirtual() const

Whether this virtual function is pure, i.e.

FunctionDecl * getInstantiatedFromMemberFunction() const

If this function is an instantiation of a member function of a class template specialization,...

Represents a prototype with parameter type info, e.g.

ExceptionSpecificationType getExceptionSpecType() const

Get the kind of exception specification on this function.

unsigned getNumParams() const

QualType getParamType(unsigned i) const

ExtProtoInfo getExtProtoInfo() const

ArrayRef< QualType > getParamTypes() const

ArrayRef< QualType > param_types() const

FunctionTemplateDecl * getTemplate() const

Retrieve the template from which this function was specialized.

FunctionType - C99 6.7.5.3 - Function Declarators.

bool getNoReturnAttr() const

Determine whether this function type includes the GNU noreturn attribute.

CallingConv getCallConv() const

QualType getReturnType() const

GlobalDecl - represents a global declaration.

GlobalDecl getCanonicalDecl() const

DynamicInitKind getDynamicInitKind() const

const Decl * getDecl() const

QualType getWrappedType() const

One of these records is kept for each identifier that is lexed.

Describes a module import declaration, which makes the contents of the named module visible in the cu...

bool isPreprocessed() const

uint64_t getMethodVTableIndex(GlobalDecl GD)

Locate a virtual function in the vtable.

CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)

Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...

An lvalue reference type, per C++11 [dcl.ref].

Represents the declaration of a label.

Describes the capture of a variable or of this, or of a C++1y init-capture.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

std::string ModuleName

The module currently being compiled as specified by -fmodule-name.

clang::ObjCRuntime ObjCRuntime

bool UseTargetPathSeparator

Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...

virtual std::string getLambdaString(const CXXRecordDecl *Lambda)=0

virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0

QualType getElementType() const

Returns type of the elements being stored in the matrix.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

A pointer to member type per C++ 8.3.3 - Pointers to members.

CXXRecordDecl * getMostRecentCXXRecordDecl() const

QualType getPointeeType() const

const Type * getClass() const

unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)

Returns the index of VBase in the vbtable of Derived.

MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)

const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)

Describes a module or submodule.

Module * Parent

The parent of this module.

std::string Name

The name of this module.

This represents a decl that may have a name.

NamedDecl * getUnderlyingDecl()

Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const

Appends a human-readable name for this declaration into the given stream.

void printQualifiedName(raw_ostream &OS) const

Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...

bool isExternallyVisible() const

Represents a C++ namespace alias.

NamedDecl * getAliasedNamespace() const

Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...

Represent a C++ namespace.

bool isAnonymousNamespace() const

Returns true if this is an anonymous namespace declaration.

bool isInline() const

Returns true if this is an inline namespace declaration.

ObjCCategoryDecl - Represents a category declaration.

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

Represents an ObjC class declaration.

ObjCImplementationDecl * getImplementation() const

Interfaces are the core concept in Objective-C for object oriented design.

ObjCInterfaceDecl * getDecl() const

Get the declaration of this interface.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCMethodDecl - Represents an instance or class method declaration.

bool isDirectMethod() const

True if the method is tagged as objc_direct.

Selector getSelector() const

bool isInstanceMethod() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

bool isObjCQualifiedIdType() const

True if this is equivalent to 'id.

QualType getPointeeType() const

Gets the type pointed to by this ObjC pointer.

Represents a class type in Objective C.

QualType getBaseType() const

Gets the base type of this object type.

Represents one property declaration in an Objective-C interface.

ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...

bool isNonFragile() const

Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?

Represents a type parameter type in Objective C.

ObjCTypeParamDecl * getDecl() const

Represents a parameter to a function.

QualType getElementType() const

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

Represents an unpacked "presumed" location which can be presented to the user.

unsigned getColumn() const

Return the presumed column number of this location.

const char * getFilename() const

Return the presumed filename of this location.

bool isInvalid() const

Return true if this object is invalid or uninitialized.

A (possibly-)qualified type.

QualType getDesugaredType(const ASTContext &Context) const

Return the specified type with any "sugar" removed from the type.

bool hasLocalQualifiers() const

Determine whether this particular QualType instance has any qualifiers, without looking through any t...

bool isNull() const

Return true if this QualType doesn't point to a type yet.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

void * getAsOpaquePtr() const

A qualifier set is used to build a set of qualifiers.

const Type * strip(QualType type)

Collect any qualifiers on the given type and return an unqualified type.

QualType apply(const ASTContext &Context, QualType QT) const

Apply the collected qualifiers to the given type.

The collection of all-type qualifiers we support.

static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)

Returns the common set of qualifiers while removing them from the given sets.

void removeObjCLifetime()

void removeAddressSpace()

An rvalue reference type, per C++11 [dcl.ref].

Represents a struct/union/class.

field_iterator field_end() const

field_range fields() const

RecordDecl * getDefinition() const

Returns the RecordDecl that actually defines this struct/union/class.

bool isAnonymousStructOrUnion() const

Whether this is an anonymous struct or union.

field_iterator field_begin() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...

redecl_range redecls() const

Returns an iterator range for all the redeclarations of the same decl.

QualType getPointeeType() const

Scope - A scope is a transient data structure that is used while parsing the program.

static SmallString< 64 > constructSetterName(StringRef Name)

Return the default setter name for the given identifier.

Smart pointer class that efficiently represents Objective-C method names.

StringRef getNameForSlot(unsigned argIndex) const

Retrieve the name at a given position in the selector.

std::string getAsString() const

Derive the full selector name (e.g.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const

Returns the "presumed" location of a SourceLocation specifies.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

Stmt - This represents one statement.

StringLiteral - This represents a string literal expression, e.g.

Represents the declaration of a struct/union/class/enum.

bool isCompleteDefinition() const

Return true if this decl has its body fully specified.

TypedefNameDecl * getTypedefNameForAnonDecl() const

bool isCompleteDefinitionRequired() const

Return true if this complete decl is required to be complete for some existing use.

TagDecl * getDecl() const

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

bool isItaniumFamily() const

Does this ABI generally fall into the Itanium family of ABIs?

virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

uint64_t getPointerWidth(LangAS AddrSpace) const

Return the width of pointers on this target, for the specified address space.

virtual unsigned getVtblPtrAddressSpace() const

uint64_t getPointerAlign(LangAS AddrSpace) const

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

A template argument list.

ArrayRef< TemplateArgument > asArray() const

Produce this as an array ref.

Represents a template argument.

ArrayRef< TemplateArgument > getPackAsArray() const

Return the array of arguments in this template argument pack.

QualType getStructuralValueType() const

Get the type of a StructuralValue.

QualType getParamTypeForDecl() const

Expr * getAsExpr() const

Retrieve the template argument as an expression.

QualType getAsType() const

Retrieve the type for a type template argument.

llvm::APSInt getAsIntegral() const

Retrieve the template argument as an integral value.

QualType getNullPtrType() const

Retrieve the type for null non-type template argument.

TemplateName getAsTemplate() const

Retrieve the template name for a template name argument.

QualType getIntegralType() const

Retrieve the type of the integral value.

bool getIsDefaulted() const

If returns 'true', this TemplateArgument corresponds to a default template parameter.

ValueDecl * getAsDecl() const

Retrieve the declaration for a declaration non-type template argument.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

The template argument is a template name that was provided for a template template parameter.

@ StructuralValue

The template argument is a non-type template argument that can't be represented by the special-case D...

@ Pack

The template argument is actually a parameter pack.

@ TemplateExpansion

The template argument is a pack expansion of a template name that was provided for a template templat...

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

@ Null

Represents an empty template argument, e.g., one that has not been deduced.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

const APValue & getAsStructuralValue() const

Get the value of a StructuralValue.

The base class of all kinds of template declarations (e.g., class, function, etc.).

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const

Print the template name.

Stores a list of template parameters for a TemplateDecl and its derived classes.

ArrayRef< NamedDecl * > asArray()

Represents a type template specialization; the template must be a class template, a type alias templa...

QualType getAliasedType() const

Get the aliased type, if this is a specialization of a type alias template.

ArrayRef< TemplateArgument > template_arguments() const

TemplateName getTemplateName() const

Retrieve the name of the template that we are specializing.

bool isTypeAlias() const

Determine if this template specialization type is for a type alias template that has been substituted...

Represents a declaration of a type.

const Type * getTypeForDecl() const

The base class of the type hierarchy.

bool isIncompleteArrayType() const

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

bool isExtVectorBoolType() const

AutoType * getContainedAutoType() const

Get the AutoType whose type will be deduced for a variable with an initializer of this type.

bool isInstantiationDependentType() const

Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...

bool isMemberDataPointerType() const

bool isBitIntType() const

bool isComplexIntegerType() const

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

TypeClass getTypeClass() const

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

Base class for declarations which introduce a typedef-name.

QualType getUnderlyingType() const

TypedefNameDecl * getDecl() const

Represents a C++ using-declaration.

Represents C++ using-directive.

NamespaceDecl * getNominatedNamespace()

Returns the namespace nominated by this using-directive.

Represents a C++ using-enum-declaration.

Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...

static bool hasVtableSlot(const CXXMethodDecl *MD)

Determine whether this function should be assigned a vtable slot.

ArrayRef< VTableComponent > vtable_components() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

VarDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

APValue * evaluateValue() const

Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...

bool isStaticDataMember() const

Determines whether this is a static data member.

const Expr * getInit() const

bool isEscapingByref() const

Indicates the capture is a __block variable that is captured by a block that can potentially escape (...

Declaration of a variable template.

Represents a GCC generic vector type.

unsigned getNumElements() const

QualType getElementType() const

@ Type

The l-value was considered opaque, so the alignment was determined from a type.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl

Matches block declarations.

RangeSelector name(std::string ID)

Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...

The JSON file list parser is used to communicate input to InstallAPI.

@ RQ_LValue

An lvalue ref-qualifier was provided (&).

@ RQ_RValue

An rvalue ref-qualifier was provided (&&).

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

@ Result

The result type of a method or function.

bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)

@ Dtor_Deleting

Deleting dtor.

const FunctionProtoType * T

void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)

Print a template argument list, including the '<' and '>' enclosing the template arguments.

TemplateSpecializationKind

Describes the kind of template specialization that a particular template specialization declaration r...

@ TSK_ExplicitInstantiationDeclaration

This template specialization was instantiated from a template due to an explicit instantiation declar...

@ TSK_Undeclared

This template specialization was formed from a template-id but has not yet been declared,...

CallingConv

CallingConv - Specifies the calling convention that a function uses.

@ Generic

not a target-specific vector type

@ Enum

The "enum" keyword introduces the elaborated-type-specifier.

@ CXXThis

Parameter for C++ 'this' argument.

@ ObjCSelf

Parameter for Objective-C 'self' argument.

std::string getClangFullVersion()

Retrieves a string representing the complete clang version, which includes the clang version number,...

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

Structure with information about how a bitfield should be accessed.

CharUnits StorageOffset

The offset of the bitfield storage from the start of the struct.

unsigned Offset

The offset within a contiguous run of bitfields that are represented as a single "field" within the L...

unsigned Size

The total size of the bit-field, in bits.

unsigned StorageSize

The storage size in bits which should be used when accessing this bitfield.

unsigned IsSigned

Whether the bit-field is signed.

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

unsigned char PointerWidthInBits

The width of a pointer into the generic address space.

EvalResult is a struct with detailed info about an evaluated expression.

Extra information about a function prototype.

uint64_t Index

Method's index in the vftable.

Describes how types, statements, expressions, and declarations should be printed.

unsigned MSVCFormatting

Use whitespace and punctuation like MSVC does.

unsigned SplitTemplateClosers

Whether nested templates must be closed like 'a<b >' rather than 'a<b>'.

unsigned PrintCanonicalTypes

Whether to print types as written or canonically.

unsigned AlwaysIncludeTypeForTemplateArgument

Whether to use type suffixes (eg: 1U) on integral non-type template parameters.

unsigned UsePreferredNames

Whether to use C++ template preferred_name attributes when printing templates.

unsigned UseEnumerators

Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...

unsigned SuppressInlineNamespace

Suppress printing parts of scope specifiers that correspond to inline namespaces.

const PrintingCallbacks * Callbacks

Callbacks to use to allow the behavior of printing to be customized.

A this pointer adjustment.