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();
1946 }
else if (
Capture.capturesVariable()) {
1949 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
1950 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
1957 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1959 elements.push_back(createFieldType(
1961 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
1965llvm::DIDerivedType *
1966CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1967 const RecordDecl *RD) {
1971 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1972 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1974 unsigned LineNumber = getLineNumber(Var->
getLocation());
1975 StringRef VName = Var->
getName();
1979 llvm::Constant *
C =
nullptr;
1984 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
1985 if (
Value->isFloat())
1986 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
1991 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
1992 ? llvm::dwarf::DW_TAG_variable
1993 : llvm::dwarf::DW_TAG_member;
1995 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1996 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2001void CGDebugInfo::CollectRecordNormalField(
2002 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2003 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2004 const RecordDecl *RD) {
2009 if (
name.empty() && !
type->isRecordType())
2012 llvm::DIType *FieldType;
2014 llvm::DIDerivedType *BitFieldType;
2015 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2016 if (llvm::DIType *Separator =
2017 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2018 elements.push_back(Separator);
2021 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2024 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2027 elements.push_back(FieldType);
2030void CGDebugInfo::CollectRecordNestedType(
2031 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2032 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2039 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2040 elements.push_back(nestedType);
2043void CGDebugInfo::CollectRecordFields(
2044 const RecordDecl *record, llvm::DIFile *tunit,
2045 SmallVectorImpl<llvm::Metadata *> &elements,
2046 llvm::DICompositeType *RecordTy) {
2047 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2049 if (CXXDecl && CXXDecl->
isLambda())
2050 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2052 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2055 unsigned fieldNo = 0;
2059 for (
const auto *I : record->
decls())
2060 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2061 if (
V->hasAttr<NoDebugAttr>())
2066 if (CGM.getCodeGenOpts().EmitCodeView &&
2074 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2075 if (MI != StaticDataMemberCache.end()) {
2076 assert(MI->second &&
2077 "Static data member declaration should still exist");
2078 elements.push_back(MI->second);
2080 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2081 elements.push_back(Field);
2083 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2084 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2085 elements, RecordTy, record);
2089 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2092 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2097 if (!nestedType->isImplicit() &&
2098 nestedType->getDeclContext() == record)
2099 CollectRecordNestedType(nestedType, elements);
2105llvm::DISubroutineType *
2106CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2107 llvm::DIFile *Unit) {
2108 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2110 return cast_or_null<llvm::DISubroutineType>(
2111 getOrCreateType(QualType(
Func, 0), Unit));
2114 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2115 ThisType =
Method->getThisType();
2117 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2120llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2121 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2122 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2124 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2127llvm::DISubroutineType *
2128CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2129 const FunctionProtoType *
Func,
2130 llvm::DIFile *Unit,
bool SkipFirst) {
2131 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2146 getOrCreateType(CGM.getContext().getFunctionType(
2147 Func->getReturnType(),
Func->getParamTypes(), EPI),
2149 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2150 assert(Args.size() &&
"Invalid number of arguments!");
2152 SmallVector<llvm::Metadata *, 16> Elts;
2155 Elts.push_back(Args[0]);
2157 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2161 if (!HasExplicitObjectParameter) {
2162 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2165 DBuilder.createObjectPointerType(ThisPtrType,
true);
2166 Elts.push_back(ThisPtrType);
2170 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2171 Elts.push_back(Args[i]);
2174 if (HasExplicitObjectParameter) {
2175 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2176 "Expected at least return type and object parameter.");
2177 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2180 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2182 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2189 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2197CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2200 const bool IsCtorOrDtor =
2203 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2210 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2213 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2216 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2219 return CGM.getMangledName(
Method);
2222llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2223 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2226 StringRef MethodName = getFunctionName(
Method);
2227 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2229 StringRef MethodLinkageName;
2236 MethodLinkageName = GetMethodLinkageName(
Method);
2239 llvm::DIFile *MethodDefUnit =
nullptr;
2240 unsigned MethodLine = 0;
2241 if (!
Method->isImplicit()) {
2242 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2243 MethodLine = getLineNumber(
Method->getLocation());
2247 llvm::DIType *ContainingType =
nullptr;
2248 unsigned VIndex = 0;
2249 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2250 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2251 int ThisAdjustment = 0;
2254 if (
Method->isPureVirtual())
2255 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2257 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2259 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2263 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2267 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2269 MethodVFTableLocation ML =
2270 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2278 if (
Method->size_overridden_methods() == 0)
2279 Flags |= llvm::DINode::FlagIntroducedVirtual;
2284 ThisAdjustment = CGM.getCXXABI()
2285 .getVirtualFunctionPrologueThisAdjustment(GD)
2288 ContainingType = RecordTy;
2291 if (
Method->getCanonicalDecl()->isDeleted())
2292 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2294 if (
Method->isNoReturn())
2295 Flags |= llvm::DINode::FlagNoReturn;
2298 Flags |= llvm::DINode::FlagStaticMember;
2299 if (
Method->isImplicit())
2300 Flags |= llvm::DINode::FlagArtificial;
2302 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2303 if (CXXC->isExplicit())
2304 Flags |= llvm::DINode::FlagExplicit;
2305 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2306 if (CXXC->isExplicit())
2307 Flags |= llvm::DINode::FlagExplicit;
2309 if (
Method->hasPrototype())
2310 Flags |= llvm::DINode::FlagPrototyped;
2312 Flags |= llvm::DINode::FlagLValueReference;
2314 Flags |= llvm::DINode::FlagRValueReference;
2315 if (!
Method->isExternallyVisible())
2316 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2317 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2318 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2322 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2323 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2326 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2327 llvm::DISubprogram *SP = DBuilder.createMethod(
2328 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2329 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2330 TParamsArray.get(),
nullptr,
2331 CGM.getCodeGenOpts().DebugKeyInstructions);
2333 SPCache[
Method->getCanonicalDecl()].reset(SP);
2338void CGDebugInfo::CollectCXXMemberFunctions(
2339 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2340 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2345 for (
const auto *I : RD->
decls()) {
2346 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2360 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2369 auto MI = SPCache.find(
Method->getCanonicalDecl());
2370 EltTys.push_back(MI == SPCache.end()
2371 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2372 :
static_cast<llvm::Metadata *
>(MI->second));
2376void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2377 SmallVectorImpl<llvm::Metadata *> &EltTys,
2378 llvm::DIType *RecordTy) {
2379 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2380 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2381 llvm::DINode::FlagZero);
2385 if (CGM.getCodeGenOpts().EmitCodeView) {
2386 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2387 llvm::DINode::FlagIndirectVirtualBase);
2391void CGDebugInfo::CollectCXXBasesAux(
2392 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2393 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2395 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2396 llvm::DINode::DIFlags StartingFlags) {
2397 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2398 for (
const auto &BI : Bases) {
2401 BI.getType()->castAsCanonical<RecordType>()->getOriginalDecl())
2403 if (!SeenTypes.insert(Base).second)
2405 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2406 llvm::DINode::DIFlags BFlags = StartingFlags;
2410 if (BI.isVirtual()) {
2411 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2414 BaseOffset = 0 - CGM.getItaniumVTableContext()
2415 .getVirtualBaseOffsetOffset(RD, Base)
2421 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2422 VBPtrOffset = CGM.getContext()
2423 .getASTRecordLayout(RD)
2427 BFlags |= llvm::DINode::FlagVirtual;
2434 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2435 VBPtrOffset, BFlags);
2436 EltTys.push_back(DTy);
2441CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2442 llvm::DIFile *Unit) {
2444 return llvm::DINodeArray();
2445 TemplateArgs &Args = *OArgs;
2446 SmallVector<llvm::Metadata *, 16> TemplateParams;
2447 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2448 const TemplateArgument &TA = Args.Args[i];
2452 Name = Args.TList->getParam(i)->getName();
2456 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2457 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2458 TheCU, Name, TTy, defaultParameter));
2463 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2464 TheCU, Name, TTy, defaultParameter,
2465 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2470 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2471 llvm::Constant *
V =
nullptr;
2474 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2475 !D->
hasAttr<CUDADeviceAttr>()) {
2478 if (
const auto *VD = dyn_cast<VarDecl>(D))
2479 V = CGM.GetAddrOfGlobalVar(VD);
2482 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2483 MD && MD->isImplicitObjectMemberFunction())
2484 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2485 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2486 V = CGM.GetAddrOfFunction(FD);
2489 else if (
const auto *MPT =
2490 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2494 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2496 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2497 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2498 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2499 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2500 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2502 V = ConstantEmitter(CGM).emitAbstract(
2503 SourceLocation(), TPO->getValue(), TPO->getType());
2505 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2507 assert(
V &&
"Failed to find template parameter pointer");
2508 V =
V->stripPointerCasts();
2510 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2511 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2515 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2516 llvm::Constant *
V =
nullptr;
2519 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2525 if (MPT->isMemberDataPointer())
2526 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2528 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2529 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2530 TheCU, Name, TTy, defaultParameter,
V));
2534 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2535 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2537 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2538 TheCU, Name, TTy, defaultParameter,
V));
2541 std::string QualName;
2542 llvm::raw_string_ostream
OS(QualName);
2544 OS, getPrintingPolicy());
2545 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2546 TheCU, Name,
nullptr, QualName, defaultParameter));
2550 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2551 TheCU, Name,
nullptr,
2558 T = CGM.getContext().getLValueReferenceType(
T);
2559 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2560 assert(
V &&
"Expression in template argument isn't constant");
2561 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2562 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2563 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2569 "These argument types shouldn't exist in concrete types");
2572 return DBuilder.getOrCreateArray(TemplateParams);
2575std::optional<CGDebugInfo::TemplateArgs>
2576CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2584 return std::nullopt;
2586std::optional<CGDebugInfo::TemplateArgs>
2587CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2591 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2593 return std::nullopt;
2594 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2595 const TemplateParameterList *TList =
T->getTemplateParameters();
2596 auto TA = TS->getTemplateArgs().asArray();
2597 return {{TList, TA}};
2599std::optional<CGDebugInfo::TemplateArgs>
2600CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2601 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2605 TemplateParameterList *TPList =
2606 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2607 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2608 return {{TPList, TAList.
asArray()}};
2610 return std::nullopt;
2614CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2615 llvm::DIFile *Unit) {
2616 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2619llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2620 llvm::DIFile *Unit) {
2621 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2624llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2625 llvm::DIFile *Unit) {
2626 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2629llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2630 if (!D->
hasAttr<BTFDeclTagAttr>())
2633 SmallVector<llvm::Metadata *, 4> Annotations;
2635 llvm::Metadata *Ops[2] = {
2636 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2637 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2638 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2640 return DBuilder.getOrCreateArray(Annotations);
2643llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2645 return VTablePtrType;
2647 ASTContext &Context = CGM.getContext();
2650 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2651 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2652 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2654 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2655 std::optional<unsigned> DWARFAddressSpace =
2656 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2658 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2659 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2660 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2661 return VTablePtrType;
2664StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2676 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2678 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2688 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2689 VTable->isDeclarationForLinker())
2693 StringRef SymbolName =
"_vtable$";
2695 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2704 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2706 llvm::DIFile *Unit = getOrCreateFile(Loc);
2707 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2709 llvm::DINode::FlagArtificial;
2710 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2711 ? llvm::dwarf::DW_TAG_variable
2712 : llvm::dwarf::DW_TAG_member;
2713 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2714 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2718 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2722 llvm::DIGlobalVariableExpression *GVE =
2723 DBuilder.createGlobalVariableExpression(
2724 TheCU, SymbolName, VTable->getName(), Unit, 0,
2725 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2726 true,
nullptr, DT,
nullptr,
2728 VTable->addDebugInfo(GVE);
2731StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2733 llvm::Function *InitFn) {
2738 return InitFn->getName();
2748 llvm::raw_svector_ostream OS(QualifiedGV);
2750 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2752 std::swap(Quals, GVName);
2756 llvm::raw_svector_ostream OS(InitName);
2758 OS << Quals <<
"::";
2763 llvm_unreachable(
"not an initializer");
2765 OS <<
"`dynamic initializer for '";
2768 OS <<
"`dynamic atexit destructor for '";
2775 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2776 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2777 getPrintingPolicy());
2782 return internString(
OS.str());
2785void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2786 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2795 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2802 llvm::DIType *VPtrTy =
nullptr;
2803 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2804 CGM.getTarget().getCXXABI().isMicrosoft();
2805 if (NeedVTableShape) {
2807 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2808 const VTableLayout &VFTLayout =
2809 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2810 unsigned VSlotCount =
2812 unsigned VTableWidth = PtrWidth * VSlotCount;
2813 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2814 std::optional<unsigned> DWARFAddressSpace =
2815 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2818 llvm::DIType *VTableType = DBuilder.createPointerType(
2819 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2820 EltTys.push_back(VTableType);
2823 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2831 VPtrTy = getOrCreateVTablePtrType(Unit);
2833 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2834 llvm::DIType *VPtrMember =
2835 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2836 llvm::DINode::FlagArtificial, VPtrTy);
2837 EltTys.push_back(VPtrMember);
2842 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2843 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2854 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2855 assert(!D.
isNull() &&
"null type");
2856 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2857 assert(
T &&
"could not create debug info for type");
2866 if (CGM.getCodeGenOpts().getDebugInfo() <=
2867 llvm::codegenoptions::DebugLineTablesOnly)
2871 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2873 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2875 CI->setMetadata(
"heapallocsite", node);
2879 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2881 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2883 auto I = TypeCache.find(TyPtr);
2886 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2887 assert(!Res->isForwardDecl());
2888 TypeCache[TyPtr].reset(Res);
2892 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2893 !CGM.getLangOpts().CPlusPlus)
2899 if (RD->
hasAttr<DLLImportAttr>())
2902 if (MD->hasAttr<DLLImportAttr>())
2915 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2925 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2926 Explicit = TD->isExplicitInstantiationOrSpecialization();
2930 if (CXXDecl->
fields().empty())
2940 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2941 if (CXXRD->isDynamicClass() &&
2942 CGM.getVTableLinkage(CXXRD) ==
2943 llvm::GlobalValue::AvailableExternallyLinkage &&
2954 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2956 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
2958 auto I = TypeCache.find(TyPtr);
2965 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
2966 assert(!Res->isForwardDecl());
2967 TypeCache[TyPtr].reset(Res);
2974 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2975 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2998 if (Ctor->isCopyOrMoveConstructor())
3000 if (!Ctor->isDeleted())
3019 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3022 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3023 RD->
hasAttr<StandaloneDebugAttr>())
3026 if (!LangOpts.CPlusPlus)
3032 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3048 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3049 Spec = SD->getSpecializationKind();
3058 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3069 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3070 llvm::DIType *
T = getTypeOrNull(Ty);
3071 if (
T &&
T->isForwardDecl())
3075llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3076 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3077 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3081 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3085 auto [Def, Pref] = CreateTypeDefinition(Ty);
3087 return Pref ? Pref : Def;
3090llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3091 llvm::DIFile *Unit) {
3095 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3099 return getOrCreateType(PNA->getTypedefType(), Unit);
3102std::pair<llvm::DIType *, llvm::DIType *>
3103CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3104 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3107 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3115 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3119 return {FwdDecl,
nullptr};
3121 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3122 CollectContainingType(CXXDecl, FwdDecl);
3125 LexicalBlockStack.emplace_back(&*FwdDecl);
3126 RegionMap[RD].reset(FwdDecl);
3129 SmallVector<llvm::Metadata *, 16> EltTys;
3136 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3138 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3139 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3143 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3144 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3145 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3147 LexicalBlockStack.pop_back();
3148 RegionMap.erase(RD);
3150 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3151 DBuilder.replaceArrays(FwdDecl, Elements);
3153 if (FwdDecl->isTemporary())
3155 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3157 RegionMap[RD].reset(FwdDecl);
3159 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3160 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3161 return {FwdDecl, PrefDI};
3163 return {FwdDecl,
nullptr};
3166llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3167 llvm::DIFile *Unit) {
3169 return getOrCreateType(Ty->getBaseType(), Unit);
3172llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3173 llvm::DIFile *Unit) {
3175 SourceLocation Loc = Ty->getDecl()->getLocation();
3178 return DBuilder.createTypedef(
3179 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3180 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3181 getDeclContextDescriptor(Ty->getDecl()));
3208llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3209 llvm::DIFile *Unit) {
3215 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
3220 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3221 !
ID->getImplementation())
3222 return DBuilder.createForwardDecl(
3223 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3224 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3227 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3228 unsigned Line = getLineNumber(
ID->getLocation());
3232 ObjCInterfaceDecl *Def =
ID->getDefinition();
3234 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3235 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3236 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3237 DefUnit,
Line, RuntimeLang);
3238 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3242 return CreateTypeDefinition(Ty, Unit);
3245llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3246 bool CreateSkeletonCU) {
3251 auto ModRef = ModuleCache.find(M);
3252 if (ModRef != ModuleCache.end())
3256 SmallString<128> ConfigMacros;
3258 llvm::raw_svector_ostream
OS(ConfigMacros);
3259 const auto &PPOpts = CGM.getPreprocessorOpts();
3262 for (
auto &M : PPOpts.Macros) {
3265 const std::string &
Macro = M.first;
3266 bool Undef = M.second;
3267 OS <<
"\"-" << (Undef ?
'U' :
'D');
3283 bool IsRootModule = M ? !M->
Parent :
true;
3287 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3288 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3289 "clang module without ASTFile must be specified by -fmodule-name");
3292 auto RemapPath = [
this](StringRef Path) -> std::string {
3294 StringRef Relative(Remapped);
3295 StringRef CompDir = TheCU->getDirectory();
3296 if (CompDir.empty())
3299 if (Relative.consume_front(CompDir))
3300 Relative.consume_front(llvm::sys::path::get_separator());
3302 return Relative.str();
3305 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3312 Signature = ModSig.truncatedValue();
3316 llvm::DIBuilder DIB(CGM.getModule());
3318 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3319 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3320 PCM = getCurrentDirname();
3324 llvm::sys::path::append(PCM, Mod.
getASTFile());
3325 DIB.createCompileUnit(
3326 TheCU->getSourceLanguage(),
3329 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3330 llvm::DICompileUnit::FullDebug, Signature);
3334 llvm::DIModule *Parent =
3336 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3338 std::string IncludePath = Mod.
getPath().str();
3339 llvm::DIModule *DIMod =
3340 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3341 RemapPath(IncludePath));
3342 ModuleCache[M].reset(DIMod);
3346llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3347 llvm::DIFile *Unit) {
3349 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3350 unsigned Line = getLineNumber(
ID->getLocation());
3351 unsigned RuntimeLang = TheCU->getSourceLanguage();
3357 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3358 if (
ID->getImplementation())
3359 Flags |= llvm::DINode::FlagObjcClassComplete;
3361 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3362 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3363 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3364 nullptr, llvm::DINodeArray(), RuntimeLang);
3366 QualType QTy(Ty, 0);
3367 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3370 LexicalBlockStack.emplace_back(RealDecl);
3371 RegionMap[Ty->
getDecl()].reset(RealDecl);
3374 SmallVector<llvm::Metadata *, 16> EltTys;
3376 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3378 llvm::DIType *SClassTy =
3379 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3383 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3384 llvm::DINode::FlagZero);
3385 EltTys.push_back(InhTag);
3389 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3390 SourceLocation Loc = PD->getLocation();
3391 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3392 unsigned PLine = getLineNumber(Loc);
3393 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3394 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3395 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3396 PD->getName(), PUnit, PLine,
3398 : getSelectorName(PD->getGetterName()),
3400 : getSelectorName(PD->getSetterName()),
3401 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3402 EltTys.push_back(PropertyNode);
3407 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3411 llvm::DenseSet<IsClassAndIdent> PropertySet;
3413 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3414 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3416 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3417 for (
auto *PD : ClassExt->properties()) {
3418 PropertySet.insert(GetIsClassAndIdent(PD));
3421 for (
const auto *PD :
ID->properties()) {
3424 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3430 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3431 unsigned FieldNo = 0;
3432 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3433 Field =
Field->getNextIvar(), ++FieldNo) {
3434 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3438 StringRef FieldName =
Field->getName();
3441 if (FieldName.empty())
3445 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3446 unsigned FieldLine = getLineNumber(
Field->getLocation());
3447 QualType FType =
Field->getType();
3454 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3455 : CGM.getContext().getTypeSize(FType);
3460 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3464 if (
Field->isBitField()) {
3466 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3467 FieldOffset %= CGM.getContext().getCharWidth();
3475 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3477 Flags = llvm::DINode::FlagProtected;
3479 Flags = llvm::DINode::FlagPrivate;
3481 Flags = llvm::DINode::FlagPublic;
3483 if (
Field->isBitField())
3484 Flags |= llvm::DINode::FlagBitField;
3486 llvm::MDNode *PropertyNode =
nullptr;
3487 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3488 if (ObjCPropertyImplDecl *PImpD =
3489 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3490 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3491 SourceLocation Loc = PD->getLocation();
3492 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3493 unsigned PLine = getLineNumber(Loc);
3494 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3495 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3496 PropertyNode = DBuilder.createObjCProperty(
3497 PD->getName(), PUnit, PLine,
3500 : getSelectorName(PD->getGetterName()),
3503 : getSelectorName(PD->getSetterName()),
3504 PD->getPropertyAttributes(),
3505 getOrCreateType(PD->getType(), PUnit));
3509 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3510 FieldSize, FieldAlign, FieldOffset, Flags,
3511 FieldTy, PropertyNode);
3512 EltTys.push_back(FieldTy);
3515 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3516 DBuilder.replaceArrays(RealDecl, Elements);
3518 LexicalBlockStack.pop_back();
3522llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3523 llvm::DIFile *Unit) {
3531 auto &Ctx = CGM.getContext();
3536 QualType CharVecTy =
3538 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3541 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3544 llvm::Metadata *Subscript;
3545 QualType QTy(Ty, 0);
3546 auto SizeExpr = SizeExprCache.find(QTy);
3547 if (SizeExpr != SizeExprCache.end())
3548 Subscript = DBuilder.getOrCreateSubrange(
3549 SizeExpr->getSecond() ,
nullptr ,
3550 nullptr ,
nullptr );
3553 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3554 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3555 Subscript = DBuilder.getOrCreateSubrange(
3556 CountNode ,
nullptr ,
nullptr ,
3559 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3564 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3567llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3568 llvm::DIFile *Unit) {
3572 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3577 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3578 auto *ColumnCountNode =
3579 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3580 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3581 auto *RowCountNode =
3582 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3583 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3584 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3585 ColumnCountNode ,
nullptr ,
nullptr ,
3587 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3588 RowCountNode ,
nullptr ,
nullptr ,
3590 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3591 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3594llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3599 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3614 Size = CGM.getContext().getTypeSize(Ty);
3621 SmallVector<llvm::Metadata *, 8> Subscripts;
3622 QualType EltTy(Ty, 0);
3623 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3632 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3633 Count = CAT->getZExtSize();
3634 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3635 if (Expr *Size = VAT->getSizeExpr()) {
3637 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3638 Count =
Result.Val.getInt().getExtValue();
3642 auto SizeNode = SizeExprCache.find(EltTy);
3643 if (SizeNode != SizeExprCache.end())
3644 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3645 SizeNode->getSecond() ,
nullptr ,
3646 nullptr ,
nullptr ));
3649 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3650 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3651 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3652 CountNode ,
nullptr ,
nullptr ,
3658 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3660 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3664llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3665 llvm::DIFile *Unit) {
3666 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3670llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3671 llvm::DIFile *Unit) {
3672 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3674 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3675 CGM.getCodeGenOpts().DwarfVersion < 4)
3676 Tag = llvm::dwarf::DW_TAG_reference_type;
3678 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3681llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3683 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3687 Size = CGM.getContext().getTypeSize(Ty);
3690 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3693 Flags |= llvm::DINode::FlagSingleInheritance;
3696 Flags |= llvm::DINode::FlagMultipleInheritance;
3699 Flags |= llvm::DINode::FlagVirtualInheritance;
3709 llvm::DIType *ClassType = getOrCreateType(
T, U);
3711 return DBuilder.createMemberPointerType(
3715 const FunctionProtoType *FPT =
3717 return DBuilder.createMemberPointerType(
3718 getOrCreateInstanceMethodType(
3721 ClassType, Size, 0, Flags);
3724llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3726 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3729llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3733llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3735 return getOrCreateType(Ty->getWrappedType(), U);
3738llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3745 const EnumType *Ty) {
3757llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3760 bool isImportedFromModule =
3761 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3765 if (isImportedFromModule || !ED->getDefinition()) {
3772 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3773 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3774 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3775 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3777 unsigned Line = getLineNumber(ED->getLocation());
3778 StringRef EDName = ED->getName();
3779 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3780 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3781 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3783 ReplaceMap.emplace_back(
3784 std::piecewise_construct, std::make_tuple(Ty),
3785 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3789 return CreateTypeDefinition(Ty);
3792llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3795 SmallVector<llvm::Metadata *, 16> Enumerators;
3796 ED = ED->getDefinition();
3797 assert(ED &&
"An enumeration definition is required");
3798 for (
const auto *
Enum : ED->enumerators()) {
3799 Enumerators.push_back(
3800 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3803 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3804 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3805 EnumKind = Attr->getExtensibility();
3808 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3810 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3811 unsigned Line = getLineNumber(ED->getLocation());
3812 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3813 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3814 return DBuilder.createEnumerationType(
3815 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3816 0, Identifier, ED->isScoped(), EnumKind);
3821 StringRef Name, StringRef
Value) {
3822 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3823 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3829 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3830 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3831 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3835 StringRef FuncName) {
3836 llvm::DISubprogram *SP =
3837 createInlinedSubprogram(FuncName, Location->getFile());
3838 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3843 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3849 FuncName += Category;
3851 FuncName += FailureMsg;
3863 Quals += InnerQuals;
3865 switch (
T->getTypeClass()) {
3867 return C.getQualifiedType(
T.getTypePtr(), Quals);
3870 case Type::InjectedClassName:
3871 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3873 case Type::TemplateSpecialization: {
3875 if (Spec->isTypeAlias())
3876 return C.getQualifiedType(
T.getTypePtr(), Quals);
3877 T = Spec->desugar();
3880 case Type::TypeOfExpr:
3886 case Type::Decltype:
3889 case Type::UnaryTransform:
3892 case Type::Attributed:
3895 case Type::BTFTagAttributed:
3898 case Type::CountAttributed:
3907 case Type::MacroQualified:
3910 case Type::SubstTemplateTypeParm:
3914 case Type::DeducedTemplateSpecialization: {
3916 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3920 case Type::PackIndexing: {
3924 case Type::Adjusted:
3931 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3936llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
3939 if (It != TypeCache.end()) {
3941 if (llvm::Metadata *
V = It->second)
3954 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3961 RetainedTypes.push_back(
3962 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
3965llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3969 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3971 llvm::raw_string_ostream OS(Name);
3972 Ty.
print(OS, getPrintingPolicy());
3979 if (
auto *
T = getTypeOrNull(Ty))
3982 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3983 void *TyPtr = Ty.getAsOpaquePtr();
3986 TypeCache[TyPtr].reset(Res);
3991llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3999 auto Info = Reader->getSourceDescriptor(Idx);
4001 return getOrCreateModuleRef(*Info,
true);
4002 }
else if (ClangModuleMap) {
4015 auto Info = ASTSourceDescriptor(*M);
4016 return getOrCreateModuleRef(Info,
false);
4019 return getOrCreateModuleRef(PCHDescriptor,
false);
4026llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4029 return CreateQualifiedType(Ty, Unit);
4033#define TYPE(Class, Base)
4034#define ABSTRACT_TYPE(Class, Base)
4035#define NON_CANONICAL_TYPE(Class, Base)
4036#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4037#include "clang/AST/TypeNodes.inc"
4038 llvm_unreachable(
"Dependent types cannot show up in debug information");
4040 case Type::ExtVector:
4043 case Type::ConstantMatrix:
4045 case Type::ObjCObjectPointer:
4047 case Type::ObjCObject:
4049 case Type::ObjCTypeParam:
4051 case Type::ObjCInterface:
4059 case Type::BlockPointer:
4067 case Type::FunctionProto:
4068 case Type::FunctionNoProto:
4070 case Type::ConstantArray:
4071 case Type::VariableArray:
4072 case Type::IncompleteArray:
4073 case Type::ArrayParameter:
4076 case Type::LValueReference:
4078 case Type::RValueReference:
4081 case Type::MemberPointer:
4092 case Type::TemplateSpecialization:
4094 case Type::HLSLAttributedResource:
4096 case Type::HLSLInlineSpirv:
4098 case Type::PredefinedSugar:
4100 case Type::CountAttributed:
4102 case Type::Attributed:
4103 case Type::BTFTagAttributed:
4104 case Type::Adjusted:
4106 case Type::DeducedTemplateSpecialization:
4109 case Type::MacroQualified:
4110 case Type::SubstTemplateTypeParm:
4111 case Type::TypeOfExpr:
4113 case Type::Decltype:
4114 case Type::PackIndexing:
4115 case Type::UnaryTransform:
4119 llvm_unreachable(
"type should have been unwrapped!");
4122llvm::DICompositeType *
4123CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4124 QualType QTy(Ty, 0);
4126 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4131 if (
T && !
T->isForwardDecl())
4135 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4140 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4143 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4148llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4149 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
4152 StringRef RDName = getClassName(RD);
4154 llvm::DIFile *DefUnit =
nullptr;
4157 DefUnit = getOrCreateFile(Loc);
4158 Line = getLineNumber(Loc);
4161 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4165 auto *
T = cast_or_null<llvm::DICompositeType>(
4166 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4174 return getOrCreateRecordFwdDecl(Ty, RDContext);
4187 auto Flags = llvm::DINode::FlagZero;
4188 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4190 Flags |= llvm::DINode::FlagTypePassByReference;
4192 Flags |= llvm::DINode::FlagTypePassByValue;
4195 if (!CXXRD->isTrivial())
4196 Flags |= llvm::DINode::FlagNonTrivial;
4199 if (CXXRD->isAnonymousStructOrUnion())
4200 Flags |= llvm::DINode::FlagExportSymbols;
4203 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4206 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4207 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4209 Flags, Identifier, Annotations);
4213 switch (RealDecl->getTag()) {
4215 llvm_unreachable(
"invalid composite type tag");
4217 case llvm::dwarf::DW_TAG_array_type:
4218 case llvm::dwarf::DW_TAG_enumeration_type:
4223 if (Identifier.empty())
4227 case llvm::dwarf::DW_TAG_structure_type:
4228 case llvm::dwarf::DW_TAG_union_type:
4229 case llvm::dwarf::DW_TAG_class_type:
4232 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4237 dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
4238 CXXRecordDecl *TemplateDecl =
4239 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4240 RegionMap[TemplateDecl].reset(RealDecl);
4242 RegionMap[RD].reset(RealDecl);
4244 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4246 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4247 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4248 CollectCXXTemplateParams(TSpecial, DefUnit));
4252void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4253 llvm::DICompositeType *RealDecl) {
4255 llvm::DIType *ContainingType =
nullptr;
4256 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4260 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4267 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4268 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4270 ContainingType = RealDecl;
4272 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4275llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4276 StringRef Name, uint64_t *Offset) {
4277 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4278 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4281 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4282 *Offset, llvm::DINode::FlagZero, FieldTy);
4283 *Offset += FieldSize;
4287void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4289 StringRef &LinkageName,
4290 llvm::DIScope *&FDContext,
4291 llvm::DINodeArray &TParamsArray,
4292 llvm::DINode::DIFlags &Flags) {
4294 Name = getFunctionName(FD);
4297 LinkageName = CGM.getMangledName(GD);
4299 Flags |= llvm::DINode::FlagPrototyped;
4303 if (LinkageName == Name ||
4304 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4305 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4306 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4307 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4308 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4309 LinkageName = StringRef();
4313 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4314 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4315 CGM.getCodeGenOpts().EmitCodeView)) {
4316 if (
const NamespaceDecl *NSDecl =
4318 FDContext = getOrCreateNamespace(NSDecl);
4319 else if (
const RecordDecl *RDecl =
4321 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4322 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4325 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4328 Flags |= llvm::DINode::FlagNoReturn;
4330 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4334void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4335 unsigned &LineNo, QualType &
T,
4336 StringRef &Name, StringRef &LinkageName,
4337 llvm::MDTuple *&TemplateParameters,
4338 llvm::DIScope *&VDContext) {
4347 llvm::APInt ConstVal(32, 1);
4348 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4350 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4357 LinkageName = CGM.getMangledName(VD);
4358 if (LinkageName == Name)
4359 LinkageName = StringRef();
4362 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4363 TemplateParameters = parameterNodes.get();
4365 TemplateParameters =
nullptr;
4383 DC = CGM.getContext().getTranslationUnitDecl();
4385 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4386 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4389llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4391 llvm::DINodeArray TParamsArray;
4392 StringRef Name, LinkageName;
4393 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4394 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4396 llvm::DIFile *Unit = getOrCreateFile(Loc);
4397 llvm::DIScope *DContext = Unit;
4398 unsigned Line = getLineNumber(Loc);
4399 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4404 SmallVector<QualType, 16> ArgTypes;
4405 for (
const ParmVarDecl *Parm : FD->
parameters())
4406 ArgTypes.push_back(Parm->getType());
4409 QualType FnType = CGM.getContext().getFunctionType(
4410 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4412 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4413 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4414 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4417 Flags |= getCallSiteRelatedAttrs();
4418 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4419 return DBuilder.createFunction(
4420 DContext, Name, LinkageName, Unit,
Line,
4421 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4422 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4424 CGM.getCodeGenOpts().DebugKeyInstructions);
4427 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4428 DContext, Name, LinkageName, Unit,
Line,
4429 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4430 TParamsArray.get(), getFunctionDeclaration(FD));
4432 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4433 std::make_tuple(CanonDecl),
4434 std::make_tuple(SP));
4438llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4439 return getFunctionFwdDeclOrStub(GD,
false);
4442llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4443 return getFunctionFwdDeclOrStub(GD,
true);
4446llvm::DIGlobalVariable *
4447CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4449 StringRef Name, LinkageName;
4451 llvm::DIFile *Unit = getOrCreateFile(Loc);
4452 llvm::DIScope *DContext = Unit;
4453 unsigned Line = getLineNumber(Loc);
4454 llvm::MDTuple *TemplateParameters =
nullptr;
4456 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4459 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4460 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4462 FwdDeclReplaceMap.emplace_back(
4463 std::piecewise_construct,
4465 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4469llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4474 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4475 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4476 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4480 if (I != DeclCache.end()) {
4482 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4483 return GVE->getVariable();
4491 if (IE != ImportedDeclCache.end()) {
4492 auto N = IE->second;
4493 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4495 return dyn_cast_or_null<llvm::DINode>(N);
4500 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4501 return getFunctionForwardDeclaration(FD);
4502 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4503 return getGlobalVariableForwardDeclaration(VD);
4508llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4509 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4512 const auto *FD = dyn_cast<FunctionDecl>(D);
4517 auto *S = getDeclContextDescriptor(D);
4520 if (MI == SPCache.end()) {
4522 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4526 if (MI != SPCache.end()) {
4527 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4528 if (SP && !SP->isDefinition())
4532 for (
auto *NextFD : FD->
redecls()) {
4533 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4534 if (MI != SPCache.end()) {
4535 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4536 if (SP && !SP->isDefinition())
4543llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4544 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4545 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4546 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4549 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4553 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4557 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4566 QualType QTy(
ID->getTypeForDecl(), 0);
4567 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4568 if (It == TypeCache.end())
4571 llvm::DISubprogram *FD = DBuilder.createFunction(
4572 InterfaceType, getObjCMethodName(OMD), StringRef(),
4573 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4574 DBuilder.finalizeSubprogram(FD);
4581llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4586 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4587 !CGM.getCodeGenOpts().EmitCodeView))
4590 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4592 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4595 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4598 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4599 return getOrCreateMethodType(
Method, F);
4601 const auto *FTy = FnType->
getAs<FunctionType>();
4604 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4606 SmallVector<llvm::Metadata *, 16> Elts;
4609 QualType ResultTy = OMethod->getReturnType();
4612 if (ResultTy == CGM.getContext().getObjCInstanceType())
4613 ResultTy = CGM.getContext().getPointerType(
4614 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4616 Elts.push_back(getOrCreateType(ResultTy, F));
4618 QualType SelfDeclTy;
4619 if (
auto *SelfDecl = OMethod->getSelfDecl())
4620 SelfDeclTy = SelfDecl->getType();
4621 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4624 if (!SelfDeclTy.
isNull())
4626 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4628 Elts.push_back(DBuilder.createArtificialType(
4629 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4631 for (
const auto *PI : OMethod->parameters())
4632 Elts.push_back(getOrCreateType(PI->getType(), F));
4634 if (OMethod->isVariadic())
4635 Elts.push_back(DBuilder.createUnspecifiedParameter());
4637 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4638 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4644 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4645 if (FD->isVariadic()) {
4646 SmallVector<llvm::Metadata *, 16> EltTys;
4647 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4648 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4650 EltTys.push_back(getOrCreateType(ParamType, F));
4651 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4652 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4653 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4666 CC = SrcFnTy->getCallConv();
4668 for (
const VarDecl *VD : Args)
4669 ArgTypes.push_back(VD->
getType());
4670 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4676 llvm::Function *Fn,
bool CurFuncIsThunk) {
4678 StringRef LinkageName;
4680 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4683 bool HasDecl = (D !=
nullptr);
4685 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4686 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4687 llvm::DIFile *Unit = getOrCreateFile(Loc);
4688 llvm::DIScope *FDContext = Unit;
4689 llvm::DINodeArray TParamsArray;
4690 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4693 LinkageName = Fn->getName();
4694 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4696 auto FI = SPCache.find(FD->getCanonicalDecl());
4697 if (FI != SPCache.end()) {
4698 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4699 if (SP && SP->isDefinition()) {
4700 LexicalBlockStack.emplace_back(SP);
4701 RegionMap[D].reset(SP);
4705 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4706 TParamsArray, Flags);
4709 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4710 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4711 Name = getObjCMethodName(OMD);
4712 Flags |= llvm::DINode::FlagPrototyped;
4719 Name = Fn->getName();
4724 Flags |= llvm::DINode::FlagPrototyped;
4726 Name.consume_front(
"\01");
4730 "Unexpected DynamicInitKind !");
4734 Flags |= llvm::DINode::FlagArtificial;
4740 Flags |= llvm::DINode::FlagThunk;
4742 if (Fn->hasLocalLinkage())
4743 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4744 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4745 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4747 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4748 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4749 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4751 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4752 unsigned ScopeLine = getLineNumber(ScopeLoc);
4753 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4754 llvm::DISubprogram *
Decl =
nullptr;
4755 llvm::DINodeArray Annotations =
nullptr;
4758 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4759 : getFunctionDeclaration(D);
4760 Annotations = CollectBTFDeclTagAnnotations(D);
4768 llvm::DISubprogram *SP = DBuilder.createFunction(
4769 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4770 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4771 Annotations,
"", KeyInstructions);
4772 Fn->setSubprogram(SP);
4781 LexicalBlockStack.emplace_back(SP);
4784 RegionMap[D].reset(SP);
4788 QualType FnType, llvm::Function *Fn) {
4790 StringRef LinkageName;
4796 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4797 return GetName(D,
true);
4800 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4801 llvm::DIFile *Unit = getOrCreateFile(Loc);
4802 bool IsDeclForCallSite = Fn ?
true :
false;
4803 llvm::DIScope *FDContext =
4804 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4805 llvm::DINodeArray TParamsArray;
4808 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4809 TParamsArray, Flags);
4810 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4811 Name = getObjCMethodName(OMD);
4812 Flags |= llvm::DINode::FlagPrototyped;
4814 llvm_unreachable(
"not a function or ObjC method");
4816 Name.consume_front(
"\01");
4819 Flags |= llvm::DINode::FlagArtificial;
4824 unsigned LineNo = getLineNumber(Loc);
4825 unsigned ScopeLine = 0;
4826 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4827 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4828 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4830 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4831 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4833 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4834 llvm::DISubprogram *SP = DBuilder.createFunction(
4835 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4836 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4842 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4843 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4844 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4847 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4848 DBuilder.createParameterVariable(
4849 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4850 llvm::DINode::FlagZero, ParamAnnotations);
4856 if (IsDeclForCallSite)
4857 Fn->setSubprogram(SP);
4865 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4868 if (
Func->getSubprogram())
4873 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4874 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4887 auto FI = SPCache.find(FD->getCanonicalDecl());
4888 llvm::DISubprogram *SP =
nullptr;
4889 if (FI != SPCache.end())
4890 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4891 if (!SP || !SP->isDefinition())
4892 SP = getFunctionStub(GD);
4893 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4894 LexicalBlockStack.emplace_back(SP);
4900 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4909 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4912 llvm::MDNode *
Scope = LexicalBlockStack.back();
4913 Builder.SetCurrentDebugLocation(
4914 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
4915 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4919 llvm::MDNode *Back =
nullptr;
4920 if (!LexicalBlockStack.empty())
4921 Back = LexicalBlockStack.back().get();
4922 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4924 getColumnNumber(CurLoc)));
4927void CGDebugInfo::AppendAddressSpaceXDeref(
4929 std::optional<unsigned> DWARFAddressSpace =
4931 if (!DWARFAddressSpace)
4934 Expr.push_back(llvm::dwarf::DW_OP_constu);
4935 Expr.push_back(*DWARFAddressSpace);
4936 Expr.push_back(llvm::dwarf::DW_OP_swap);
4937 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4946 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4947 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
4948 LexicalBlockStack.back(), CurInlinedAt));
4950 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4954 CreateLexicalBlock(Loc);
4959 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4964 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4967 LexicalBlockStack.pop_back();
4971 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4972 unsigned RCount = FnBeginRegionCount.back();
4973 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4976 while (LexicalBlockStack.size() != RCount) {
4979 LexicalBlockStack.pop_back();
4981 FnBeginRegionCount.pop_back();
4983 if (Fn && Fn->getSubprogram())
4984 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4987CGDebugInfo::BlockByRefType
4988CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4989 uint64_t *XOffset) {
4992 uint64_t FieldSize, FieldOffset;
4993 uint32_t FieldAlign;
4995 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5000 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5001 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5003 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5004 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5007 if (HasCopyAndDispose) {
5010 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5012 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5014 bool HasByrefExtendedLayout;
5017 HasByrefExtendedLayout) &&
5018 HasByrefExtendedLayout) {
5021 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5030 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5033 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5036 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5041 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5042 FieldSize = CGM.getContext().getTypeSize(FType);
5043 FieldAlign = CGM.getContext().toBits(Align);
5045 *XOffset = FieldOffset;
5046 llvm::DIType *FieldTy = DBuilder.createMemberType(
5047 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5048 llvm::DINode::FlagZero, WrappedTy);
5049 EltTys.push_back(FieldTy);
5050 FieldOffset += FieldSize;
5052 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5053 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5054 llvm::DINode::FlagZero,
nullptr, Elements),
5058llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5059 llvm::Value *Storage,
5060 std::optional<unsigned> ArgNo,
5062 const bool UsePointerValue) {
5063 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5064 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5065 if (VD->
hasAttr<NoDebugAttr>())
5070 llvm::DIFile *Unit =
nullptr;
5071 if (!VarIsArtificial)
5075 if (VD->
hasAttr<BlocksAttr>())
5076 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5078 Ty = getOrCreateType(VD->
getType(), Unit);
5088 if (!VarIsArtificial) {
5092 SmallVector<uint64_t, 13> Expr;
5093 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5094 if (VarIsArtificial)
5095 Flags |= llvm::DINode::FlagArtificial;
5099 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5100 AppendAddressSpaceXDeref(AddressSpace, Expr);
5104 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5107 Flags |= llvm::DINode::FlagObjectPointer;
5108 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5109 if (PVD->isExplicitObjectParameter())
5110 Flags |= llvm::DINode::FlagObjectPointer;
5118 StringRef Name = VD->
getName();
5119 if (!Name.empty()) {
5125 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5127 offset = CGM.getContext().toCharUnitsFromBits(
5130 Expr.push_back(llvm::dwarf::DW_OP_deref);
5131 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5133 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5136 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5148 for (
const auto *Field : RD->
fields()) {
5149 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5150 StringRef FieldName =
Field->getName();
5158 auto *D = DBuilder.createAutoVariable(
5159 Scope, FieldName, Unit,
Line, FieldTy,
5160 CGM.getCodeGenOpts().OptimizationLevel != 0,
5161 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5164 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5165 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5168 Builder.GetInsertBlock());
5176 if (UsePointerValue) {
5177 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5178 "Debug info already contains DW_OP_deref.");
5179 Expr.push_back(llvm::dwarf::DW_OP_deref);
5183 llvm::DILocalVariable *D =
nullptr;
5185 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5186 D = DBuilder.createParameterVariable(
5187 Scope, Name, *ArgNo, Unit,
Line, Ty,
5188 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5197 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5203 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5204 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5205 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5206 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5208 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5214 if (Iter != CoroutineParameterMappings.end()) {
5215 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5216 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5217 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5219 if (Iter2 != ParamDbgMappings.end())
5220 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5226 D = RemapCoroArgToLocalVar();
5229 D = DBuilder.createAutoVariable(
5230 Scope, Name, Unit,
Line, Ty,
5231 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5234 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5235 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5236 Column, Scope, CurInlinedAt),
5237 Builder.GetInsertBlock());
5242llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5243 llvm::Value *Storage,
5244 std::optional<unsigned> ArgNo,
5246 const bool UsePointerValue) {
5247 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5248 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5249 if (BD->
hasAttr<NoDebugAttr>())
5256 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5257 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5265 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5267 SmallVector<uint64_t, 3> Expr;
5268 AppendAddressSpaceXDeref(AddressSpace, Expr);
5273 if (UsePointerValue) {
5274 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5275 "Debug info already contains DW_OP_deref.");
5276 Expr.push_back(llvm::dwarf::DW_OP_deref);
5281 StringRef Name = BD->
getName();
5284 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5285 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5286 llvm::DINode::FlagZero, Align);
5288 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5289 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5290 const unsigned fieldIndex = FD->getFieldIndex();
5291 const clang::CXXRecordDecl *parent =
5292 (
const CXXRecordDecl *)FD->getParent();
5293 const ASTRecordLayout &layout =
5294 CGM.getContext().getASTRecordLayout(parent);
5296 if (FD->isBitField()) {
5297 const CGRecordLayout &RL =
5298 CGM.getTypes().getCGRecordLayout(FD->getParent());
5303 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5309 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5310 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5311 Expr.push_back(Info.
Offset);
5314 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5315 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5316 }
else if (fieldOffset != 0) {
5317 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5318 "Unexpected non-bitfield with non-byte-aligned offset");
5319 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5321 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5324 }
else if (
const ArraySubscriptExpr *ASE =
5325 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5326 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5327 const uint64_t value = IL->getValue().getZExtValue();
5328 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5331 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5332 Expr.push_back(CGM.getContext()
5333 .toCharUnitsFromBits(value * typeSize)
5340 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5341 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5342 Column, Scope, CurInlinedAt),
5343 Builder.GetInsertBlock());
5348llvm::DILocalVariable *
5351 const bool UsePointerValue) {
5352 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5354 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5356 EmitDeclare(B, Storage, std::nullopt, Builder,
5363 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5367 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5368 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5370 if (D->
hasAttr<NoDebugAttr>())
5374 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5380 StringRef Name = D->
getName();
5386 CGM.getCodeGenOpts().OptimizationLevel != 0);
5389 DBuilder.insertLabel(L,
5390 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5391 Scope, CurInlinedAt),
5392 Builder.GetInsertBlock()->end());
5395llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5397 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5400 return DBuilder.createObjectPointerType(Ty,
true);
5405 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5406 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5407 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5409 if (Builder.GetInsertBlock() ==
nullptr)
5411 if (VD->
hasAttr<NoDebugAttr>())
5414 bool isByRef = VD->
hasAttr<BlocksAttr>();
5416 uint64_t XOffset = 0;
5417 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5420 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5422 Ty = getOrCreateType(VD->
getType(), Unit);
5426 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5428 Ty = CreateSelfType(VD->
getType(), Ty);
5431 const unsigned Line =
5435 const llvm::DataLayout &target = CGM.getDataLayout();
5442 addr.push_back(llvm::dwarf::DW_OP_deref);
5443 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5446 addr.push_back(llvm::dwarf::DW_OP_deref);
5447 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5450 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5452 addr.push_back(llvm::dwarf::DW_OP_deref);
5453 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5455 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5461 auto *D = DBuilder.createAutoVariable(
5463 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5466 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5467 LexicalBlockStack.back(), CurInlinedAt);
5468 auto *
Expr = DBuilder.createExpression(addr);
5470 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5472 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5475llvm::DILocalVariable *
5478 bool UsePointerValue) {
5479 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5480 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5484struct BlockLayoutChunk {
5485 uint64_t OffsetInBits;
5488bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5489 return l.OffsetInBits < r.OffsetInBits;
5493void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5495 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5496 SmallVectorImpl<llvm::Metadata *> &Fields) {
5500 if (CGM.getLangOpts().OpenCL) {
5501 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5502 BlockLayout.getElementOffsetInBits(0),
5504 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5505 BlockLayout.getElementOffsetInBits(1),
5509 BlockLayout.getElementOffsetInBits(0),
5511 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5512 BlockLayout.getElementOffsetInBits(1),
5516 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5517 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5518 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5519 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5520 BlockLayout.getElementOffsetInBits(3),
5522 Fields.push_back(createFieldType(
5527 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5534 llvm::AllocaInst *Alloca,
5536 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5542 llvm::DIFile *tunit = getOrCreateFile(loc);
5543 unsigned line = getLineNumber(loc);
5544 unsigned column = getColumnNumber(loc);
5549 const llvm::StructLayout *blockLayout =
5553 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5562 BlockLayoutChunk chunk;
5563 chunk.OffsetInBits =
5564 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5565 chunk.Capture =
nullptr;
5566 chunks.push_back(chunk);
5570 for (
const auto &capture :
blockDecl->captures()) {
5571 const VarDecl *variable = capture.getVariable();
5578 BlockLayoutChunk chunk;
5579 chunk.OffsetInBits =
5580 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5581 chunk.Capture = &capture;
5582 chunks.push_back(chunk);
5586 llvm::array_pod_sort(chunks.begin(), chunks.end());
5588 for (
const BlockLayoutChunk &Chunk : chunks) {
5589 uint64_t offsetInBits = Chunk.OffsetInBits;
5596 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5598 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5599 type = CGM.getContext().getCanonicalTagType(RDecl);
5601 llvm_unreachable(
"unexpected block declcontext");
5603 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5604 offsetInBits, tunit, tunit));
5609 StringRef name = variable->
getName();
5611 llvm::DIType *fieldType;
5613 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5618 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5619 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5620 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5621 PtrInfo.
Width, Align, offsetInBits,
5622 llvm::DINode::FlagZero, fieldType);
5626 offsetInBits, Align, tunit, tunit);
5628 fields.push_back(fieldType);
5632 llvm::raw_svector_ostream(typeName)
5633 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5635 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5637 llvm::DIType *
type =
5638 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5639 CGM.getContext().toBits(block.
BlockSize), 0,
5640 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5641 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5644 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5648 auto *debugVar = DBuilder.createParameterVariable(
5649 scope, Name, ArgNo, tunit, line,
type,
5650 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5653 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5654 llvm::DILocation::get(CGM.getLLVMContext(), line,
5655 column, scope, CurInlinedAt),
5656 Builder.GetInsertBlock());
5659llvm::DIDerivedType *
5660CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5665 if (MI != StaticDataMemberCache.end()) {
5666 assert(MI->second &&
"Static data member declaration should still exist");
5677llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5678 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5679 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5680 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5682 for (
const auto *Field : RD->
fields()) {
5683 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5684 StringRef FieldName = Field->getName();
5687 if (FieldName.empty()) {
5688 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5690 CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
5691 Unit, LineNo, LinkageName, Var, DContext);
5695 GVE = DBuilder.createGlobalVariableExpression(
5696 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5697 Var->hasLocalLinkage());
5698 Var->addDebugInfo(GVE);
5710 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
5715 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5726 struct ReferencesAnonymous
5728 bool RefAnon =
false;
5729 bool VisitRecordType(RecordType *RT) {
5737 ReferencesAnonymous RT;
5750struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5751 bool Reconstitutable =
true;
5752 bool VisitVectorType(VectorType *FT) {
5753 Reconstitutable =
false;
5756 bool VisitAtomicType(AtomicType *FT) {
5757 Reconstitutable =
false;
5760 bool VisitType(
Type *
T) {
5764 Reconstitutable =
false;
5769 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5772 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
5773 if (!ED->getIdentifier()) {
5774 Reconstitutable =
false;
5777 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5778 Reconstitutable =
false;
5784 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5788 return Reconstitutable;
5790 bool VisitRecordType(RecordType *RT,
bool =
false) {
5792 Reconstitutable =
false;
5802 ReconstitutableType
T;
5804 return T.Reconstitutable;
5807bool CGDebugInfo::HasReconstitutableArgs(
5808 ArrayRef<TemplateArgument> Args)
const {
5809 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5849 llvm_unreachable(
"Other, unresolved, template arguments should "
5850 "not be seen here");
5855std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5857 llvm::raw_string_ostream
OS(Name);
5858 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5861 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5862 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5864 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5865 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5867 std::optional<TemplateArgs> Args;
5869 bool IsOperatorOverload =
false;
5870 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5871 Args = GetTemplateArgs(RD);
5872 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5873 Args = GetTemplateArgs(FD);
5875 IsOperatorOverload |=
5878 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5879 Args = GetTemplateArgs(VD);
5903 bool Reconstitutable =
5904 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5906 PrintingPolicy PP = getPrintingPolicy();
5908 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5912 bool Mangled = TemplateNamesKind ==
5913 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5919 std::string EncodedOriginalName;
5920 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5925 printTemplateArgumentList(OS, Args->Args, PP);
5926 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
5928 std::string CanonicalOriginalName;
5929 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5931 assert(EncodedOriginalName == CanonicalOriginalName);
5940 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5941 if (D->
hasAttr<NoDebugAttr>())
5944 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5945 return GetName(D,
true);
5951 if (Cached != DeclCache.end())
5952 return Var->addDebugInfo(
5956 llvm::DIFile *Unit =
nullptr;
5957 llvm::DIScope *DContext =
nullptr;
5959 StringRef DeclName, LinkageName;
5961 llvm::MDTuple *TemplateParameters =
nullptr;
5962 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5963 TemplateParameters, DContext);
5967 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5972 if (
T->isUnionType() && DeclName.empty()) {
5973 const auto *RD =
T->castAsRecordDecl();
5975 "unnamed non-anonymous struct or union?");
5976 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5981 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
5982 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
5983 if (D->
hasAttr<CUDASharedAttr>())
5986 else if (D->
hasAttr<CUDAConstantAttr>())
5990 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5992 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5993 GVE = DBuilder.createGlobalVariableExpression(
5994 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5995 Var->hasLocalLinkage(),
true,
5996 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5997 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5998 Align, Annotations);
5999 Var->addDebugInfo(GVE);
6005 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6006 if (VD->
hasAttr<NoDebugAttr>())
6008 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6009 return GetName(VD,
true);
6014 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6015 StringRef Name = VD->
getName();
6016 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6018 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6020 if (CGM.getCodeGenOpts().EmitCodeView) {
6031 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6032 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6033 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6043 auto *VarD = dyn_cast<VarDecl>(VD);
6044 if (VarD && VarD->isStaticDataMember()) {
6046 getDeclContextDescriptor(VarD);
6051 RetainedTypes.push_back(
6052 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6056 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6058 auto &GV = DeclCache[VD];
6062 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6063 llvm::MDTuple *TemplateParameters =
nullptr;
6067 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6068 TemplateParameters = parameterNodes.get();
6071 GV.reset(DBuilder.createGlobalVariableExpression(
6072 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6073 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6074 TemplateParameters, Align));
6079 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6080 if (D->
hasAttr<NoDebugAttr>())
6084 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6085 StringRef Name = D->
getName();
6086 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6088 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6089 llvm::DIGlobalVariableExpression *GVE =
6090 DBuilder.createGlobalVariableExpression(
6091 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6092 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6093 Var->addDebugInfo(GVE);
6100 if (CGM.getCodeGenOpts().getDebugInfo() <=
6101 llvm::codegenoptions::DebugLineTablesOnly)
6104 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6108 llvm::DIFile *Unit = DIL->getFile();
6109 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6114 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6115 llvm::Value *Var = Load->getPointerOperand();
6120 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6121 return DbgDeclare->getVariable()->getType() ==
Type;
6123 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6127 llvm::DILocalVariable *D =
6128 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6129 Type,
false, llvm::DINode::FlagArtificial);
6131 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6132 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6142 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6146 if (D->
hasAttr<NoDebugAttr>())
6149 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6164 if (!(DI = getDeclarationOrDefinition(
6165 AliaseeDecl.getCanonicalDecl().getDecl())))
6168 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6171 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6172 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6181 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
6185 llvm::DIFile *
File = getOrCreateFile(Loc);
6186 llvm::DIGlobalVariableExpression *Debug =
6187 DBuilder.createGlobalVariableExpression(
6188 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6189 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6190 GV->addDebugInfo(Debug);
6193llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6194 if (!LexicalBlockStack.empty())
6195 return LexicalBlockStack.back();
6196 llvm::DIScope *Mod = getParentModuleOrNull(D);
6197 return getContextDescriptor(D, Mod ? Mod : TheCU);
6201 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6205 CGM.getCodeGenOpts().DebugExplicitImport) {
6209 DBuilder.createImportedModule(
6211 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6216 if (llvm::DINode *
Target =
6219 DBuilder.createImportedDeclaration(
6221 getOrCreateFile(Loc), getLineNumber(Loc));
6226 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6229 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6231 for (
const auto *USD : UD.
shadows()) {
6236 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6237 if (
const auto *AT = FD->getType()
6240 if (AT->getDeducedType().isNull())
6251 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6254 "We shouldn't be codegening an invalid UsingEnumDecl"
6255 " containing no decls");
6257 for (
const auto *USD : UD.
shadows())
6262 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6264 if (
Module *M = ID.getImportedModule()) {
6266 auto Loc = ID.getLocation();
6267 DBuilder.createImportedDeclaration(
6268 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6269 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6270 getLineNumber(Loc));
6274llvm::DIImportedEntity *
6276 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6278 auto &VH = NamespaceAliasCache[&NA];
6281 llvm::DIImportedEntity *R;
6283 if (
const auto *Underlying =
6286 R = DBuilder.createImportedDeclaration(
6289 getLineNumber(Loc), NA.
getName());
6291 R = DBuilder.createImportedDeclaration(
6294 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6300CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6304 auto I = NamespaceCache.find(NSDecl);
6305 if (I != NamespaceCache.end())
6308 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6310 llvm::DINamespace *NS =
6311 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6312 NamespaceCache[NSDecl].reset(NS);
6317 assert(TheCU &&
"no main compile unit");
6318 TheCU->setDWOId(Signature);
6324 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6325 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6327 ? CreateTypeDefinition(E.Type, E.Unit)
6329 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6333 for (
const auto &P : ObjCMethodCache) {
6334 if (P.second.empty())
6337 QualType QTy(P.first->getTypeForDecl(), 0);
6339 assert(It != TypeCache.end());
6341 llvm::DICompositeType *InterfaceDecl =
6344 auto CurElts = InterfaceDecl->getElements();
6348 for (
auto &SubprogramDirect : P.second)
6349 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6350 EltTys.push_back(SubprogramDirect.getPointer());
6352 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6353 DBuilder.replaceArrays(InterfaceDecl, Elements);
6356 for (
const auto &P : ReplaceMap) {
6359 assert(Ty->isForwardDecl());
6361 auto It = TypeCache.find(P.first);
6362 assert(It != TypeCache.end());
6365 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6369 for (
const auto &P : FwdDeclReplaceMap) {
6372 llvm::Metadata *Repl;
6374 auto It = DeclCache.find(P.first);
6378 if (It == DeclCache.end())
6383 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6384 Repl = GVE->getVariable();
6390 for (
auto &RT : RetainedTypes)
6391 if (
auto MD = TypeCache[RT])
6394 DBuilder.finalize();
6399 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6400 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6401 DBuilder.retainType(DieTy);
6405 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6406 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6407 DBuilder.retainType(DieTy);
6411 if (LexicalBlockStack.empty())
6412 return llvm::DebugLoc();
6414 llvm::MDNode *
Scope = LexicalBlockStack.back();
6415 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6416 getColumnNumber(Loc),
Scope);
6419llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6423 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6424 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6425 return llvm::DINode::FlagZero;
6430 bool SupportsDWARFv4Ext =
6432 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6433 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6435 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6436 return llvm::DINode::FlagZero;
6438 return llvm::DINode::FlagAllCallsDescribed;
6449 return DBuilder.createConstantValueExpression(
6450 Val.
getFloat().bitcastToAPInt().getZExtValue());
6455 llvm::APSInt
const &ValInt = Val.
getInt();
6456 std::optional<uint64_t> ValIntOpt;
6457 if (ValInt.isUnsigned())
6458 ValIntOpt = ValInt.tryZExtValue();
6459 else if (
auto tmp = ValInt.trySExtValue())
6462 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6465 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6470CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6472 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6473 CGF.CurLexicalScope =
this;
6475 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6480 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6493#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6495 Label = "__ubsan_check_" #Name; \
6499#undef SANITIZER_CHECK
6510#define SANITIZER(NAME, ID) \
6511 case SanitizerKind::SO_##ID: \
6512 Label = "__ubsan_check_" NAME; \
6514#include "clang/Basic/Sanitizers.def"
6516 llvm_unreachable(
"unexpected sanitizer kind");
6521 for (
unsigned int i = 0; i < Label.length(); i++)
6522 if (!std::isalpha(Label[i]))
6531 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6533 if (!DI || !CheckDebugLoc)
6534 return CheckDebugLoc;
6535 const auto &AnnotateDebugInfo =
6536 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6537 if (AnnotateDebugInfo.empty())
6538 return CheckDebugLoc;
6541 if (Ordinals.size() == 1)
6546 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6547 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6549 return CheckDebugLoc;
6557 assert(!CGF->IsSanitizerScope);
6558 CGF->IsSanitizerScope =
true;
6562 assert(CGF->IsSanitizerScope);
6563 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.