41#include "llvm/ADT/DenseSet.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DerivedTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/Metadata.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/MD5.h"
53#include "llvm/Support/Path.h"
54#include "llvm/Support/SHA1.h"
55#include "llvm/Support/SHA256.h"
56#include "llvm/Support/TimeProfiler.h"
64 if (TI.isAlignRequired())
92 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
96 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
114 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
115 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
116 DBuilder(CGM.getModule()) {
121 assert(LexicalBlockStack.empty() &&
122 "Region stack mismatch, stack not empty!");
125void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
126 uint64_t Group, uint8_t Rank) {
127 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
131 Rank = std::min<uint8_t>(Rank, 7);
133 const llvm::DebugLoc &DL = I->getDebugLoc();
138 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
139 Group = DL->getAtomGroup();
140 Rank = DL->getAtomRank();
145 KeyInstructionsInfo.HighestEmittedAtom =
146 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
149 llvm::DILocation *NewDL = llvm::DILocation::get(
150 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
151 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
152 I->setDebugLoc(NewDL);
156 llvm::Value *Backup) {
158 KeyInstructionsInfo.CurrentAtom);
164 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
167 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
168 if (!SP || !SP->getKeyInstructionsEnabled())
171 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
173 llvm::Instruction *BackupI =
174 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
179 addInstSourceAtomMetadata(BackupI, Group, 2);
185 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
186 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
189 addInstSourceAtomMetadata(BackupI, Group, Rank++);
195 KeyInstructionsInfo.NextAtom = 1;
196 KeyInstructionsInfo.HighestEmittedAtom = 0;
197 KeyInstructionsInfo.CurrentAtom = 0;
203 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
204 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
212 DI->KeyInstructionsInfo.NextAtom =
213 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
214 DI->KeyInstructionsInfo.NextAtom);
216 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
222 init(TemporaryLocation);
229 init(TemporaryLocation, DefaultToEmpty);
233 bool DefaultToEmpty) {
240 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
242 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
245 if (TemporaryLocation.
isValid()) {
246 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
250 if (DefaultToEmpty) {
251 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
256 assert(!DI->LexicalBlockStack.empty());
257 CGF->Builder.SetCurrentDebugLocation(
258 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
259 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
269 if (!CGF.getDebugInfo()) {
273 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
277 if (Loc->getAtomGroup())
278 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
279 Loc->getColumn(), Loc->getScope(),
280 Loc->getInlinedAt(), Loc.isImplicitCode());
281 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
289 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
295 if (!CGF.getDebugInfo()) {
299 auto &DI = *CGF.getDebugInfo();
300 SavedLocation = DI.getLocation();
301 assert((DI.getInlinedAt() ==
302 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
303 "CGDebugInfo and IRBuilder are out of sync");
305 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
311 auto &DI = *CGF->getDebugInfo();
312 DI.EmitInlineFunctionEnd(CGF->Builder);
313 DI.EmitLocation(CGF->Builder, SavedLocation);
321 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
326 if (LexicalBlockStack.empty())
332 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
335 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
336 LexicalBlockStack.pop_back();
337 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
338 LBF->getScope(), getOrCreateFile(CurLoc)));
341 LexicalBlockStack.pop_back();
342 LexicalBlockStack.emplace_back(
343 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
347llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
348 llvm::DIScope *Mod = getParentModuleOrNull(D);
353llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
358 auto I = RegionMap.find(Context);
359 if (I != RegionMap.end()) {
360 llvm::Metadata *
V = I->second;
361 return dyn_cast_or_null<llvm::DIScope>(
V);
365 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
366 return getOrCreateNamespace(NSDecl);
368 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
369 if (!RDecl->isDependentType())
375PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
376 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
383 if (CGM.getCodeGenOpts().EmitCodeView) {
404StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
405 return internString(GetName(FD));
408StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
409 SmallString<256> MethodName;
410 llvm::raw_svector_ostream
OS(MethodName);
413 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
414 OS << OID->getName();
415 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
416 OS << OID->getName();
417 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
418 if (OC->IsClassExtension()) {
419 OS << OC->getClassInterface()->getName();
421 OS << OC->getIdentifier()->getNameStart() <<
'('
422 << OC->getIdentifier()->getNameStart() <<
')';
424 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
425 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
429 return internString(
OS.str());
432StringRef CGDebugInfo::getSelectorName(Selector S) {
436StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
439 return internString(GetName(RD));
445 return II->getName();
450 if (CGM.getCodeGenOpts().EmitCodeView) {
453 "Typedef should not be in another decl context!");
454 assert(D->getDeclName().getAsIdentifierInfo() &&
455 "Typedef was not named!");
456 return D->getDeclName().getAsIdentifierInfo()->getName();
459 if (CGM.getLangOpts().CPlusPlus) {
462 ASTContext &Context = CGM.getContext();
466 Name = DD->getName();
467 else if (
const TypedefNameDecl *TND =
471 Name = TND->getName();
474 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
475 if (CXXRD->isLambda())
477 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
480 SmallString<256> UnnamedType(
"<unnamed-type-");
483 return internString(UnnamedType);
491std::optional<llvm::DIFile::ChecksumKind>
492CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
495 if (!CGM.getCodeGenOpts().EmitCodeView &&
496 CGM.getCodeGenOpts().DwarfVersion < 5)
499 SourceManager &
SM = CGM.getContext().getSourceManager();
500 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
504 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
505 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
507 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
508 return llvm::DIFile::CSK_MD5;
510 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
511 return llvm::DIFile::CSK_SHA1;
513 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
514 return llvm::DIFile::CSK_SHA256;
518 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
521std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
523 if (!CGM.getCodeGenOpts().EmbedSource)
526 bool SourceInvalid =
false;
527 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
535llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
536 SourceManager &
SM = CGM.getContext().getSourceManager();
539 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
545 FileName = TheCU->getFile()->getFilename();
546 CSInfo = TheCU->getFile()->getChecksum();
548 PresumedLoc PLoc =
SM.getPresumedLoc(Loc);
552 FileName = TheCU->getFile()->getFilename();
560 auto It = DIFileCache.find(
FileName.data());
561 if (It != DIFileCache.end()) {
563 if (llvm::Metadata *
V = It->second)
568 SmallString<64> Checksum;
570 std::optional<llvm::DIFile::ChecksumKind> CSKind =
571 computeChecksum(FID, Checksum);
573 CSInfo.emplace(*CSKind, Checksum);
575 return createFile(
FileName, CSInfo, getSource(
SM,
SM.getFileID(Loc)));
578llvm::DIFile *CGDebugInfo::createFile(
580 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
581 std::optional<StringRef> Source) {
585 std::string CurDir =
remapDIPath(getCurrentDirname());
586 SmallString<128> DirBuf;
587 SmallString<128> FileBuf;
588 if (llvm::sys::path::is_absolute(RemappedFile)) {
591 auto FileIt = llvm::sys::path::begin(RemappedFile);
592 auto FileE = llvm::sys::path::end(RemappedFile);
593 auto CurDirIt = llvm::sys::path::begin(CurDir);
594 auto CurDirE = llvm::sys::path::end(CurDir);
595 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
596 llvm::sys::path::append(DirBuf, *CurDirIt);
597 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
603 for (; FileIt != FileE; ++FileIt)
604 llvm::sys::path::append(FileBuf, *FileIt);
609 if (!llvm::sys::path::is_absolute(
FileName))
613 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
614 DIFileCache[
FileName.data()].reset(F);
620 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
621 if (llvm::sys::path::replace_path_prefix(P, From, To))
623 return P.str().str();
630 return SM.getPresumedLoc(Loc).getLine();
633unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
646StringRef CGDebugInfo::getCurrentDirname() {
650void CGDebugInfo::CreateCompileUnit() {
651 SmallString<64> Checksum;
652 std::optional<llvm::DIFile::ChecksumKind> CSKind;
653 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
663 SourceManager &
SM = CGM.getContext().getSourceManager();
664 auto &CGO = CGM.getCodeGenOpts();
665 const LangOptions &LO = CGM.getLangOpts();
666 std::string MainFileName = CGO.MainFileName;
667 if (MainFileName.empty())
668 MainFileName =
"<stdin>";
674 std::string MainFileDir;
676 SM.getFileEntryRefForID(
SM.getMainFileID())) {
677 MainFileDir = std::string(MainFile->getDir().getName());
678 if (!llvm::sys::path::is_absolute(MainFileName)) {
679 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
680 llvm::sys::path::Style Style =
682 ? (CGM.getTarget().getTriple().isOSWindows()
683 ? llvm::sys::path::Style::windows_backslash
684 : llvm::sys::path::Style::posix)
685 : llvm::sys::path::Style::native;
686 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
687 MainFileName = std::string(
688 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
695 if (MainFile->getName() == MainFileName &&
697 MainFile->getName().rsplit(
'.').second)
699 MainFileName = CGM.getModule().getName().str();
701 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
705 llvm::dwarf::SourceLanguage LangTag;
708 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
709 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
710 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
711 else if (LO.CPlusPlus14)
712 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
713 else if (LO.CPlusPlus11)
714 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
716 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
717 }
else if (LO.ObjC) {
718 LangTag = llvm::dwarf::DW_LANG_ObjC;
719 }
else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf ||
720 CGM.getCodeGenOpts().DwarfVersion >= 5)) {
721 LangTag = llvm::dwarf::DW_LANG_OpenCL;
722 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
723 LangTag = llvm::dwarf::DW_LANG_C11;
725 LangTag = llvm::dwarf::DW_LANG_C99;
727 LangTag = llvm::dwarf::DW_LANG_C89;
733 unsigned RuntimeVers = 0;
737 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
739 case llvm::codegenoptions::NoDebugInfo:
740 case llvm::codegenoptions::LocTrackingOnly:
741 EmissionKind = llvm::DICompileUnit::NoDebug;
743 case llvm::codegenoptions::DebugLineTablesOnly:
744 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
746 case llvm::codegenoptions::DebugDirectivesOnly:
747 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
749 case llvm::codegenoptions::DebugInfoConstructor:
750 case llvm::codegenoptions::LimitedDebugInfo:
751 case llvm::codegenoptions::FullDebugInfo:
752 case llvm::codegenoptions::UnusedTypeInfo:
753 EmissionKind = llvm::DICompileUnit::FullDebug;
758 auto &CGOpts = CGM.getCodeGenOpts();
764 CSInfo.emplace(*CSKind, Checksum);
765 llvm::DIFile *CUFile = DBuilder.createFile(
767 getSource(
SM,
SM.getMainFileID()));
769 StringRef Sysroot, SDK;
770 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
771 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
772 auto B = llvm::sys::path::rbegin(Sysroot);
773 auto E = llvm::sys::path::rend(Sysroot);
775 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
780 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
781 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
782 CGOpts.DebugNameTable);
783 if (CGM.getTarget().getTriple().isNVPTX())
784 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
785 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
786 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
789 TheCU = DBuilder.createCompileUnit(
790 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
791 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
792 CGOpts.PrepareForThinLTO,
793 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
794 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
795 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
798llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
802#define BUILTIN_TYPE(Id, SingletonId)
803#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
804#include "clang/AST/BuiltinTypes.def"
805 case BuiltinType::Dependent:
806 llvm_unreachable(
"Unexpected builtin type");
807 case BuiltinType::NullPtr:
808 return DBuilder.createNullPtrType();
809 case BuiltinType::Void:
811 case BuiltinType::ObjCClass:
814 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
815 "objc_class", TheCU, TheCU->getFile(), 0);
817 case BuiltinType::ObjCId: {
828 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
829 "objc_class", TheCU, TheCU->getFile(), 0);
831 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
833 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
835 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
836 (uint64_t)0, 0, llvm::DINode::FlagZero,
837 nullptr, llvm::DINodeArray());
839 DBuilder.replaceArrays(
840 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
841 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
842 llvm::DINode::FlagZero, ISATy)));
845 case BuiltinType::ObjCSel: {
847 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
848 "objc_selector", TheCU,
849 TheCU->getFile(), 0);
853#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
854 case BuiltinType::Id: \
855 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
857#include "clang/Basic/OpenCLImageTypes.def"
858 case BuiltinType::OCLSampler:
859 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
860 case BuiltinType::OCLEvent:
861 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
862 case BuiltinType::OCLClkEvent:
863 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
864 case BuiltinType::OCLQueue:
865 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
866 case BuiltinType::OCLReserveID:
867 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
868#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
869 case BuiltinType::Id: \
870 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
871#include "clang/Basic/OpenCLExtensionTypes.def"
872#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
873 case BuiltinType::Id: \
874 return getOrCreateStructPtrType(#Name, SingletonId);
875#include "clang/Basic/HLSLIntangibleTypes.def"
877#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
878#include "clang/Basic/AArch64ACLETypes.def"
880 if (BT->
getKind() == BuiltinType::MFloat8) {
881 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
882 BTName = BT->
getName(CGM.getLangOpts());
885 return DBuilder.createBasicType(BTName, Size, Encoding);
887 ASTContext::BuiltinVectorTypeInfo Info =
889 BT->
getKind() == BuiltinType::SveCount
890 ? ASTContext::BuiltinVectorTypeInfo(
891 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
893 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
900 "Unsupported number of vectors for svcount_t");
904 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
907 Info.
ElementType = CGM.getContext().UnsignedCharTy;
910 llvm::Metadata *LowerBound, *UpperBound;
911 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
912 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
913 if (Info.
EC.isScalable()) {
914 unsigned NumElemsPerVG = NumElems / 2;
915 SmallVector<uint64_t, 9> Expr(
916 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
917 46, 0, llvm::dwarf::DW_OP_mul,
918 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
919 UpperBound = DBuilder.createExpression(Expr);
921 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
922 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
924 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
925 nullptr, LowerBound, UpperBound,
nullptr);
926 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
927 llvm::DIType *ElemTy =
928 getOrCreateType(Info.
ElementType, TheCU->getFile());
930 return DBuilder.createVectorType( 0, Align, ElemTy,
935#define PPC_VECTOR_TYPE(Name, Id, size) \
936 case BuiltinType::Id:
937#include "clang/Basic/PPCTypes.def"
940#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
941#include "clang/Basic/RISCVVTypes.def"
943 ASTContext::BuiltinVectorTypeInfo Info =
944 CGM.getContext().getBuiltinVectorTypeInfo(BT);
946 unsigned ElementCount = Info.
EC.getKnownMinValue();
947 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
949 bool Fractional =
false;
952 unsigned FixedSize = ElementCount * SEW;
956 }
else if (FixedSize < 64) {
959 LMUL = 64 / FixedSize;
961 LMUL = FixedSize / 64;
965 SmallVector<uint64_t, 12> Expr(
969 {llvm::dwarf::DW_OP_bregx,
972 llvm::dwarf::DW_OP_constu,
974 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
976 Expr.push_back(llvm::dwarf::DW_OP_div);
978 Expr.push_back(llvm::dwarf::DW_OP_mul);
981 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
983 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
986 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
987 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
988 auto *UpperBound = DBuilder.createExpression(Expr);
989 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
990 nullptr, LowerBound, UpperBound,
nullptr);
991 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
992 llvm::DIType *ElemTy =
993 getOrCreateType(Info.
ElementType, TheCU->getFile());
996 return DBuilder.createVectorType(0, Align, ElemTy,
1000#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1001 case BuiltinType::Id: { \
1004 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1005 MangledName, TheCU, TheCU->getFile(), 0); \
1006 return SingletonId; \
1008#include "clang/Basic/WebAssemblyReferenceTypes.def"
1009#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1010 case BuiltinType::Id: { \
1013 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1014 TheCU, TheCU->getFile(), 0); \
1015 return SingletonId; \
1017#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1018 case BuiltinType::Id: { \
1021 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1022 return SingletonId; \
1024#include "clang/Basic/AMDGPUTypes.def"
1025 case BuiltinType::UChar:
1026 case BuiltinType::Char_U:
1027 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1029 case BuiltinType::Char_S:
1030 case BuiltinType::SChar:
1031 Encoding = llvm::dwarf::DW_ATE_signed_char;
1033 case BuiltinType::Char8:
1034 case BuiltinType::Char16:
1035 case BuiltinType::Char32:
1036 Encoding = llvm::dwarf::DW_ATE_UTF;
1038 case BuiltinType::UShort:
1039 case BuiltinType::UInt:
1040 case BuiltinType::UInt128:
1041 case BuiltinType::ULong:
1042 case BuiltinType::WChar_U:
1043 case BuiltinType::ULongLong:
1044 Encoding = llvm::dwarf::DW_ATE_unsigned;
1046 case BuiltinType::Short:
1047 case BuiltinType::Int:
1048 case BuiltinType::Int128:
1049 case BuiltinType::Long:
1050 case BuiltinType::WChar_S:
1051 case BuiltinType::LongLong:
1052 Encoding = llvm::dwarf::DW_ATE_signed;
1054 case BuiltinType::Bool:
1055 Encoding = llvm::dwarf::DW_ATE_boolean;
1057 case BuiltinType::Half:
1058 case BuiltinType::Float:
1059 case BuiltinType::LongDouble:
1060 case BuiltinType::Float16:
1061 case BuiltinType::BFloat16:
1062 case BuiltinType::Float128:
1063 case BuiltinType::Double:
1064 case BuiltinType::Ibm128:
1070 Encoding = llvm::dwarf::DW_ATE_float;
1072 case BuiltinType::ShortAccum:
1073 case BuiltinType::Accum:
1074 case BuiltinType::LongAccum:
1075 case BuiltinType::ShortFract:
1076 case BuiltinType::Fract:
1077 case BuiltinType::LongFract:
1078 case BuiltinType::SatShortFract:
1079 case BuiltinType::SatFract:
1080 case BuiltinType::SatLongFract:
1081 case BuiltinType::SatShortAccum:
1082 case BuiltinType::SatAccum:
1083 case BuiltinType::SatLongAccum:
1084 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1086 case BuiltinType::UShortAccum:
1087 case BuiltinType::UAccum:
1088 case BuiltinType::ULongAccum:
1089 case BuiltinType::UShortFract:
1090 case BuiltinType::UFract:
1091 case BuiltinType::ULongFract:
1092 case BuiltinType::SatUShortAccum:
1093 case BuiltinType::SatUAccum:
1094 case BuiltinType::SatULongAccum:
1095 case BuiltinType::SatUShortFract:
1096 case BuiltinType::SatUFract:
1097 case BuiltinType::SatULongFract:
1098 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1102 BTName = BT->
getName(CGM.getLangOpts());
1105 return DBuilder.createBasicType(BTName, Size, Encoding);
1108llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1110 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1112 ? llvm::dwarf::DW_ATE_unsigned
1113 : llvm::dwarf::DW_ATE_signed;
1115 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1119llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1121 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1123 Encoding = llvm::dwarf::DW_ATE_lo_user;
1126 return DBuilder.createBasicType(
"complex", Size, Encoding);
1140 return llvm::dwarf::DW_TAG_const_type;
1144 return llvm::dwarf::DW_TAG_volatile_type;
1148 return llvm::dwarf::DW_TAG_restrict_type;
1150 return (llvm::dwarf::Tag)0;
1153llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1154 llvm::DIFile *Unit) {
1155 QualifierCollector Qc;
1169 bool AuthenticatesNullValues =
1172 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1173 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1174 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1175 ExtraDiscr, IsaPointer,
1176 AuthenticatesNullValues);
1178 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1179 return getOrCreateType(QualType(
T, 0), Unit);
1183 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1187 return DBuilder.createQualifiedType(Tag, FromTy);
1190llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1191 llvm::DIFile *Unit) {
1200 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1205 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1211 return DBuilder.createQualifiedType(Tag, FromTy);
1214llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1215 llvm::DIFile *Unit) {
1221 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1223 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1227llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1228 llvm::DIFile *Unit) {
1229 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1235 switch (TheCU->getSourceLanguage()) {
1236 case llvm::dwarf::DW_LANG_C_plus_plus:
1237 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1238 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1240 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1269 llvm::DICompileUnit *TheCU) {
1287 llvm::DICompileUnit *TheCU) {
1293 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1295 if (RD->isDynamicClass() &&
1301 llvm::raw_svector_ostream Out(Identifier);
1308 llvm::dwarf::Tag Tag;
1310 Tag = llvm::dwarf::DW_TAG_structure_type;
1312 Tag = llvm::dwarf::DW_TAG_union_type;
1317 Tag = llvm::dwarf::DW_TAG_class_type;
1322llvm::DICompositeType *
1323CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1324 llvm::DIScope *Ctx) {
1325 const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
1326 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1328 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1329 const unsigned Line =
1331 StringRef RDName = getClassName(RD);
1338 Size = CGM.getContext().getTypeSize(Ty);
1340 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1345 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1346 if (!CXXRD->hasDefinition() ||
1347 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1348 Flags |= llvm::DINode::FlagNonTrivial;
1351 SmallString<256> Identifier;
1353 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1355 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1358 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1359 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1360 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1361 CollectCXXTemplateParams(TSpecial, DefUnit));
1362 ReplaceMap.emplace_back(
1363 std::piecewise_construct, std::make_tuple(Ty),
1364 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1368llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1371 llvm::DIFile *Unit) {
1376 std::optional<unsigned> DWARFAddressSpace =
1377 CGM.getTarget().getDWARFAddressSpace(
1378 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1380 const BTFTagAttributedType *BTFAttrTy;
1381 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1382 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1384 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1385 SmallVector<llvm::Metadata *, 4> Annots;
1387 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1389 llvm::Metadata *Ops[2] = {
1390 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1391 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1392 Annots.insert(Annots.begin(),
1393 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1395 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1398 llvm::DINodeArray Annotations =
nullptr;
1399 if (Annots.size() > 0)
1400 Annotations = DBuilder.getOrCreateArray(Annots);
1402 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1403 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1404 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1405 Size, Align, DWARFAddressSpace);
1407 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1408 Align, DWARFAddressSpace, StringRef(),
1412llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1413 llvm::DIType *&
Cache) {
1416 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1417 TheCU, TheCU->getFile(), 0);
1418 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1419 Cache = DBuilder.createPointerType(
Cache, Size);
1423uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1424 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1425 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1435 if (CGM.getLangOpts().OpenCL) {
1436 FType = CGM.getContext().IntTy;
1437 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1438 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1440 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1441 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1442 FType = CGM.getContext().IntTy;
1443 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1444 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1446 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1447 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1448 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1449 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1450 EltTys.push_back(DBuilder.createMemberType(
1451 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1452 FieldOffset, llvm::DINode::FlagZero, DescTy));
1453 FieldOffset += FieldSize;
1459llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1460 llvm::DIFile *Unit) {
1461 SmallVector<llvm::Metadata *, 8> EltTys;
1464 llvm::DINodeArray Elements;
1467 FType = CGM.getContext().UnsignedLongTy;
1468 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1469 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1471 Elements = DBuilder.getOrCreateArray(EltTys);
1474 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1477 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1478 FieldOffset, 0, Flags,
nullptr, Elements);
1483 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1485 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1488 Elements = DBuilder.getOrCreateArray(EltTys);
1494 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1495 Flags,
nullptr, Elements);
1497 return DBuilder.createPointerType(EltTy, Size);
1500static llvm::SmallVector<TemplateArgument>
1502 assert(Ty->isTypeAlias());
1511 ArrayRef SubstArgs = Ty->template_arguments();
1514 if (Param->isParameterPack()) {
1523 if (SubstArgs.empty()) {
1532 SpecArgs.push_back(SubstArgs.front());
1533 SubstArgs = SubstArgs.drop_front();
1538llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1539 llvm::DIFile *Unit) {
1540 assert(Ty->isTypeAlias());
1541 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1543 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1551 SmallString<128> NS;
1552 llvm::raw_svector_ostream
OS(NS);
1554 auto PP = getPrintingPolicy();
1557 SourceLocation Loc =
AliasDecl->getLocation();
1559 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1560 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1569 llvm::raw_string_ostream
OS(Name);
1571 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1572 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1573 !HasReconstitutableArgs(Args.Args))
1574 printTemplateArgumentList(OS, Args.Args, PP);
1576 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1577 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1578 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1582 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1584 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1601 return llvm::DINode::FlagZero;
1605 return llvm::DINode::FlagPrivate;
1607 return llvm::DINode::FlagProtected;
1609 return llvm::DINode::FlagPublic;
1611 return llvm::DINode::FlagZero;
1613 llvm_unreachable(
"unexpected access enumerator");
1616llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1617 llvm::DIFile *Unit) {
1618 llvm::DIType *Underlying =
1630 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1632 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1637 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1638 getOrCreateFile(Loc), getLineNumber(Loc),
1639 getDeclContextDescriptor(Ty->
getDecl()), Align,
1640 Flags, Annotations);
1650 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1652 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1654 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1656 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1658 return llvm::dwarf::DW_CC_BORLAND_pascal;
1660 return llvm::dwarf::DW_CC_LLVM_Win64;
1662 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1666 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1668 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1670 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1672 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1674 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1676 return llvm::dwarf::DW_CC_LLVM_Swift;
1678 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1680 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1682 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1684 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1686 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1688 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1690 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1691#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1705 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1711 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1713 Flags |= llvm::DINode::FlagLValueReference;
1715 Flags |= llvm::DINode::FlagRValueReference;
1719llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1720 llvm::DIFile *Unit) {
1721 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1723 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1729 SmallVector<llvm::Metadata *, 16> EltTys;
1732 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1734 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1738 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1741 for (
const QualType &ParamType : FPT->param_types())
1742 EltTys.push_back(getOrCreateType(ParamType, Unit));
1743 if (FPT->isVariadic())
1744 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1747 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1748 llvm::DIType *F = DBuilder.createSubroutineType(
1753llvm::DIDerivedType *
1754CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1755 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1756 StringRef Name = BitFieldDecl->
getName();
1757 QualType Ty = BitFieldDecl->
getType();
1758 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1761 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1762 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1765 llvm::DIFile *
File = getOrCreateFile(Loc);
1766 unsigned Line = getLineNumber(Loc);
1768 const CGBitFieldInfo &BitFieldInfo =
1769 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1771 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1778 if (CGM.getDataLayout().isBigEndian())
1780 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1782 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1783 return DBuilder.createBitFieldMemberType(
1784 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1785 Flags, DebugType, Annotations);
1788llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1789 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1790 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1792 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1817 if (PreviousFieldsDI.empty())
1821 auto *PreviousMDEntry =
1822 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1823 auto *PreviousMDField =
1824 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1825 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1826 PreviousMDField->getSizeInBits() == 0)
1830 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1832 assert(PreviousBitfield->isBitField());
1834 if (!PreviousBitfield->isZeroLengthBitField())
1837 QualType Ty = PreviousBitfield->getType();
1838 SourceLocation Loc = PreviousBitfield->getLocation();
1839 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1840 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1841 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1843 llvm::DIFile *
File = getOrCreateFile(Loc);
1844 unsigned Line = getLineNumber(Loc);
1850 llvm::DINode::DIFlags Flags =
1852 llvm::DINodeArray Annotations =
1853 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1854 return DBuilder.createBitFieldMemberType(
1855 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1856 Flags, DebugType, Annotations);
1859llvm::DIType *CGDebugInfo::createFieldType(
1861 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1862 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1863 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1866 llvm::DIFile *file = getOrCreateFile(loc);
1867 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1870 auto Align = AlignInBits;
1871 if (!
type->isIncompleteArrayType()) {
1872 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1873 SizeInBits = TI.
Width;
1879 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1880 offsetInBits, flags, debugType, Annotations);
1884CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1885 llvm::DIFile *FileScope) {
1889 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1892 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1893 SP = DBuilder.createFunction(
1894 FileScope, FuncName, StringRef(),
1895 FileScope, 0, DIFnTy,
1897 llvm::DINode::FlagArtificial,
1898 llvm::DISubprogram::SPFlagDefinition,
1899 nullptr,
nullptr,
nullptr,
1900 nullptr, StringRef(),
1901 CGM.getCodeGenOpts().DebugKeyInstructions);
1908CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
1910 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
1912 assert(
Capture.capturesVariable());
1914 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
1915 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
1917 return CaptureDecl->
getName();
1920void CGDebugInfo::CollectRecordLambdaFields(
1921 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
1922 llvm::DIType *RecordTy) {
1927 unsigned fieldno = 0;
1930 I != E; ++I, ++Field, ++fieldno) {
1931 const LambdaCapture &
Capture = *I;
1933 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
1935 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1945 Loc =
Field->getLocation();
1949 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
1950 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
1955 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1957 elements.push_back(createFieldType(
1959 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
1963llvm::DIDerivedType *
1964CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1965 const RecordDecl *RD) {
1969 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1970 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1972 unsigned LineNumber = getLineNumber(Var->
getLocation());
1973 StringRef VName = Var->
getName();
1977 llvm::Constant *
C =
nullptr;
1982 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
1983 if (
Value->isFloat())
1984 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
1989 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
1990 ? llvm::dwarf::DW_TAG_variable
1991 : llvm::dwarf::DW_TAG_member;
1993 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1994 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1999void CGDebugInfo::CollectRecordNormalField(
2000 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2001 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2002 const RecordDecl *RD) {
2007 if (
name.empty() && !
type->isRecordType())
2010 llvm::DIType *FieldType;
2012 llvm::DIDerivedType *BitFieldType;
2013 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2014 if (llvm::DIType *Separator =
2015 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2016 elements.push_back(Separator);
2019 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2022 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2025 elements.push_back(FieldType);
2028void CGDebugInfo::CollectRecordNestedType(
2029 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2030 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2037 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2038 elements.push_back(nestedType);
2041void CGDebugInfo::CollectRecordFields(
2042 const RecordDecl *record, llvm::DIFile *tunit,
2043 SmallVectorImpl<llvm::Metadata *> &elements,
2044 llvm::DICompositeType *RecordTy) {
2045 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2047 if (CXXDecl && CXXDecl->
isLambda())
2048 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2050 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2053 unsigned fieldNo = 0;
2057 for (
const auto *I : record->
decls())
2058 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2059 if (
V->hasAttr<NoDebugAttr>())
2064 if (CGM.getCodeGenOpts().EmitCodeView &&
2072 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2073 if (MI != StaticDataMemberCache.end()) {
2074 assert(MI->second &&
2075 "Static data member declaration should still exist");
2076 elements.push_back(MI->second);
2078 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2079 elements.push_back(Field);
2081 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2082 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2083 elements, RecordTy, record);
2087 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2090 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2095 if (!nestedType->isImplicit() &&
2096 nestedType->getDeclContext() == record)
2097 CollectRecordNestedType(nestedType, elements);
2103llvm::DISubroutineType *
2104CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2105 llvm::DIFile *Unit) {
2106 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2108 return cast_or_null<llvm::DISubroutineType>(
2109 getOrCreateType(QualType(
Func, 0), Unit));
2112 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2113 ThisType =
Method->getThisType();
2115 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2118llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2119 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2120 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2122 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2125llvm::DISubroutineType *
2126CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2127 const FunctionProtoType *
Func,
2128 llvm::DIFile *Unit,
bool SkipFirst) {
2129 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2144 getOrCreateType(CGM.getContext().getFunctionType(
2145 Func->getReturnType(),
Func->getParamTypes(), EPI),
2147 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2148 assert(Args.size() &&
"Invalid number of arguments!");
2150 SmallVector<llvm::Metadata *, 16> Elts;
2153 Elts.push_back(Args[0]);
2155 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2159 if (!HasExplicitObjectParameter) {
2160 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2163 DBuilder.createObjectPointerType(ThisPtrType,
true);
2164 Elts.push_back(ThisPtrType);
2168 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2169 Elts.push_back(Args[i]);
2172 if (HasExplicitObjectParameter) {
2173 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2174 "Expected at least return type and object parameter.");
2175 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2178 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2180 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2187 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2195CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2198 const bool IsCtorOrDtor =
2201 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2208 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2211 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2214 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2217 return CGM.getMangledName(
Method);
2220llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2221 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2224 StringRef MethodName = getFunctionName(
Method);
2225 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2227 StringRef MethodLinkageName;
2234 MethodLinkageName = GetMethodLinkageName(
Method);
2237 llvm::DIFile *MethodDefUnit =
nullptr;
2238 unsigned MethodLine = 0;
2239 if (!
Method->isImplicit()) {
2240 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2241 MethodLine = getLineNumber(
Method->getLocation());
2245 llvm::DIType *ContainingType =
nullptr;
2246 unsigned VIndex = 0;
2247 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2248 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2249 int ThisAdjustment = 0;
2252 if (
Method->isPureVirtual())
2253 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2255 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2257 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2261 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2265 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2267 MethodVFTableLocation ML =
2268 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2276 if (
Method->size_overridden_methods() == 0)
2277 Flags |= llvm::DINode::FlagIntroducedVirtual;
2282 ThisAdjustment = CGM.getCXXABI()
2283 .getVirtualFunctionPrologueThisAdjustment(GD)
2286 ContainingType = RecordTy;
2289 if (
Method->getCanonicalDecl()->isDeleted())
2290 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2292 if (
Method->isNoReturn())
2293 Flags |= llvm::DINode::FlagNoReturn;
2296 Flags |= llvm::DINode::FlagStaticMember;
2297 if (
Method->isImplicit())
2298 Flags |= llvm::DINode::FlagArtificial;
2300 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2301 if (CXXC->isExplicit())
2302 Flags |= llvm::DINode::FlagExplicit;
2303 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2304 if (CXXC->isExplicit())
2305 Flags |= llvm::DINode::FlagExplicit;
2307 if (
Method->hasPrototype())
2308 Flags |= llvm::DINode::FlagPrototyped;
2310 Flags |= llvm::DINode::FlagLValueReference;
2312 Flags |= llvm::DINode::FlagRValueReference;
2313 if (!
Method->isExternallyVisible())
2314 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2315 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2316 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2320 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2321 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2324 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2325 llvm::DISubprogram *SP = DBuilder.createMethod(
2326 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2327 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2328 TParamsArray.get(),
nullptr,
2329 CGM.getCodeGenOpts().DebugKeyInstructions);
2331 SPCache[
Method->getCanonicalDecl()].reset(SP);
2336void CGDebugInfo::CollectCXXMemberFunctions(
2337 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2338 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2343 for (
const auto *I : RD->
decls()) {
2344 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2358 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2367 auto MI = SPCache.find(
Method->getCanonicalDecl());
2368 EltTys.push_back(MI == SPCache.end()
2369 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2370 :
static_cast<llvm::Metadata *
>(MI->second));
2374void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2375 SmallVectorImpl<llvm::Metadata *> &EltTys,
2376 llvm::DIType *RecordTy) {
2377 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2378 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2379 llvm::DINode::FlagZero);
2383 if (CGM.getCodeGenOpts().EmitCodeView) {
2384 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2385 llvm::DINode::FlagIndirectVirtualBase);
2389void CGDebugInfo::CollectCXXBasesAux(
2390 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2391 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2393 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2394 llvm::DINode::DIFlags StartingFlags) {
2395 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2396 for (
const auto &BI : Bases) {
2399 BI.getType()->castAsCanonical<RecordType>()->getOriginalDecl())
2401 if (!SeenTypes.insert(Base).second)
2403 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2404 llvm::DINode::DIFlags BFlags = StartingFlags;
2408 if (BI.isVirtual()) {
2409 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2412 BaseOffset = 0 - CGM.getItaniumVTableContext()
2413 .getVirtualBaseOffsetOffset(RD, Base)
2419 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2420 VBPtrOffset = CGM.getContext()
2421 .getASTRecordLayout(RD)
2425 BFlags |= llvm::DINode::FlagVirtual;
2432 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2433 VBPtrOffset, BFlags);
2434 EltTys.push_back(DTy);
2439CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2440 llvm::DIFile *Unit) {
2442 return llvm::DINodeArray();
2443 TemplateArgs &Args = *OArgs;
2444 SmallVector<llvm::Metadata *, 16> TemplateParams;
2445 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2446 const TemplateArgument &TA = Args.Args[i];
2450 Name = Args.TList->getParam(i)->getName();
2454 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2455 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2456 TheCU, Name, TTy, defaultParameter));
2461 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2462 TheCU, Name, TTy, defaultParameter,
2463 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2468 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2469 llvm::Constant *
V =
nullptr;
2472 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2473 !D->
hasAttr<CUDADeviceAttr>()) {
2476 if (
const auto *VD = dyn_cast<VarDecl>(D))
2477 V = CGM.GetAddrOfGlobalVar(VD);
2480 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2481 MD && MD->isImplicitObjectMemberFunction())
2482 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2483 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2484 V = CGM.GetAddrOfFunction(FD);
2487 else if (
const auto *MPT =
2488 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2492 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2494 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2495 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2496 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2497 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2498 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2500 V = ConstantEmitter(CGM).emitAbstract(
2501 SourceLocation(), TPO->getValue(), TPO->getType());
2503 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2505 assert(
V &&
"Failed to find template parameter pointer");
2506 V =
V->stripPointerCasts();
2508 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2509 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2513 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2514 llvm::Constant *
V =
nullptr;
2517 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2523 if (MPT->isMemberDataPointer())
2524 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2526 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2527 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2528 TheCU, Name, TTy, defaultParameter,
V));
2532 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2533 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2535 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2536 TheCU, Name, TTy, defaultParameter,
V));
2539 std::string QualName;
2540 llvm::raw_string_ostream
OS(QualName);
2542 OS, getPrintingPolicy());
2543 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2544 TheCU, Name,
nullptr, QualName, defaultParameter));
2548 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2549 TheCU, Name,
nullptr,
2556 T = CGM.getContext().getLValueReferenceType(
T);
2557 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2558 assert(
V &&
"Expression in template argument isn't constant");
2559 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2560 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2561 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2567 "These argument types shouldn't exist in concrete types");
2570 return DBuilder.getOrCreateArray(TemplateParams);
2573std::optional<CGDebugInfo::TemplateArgs>
2574CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2582 return std::nullopt;
2584std::optional<CGDebugInfo::TemplateArgs>
2585CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2589 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2591 return std::nullopt;
2592 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2593 const TemplateParameterList *TList =
T->getTemplateParameters();
2594 auto TA = TS->getTemplateArgs().asArray();
2595 return {{TList, TA}};
2597std::optional<CGDebugInfo::TemplateArgs>
2598CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2599 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2603 TemplateParameterList *TPList =
2604 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2605 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2606 return {{TPList, TAList.
asArray()}};
2608 return std::nullopt;
2612CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2613 llvm::DIFile *Unit) {
2614 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2617llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2618 llvm::DIFile *Unit) {
2619 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2622llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2623 llvm::DIFile *Unit) {
2624 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2627llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2628 if (!D->
hasAttr<BTFDeclTagAttr>())
2631 SmallVector<llvm::Metadata *, 4> Annotations;
2633 llvm::Metadata *Ops[2] = {
2634 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2635 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2636 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2638 return DBuilder.getOrCreateArray(Annotations);
2641llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2643 return VTablePtrType;
2645 ASTContext &Context = CGM.getContext();
2648 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2649 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2650 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2652 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2653 std::optional<unsigned> DWARFAddressSpace =
2654 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2656 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2657 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2658 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2659 return VTablePtrType;
2662StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2674 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2676 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2686 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2687 VTable->isDeclarationForLinker())
2691 StringRef SymbolName =
"_vtable$";
2693 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2702 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2704 llvm::DIFile *Unit = getOrCreateFile(Loc);
2705 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2707 llvm::DINode::FlagArtificial;
2708 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2709 ? llvm::dwarf::DW_TAG_variable
2710 : llvm::dwarf::DW_TAG_member;
2711 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2712 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2716 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2720 llvm::DIGlobalVariableExpression *GVE =
2721 DBuilder.createGlobalVariableExpression(
2722 TheCU, SymbolName, VTable->getName(), Unit, 0,
2723 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2724 true,
nullptr, DT,
nullptr,
2726 VTable->addDebugInfo(GVE);
2729StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2731 llvm::Function *InitFn) {
2736 return InitFn->getName();
2746 llvm::raw_svector_ostream OS(QualifiedGV);
2748 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2750 std::swap(Quals, GVName);
2754 llvm::raw_svector_ostream OS(InitName);
2756 OS << Quals <<
"::";
2761 llvm_unreachable(
"not an initializer");
2763 OS <<
"`dynamic initializer for '";
2766 OS <<
"`dynamic atexit destructor for '";
2773 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2774 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2775 getPrintingPolicy());
2780 return internString(
OS.str());
2783void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2784 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2793 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2800 llvm::DIType *VPtrTy =
nullptr;
2801 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2802 CGM.getTarget().getCXXABI().isMicrosoft();
2803 if (NeedVTableShape) {
2805 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2806 const VTableLayout &VFTLayout =
2807 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2808 unsigned VSlotCount =
2810 unsigned VTableWidth = PtrWidth * VSlotCount;
2811 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2812 std::optional<unsigned> DWARFAddressSpace =
2813 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2816 llvm::DIType *VTableType = DBuilder.createPointerType(
2817 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2818 EltTys.push_back(VTableType);
2821 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2829 VPtrTy = getOrCreateVTablePtrType(Unit);
2831 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2832 llvm::DIType *VPtrMember =
2833 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2834 llvm::DINode::FlagArtificial, VPtrTy);
2835 EltTys.push_back(VPtrMember);
2840 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2841 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2852 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2853 assert(!D.
isNull() &&
"null type");
2854 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2855 assert(
T &&
"could not create debug info for type");
2864 if (CGM.getCodeGenOpts().getDebugInfo() <=
2865 llvm::codegenoptions::DebugLineTablesOnly)
2869 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2871 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2873 CI->setMetadata(
"heapallocsite", node);
2877 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2879 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2881 auto I = TypeCache.find(TyPtr);
2884 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2885 assert(!Res->isForwardDecl());
2886 TypeCache[TyPtr].reset(Res);
2890 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2891 !CGM.getLangOpts().CPlusPlus)
2897 if (RD->
hasAttr<DLLImportAttr>())
2900 if (MD->hasAttr<DLLImportAttr>())
2913 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2923 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2924 Explicit = TD->isExplicitInstantiationOrSpecialization();
2928 if (CXXDecl->
fields().empty())
2938 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2939 if (CXXRD->isDynamicClass() &&
2940 CGM.getVTableLinkage(CXXRD) ==
2941 llvm::GlobalValue::AvailableExternallyLinkage &&
2952 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2954 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
2956 auto I = TypeCache.find(TyPtr);
2963 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
2964 assert(!Res->isForwardDecl());
2965 TypeCache[TyPtr].reset(Res);
2972 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2973 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2996 if (Ctor->isCopyOrMoveConstructor())
2998 if (!Ctor->isDeleted())
3017 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3020 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3021 RD->
hasAttr<StandaloneDebugAttr>())
3024 if (!LangOpts.CPlusPlus)
3030 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3046 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3047 Spec = SD->getSpecializationKind();
3056 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3067 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3068 llvm::DIType *
T = getTypeOrNull(Ty);
3069 if (
T &&
T->isForwardDecl())
3073llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3074 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3075 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3079 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3083 auto [Def, Pref] = CreateTypeDefinition(Ty);
3085 return Pref ? Pref : Def;
3088llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3089 llvm::DIFile *Unit) {
3093 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3097 return getOrCreateType(PNA->getTypedefType(), Unit);
3100std::pair<llvm::DIType *, llvm::DIType *>
3101CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3102 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3105 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3113 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3117 return {FwdDecl,
nullptr};
3119 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3120 CollectContainingType(CXXDecl, FwdDecl);
3123 LexicalBlockStack.emplace_back(&*FwdDecl);
3124 RegionMap[RD].reset(FwdDecl);
3127 SmallVector<llvm::Metadata *, 16> EltTys;
3134 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3136 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3137 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3141 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3142 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3143 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3145 LexicalBlockStack.pop_back();
3146 RegionMap.erase(RD);
3148 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3149 DBuilder.replaceArrays(FwdDecl, Elements);
3151 if (FwdDecl->isTemporary())
3153 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3155 RegionMap[RD].reset(FwdDecl);
3157 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3158 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3159 return {FwdDecl, PrefDI};
3161 return {FwdDecl,
nullptr};
3164llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3165 llvm::DIFile *Unit) {
3167 return getOrCreateType(Ty->getBaseType(), Unit);
3170llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3171 llvm::DIFile *Unit) {
3173 SourceLocation Loc = Ty->getDecl()->getLocation();
3176 return DBuilder.createTypedef(
3177 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3178 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3179 getDeclContextDescriptor(Ty->getDecl()));
3206llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3207 llvm::DIFile *Unit) {
3213 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
3218 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3219 !
ID->getImplementation())
3220 return DBuilder.createForwardDecl(
3221 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3222 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3225 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3226 unsigned Line = getLineNumber(
ID->getLocation());
3230 ObjCInterfaceDecl *Def =
ID->getDefinition();
3232 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3233 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3234 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3235 DefUnit,
Line, RuntimeLang);
3236 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3240 return CreateTypeDefinition(Ty, Unit);
3243llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3244 bool CreateSkeletonCU) {
3249 auto ModRef = ModuleCache.find(M);
3250 if (ModRef != ModuleCache.end())
3254 SmallString<128> ConfigMacros;
3256 llvm::raw_svector_ostream
OS(ConfigMacros);
3257 const auto &PPOpts = CGM.getPreprocessorOpts();
3260 for (
auto &M : PPOpts.Macros) {
3263 const std::string &
Macro = M.first;
3264 bool Undef = M.second;
3265 OS <<
"\"-" << (Undef ?
'U' :
'D');
3281 bool IsRootModule = M ? !M->
Parent :
true;
3285 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3286 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3287 "clang module without ASTFile must be specified by -fmodule-name");
3290 auto RemapPath = [
this](StringRef Path) -> std::string {
3292 StringRef Relative(Remapped);
3293 StringRef CompDir = TheCU->getDirectory();
3294 if (CompDir.empty())
3297 if (Relative.consume_front(CompDir))
3298 Relative.consume_front(llvm::sys::path::get_separator());
3300 return Relative.str();
3303 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3310 Signature = ModSig.truncatedValue();
3314 llvm::DIBuilder DIB(CGM.getModule());
3316 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3317 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3318 PCM = getCurrentDirname();
3322 llvm::sys::path::append(PCM, Mod.
getASTFile());
3323 DIB.createCompileUnit(
3324 TheCU->getSourceLanguage(),
3327 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3328 llvm::DICompileUnit::FullDebug, Signature);
3332 llvm::DIModule *Parent =
3334 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3336 std::string IncludePath = Mod.
getPath().str();
3337 llvm::DIModule *DIMod =
3338 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3339 RemapPath(IncludePath));
3340 ModuleCache[M].reset(DIMod);
3344llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3345 llvm::DIFile *Unit) {
3347 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3348 unsigned Line = getLineNumber(
ID->getLocation());
3349 unsigned RuntimeLang = TheCU->getSourceLanguage();
3355 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3356 if (
ID->getImplementation())
3357 Flags |= llvm::DINode::FlagObjcClassComplete;
3359 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3360 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3361 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3362 nullptr, llvm::DINodeArray(), RuntimeLang);
3364 QualType QTy(Ty, 0);
3365 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3368 LexicalBlockStack.emplace_back(RealDecl);
3369 RegionMap[Ty->
getDecl()].reset(RealDecl);
3372 SmallVector<llvm::Metadata *, 16> EltTys;
3374 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3376 llvm::DIType *SClassTy =
3377 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3381 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3382 llvm::DINode::FlagZero);
3383 EltTys.push_back(InhTag);
3387 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3388 SourceLocation Loc = PD->getLocation();
3389 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3390 unsigned PLine = getLineNumber(Loc);
3391 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3392 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3393 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3394 PD->getName(), PUnit, PLine,
3396 : getSelectorName(PD->getGetterName()),
3398 : getSelectorName(PD->getSetterName()),
3399 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3400 EltTys.push_back(PropertyNode);
3405 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3409 llvm::DenseSet<IsClassAndIdent> PropertySet;
3411 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3412 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3414 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3415 for (
auto *PD : ClassExt->properties()) {
3416 PropertySet.insert(GetIsClassAndIdent(PD));
3419 for (
const auto *PD :
ID->properties()) {
3422 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3428 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3429 unsigned FieldNo = 0;
3430 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3431 Field =
Field->getNextIvar(), ++FieldNo) {
3432 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3436 StringRef FieldName =
Field->getName();
3439 if (FieldName.empty())
3443 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3444 unsigned FieldLine = getLineNumber(
Field->getLocation());
3445 QualType FType =
Field->getType();
3452 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3453 : CGM.getContext().getTypeSize(FType);
3458 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3462 if (
Field->isBitField()) {
3464 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3465 FieldOffset %= CGM.getContext().getCharWidth();
3473 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3475 Flags = llvm::DINode::FlagProtected;
3477 Flags = llvm::DINode::FlagPrivate;
3479 Flags = llvm::DINode::FlagPublic;
3481 if (
Field->isBitField())
3482 Flags |= llvm::DINode::FlagBitField;
3484 llvm::MDNode *PropertyNode =
nullptr;
3485 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3486 if (ObjCPropertyImplDecl *PImpD =
3487 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3488 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3489 SourceLocation Loc = PD->getLocation();
3490 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3491 unsigned PLine = getLineNumber(Loc);
3492 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3493 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3494 PropertyNode = DBuilder.createObjCProperty(
3495 PD->getName(), PUnit, PLine,
3498 : getSelectorName(PD->getGetterName()),
3501 : getSelectorName(PD->getSetterName()),
3502 PD->getPropertyAttributes(),
3503 getOrCreateType(PD->getType(), PUnit));
3507 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3508 FieldSize, FieldAlign, FieldOffset, Flags,
3509 FieldTy, PropertyNode);
3510 EltTys.push_back(FieldTy);
3513 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3514 DBuilder.replaceArrays(RealDecl, Elements);
3516 LexicalBlockStack.pop_back();
3520llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3521 llvm::DIFile *Unit) {
3529 auto &Ctx = CGM.getContext();
3534 QualType CharVecTy =
3536 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3539 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3542 llvm::Metadata *Subscript;
3543 QualType QTy(Ty, 0);
3544 auto SizeExpr = SizeExprCache.find(QTy);
3545 if (SizeExpr != SizeExprCache.end())
3546 Subscript = DBuilder.getOrCreateSubrange(
3547 SizeExpr->getSecond() ,
nullptr ,
3548 nullptr ,
nullptr );
3551 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3552 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3553 Subscript = DBuilder.getOrCreateSubrange(
3554 CountNode ,
nullptr ,
nullptr ,
3557 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3562 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3565llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3566 llvm::DIFile *Unit) {
3570 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3575 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3576 auto *ColumnCountNode =
3577 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3578 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3579 auto *RowCountNode =
3580 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3581 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3582 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3583 ColumnCountNode ,
nullptr ,
nullptr ,
3585 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3586 RowCountNode ,
nullptr ,
nullptr ,
3588 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3589 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3592llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3597 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3612 Size = CGM.getContext().getTypeSize(Ty);
3619 SmallVector<llvm::Metadata *, 8> Subscripts;
3620 QualType EltTy(Ty, 0);
3621 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3630 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3631 Count = CAT->getZExtSize();
3632 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3633 if (Expr *Size = VAT->getSizeExpr()) {
3635 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3636 Count =
Result.Val.getInt().getExtValue();
3640 auto SizeNode = SizeExprCache.find(EltTy);
3641 if (SizeNode != SizeExprCache.end())
3642 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3643 SizeNode->getSecond() ,
nullptr ,
3644 nullptr ,
nullptr ));
3647 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3648 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3649 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3650 CountNode ,
nullptr ,
nullptr ,
3656 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3658 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3662llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3663 llvm::DIFile *Unit) {
3664 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3668llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3669 llvm::DIFile *Unit) {
3670 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3672 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3673 CGM.getCodeGenOpts().DwarfVersion < 4)
3674 Tag = llvm::dwarf::DW_TAG_reference_type;
3676 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3679llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3681 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3685 Size = CGM.getContext().getTypeSize(Ty);
3688 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3691 Flags |= llvm::DINode::FlagSingleInheritance;
3694 Flags |= llvm::DINode::FlagMultipleInheritance;
3697 Flags |= llvm::DINode::FlagVirtualInheritance;
3707 llvm::DIType *ClassType = getOrCreateType(
T, U);
3709 return DBuilder.createMemberPointerType(
3713 const FunctionProtoType *FPT =
3715 return DBuilder.createMemberPointerType(
3716 getOrCreateInstanceMethodType(
3719 ClassType, Size, 0, Flags);
3722llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3724 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3727llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3731llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3733 return getOrCreateType(Ty->getWrappedType(), U);
3736llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3743 const EnumType *Ty) {
3755llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3758 bool isImportedFromModule =
3759 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3763 if (isImportedFromModule || !ED->getDefinition()) {
3770 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3771 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3772 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3773 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3775 unsigned Line = getLineNumber(ED->getLocation());
3776 StringRef EDName = ED->getName();
3777 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3778 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3779 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3781 ReplaceMap.emplace_back(
3782 std::piecewise_construct, std::make_tuple(Ty),
3783 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3787 return CreateTypeDefinition(Ty);
3790llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3793 SmallVector<llvm::Metadata *, 16> Enumerators;
3794 ED = ED->getDefinition();
3795 assert(ED &&
"An enumeration definition is required");
3796 for (
const auto *
Enum : ED->enumerators()) {
3797 Enumerators.push_back(
3798 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3801 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3802 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3803 EnumKind = Attr->getExtensibility();
3806 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3808 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3809 unsigned Line = getLineNumber(ED->getLocation());
3810 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3811 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3812 return DBuilder.createEnumerationType(
3813 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3814 0, Identifier, ED->isScoped(), EnumKind);
3819 StringRef Name, StringRef
Value) {
3820 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3821 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3827 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3828 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3829 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3833 StringRef FuncName) {
3834 llvm::DISubprogram *SP =
3835 createInlinedSubprogram(FuncName, Location->getFile());
3836 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3841 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3847 FuncName += Category;
3849 FuncName += FailureMsg;
3861 Quals += InnerQuals;
3863 switch (
T->getTypeClass()) {
3865 return C.getQualifiedType(
T.getTypePtr(), Quals);
3868 case Type::InjectedClassName:
3869 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3871 case Type::TemplateSpecialization: {
3873 if (Spec->isTypeAlias())
3874 return C.getQualifiedType(
T.getTypePtr(), Quals);
3875 T = Spec->desugar();
3878 case Type::TypeOfExpr:
3884 case Type::Decltype:
3887 case Type::UnaryTransform:
3890 case Type::Attributed:
3893 case Type::BTFTagAttributed:
3896 case Type::CountAttributed:
3905 case Type::MacroQualified:
3908 case Type::SubstTemplateTypeParm:
3912 case Type::DeducedTemplateSpecialization: {
3914 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3918 case Type::PackIndexing: {
3922 case Type::Adjusted:
3929 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3934llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
3937 if (It != TypeCache.end()) {
3939 if (llvm::Metadata *
V = It->second)
3952 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3959 RetainedTypes.push_back(
3960 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
3963llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3967 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3969 llvm::raw_string_ostream OS(Name);
3970 Ty.
print(OS, getPrintingPolicy());
3977 if (
auto *
T = getTypeOrNull(Ty))
3980 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3981 void *TyPtr = Ty.getAsOpaquePtr();
3984 TypeCache[TyPtr].reset(Res);
3989llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3997 auto Info = Reader->getSourceDescriptor(Idx);
3999 return getOrCreateModuleRef(*Info,
true);
4000 }
else if (ClangModuleMap) {
4013 auto Info = ASTSourceDescriptor(*M);
4014 return getOrCreateModuleRef(Info,
false);
4017 return getOrCreateModuleRef(PCHDescriptor,
false);
4024llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4027 return CreateQualifiedType(Ty, Unit);
4031#define TYPE(Class, Base)
4032#define ABSTRACT_TYPE(Class, Base)
4033#define NON_CANONICAL_TYPE(Class, Base)
4034#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4035#include "clang/AST/TypeNodes.inc"
4036 llvm_unreachable(
"Dependent types cannot show up in debug information");
4038 case Type::ExtVector:
4041 case Type::ConstantMatrix:
4043 case Type::ObjCObjectPointer:
4045 case Type::ObjCObject:
4047 case Type::ObjCTypeParam:
4049 case Type::ObjCInterface:
4057 case Type::BlockPointer:
4065 case Type::FunctionProto:
4066 case Type::FunctionNoProto:
4068 case Type::ConstantArray:
4069 case Type::VariableArray:
4070 case Type::IncompleteArray:
4071 case Type::ArrayParameter:
4074 case Type::LValueReference:
4076 case Type::RValueReference:
4079 case Type::MemberPointer:
4090 case Type::TemplateSpecialization:
4092 case Type::HLSLAttributedResource:
4094 case Type::HLSLInlineSpirv:
4096 case Type::PredefinedSugar:
4098 case Type::CountAttributed:
4100 case Type::Attributed:
4101 case Type::BTFTagAttributed:
4102 case Type::Adjusted:
4104 case Type::DeducedTemplateSpecialization:
4107 case Type::MacroQualified:
4108 case Type::SubstTemplateTypeParm:
4109 case Type::TypeOfExpr:
4111 case Type::Decltype:
4112 case Type::PackIndexing:
4113 case Type::UnaryTransform:
4117 llvm_unreachable(
"type should have been unwrapped!");
4120llvm::DICompositeType *
4121CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4122 QualType QTy(Ty, 0);
4124 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4129 if (
T && !
T->isForwardDecl())
4133 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4138 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4141 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4146llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4147 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
4150 StringRef RDName = getClassName(RD);
4152 llvm::DIFile *DefUnit =
nullptr;
4155 DefUnit = getOrCreateFile(Loc);
4156 Line = getLineNumber(Loc);
4159 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4163 auto *
T = cast_or_null<llvm::DICompositeType>(
4164 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4172 return getOrCreateRecordFwdDecl(Ty, RDContext);
4185 auto Flags = llvm::DINode::FlagZero;
4186 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4188 Flags |= llvm::DINode::FlagTypePassByReference;
4190 Flags |= llvm::DINode::FlagTypePassByValue;
4193 if (!CXXRD->isTrivial())
4194 Flags |= llvm::DINode::FlagNonTrivial;
4197 if (CXXRD->isAnonymousStructOrUnion())
4198 Flags |= llvm::DINode::FlagExportSymbols;
4201 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4204 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4205 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4207 Flags, Identifier, Annotations);
4211 switch (RealDecl->getTag()) {
4213 llvm_unreachable(
"invalid composite type tag");
4215 case llvm::dwarf::DW_TAG_array_type:
4216 case llvm::dwarf::DW_TAG_enumeration_type:
4221 if (Identifier.empty())
4225 case llvm::dwarf::DW_TAG_structure_type:
4226 case llvm::dwarf::DW_TAG_union_type:
4227 case llvm::dwarf::DW_TAG_class_type:
4230 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4235 dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
4236 CXXRecordDecl *TemplateDecl =
4237 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4238 RegionMap[TemplateDecl].reset(RealDecl);
4240 RegionMap[RD].reset(RealDecl);
4242 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4244 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4245 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4246 CollectCXXTemplateParams(TSpecial, DefUnit));
4250void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4251 llvm::DICompositeType *RealDecl) {
4253 llvm::DIType *ContainingType =
nullptr;
4254 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4258 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4265 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4266 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4268 ContainingType = RealDecl;
4270 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4273llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4274 StringRef Name, uint64_t *Offset) {
4275 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4276 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4279 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4280 *Offset, llvm::DINode::FlagZero, FieldTy);
4281 *Offset += FieldSize;
4285void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4287 StringRef &LinkageName,
4288 llvm::DIScope *&FDContext,
4289 llvm::DINodeArray &TParamsArray,
4290 llvm::DINode::DIFlags &Flags) {
4292 Name = getFunctionName(FD);
4295 LinkageName = CGM.getMangledName(GD);
4297 Flags |= llvm::DINode::FlagPrototyped;
4301 if (LinkageName == Name ||
4302 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4303 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4304 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4305 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4306 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4307 LinkageName = StringRef();
4311 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4312 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4313 CGM.getCodeGenOpts().EmitCodeView)) {
4314 if (
const NamespaceDecl *NSDecl =
4316 FDContext = getOrCreateNamespace(NSDecl);
4317 else if (
const RecordDecl *RDecl =
4319 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4320 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4323 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4326 Flags |= llvm::DINode::FlagNoReturn;
4328 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4332void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4333 unsigned &LineNo, QualType &
T,
4334 StringRef &Name, StringRef &LinkageName,
4335 llvm::MDTuple *&TemplateParameters,
4336 llvm::DIScope *&VDContext) {
4345 llvm::APInt ConstVal(32, 1);
4346 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4348 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4355 LinkageName = CGM.getMangledName(VD);
4356 if (LinkageName == Name)
4357 LinkageName = StringRef();
4360 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4361 TemplateParameters = parameterNodes.get();
4363 TemplateParameters =
nullptr;
4381 DC = CGM.getContext().getTranslationUnitDecl();
4383 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4384 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4387llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4389 llvm::DINodeArray TParamsArray;
4390 StringRef Name, LinkageName;
4391 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4392 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4394 llvm::DIFile *Unit = getOrCreateFile(Loc);
4395 llvm::DIScope *DContext = Unit;
4396 unsigned Line = getLineNumber(Loc);
4397 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4402 SmallVector<QualType, 16> ArgTypes;
4403 for (
const ParmVarDecl *Parm : FD->
parameters())
4404 ArgTypes.push_back(Parm->getType());
4407 QualType FnType = CGM.getContext().getFunctionType(
4408 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4410 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4411 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4412 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4415 Flags |= getCallSiteRelatedAttrs();
4416 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4417 return DBuilder.createFunction(
4418 DContext, Name, LinkageName, Unit,
Line,
4419 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4420 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4422 CGM.getCodeGenOpts().DebugKeyInstructions);
4425 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4426 DContext, Name, LinkageName, Unit,
Line,
4427 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4428 TParamsArray.get(), getFunctionDeclaration(FD));
4430 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4431 std::make_tuple(CanonDecl),
4432 std::make_tuple(SP));
4436llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4437 return getFunctionFwdDeclOrStub(GD,
false);
4440llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4441 return getFunctionFwdDeclOrStub(GD,
true);
4444llvm::DIGlobalVariable *
4445CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4447 StringRef Name, LinkageName;
4449 llvm::DIFile *Unit = getOrCreateFile(Loc);
4450 llvm::DIScope *DContext = Unit;
4451 unsigned Line = getLineNumber(Loc);
4452 llvm::MDTuple *TemplateParameters =
nullptr;
4454 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4457 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4458 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4460 FwdDeclReplaceMap.emplace_back(
4461 std::piecewise_construct,
4463 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4467llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4472 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4473 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4474 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4478 if (I != DeclCache.end()) {
4480 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4481 return GVE->getVariable();
4489 if (IE != ImportedDeclCache.end()) {
4490 auto N = IE->second;
4491 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4493 return dyn_cast_or_null<llvm::DINode>(N);
4498 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4499 return getFunctionForwardDeclaration(FD);
4500 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4501 return getGlobalVariableForwardDeclaration(VD);
4506llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4507 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4510 const auto *FD = dyn_cast<FunctionDecl>(D);
4515 auto *S = getDeclContextDescriptor(D);
4518 if (MI == SPCache.end()) {
4520 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4524 if (MI != SPCache.end()) {
4525 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4526 if (SP && !SP->isDefinition())
4530 for (
auto *NextFD : FD->
redecls()) {
4531 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4532 if (MI != SPCache.end()) {
4533 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4534 if (SP && !SP->isDefinition())
4541llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4542 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4543 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4544 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4547 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4551 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4555 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4564 QualType QTy(
ID->getTypeForDecl(), 0);
4565 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4566 if (It == TypeCache.end())
4569 llvm::DISubprogram *FD = DBuilder.createFunction(
4570 InterfaceType, getObjCMethodName(OMD), StringRef(),
4571 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4572 DBuilder.finalizeSubprogram(FD);
4579llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4584 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4585 !CGM.getCodeGenOpts().EmitCodeView))
4588 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4590 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4593 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4596 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4597 return getOrCreateMethodType(
Method, F);
4599 const auto *FTy = FnType->
getAs<FunctionType>();
4602 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4604 SmallVector<llvm::Metadata *, 16> Elts;
4607 QualType ResultTy = OMethod->getReturnType();
4610 if (ResultTy == CGM.getContext().getObjCInstanceType())
4611 ResultTy = CGM.getContext().getPointerType(
4612 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4614 Elts.push_back(getOrCreateType(ResultTy, F));
4616 QualType SelfDeclTy;
4617 if (
auto *SelfDecl = OMethod->getSelfDecl())
4618 SelfDeclTy = SelfDecl->getType();
4619 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4622 if (!SelfDeclTy.
isNull())
4624 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4626 Elts.push_back(DBuilder.createArtificialType(
4627 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4629 for (
const auto *PI : OMethod->parameters())
4630 Elts.push_back(getOrCreateType(PI->getType(), F));
4632 if (OMethod->isVariadic())
4633 Elts.push_back(DBuilder.createUnspecifiedParameter());
4635 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4636 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4642 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4643 if (FD->isVariadic()) {
4644 SmallVector<llvm::Metadata *, 16> EltTys;
4645 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4646 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4648 EltTys.push_back(getOrCreateType(ParamType, F));
4649 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4650 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4651 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4664 CC = SrcFnTy->getCallConv();
4666 for (
const VarDecl *VD : Args)
4667 ArgTypes.push_back(VD->
getType());
4668 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4674 llvm::Function *Fn,
bool CurFuncIsThunk) {
4676 StringRef LinkageName;
4678 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4681 bool HasDecl = (D !=
nullptr);
4683 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4684 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4685 llvm::DIFile *Unit = getOrCreateFile(Loc);
4686 llvm::DIScope *FDContext = Unit;
4687 llvm::DINodeArray TParamsArray;
4688 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4691 LinkageName = Fn->getName();
4692 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4694 auto FI = SPCache.find(FD->getCanonicalDecl());
4695 if (FI != SPCache.end()) {
4696 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4697 if (SP && SP->isDefinition()) {
4698 LexicalBlockStack.emplace_back(SP);
4699 RegionMap[D].reset(SP);
4703 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4704 TParamsArray, Flags);
4707 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4708 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4709 Name = getObjCMethodName(OMD);
4710 Flags |= llvm::DINode::FlagPrototyped;
4717 Name = Fn->getName();
4722 Flags |= llvm::DINode::FlagPrototyped;
4724 Name.consume_front(
"\01");
4728 "Unexpected DynamicInitKind !");
4732 Flags |= llvm::DINode::FlagArtificial;
4738 Flags |= llvm::DINode::FlagThunk;
4740 if (Fn->hasLocalLinkage())
4741 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4742 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4743 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4745 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4746 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4747 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4749 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4750 unsigned ScopeLine = getLineNumber(ScopeLoc);
4751 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4752 llvm::DISubprogram *
Decl =
nullptr;
4753 llvm::DINodeArray Annotations =
nullptr;
4756 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4757 : getFunctionDeclaration(D);
4758 Annotations = CollectBTFDeclTagAnnotations(D);
4766 llvm::DISubprogram *SP = DBuilder.createFunction(
4767 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4768 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4769 Annotations,
"", KeyInstructions);
4770 Fn->setSubprogram(SP);
4779 LexicalBlockStack.emplace_back(SP);
4782 RegionMap[D].reset(SP);
4786 QualType FnType, llvm::Function *Fn) {
4788 StringRef LinkageName;
4794 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4795 return GetName(D,
true);
4798 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4799 llvm::DIFile *Unit = getOrCreateFile(Loc);
4800 bool IsDeclForCallSite = Fn ?
true :
false;
4801 llvm::DIScope *FDContext =
4802 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4803 llvm::DINodeArray TParamsArray;
4806 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4807 TParamsArray, Flags);
4808 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4809 Name = getObjCMethodName(OMD);
4810 Flags |= llvm::DINode::FlagPrototyped;
4812 llvm_unreachable(
"not a function or ObjC method");
4814 Name.consume_front(
"\01");
4817 Flags |= llvm::DINode::FlagArtificial;
4822 unsigned LineNo = getLineNumber(Loc);
4823 unsigned ScopeLine = 0;
4824 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4825 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4826 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4828 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4829 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4831 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4832 llvm::DISubprogram *SP = DBuilder.createFunction(
4833 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4834 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4840 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4841 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4842 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4845 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4846 DBuilder.createParameterVariable(
4847 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4848 llvm::DINode::FlagZero, ParamAnnotations);
4854 if (IsDeclForCallSite)
4855 Fn->setSubprogram(SP);
4863 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4866 if (
Func->getSubprogram())
4871 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4872 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4885 auto FI = SPCache.find(FD->getCanonicalDecl());
4886 llvm::DISubprogram *SP =
nullptr;
4887 if (FI != SPCache.end())
4888 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4889 if (!SP || !SP->isDefinition())
4890 SP = getFunctionStub(GD);
4891 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4892 LexicalBlockStack.emplace_back(SP);
4898 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4907 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4910 llvm::MDNode *
Scope = LexicalBlockStack.back();
4911 Builder.SetCurrentDebugLocation(
4912 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
4913 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4917 llvm::MDNode *Back =
nullptr;
4918 if (!LexicalBlockStack.empty())
4919 Back = LexicalBlockStack.back().get();
4920 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4922 getColumnNumber(CurLoc)));
4925void CGDebugInfo::AppendAddressSpaceXDeref(
4927 std::optional<unsigned> DWARFAddressSpace =
4929 if (!DWARFAddressSpace)
4932 Expr.push_back(llvm::dwarf::DW_OP_constu);
4933 Expr.push_back(*DWARFAddressSpace);
4934 Expr.push_back(llvm::dwarf::DW_OP_swap);
4935 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4944 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4945 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
4946 LexicalBlockStack.back(), CurInlinedAt));
4948 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4952 CreateLexicalBlock(Loc);
4957 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4962 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4965 LexicalBlockStack.pop_back();
4969 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4970 unsigned RCount = FnBeginRegionCount.back();
4971 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4974 while (LexicalBlockStack.size() != RCount) {
4977 LexicalBlockStack.pop_back();
4979 FnBeginRegionCount.pop_back();
4981 if (Fn && Fn->getSubprogram())
4982 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4985CGDebugInfo::BlockByRefType
4986CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4987 uint64_t *XOffset) {
4990 uint64_t FieldSize, FieldOffset;
4991 uint32_t FieldAlign;
4993 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4998 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4999 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5001 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5002 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5005 if (HasCopyAndDispose) {
5008 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5010 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5012 bool HasByrefExtendedLayout;
5015 HasByrefExtendedLayout) &&
5016 HasByrefExtendedLayout) {
5019 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5028 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5031 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5034 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5039 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5040 FieldSize = CGM.getContext().getTypeSize(FType);
5041 FieldAlign = CGM.getContext().toBits(Align);
5043 *XOffset = FieldOffset;
5044 llvm::DIType *FieldTy = DBuilder.createMemberType(
5045 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5046 llvm::DINode::FlagZero, WrappedTy);
5047 EltTys.push_back(FieldTy);
5048 FieldOffset += FieldSize;
5050 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5051 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5052 llvm::DINode::FlagZero,
nullptr, Elements),
5056llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5057 llvm::Value *Storage,
5058 std::optional<unsigned> ArgNo,
5060 const bool UsePointerValue) {
5061 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5062 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5063 if (VD->
hasAttr<NoDebugAttr>())
5068 llvm::DIFile *Unit =
nullptr;
5069 if (!VarIsArtificial)
5073 if (VD->
hasAttr<BlocksAttr>())
5074 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5076 Ty = getOrCreateType(VD->
getType(), Unit);
5086 if (!VarIsArtificial) {
5090 SmallVector<uint64_t, 13> Expr;
5091 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5092 if (VarIsArtificial)
5093 Flags |= llvm::DINode::FlagArtificial;
5097 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5098 AppendAddressSpaceXDeref(AddressSpace, Expr);
5102 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5105 Flags |= llvm::DINode::FlagObjectPointer;
5106 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5107 if (PVD->isExplicitObjectParameter())
5108 Flags |= llvm::DINode::FlagObjectPointer;
5116 StringRef Name = VD->
getName();
5117 if (!Name.empty()) {
5123 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5125 offset = CGM.getContext().toCharUnitsFromBits(
5128 Expr.push_back(llvm::dwarf::DW_OP_deref);
5129 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5131 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5134 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5146 for (
const auto *Field : RD->
fields()) {
5147 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5148 StringRef FieldName =
Field->getName();
5156 auto *D = DBuilder.createAutoVariable(
5157 Scope, FieldName, Unit,
Line, FieldTy,
5158 CGM.getCodeGenOpts().OptimizationLevel != 0,
5159 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5162 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5163 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5166 Builder.GetInsertBlock());
5174 if (UsePointerValue) {
5175 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5176 "Debug info already contains DW_OP_deref.");
5177 Expr.push_back(llvm::dwarf::DW_OP_deref);
5181 llvm::DILocalVariable *D =
nullptr;
5183 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5184 D = DBuilder.createParameterVariable(
5185 Scope, Name, *ArgNo, Unit,
Line, Ty,
5186 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5195 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5201 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5202 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5203 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5204 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5206 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5212 if (Iter != CoroutineParameterMappings.end()) {
5213 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5214 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5215 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5217 if (Iter2 != ParamDbgMappings.end())
5218 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5224 D = RemapCoroArgToLocalVar();
5227 D = DBuilder.createAutoVariable(
5228 Scope, Name, Unit,
Line, Ty,
5229 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5232 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5233 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5234 Column, Scope, CurInlinedAt),
5235 Builder.GetInsertBlock());
5240llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5241 llvm::Value *Storage,
5242 std::optional<unsigned> ArgNo,
5244 const bool UsePointerValue) {
5245 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5246 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5247 if (BD->
hasAttr<NoDebugAttr>())
5254 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5255 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5263 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5265 SmallVector<uint64_t, 3> Expr;
5266 AppendAddressSpaceXDeref(AddressSpace, Expr);
5271 if (UsePointerValue) {
5272 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5273 "Debug info already contains DW_OP_deref.");
5274 Expr.push_back(llvm::dwarf::DW_OP_deref);
5279 StringRef Name = BD->
getName();
5282 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5283 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5284 llvm::DINode::FlagZero, Align);
5286 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5287 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5288 const unsigned fieldIndex = FD->getFieldIndex();
5289 const clang::CXXRecordDecl *parent =
5290 (
const CXXRecordDecl *)FD->getParent();
5291 const ASTRecordLayout &layout =
5292 CGM.getContext().getASTRecordLayout(parent);
5294 if (FD->isBitField()) {
5295 const CGRecordLayout &RL =
5296 CGM.getTypes().getCGRecordLayout(FD->getParent());
5301 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5307 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5308 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5309 Expr.push_back(Info.
Offset);
5312 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5313 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5314 }
else if (fieldOffset != 0) {
5315 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5316 "Unexpected non-bitfield with non-byte-aligned offset");
5317 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5319 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5322 }
else if (
const ArraySubscriptExpr *ASE =
5323 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5324 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5325 const uint64_t value = IL->getValue().getZExtValue();
5326 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5329 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5330 Expr.push_back(CGM.getContext()
5331 .toCharUnitsFromBits(value * typeSize)
5338 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5339 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5340 Column, Scope, CurInlinedAt),
5341 Builder.GetInsertBlock());
5346llvm::DILocalVariable *
5349 const bool UsePointerValue) {
5350 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5352 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5354 EmitDeclare(B, Storage, std::nullopt, Builder,
5361 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5365 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5366 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5368 if (D->
hasAttr<NoDebugAttr>())
5372 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5378 StringRef Name = D->
getName();
5384 CGM.getCodeGenOpts().OptimizationLevel != 0);
5387 DBuilder.insertLabel(L,
5388 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5389 Scope, CurInlinedAt),
5390 Builder.GetInsertBlock()->end());
5393llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5395 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5398 return DBuilder.createObjectPointerType(Ty,
true);
5403 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5404 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5405 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5407 if (Builder.GetInsertBlock() ==
nullptr)
5409 if (VD->
hasAttr<NoDebugAttr>())
5412 bool isByRef = VD->
hasAttr<BlocksAttr>();
5414 uint64_t XOffset = 0;
5415 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5418 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5420 Ty = getOrCreateType(VD->
getType(), Unit);
5424 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5426 Ty = CreateSelfType(VD->
getType(), Ty);
5429 const unsigned Line =
5433 const llvm::DataLayout &target = CGM.getDataLayout();
5440 addr.push_back(llvm::dwarf::DW_OP_deref);
5441 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5444 addr.push_back(llvm::dwarf::DW_OP_deref);
5445 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5448 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5450 addr.push_back(llvm::dwarf::DW_OP_deref);
5451 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5453 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5459 auto *D = DBuilder.createAutoVariable(
5461 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5464 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5465 LexicalBlockStack.back(), CurInlinedAt);
5466 auto *
Expr = DBuilder.createExpression(addr);
5468 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5470 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5473llvm::DILocalVariable *
5476 bool UsePointerValue) {
5477 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5478 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5482struct BlockLayoutChunk {
5483 uint64_t OffsetInBits;
5486bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5487 return l.OffsetInBits < r.OffsetInBits;
5491void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5493 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5494 SmallVectorImpl<llvm::Metadata *> &Fields) {
5498 if (CGM.getLangOpts().OpenCL) {
5499 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5500 BlockLayout.getElementOffsetInBits(0),
5502 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5503 BlockLayout.getElementOffsetInBits(1),
5507 BlockLayout.getElementOffsetInBits(0),
5509 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5510 BlockLayout.getElementOffsetInBits(1),
5514 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5515 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5516 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5517 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5518 BlockLayout.getElementOffsetInBits(3),
5520 Fields.push_back(createFieldType(
5525 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5532 llvm::AllocaInst *Alloca,
5534 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5540 llvm::DIFile *tunit = getOrCreateFile(loc);
5541 unsigned line = getLineNumber(loc);
5542 unsigned column = getColumnNumber(loc);
5547 const llvm::StructLayout *blockLayout =
5551 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5560 BlockLayoutChunk chunk;
5561 chunk.OffsetInBits =
5562 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5563 chunk.Capture =
nullptr;
5564 chunks.push_back(chunk);
5568 for (
const auto &capture :
blockDecl->captures()) {
5569 const VarDecl *variable = capture.getVariable();
5576 BlockLayoutChunk chunk;
5577 chunk.OffsetInBits =
5578 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5579 chunk.Capture = &capture;
5580 chunks.push_back(chunk);
5584 llvm::array_pod_sort(chunks.begin(), chunks.end());
5586 for (
const BlockLayoutChunk &Chunk : chunks) {
5587 uint64_t offsetInBits = Chunk.OffsetInBits;
5594 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5596 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5597 type = CGM.getContext().getCanonicalTagType(RDecl);
5599 llvm_unreachable(
"unexpected block declcontext");
5601 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5602 offsetInBits, tunit, tunit));
5607 StringRef name = variable->
getName();
5609 llvm::DIType *fieldType;
5611 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5616 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5617 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5618 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5619 PtrInfo.
Width, Align, offsetInBits,
5620 llvm::DINode::FlagZero, fieldType);
5624 offsetInBits, Align, tunit, tunit);
5626 fields.push_back(fieldType);
5630 llvm::raw_svector_ostream(typeName)
5631 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5633 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5635 llvm::DIType *
type =
5636 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5637 CGM.getContext().toBits(block.
BlockSize), 0,
5638 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5639 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5642 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5646 auto *debugVar = DBuilder.createParameterVariable(
5647 scope, Name, ArgNo, tunit, line,
type,
5648 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5651 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5652 llvm::DILocation::get(CGM.getLLVMContext(), line,
5653 column, scope, CurInlinedAt),
5654 Builder.GetInsertBlock());
5657llvm::DIDerivedType *
5658CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5663 if (MI != StaticDataMemberCache.end()) {
5664 assert(MI->second &&
"Static data member declaration should still exist");
5675llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5676 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5677 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5678 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5680 for (
const auto *Field : RD->
fields()) {
5681 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5682 StringRef FieldName = Field->getName();
5685 if (FieldName.empty()) {
5686 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5688 CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
5689 Unit, LineNo, LinkageName, Var, DContext);
5693 GVE = DBuilder.createGlobalVariableExpression(
5694 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5695 Var->hasLocalLinkage());
5696 Var->addDebugInfo(GVE);
5708 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
5713 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5724 struct ReferencesAnonymous
5726 bool RefAnon =
false;
5727 bool VisitRecordType(RecordType *RT) {
5735 ReferencesAnonymous RT;
5748struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5749 bool Reconstitutable =
true;
5750 bool VisitVectorType(VectorType *FT) {
5751 Reconstitutable =
false;
5754 bool VisitAtomicType(AtomicType *FT) {
5755 Reconstitutable =
false;
5758 bool VisitType(
Type *
T) {
5762 Reconstitutable =
false;
5767 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5770 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
5771 if (!ED->getIdentifier()) {
5772 Reconstitutable =
false;
5775 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5776 Reconstitutable =
false;
5782 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5786 return Reconstitutable;
5788 bool VisitRecordType(RecordType *RT,
bool =
false) {
5790 Reconstitutable =
false;
5800 ReconstitutableType
T;
5802 return T.Reconstitutable;
5805bool CGDebugInfo::HasReconstitutableArgs(
5806 ArrayRef<TemplateArgument> Args)
const {
5807 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5847 llvm_unreachable(
"Other, unresolved, template arguments should "
5848 "not be seen here");
5853std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5855 llvm::raw_string_ostream
OS(Name);
5856 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5859 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5860 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5862 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5863 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5865 std::optional<TemplateArgs> Args;
5867 bool IsOperatorOverload =
false;
5868 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5869 Args = GetTemplateArgs(RD);
5870 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5871 Args = GetTemplateArgs(FD);
5873 IsOperatorOverload |=
5876 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5877 Args = GetTemplateArgs(VD);
5901 bool Reconstitutable =
5902 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5904 PrintingPolicy PP = getPrintingPolicy();
5906 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5910 bool Mangled = TemplateNamesKind ==
5911 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5917 std::string EncodedOriginalName;
5918 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5923 printTemplateArgumentList(OS, Args->Args, PP);
5924 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
5926 std::string CanonicalOriginalName;
5927 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5929 assert(EncodedOriginalName == CanonicalOriginalName);
5938 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5939 if (D->
hasAttr<NoDebugAttr>())
5942 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5943 return GetName(D,
true);
5949 if (Cached != DeclCache.end())
5950 return Var->addDebugInfo(
5954 llvm::DIFile *Unit =
nullptr;
5955 llvm::DIScope *DContext =
nullptr;
5957 StringRef DeclName, LinkageName;
5959 llvm::MDTuple *TemplateParameters =
nullptr;
5960 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5961 TemplateParameters, DContext);
5965 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5970 if (
T->isUnionType() && DeclName.empty()) {
5971 const auto *RD =
T->castAsRecordDecl();
5973 "unnamed non-anonymous struct or union?");
5974 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5979 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
5980 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
5981 if (D->
hasAttr<CUDASharedAttr>())
5984 else if (D->
hasAttr<CUDAConstantAttr>())
5988 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5990 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5991 GVE = DBuilder.createGlobalVariableExpression(
5992 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5993 Var->hasLocalLinkage(),
true,
5994 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5995 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5996 Align, Annotations);
5997 Var->addDebugInfo(GVE);
6003 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6004 if (VD->
hasAttr<NoDebugAttr>())
6006 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6007 return GetName(VD,
true);
6012 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6013 StringRef Name = VD->
getName();
6014 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6016 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6018 if (CGM.getCodeGenOpts().EmitCodeView) {
6029 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6030 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6031 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6041 auto *VarD = dyn_cast<VarDecl>(VD);
6042 if (VarD && VarD->isStaticDataMember()) {
6044 getDeclContextDescriptor(VarD);
6049 RetainedTypes.push_back(
6050 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6054 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6056 auto &GV = DeclCache[VD];
6060 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6061 llvm::MDTuple *TemplateParameters =
nullptr;
6065 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6066 TemplateParameters = parameterNodes.get();
6069 GV.reset(DBuilder.createGlobalVariableExpression(
6070 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6071 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6072 TemplateParameters, Align));
6077 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6078 if (D->
hasAttr<NoDebugAttr>())
6082 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6083 StringRef Name = D->
getName();
6084 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6086 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6087 llvm::DIGlobalVariableExpression *GVE =
6088 DBuilder.createGlobalVariableExpression(
6089 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6090 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6091 Var->addDebugInfo(GVE);
6098 if (CGM.getCodeGenOpts().getDebugInfo() <=
6099 llvm::codegenoptions::DebugLineTablesOnly)
6102 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6106 llvm::DIFile *Unit = DIL->getFile();
6107 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6112 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6113 llvm::Value *Var = Load->getPointerOperand();
6118 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6119 return DbgDeclare->getVariable()->getType() ==
Type;
6121 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6125 llvm::DILocalVariable *D =
6126 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6127 Type,
false, llvm::DINode::FlagArtificial);
6129 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6130 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6140 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6144 if (D->
hasAttr<NoDebugAttr>())
6147 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6162 if (!(DI = getDeclarationOrDefinition(
6163 AliaseeDecl.getCanonicalDecl().getDecl())))
6166 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6169 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6170 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6179 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
6183 llvm::DIFile *
File = getOrCreateFile(Loc);
6184 llvm::DIGlobalVariableExpression *Debug =
6185 DBuilder.createGlobalVariableExpression(
6186 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6187 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6188 GV->addDebugInfo(Debug);
6191llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6192 if (!LexicalBlockStack.empty())
6193 return LexicalBlockStack.back();
6194 llvm::DIScope *Mod = getParentModuleOrNull(D);
6195 return getContextDescriptor(D, Mod ? Mod : TheCU);
6199 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6203 CGM.getCodeGenOpts().DebugExplicitImport) {
6207 DBuilder.createImportedModule(
6209 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6214 if (llvm::DINode *
Target =
6217 DBuilder.createImportedDeclaration(
6219 getOrCreateFile(Loc), getLineNumber(Loc));
6224 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6227 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6229 for (
const auto *USD : UD.
shadows()) {
6234 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6235 if (
const auto *AT = FD->getType()
6238 if (AT->getDeducedType().isNull())
6249 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6252 "We shouldn't be codegening an invalid UsingEnumDecl"
6253 " containing no decls");
6255 for (
const auto *USD : UD.
shadows())
6260 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6262 if (
Module *M = ID.getImportedModule()) {
6264 auto Loc = ID.getLocation();
6265 DBuilder.createImportedDeclaration(
6266 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6267 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6268 getLineNumber(Loc));
6272llvm::DIImportedEntity *
6274 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6276 auto &VH = NamespaceAliasCache[&NA];
6279 llvm::DIImportedEntity *R;
6281 if (
const auto *Underlying =
6284 R = DBuilder.createImportedDeclaration(
6287 getLineNumber(Loc), NA.
getName());
6289 R = DBuilder.createImportedDeclaration(
6292 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6298CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6302 auto I = NamespaceCache.find(NSDecl);
6303 if (I != NamespaceCache.end())
6306 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6308 llvm::DINamespace *NS =
6309 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6310 NamespaceCache[NSDecl].reset(NS);
6315 assert(TheCU &&
"no main compile unit");
6316 TheCU->setDWOId(Signature);
6322 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6323 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6325 ? CreateTypeDefinition(E.Type, E.Unit)
6327 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6331 for (
const auto &P : ObjCMethodCache) {
6332 if (P.second.empty())
6335 QualType QTy(P.first->getTypeForDecl(), 0);
6337 assert(It != TypeCache.end());
6339 llvm::DICompositeType *InterfaceDecl =
6342 auto CurElts = InterfaceDecl->getElements();
6346 for (
auto &SubprogramDirect : P.second)
6347 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6348 EltTys.push_back(SubprogramDirect.getPointer());
6350 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6351 DBuilder.replaceArrays(InterfaceDecl, Elements);
6354 for (
const auto &P : ReplaceMap) {
6357 assert(Ty->isForwardDecl());
6359 auto It = TypeCache.find(P.first);
6360 assert(It != TypeCache.end());
6363 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6367 for (
const auto &P : FwdDeclReplaceMap) {
6370 llvm::Metadata *Repl;
6372 auto It = DeclCache.find(P.first);
6376 if (It == DeclCache.end())
6381 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6382 Repl = GVE->getVariable();
6388 for (
auto &RT : RetainedTypes)
6389 if (
auto MD = TypeCache[RT])
6392 DBuilder.finalize();
6397 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6398 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6399 DBuilder.retainType(DieTy);
6403 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6404 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6405 DBuilder.retainType(DieTy);
6409 if (LexicalBlockStack.empty())
6410 return llvm::DebugLoc();
6412 llvm::MDNode *
Scope = LexicalBlockStack.back();
6413 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6414 getColumnNumber(Loc),
Scope);
6417llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6421 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6422 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6423 return llvm::DINode::FlagZero;
6428 bool SupportsDWARFv4Ext =
6430 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6431 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6433 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6434 return llvm::DINode::FlagZero;
6436 return llvm::DINode::FlagAllCallsDescribed;
6447 return DBuilder.createConstantValueExpression(
6448 Val.
getFloat().bitcastToAPInt().getZExtValue());
6453 llvm::APSInt
const &ValInt = Val.
getInt();
6454 std::optional<uint64_t> ValIntOpt;
6455 if (ValInt.isUnsigned())
6456 ValIntOpt = ValInt.tryZExtValue();
6457 else if (
auto tmp = ValInt.trySExtValue())
6460 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6463 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6468CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6470 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6471 CGF.CurLexicalScope =
this;
6473 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6478 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6491#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6493 Label = "__ubsan_check_" #Name; \
6497#undef SANITIZER_CHECK
6508#define SANITIZER(NAME, ID) \
6509 case SanitizerKind::SO_##ID: \
6510 Label = "__ubsan_check_" NAME; \
6512#include "clang/Basic/Sanitizers.def"
6514 llvm_unreachable(
"unexpected sanitizer kind");
6519 for (
unsigned int i = 0; i < Label.length(); i++)
6520 if (!std::isalpha(Label[i]))
6529 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6531 if (!DI || !CheckDebugLoc)
6532 return CheckDebugLoc;
6533 const auto &AnnotateDebugInfo =
6534 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6535 if (AnnotateDebugInfo.empty())
6536 return CheckDebugLoc;
6539 if (Ordinals.size() == 1)
6544 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6545 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6547 return CheckDebugLoc;
6555 assert(!CGF->IsSanitizerScope);
6556 CGF->IsSanitizerScope =
true;
6560 assert(CGF->IsSanitizerScope);
6561 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
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 auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
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.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
#define LIST_SANITIZER_CHECKS
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.
SourceManager & getSourceManager()
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
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.
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.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
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.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
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
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
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 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
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
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).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
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
const LambdaCapture * capture_const_iterator
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
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
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...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
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
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to the current atom group, created using ApplyA...
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 completeFunction()
Reset internal state.
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)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
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 emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
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 addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
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 directive...
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.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
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.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
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.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() 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...
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...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
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.
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.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
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.
NamespaceBaseDecl * 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.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
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()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
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
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()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
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.
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.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
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 * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
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.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
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<specific type>'.
bool isRecordType() const
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 (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
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
U cast(CodeGen::Address addr)
@ 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,...
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.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
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.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.