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
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 (.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 (->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(->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() && ->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 ->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 ()
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 (->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(.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 ()
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 ( ||
->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 ->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:
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 && ->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 ( ||
->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 ( || 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 ( || 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 ( || (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(( || !isa(D) ||
4464 "Unexpected DynamicInitKind !");
4465
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) {
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 ()
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) || ->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 ()
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
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 ( ||
->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
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
5712 AddressSpace =
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
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());
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.