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() {
654 assert(CGO.DwarfVersion <= 5);
656 llvm::dwarf::SourceLanguage LangTag;
659 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
660 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
661 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
662 else if (LO.CPlusPlus14)
663 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
664 else if (LO.CPlusPlus11)
665 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
667 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
668 }
else if (LO.ObjC) {
669 LangTag = llvm::dwarf::DW_LANG_ObjC;
670 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
671 LangTag = llvm::dwarf::DW_LANG_OpenCL;
672 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
673 LangTag = llvm::dwarf::DW_LANG_C11;
675 LangTag = llvm::dwarf::DW_LANG_C99;
677 LangTag = llvm::dwarf::DW_LANG_C89;
683static llvm::DISourceLanguageName
691 uint32_t LangVersion = 0;
692 llvm::dwarf::SourceLanguageName LangTag;
695 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
697 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
700 }
else if (LO.ObjC) {
701 LangTag = llvm::dwarf::DW_LNAME_ObjC;
702 }
else if (LO.OpenCL) {
703 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
705 LangTag = llvm::dwarf::DW_LNAME_C;
709 return llvm::DISourceLanguageName(LangTag, LangVersion);
712void CGDebugInfo::CreateCompileUnit() {
713 SmallString<64> Checksum;
714 std::optional<llvm::DIFile::ChecksumKind> CSKind;
715 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
725 SourceManager &
SM = CGM.getContext().getSourceManager();
726 auto &CGO = CGM.getCodeGenOpts();
727 const LangOptions &LO = CGM.getLangOpts();
728 std::string MainFileName = CGO.MainFileName;
729 if (MainFileName.empty())
730 MainFileName =
"<stdin>";
736 std::string MainFileDir;
738 SM.getFileEntryRefForID(
SM.getMainFileID())) {
739 MainFileDir = std::string(MainFile->getDir().getName());
740 if (!llvm::sys::path::is_absolute(MainFileName)) {
741 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
742 llvm::sys::path::Style Style =
744 ? (CGM.getTarget().getTriple().isOSWindows()
745 ? llvm::sys::path::Style::windows_backslash
746 : llvm::sys::path::Style::posix)
747 : llvm::sys::path::Style::native;
748 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
749 MainFileName = std::string(
750 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
757 if (MainFile->getName() == MainFileName &&
759 MainFile->getName().rsplit(
'.').second)
761 MainFileName = CGM.getModule().getName().str();
763 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
770 unsigned RuntimeVers = 0;
774 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
776 case llvm::codegenoptions::NoDebugInfo:
777 case llvm::codegenoptions::LocTrackingOnly:
778 EmissionKind = llvm::DICompileUnit::NoDebug;
780 case llvm::codegenoptions::DebugLineTablesOnly:
781 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
783 case llvm::codegenoptions::DebugDirectivesOnly:
784 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
786 case llvm::codegenoptions::DebugInfoConstructor:
787 case llvm::codegenoptions::LimitedDebugInfo:
788 case llvm::codegenoptions::FullDebugInfo:
789 case llvm::codegenoptions::UnusedTypeInfo:
790 EmissionKind = llvm::DICompileUnit::FullDebug;
795 auto &CGOpts = CGM.getCodeGenOpts();
801 CSInfo.emplace(*CSKind, Checksum);
802 llvm::DIFile *CUFile = DBuilder.createFile(
804 getSource(
SM,
SM.getMainFileID()));
806 StringRef Sysroot, SDK;
807 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
808 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
809 auto B = llvm::sys::path::rbegin(Sysroot);
810 auto E = llvm::sys::path::rend(Sysroot);
812 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
817 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
818 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
819 CGOpts.DebugNameTable);
820 if (CGM.getTarget().getTriple().isNVPTX())
821 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
822 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
823 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
826 TheCU = DBuilder.createCompileUnit(
828 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
829 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
830 CGOpts.PrepareForThinLTO,
831 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
832 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
833 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
836llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
840#define BUILTIN_TYPE(Id, SingletonId)
841#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
842#include "clang/AST/BuiltinTypes.def"
843 case BuiltinType::Dependent:
844 llvm_unreachable(
"Unexpected builtin type");
845 case BuiltinType::NullPtr:
846 return DBuilder.createNullPtrType();
847 case BuiltinType::Void:
849 case BuiltinType::ObjCClass:
852 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
853 "objc_class", TheCU, TheCU->getFile(), 0);
855 case BuiltinType::ObjCId: {
866 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
867 "objc_class", TheCU, TheCU->getFile(), 0);
869 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
871 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
873 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
874 (uint64_t)0, 0, llvm::DINode::FlagZero,
875 nullptr, llvm::DINodeArray());
877 DBuilder.replaceArrays(
878 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
879 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
880 llvm::DINode::FlagZero, ISATy)));
883 case BuiltinType::ObjCSel: {
885 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
886 "objc_selector", TheCU,
887 TheCU->getFile(), 0);
891#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
892 case BuiltinType::Id: \
893 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
895#include "clang/Basic/OpenCLImageTypes.def"
896 case BuiltinType::OCLSampler:
897 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
898 case BuiltinType::OCLEvent:
899 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
900 case BuiltinType::OCLClkEvent:
901 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
902 case BuiltinType::OCLQueue:
903 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
904 case BuiltinType::OCLReserveID:
905 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
906#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
907 case BuiltinType::Id: \
908 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
909#include "clang/Basic/OpenCLExtensionTypes.def"
910#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
911 case BuiltinType::Id: \
912 return getOrCreateStructPtrType(#Name, SingletonId);
913#include "clang/Basic/HLSLIntangibleTypes.def"
915#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
916#include "clang/Basic/AArch64ACLETypes.def"
918 if (BT->
getKind() == BuiltinType::MFloat8) {
919 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
920 BTName = BT->
getName(CGM.getLangOpts());
923 return DBuilder.createBasicType(BTName, Size, Encoding);
925 ASTContext::BuiltinVectorTypeInfo Info =
927 BT->
getKind() == BuiltinType::SveCount
928 ? ASTContext::BuiltinVectorTypeInfo(
929 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
931 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
938 "Unsupported number of vectors for svcount_t");
940 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
941 llvm::Metadata *BitStride =
nullptr;
942 if (BT->
getKind() == BuiltinType::SveBool) {
943 Info.
ElementType = CGM.getContext().UnsignedCharTy;
944 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
945 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
946 }
else if (BT->
getKind() == BuiltinType::SveCount) {
948 Info.
ElementType = CGM.getContext().UnsignedCharTy;
951 llvm::Metadata *LowerBound, *UpperBound;
952 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
953 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
954 if (Info.
EC.isScalable()) {
955 unsigned NumElemsPerVG = NumElems / 2;
956 SmallVector<uint64_t, 9> Expr(
957 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
958 46, 0, llvm::dwarf::DW_OP_mul,
959 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
960 UpperBound = DBuilder.createExpression(Expr);
962 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
963 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
965 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
966 nullptr, LowerBound, UpperBound,
nullptr);
967 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
968 llvm::DIType *ElemTy =
969 getOrCreateType(Info.
ElementType, TheCU->getFile());
971 return DBuilder.createVectorType( 0, Align, ElemTy,
972 SubscriptArray, BitStride);
976#define PPC_VECTOR_TYPE(Name, Id, size) \
977 case BuiltinType::Id:
978#include "clang/Basic/PPCTypes.def"
981#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
982#include "clang/Basic/RISCVVTypes.def"
984 ASTContext::BuiltinVectorTypeInfo Info =
985 CGM.getContext().getBuiltinVectorTypeInfo(BT);
987 unsigned ElementCount = Info.
EC.getKnownMinValue();
988 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
990 bool Fractional =
false;
993 unsigned FixedSize = ElementCount * SEW;
997 }
else if (FixedSize < 64) {
1000 LMUL = 64 / FixedSize;
1002 LMUL = FixedSize / 64;
1006 SmallVector<uint64_t, 12> Expr(
1010 {llvm::dwarf::DW_OP_bregx,
1013 llvm::dwarf::DW_OP_constu,
1015 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1017 Expr.push_back(llvm::dwarf::DW_OP_div);
1019 Expr.push_back(llvm::dwarf::DW_OP_mul);
1022 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1024 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1027 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1028 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1029 auto *UpperBound = DBuilder.createExpression(Expr);
1030 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1031 nullptr, LowerBound, UpperBound,
nullptr);
1032 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1033 llvm::DIType *ElemTy =
1034 getOrCreateType(Info.
ElementType, TheCU->getFile());
1037 return DBuilder.createVectorType(0, Align, ElemTy,
1041#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1042 case BuiltinType::Id: { \
1045 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1046 MangledName, TheCU, TheCU->getFile(), 0); \
1047 return SingletonId; \
1049#include "clang/Basic/WebAssemblyReferenceTypes.def"
1050#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1051 case BuiltinType::Id: { \
1054 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1055 TheCU, TheCU->getFile(), 0); \
1056 return SingletonId; \
1058#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1059 case BuiltinType::Id: { \
1062 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1063 return SingletonId; \
1065#include "clang/Basic/AMDGPUTypes.def"
1066 case BuiltinType::UChar:
1067 case BuiltinType::Char_U:
1068 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1070 case BuiltinType::Char_S:
1071 case BuiltinType::SChar:
1072 Encoding = llvm::dwarf::DW_ATE_signed_char;
1074 case BuiltinType::Char8:
1075 case BuiltinType::Char16:
1076 case BuiltinType::Char32:
1077 Encoding = llvm::dwarf::DW_ATE_UTF;
1079 case BuiltinType::UShort:
1080 case BuiltinType::UInt:
1081 case BuiltinType::UInt128:
1082 case BuiltinType::ULong:
1083 case BuiltinType::WChar_U:
1084 case BuiltinType::ULongLong:
1085 Encoding = llvm::dwarf::DW_ATE_unsigned;
1087 case BuiltinType::Short:
1088 case BuiltinType::Int:
1089 case BuiltinType::Int128:
1090 case BuiltinType::Long:
1091 case BuiltinType::WChar_S:
1092 case BuiltinType::LongLong:
1093 Encoding = llvm::dwarf::DW_ATE_signed;
1095 case BuiltinType::Bool:
1096 Encoding = llvm::dwarf::DW_ATE_boolean;
1098 case BuiltinType::Half:
1099 case BuiltinType::Float:
1100 case BuiltinType::LongDouble:
1101 case BuiltinType::Float16:
1102 case BuiltinType::BFloat16:
1103 case BuiltinType::Float128:
1104 case BuiltinType::Double:
1105 case BuiltinType::Ibm128:
1111 Encoding = llvm::dwarf::DW_ATE_float;
1113 case BuiltinType::ShortAccum:
1114 case BuiltinType::Accum:
1115 case BuiltinType::LongAccum:
1116 case BuiltinType::ShortFract:
1117 case BuiltinType::Fract:
1118 case BuiltinType::LongFract:
1119 case BuiltinType::SatShortFract:
1120 case BuiltinType::SatFract:
1121 case BuiltinType::SatLongFract:
1122 case BuiltinType::SatShortAccum:
1123 case BuiltinType::SatAccum:
1124 case BuiltinType::SatLongAccum:
1125 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1127 case BuiltinType::UShortAccum:
1128 case BuiltinType::UAccum:
1129 case BuiltinType::ULongAccum:
1130 case BuiltinType::UShortFract:
1131 case BuiltinType::UFract:
1132 case BuiltinType::ULongFract:
1133 case BuiltinType::SatUShortAccum:
1134 case BuiltinType::SatUAccum:
1135 case BuiltinType::SatULongAccum:
1136 case BuiltinType::SatUShortFract:
1137 case BuiltinType::SatUFract:
1138 case BuiltinType::SatULongFract:
1139 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1143 BTName = BT->
getName(CGM.getLangOpts());
1146 return DBuilder.createBasicType(BTName, Size, Encoding);
1149llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1151 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1153 ? llvm::dwarf::DW_ATE_unsigned
1154 : llvm::dwarf::DW_ATE_signed;
1156 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1160llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1162 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1164 Encoding = llvm::dwarf::DW_ATE_lo_user;
1167 return DBuilder.createBasicType(
"complex", Size, Encoding);
1181 return llvm::dwarf::DW_TAG_const_type;
1185 return llvm::dwarf::DW_TAG_volatile_type;
1189 return llvm::dwarf::DW_TAG_restrict_type;
1191 return (llvm::dwarf::Tag)0;
1194llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1195 llvm::DIFile *Unit) {
1196 QualifierCollector Qc;
1210 bool AuthenticatesNullValues =
1213 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1214 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1215 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1216 ExtraDiscr, IsaPointer,
1217 AuthenticatesNullValues);
1219 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1220 return getOrCreateType(QualType(
T, 0), Unit);
1224 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1228 return DBuilder.createQualifiedType(Tag, FromTy);
1231llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1232 llvm::DIFile *Unit) {
1241 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1246 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1252 return DBuilder.createQualifiedType(Tag, FromTy);
1255llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1256 llvm::DIFile *Unit) {
1262 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1264 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1268llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1269 llvm::DIFile *Unit) {
1270 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1276 case llvm::dwarf::DW_LANG_C_plus_plus:
1277 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1278 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1280 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1290 case llvm::dwarf::DW_LNAME_C_plus_plus:
1292 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1303 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1304 SourceLang.hasVersionedName())
1306 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1310 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1336 llvm::DICompileUnit *TheCU) {
1354 llvm::DICompileUnit *TheCU) {
1360 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1362 if (RD->isDynamicClass() &&
1368 llvm::raw_svector_ostream Out(Identifier);
1375 llvm::dwarf::Tag Tag;
1377 Tag = llvm::dwarf::DW_TAG_structure_type;
1379 Tag = llvm::dwarf::DW_TAG_union_type;
1384 Tag = llvm::dwarf::DW_TAG_class_type;
1389llvm::DICompositeType *
1390CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1391 llvm::DIScope *Ctx) {
1392 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1393 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1395 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1396 const unsigned Line =
1398 StringRef RDName = getClassName(RD);
1405 Size = CGM.getContext().getTypeSize(Ty);
1407 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1412 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1413 if (!CXXRD->hasDefinition() ||
1414 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1415 Flags |= llvm::DINode::FlagNonTrivial;
1418 SmallString<256> Identifier;
1420 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1422 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1425 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1426 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1427 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1428 CollectCXXTemplateParams(TSpecial, DefUnit));
1429 ReplaceMap.emplace_back(
1430 std::piecewise_construct, std::make_tuple(Ty),
1431 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1435llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1438 llvm::DIFile *Unit) {
1443 std::optional<unsigned> DWARFAddressSpace =
1444 CGM.getTarget().getDWARFAddressSpace(
1445 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1447 const BTFTagAttributedType *BTFAttrTy;
1448 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1449 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1451 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1452 SmallVector<llvm::Metadata *, 4> Annots;
1454 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1456 llvm::Metadata *Ops[2] = {
1457 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1458 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1459 Annots.insert(Annots.begin(),
1460 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1462 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1465 llvm::DINodeArray Annotations =
nullptr;
1466 if (Annots.size() > 0)
1467 Annotations = DBuilder.getOrCreateArray(Annots);
1469 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1470 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1471 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1472 Size, Align, DWARFAddressSpace);
1474 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1475 Align, DWARFAddressSpace, StringRef(),
1479llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1480 llvm::DIType *&
Cache) {
1483 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1484 TheCU, TheCU->getFile(), 0);
1485 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1486 Cache = DBuilder.createPointerType(
Cache, Size);
1490uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1491 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1492 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1502 if (CGM.getLangOpts().OpenCL) {
1503 FType = CGM.getContext().IntTy;
1504 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1505 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1507 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1508 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1509 FType = CGM.getContext().IntTy;
1510 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1511 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1513 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1514 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1515 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1516 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1517 EltTys.push_back(DBuilder.createMemberType(
1518 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1519 FieldOffset, llvm::DINode::FlagZero, DescTy));
1520 FieldOffset += FieldSize;
1526llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1527 llvm::DIFile *Unit) {
1528 SmallVector<llvm::Metadata *, 8> EltTys;
1531 llvm::DINodeArray Elements;
1534 FType = CGM.getContext().UnsignedLongTy;
1535 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1536 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1538 Elements = DBuilder.getOrCreateArray(EltTys);
1541 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1544 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1545 FieldOffset, 0, Flags,
nullptr, Elements);
1550 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1552 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1555 Elements = DBuilder.getOrCreateArray(EltTys);
1561 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1562 Flags,
nullptr, Elements);
1564 return DBuilder.createPointerType(EltTy, Size);
1567static llvm::SmallVector<TemplateArgument>
1569 assert(Ty->isTypeAlias());
1578 ArrayRef SubstArgs = Ty->template_arguments();
1581 if (Param->isParameterPack()) {
1590 if (SubstArgs.empty()) {
1599 SpecArgs.push_back(SubstArgs.front());
1600 SubstArgs = SubstArgs.drop_front();
1605llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1606 llvm::DIFile *Unit) {
1607 assert(Ty->isTypeAlias());
1608 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1610 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1618 SmallString<128> NS;
1619 llvm::raw_svector_ostream
OS(NS);
1621 auto PP = getPrintingPolicy();
1624 SourceLocation Loc =
AliasDecl->getLocation();
1626 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1627 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1636 llvm::raw_string_ostream
OS(Name);
1638 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1639 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1640 !HasReconstitutableArgs(Args.Args))
1641 printTemplateArgumentList(OS, Args.Args, PP);
1643 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1644 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1645 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1649 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1651 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1668 return llvm::DINode::FlagZero;
1672 return llvm::DINode::FlagPrivate;
1674 return llvm::DINode::FlagProtected;
1676 return llvm::DINode::FlagPublic;
1678 return llvm::DINode::FlagZero;
1680 llvm_unreachable(
"unexpected access enumerator");
1683llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1684 llvm::DIFile *Unit) {
1685 llvm::DIType *Underlying =
1697 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1699 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1704 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1705 getOrCreateFile(Loc), getLineNumber(Loc),
1706 getDeclContextDescriptor(Ty->
getDecl()), Align,
1707 Flags, Annotations);
1717 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1719 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1721 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1723 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1725 return llvm::dwarf::DW_CC_BORLAND_pascal;
1727 return llvm::dwarf::DW_CC_LLVM_Win64;
1729 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1733 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1735 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1737 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1739 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1741 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1743 return llvm::dwarf::DW_CC_LLVM_Swift;
1745 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1747 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1749 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1751 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1753 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1755 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1757 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1758#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1772 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1778 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1780 Flags |= llvm::DINode::FlagLValueReference;
1782 Flags |= llvm::DINode::FlagRValueReference;
1786llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1787 llvm::DIFile *Unit) {
1788 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1790 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1796 SmallVector<llvm::Metadata *, 16> EltTys;
1799 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1801 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1805 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1808 for (
const QualType &ParamType : FPT->param_types())
1809 EltTys.push_back(getOrCreateType(ParamType, Unit));
1810 if (FPT->isVariadic())
1811 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1814 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1815 llvm::DIType *F = DBuilder.createSubroutineType(
1820llvm::DIDerivedType *
1821CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1822 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1823 StringRef Name = BitFieldDecl->
getName();
1824 QualType Ty = BitFieldDecl->
getType();
1825 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1828 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1829 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1832 llvm::DIFile *
File = getOrCreateFile(Loc);
1833 unsigned Line = getLineNumber(Loc);
1835 const CGBitFieldInfo &BitFieldInfo =
1836 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1838 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1845 if (CGM.getDataLayout().isBigEndian())
1847 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1849 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1850 return DBuilder.createBitFieldMemberType(
1851 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1852 Flags, DebugType, Annotations);
1855llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1856 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1857 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1859 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1884 if (PreviousFieldsDI.empty())
1888 auto *PreviousMDEntry =
1889 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1890 auto *PreviousMDField =
1891 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1892 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1893 PreviousMDField->getSizeInBits() == 0)
1897 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1899 assert(PreviousBitfield->isBitField());
1901 if (!PreviousBitfield->isZeroLengthBitField())
1904 QualType Ty = PreviousBitfield->getType();
1905 SourceLocation Loc = PreviousBitfield->getLocation();
1906 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1907 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1908 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1910 llvm::DIFile *
File = getOrCreateFile(Loc);
1911 unsigned Line = getLineNumber(Loc);
1917 llvm::DINode::DIFlags Flags =
1919 llvm::DINodeArray Annotations =
1920 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1921 return DBuilder.createBitFieldMemberType(
1922 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1923 Flags, DebugType, Annotations);
1926llvm::DIType *CGDebugInfo::createFieldType(
1928 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1929 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1930 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1933 llvm::DIFile *file = getOrCreateFile(loc);
1934 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1937 auto Align = AlignInBits;
1938 if (!
type->isIncompleteArrayType()) {
1939 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1940 SizeInBits = TI.
Width;
1946 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1947 offsetInBits, flags, debugType, Annotations);
1951CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1952 llvm::DIFile *FileScope) {
1956 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1959 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1960 SP = DBuilder.createFunction(
1961 FileScope, FuncName, StringRef(),
1962 FileScope, 0, DIFnTy,
1964 llvm::DINode::FlagArtificial,
1965 llvm::DISubprogram::SPFlagDefinition,
1966 nullptr,
nullptr,
nullptr,
1967 nullptr, StringRef(),
1968 CGM.getCodeGenOpts().DebugKeyInstructions);
1975CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
1977 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
1979 assert(
Capture.capturesVariable());
1981 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
1982 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
1984 return CaptureDecl->
getName();
1987void CGDebugInfo::CollectRecordLambdaFields(
1988 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
1989 llvm::DIType *RecordTy) {
1994 unsigned fieldno = 0;
1997 I != E; ++I, ++Field, ++fieldno) {
1998 const LambdaCapture &
Capture = *I;
2000 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2002 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2012 Loc =
Field->getLocation();
2013 }
else if (
Capture.capturesVariable()) {
2016 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2017 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2024 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2026 elements.push_back(createFieldType(
2028 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2032llvm::DIDerivedType *
2033CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2034 const RecordDecl *RD) {
2038 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2039 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2041 unsigned LineNumber = getLineNumber(Var->
getLocation());
2042 StringRef VName = Var->
getName();
2046 llvm::Constant *
C =
nullptr;
2051 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2052 if (
Value->isFloat())
2053 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2058 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2059 ? llvm::dwarf::DW_TAG_variable
2060 : llvm::dwarf::DW_TAG_member;
2062 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2063 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2068void CGDebugInfo::CollectRecordNormalField(
2069 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2070 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2071 const RecordDecl *RD) {
2076 if (
name.empty() && !
type->isRecordType())
2079 llvm::DIType *FieldType;
2081 llvm::DIDerivedType *BitFieldType;
2082 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2083 if (llvm::DIType *Separator =
2084 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2085 elements.push_back(Separator);
2088 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2091 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2094 elements.push_back(FieldType);
2097void CGDebugInfo::CollectRecordNestedType(
2098 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2099 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2106 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2107 elements.push_back(nestedType);
2110void CGDebugInfo::CollectRecordFields(
2111 const RecordDecl *record, llvm::DIFile *tunit,
2112 SmallVectorImpl<llvm::Metadata *> &elements,
2113 llvm::DICompositeType *RecordTy) {
2114 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2116 if (CXXDecl && CXXDecl->
isLambda())
2117 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2119 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2122 unsigned fieldNo = 0;
2126 for (
const auto *I : record->
decls())
2127 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2128 if (
V->hasAttr<NoDebugAttr>())
2133 if (CGM.getCodeGenOpts().EmitCodeView &&
2141 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2142 if (MI != StaticDataMemberCache.end()) {
2143 assert(MI->second &&
2144 "Static data member declaration should still exist");
2145 elements.push_back(MI->second);
2147 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2148 elements.push_back(Field);
2150 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2151 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2152 elements, RecordTy, record);
2156 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2159 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2164 if (!nestedType->isImplicit() &&
2165 nestedType->getDeclContext() == record)
2166 CollectRecordNestedType(nestedType, elements);
2172llvm::DISubroutineType *
2173CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2174 llvm::DIFile *Unit) {
2175 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2177 return cast_or_null<llvm::DISubroutineType>(
2178 getOrCreateType(QualType(
Func, 0), Unit));
2181 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2182 ThisType =
Method->getThisType();
2184 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2187llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2188 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2189 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2191 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2194llvm::DISubroutineType *
2195CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2196 const FunctionProtoType *
Func,
2197 llvm::DIFile *Unit,
bool SkipFirst) {
2198 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2213 getOrCreateType(CGM.getContext().getFunctionType(
2214 Func->getReturnType(),
Func->getParamTypes(), EPI),
2216 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2217 assert(Args.size() &&
"Invalid number of arguments!");
2219 SmallVector<llvm::Metadata *, 16> Elts;
2222 Elts.push_back(Args[0]);
2224 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2228 if (!HasExplicitObjectParameter) {
2229 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2232 DBuilder.createObjectPointerType(ThisPtrType,
true);
2233 Elts.push_back(ThisPtrType);
2237 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2238 Elts.push_back(Args[i]);
2241 if (HasExplicitObjectParameter) {
2242 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2243 "Expected at least return type and object parameter.");
2244 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2247 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2249 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2256 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2264CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2267 const bool IsCtorOrDtor =
2270 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2277 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2280 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2283 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2286 return CGM.getMangledName(
Method);
2289llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2290 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2293 StringRef MethodName = getFunctionName(
Method);
2294 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2296 StringRef MethodLinkageName;
2303 MethodLinkageName = GetMethodLinkageName(
Method);
2306 llvm::DIFile *MethodDefUnit =
nullptr;
2307 unsigned MethodLine = 0;
2308 if (!
Method->isImplicit()) {
2309 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2310 MethodLine = getLineNumber(
Method->getLocation());
2314 llvm::DIType *ContainingType =
nullptr;
2315 unsigned VIndex = 0;
2316 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2317 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2318 int ThisAdjustment = 0;
2321 if (
Method->isPureVirtual())
2322 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2324 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2326 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2330 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2334 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2336 MethodVFTableLocation ML =
2337 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2345 if (
Method->size_overridden_methods() == 0)
2346 Flags |= llvm::DINode::FlagIntroducedVirtual;
2351 ThisAdjustment = CGM.getCXXABI()
2352 .getVirtualFunctionPrologueThisAdjustment(GD)
2355 ContainingType = RecordTy;
2358 if (
Method->getCanonicalDecl()->isDeleted())
2359 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2361 if (
Method->isNoReturn())
2362 Flags |= llvm::DINode::FlagNoReturn;
2365 Flags |= llvm::DINode::FlagStaticMember;
2366 if (
Method->isImplicit())
2367 Flags |= llvm::DINode::FlagArtificial;
2369 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2370 if (CXXC->isExplicit())
2371 Flags |= llvm::DINode::FlagExplicit;
2372 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2373 if (CXXC->isExplicit())
2374 Flags |= llvm::DINode::FlagExplicit;
2376 if (
Method->hasPrototype())
2377 Flags |= llvm::DINode::FlagPrototyped;
2379 Flags |= llvm::DINode::FlagLValueReference;
2381 Flags |= llvm::DINode::FlagRValueReference;
2382 if (!
Method->isExternallyVisible())
2383 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2384 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2385 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2389 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2390 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2393 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2394 llvm::DISubprogram *SP = DBuilder.createMethod(
2395 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2396 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2397 TParamsArray.get(),
nullptr,
2398 CGM.getCodeGenOpts().DebugKeyInstructions);
2400 SPCache[
Method->getCanonicalDecl()].reset(SP);
2405void CGDebugInfo::CollectCXXMemberFunctions(
2406 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2407 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2412 for (
const auto *I : RD->
decls()) {
2413 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2427 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2436 auto MI = SPCache.find(
Method->getCanonicalDecl());
2437 EltTys.push_back(MI == SPCache.end()
2438 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2439 :
static_cast<llvm::Metadata *
>(MI->second));
2443void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2444 SmallVectorImpl<llvm::Metadata *> &EltTys,
2445 llvm::DIType *RecordTy) {
2446 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2447 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2448 llvm::DINode::FlagZero);
2452 if (CGM.getCodeGenOpts().EmitCodeView) {
2453 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2454 llvm::DINode::FlagIndirectVirtualBase);
2458void CGDebugInfo::CollectCXXBasesAux(
2459 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2460 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2462 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2463 llvm::DINode::DIFlags StartingFlags) {
2464 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2465 for (
const auto &BI : Bases) {
2468 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2470 if (!SeenTypes.insert(Base).second)
2472 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2473 llvm::DINode::DIFlags BFlags = StartingFlags;
2477 if (BI.isVirtual()) {
2478 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2481 BaseOffset = 0 - CGM.getItaniumVTableContext()
2482 .getVirtualBaseOffsetOffset(RD, Base)
2488 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2489 VBPtrOffset = CGM.getContext()
2490 .getASTRecordLayout(RD)
2494 BFlags |= llvm::DINode::FlagVirtual;
2501 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2502 VBPtrOffset, BFlags);
2503 EltTys.push_back(DTy);
2508CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2509 llvm::DIFile *Unit) {
2511 return llvm::DINodeArray();
2512 TemplateArgs &Args = *OArgs;
2513 SmallVector<llvm::Metadata *, 16> TemplateParams;
2514 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2515 const TemplateArgument &TA = Args.Args[i];
2519 Name = Args.TList->getParam(i)->getName();
2523 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2524 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2525 TheCU, Name, TTy, defaultParameter));
2530 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2531 TheCU, Name, TTy, defaultParameter,
2532 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2537 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2538 llvm::Constant *
V =
nullptr;
2541 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2542 !D->
hasAttr<CUDADeviceAttr>()) {
2545 if (
const auto *VD = dyn_cast<VarDecl>(D))
2546 V = CGM.GetAddrOfGlobalVar(VD);
2549 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2550 MD && MD->isImplicitObjectMemberFunction())
2551 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2552 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2553 V = CGM.GetAddrOfFunction(FD);
2556 else if (
const auto *MPT =
2557 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2561 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2563 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2564 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2565 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2566 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2567 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2569 V = ConstantEmitter(CGM).emitAbstract(
2570 SourceLocation(), TPO->getValue(), TPO->getType());
2572 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2574 assert(
V &&
"Failed to find template parameter pointer");
2575 V =
V->stripPointerCasts();
2577 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2578 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2582 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2583 llvm::Constant *
V =
nullptr;
2586 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2592 if (MPT->isMemberDataPointer())
2593 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2595 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2596 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2597 TheCU, Name, TTy, defaultParameter,
V));
2601 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2602 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2604 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2605 TheCU, Name, TTy, defaultParameter,
V));
2608 std::string QualName;
2609 llvm::raw_string_ostream
OS(QualName);
2611 OS, getPrintingPolicy());
2612 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2613 TheCU, Name,
nullptr, QualName, defaultParameter));
2617 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2618 TheCU, Name,
nullptr,
2625 T = CGM.getContext().getLValueReferenceType(
T);
2626 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2627 assert(
V &&
"Expression in template argument isn't constant");
2628 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2629 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2630 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2636 "These argument types shouldn't exist in concrete types");
2639 return DBuilder.getOrCreateArray(TemplateParams);
2642std::optional<CGDebugInfo::TemplateArgs>
2643CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2651 return std::nullopt;
2653std::optional<CGDebugInfo::TemplateArgs>
2654CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2658 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2660 return std::nullopt;
2661 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2662 const TemplateParameterList *TList =
T->getTemplateParameters();
2663 auto TA = TS->getTemplateArgs().asArray();
2664 return {{TList, TA}};
2666std::optional<CGDebugInfo::TemplateArgs>
2667CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2668 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2672 TemplateParameterList *TPList =
2673 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2674 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2675 return {{TPList, TAList.
asArray()}};
2677 return std::nullopt;
2681CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2682 llvm::DIFile *Unit) {
2683 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2686llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2687 llvm::DIFile *Unit) {
2688 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2691llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2692 llvm::DIFile *Unit) {
2693 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2696llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2697 if (!D->
hasAttr<BTFDeclTagAttr>())
2700 SmallVector<llvm::Metadata *, 4> Annotations;
2702 llvm::Metadata *Ops[2] = {
2703 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2704 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2705 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2707 return DBuilder.getOrCreateArray(Annotations);
2710llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2712 return VTablePtrType;
2714 ASTContext &Context = CGM.getContext();
2717 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2718 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2719 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2721 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2722 std::optional<unsigned> DWARFAddressSpace =
2723 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2725 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2726 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2727 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2728 return VTablePtrType;
2731StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2743 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2745 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2755 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2756 VTable->isDeclarationForLinker())
2760 StringRef SymbolName =
"_vtable$";
2762 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2771 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2773 llvm::DIFile *Unit = getOrCreateFile(Loc);
2774 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2776 llvm::DINode::FlagArtificial;
2777 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2778 ? llvm::dwarf::DW_TAG_variable
2779 : llvm::dwarf::DW_TAG_member;
2780 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2781 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2785 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2789 llvm::DIGlobalVariableExpression *GVE =
2790 DBuilder.createGlobalVariableExpression(
2791 TheCU, SymbolName, VTable->getName(), Unit, 0,
2792 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2793 true,
nullptr, DT,
nullptr,
2795 VTable->addDebugInfo(GVE);
2798StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2800 llvm::Function *InitFn) {
2805 return InitFn->getName();
2815 llvm::raw_svector_ostream OS(QualifiedGV);
2817 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2819 std::swap(Quals, GVName);
2823 llvm::raw_svector_ostream OS(InitName);
2825 OS << Quals <<
"::";
2830 llvm_unreachable(
"not an initializer");
2832 OS <<
"`dynamic initializer for '";
2835 OS <<
"`dynamic atexit destructor for '";
2842 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2843 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2844 getPrintingPolicy());
2849 return internString(
OS.str());
2852void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2853 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2862 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2869 llvm::DIType *VPtrTy =
nullptr;
2870 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2871 CGM.getTarget().getCXXABI().isMicrosoft();
2872 if (NeedVTableShape) {
2874 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2875 const VTableLayout &VFTLayout =
2876 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2877 unsigned VSlotCount =
2879 unsigned VTableWidth = PtrWidth * VSlotCount;
2880 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2881 std::optional<unsigned> DWARFAddressSpace =
2882 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2885 llvm::DIType *VTableType = DBuilder.createPointerType(
2886 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2887 EltTys.push_back(VTableType);
2890 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2898 VPtrTy = getOrCreateVTablePtrType(Unit);
2900 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2901 llvm::DIType *VPtrMember =
2902 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2903 llvm::DINode::FlagArtificial, VPtrTy);
2904 EltTys.push_back(VPtrMember);
2909 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2910 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2921 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2922 assert(!D.
isNull() &&
"null type");
2923 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2924 assert(
T &&
"could not create debug info for type");
2933 if (CGM.getCodeGenOpts().getDebugInfo() <=
2934 llvm::codegenoptions::DebugLineTablesOnly)
2938 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2940 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2942 CI->setMetadata(
"heapallocsite", node);
2946 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2948 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2950 auto I = TypeCache.find(TyPtr);
2953 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2954 assert(!Res->isForwardDecl());
2955 TypeCache[TyPtr].reset(Res);
2959 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2960 !CGM.getLangOpts().CPlusPlus)
2966 if (RD->
hasAttr<DLLImportAttr>())
2969 if (MD->hasAttr<DLLImportAttr>())
2982 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2992 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2993 Explicit = TD->isExplicitInstantiationOrSpecialization();
2997 if (CXXDecl->
fields().empty())
3007 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3008 if (CXXRD->isDynamicClass() &&
3009 CGM.getVTableLinkage(CXXRD) ==
3010 llvm::GlobalValue::AvailableExternallyLinkage &&
3021 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3023 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3025 auto I = TypeCache.find(TyPtr);
3032 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3033 assert(!Res->isForwardDecl());
3034 TypeCache[TyPtr].reset(Res);
3041 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3042 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3065 if (Ctor->isCopyOrMoveConstructor())
3067 if (!Ctor->isDeleted())
3086 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3089 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3090 RD->
hasAttr<StandaloneDebugAttr>())
3093 if (!LangOpts.CPlusPlus)
3099 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3115 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3116 Spec = SD->getSpecializationKind();
3125 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3136 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3137 llvm::DIType *
T = getTypeOrNull(Ty);
3138 if (
T &&
T->isForwardDecl())
3142llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3143 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3144 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3148 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3152 auto [Def, Pref] = CreateTypeDefinition(Ty);
3154 return Pref ? Pref : Def;
3157llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3158 llvm::DIFile *Unit) {
3162 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3166 return getOrCreateType(PNA->getTypedefType(), Unit);
3169std::pair<llvm::DIType *, llvm::DIType *>
3170CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3171 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3174 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3182 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3186 return {FwdDecl,
nullptr};
3188 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3189 CollectContainingType(CXXDecl, FwdDecl);
3192 LexicalBlockStack.emplace_back(&*FwdDecl);
3193 RegionMap[RD].reset(FwdDecl);
3196 SmallVector<llvm::Metadata *, 16> EltTys;
3203 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3205 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3206 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3210 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3211 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3212 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3214 LexicalBlockStack.pop_back();
3215 RegionMap.erase(RD);
3217 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3218 DBuilder.replaceArrays(FwdDecl, Elements);
3220 if (FwdDecl->isTemporary())
3222 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3224 RegionMap[RD].reset(FwdDecl);
3226 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3227 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3228 return {FwdDecl, PrefDI};
3230 return {FwdDecl,
nullptr};
3233llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3234 llvm::DIFile *Unit) {
3236 return getOrCreateType(Ty->getBaseType(), Unit);
3239llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3240 llvm::DIFile *Unit) {
3242 SourceLocation Loc = Ty->getDecl()->getLocation();
3245 return DBuilder.createTypedef(
3246 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3247 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3248 getDeclContextDescriptor(Ty->getDecl()));
3275llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3276 llvm::DIFile *Unit) {
3281 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3282 TheCU->getSourceLanguage().getUnversionedName());
3287 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3288 !
ID->getImplementation())
3289 return DBuilder.createForwardDecl(
3290 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3291 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3294 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3295 unsigned Line = getLineNumber(
ID->getLocation());
3299 ObjCInterfaceDecl *Def =
ID->getDefinition();
3301 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3302 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3303 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3304 DefUnit,
Line, RuntimeLang);
3305 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3309 return CreateTypeDefinition(Ty, Unit);
3312llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3313 bool CreateSkeletonCU) {
3318 auto ModRef = ModuleCache.find(M);
3319 if (ModRef != ModuleCache.end())
3323 SmallString<128> ConfigMacros;
3325 llvm::raw_svector_ostream
OS(ConfigMacros);
3326 const auto &PPOpts = CGM.getPreprocessorOpts();
3329 for (
auto &M : PPOpts.Macros) {
3332 const std::string &
Macro = M.first;
3333 bool Undef = M.second;
3334 OS <<
"\"-" << (Undef ?
'U' :
'D');
3350 bool IsRootModule = M ? !M->
Parent :
true;
3354 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3355 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3356 "clang module without ASTFile must be specified by -fmodule-name");
3359 auto RemapPath = [
this](StringRef Path) -> std::string {
3361 StringRef Relative(Remapped);
3362 StringRef CompDir = TheCU->getDirectory();
3363 if (CompDir.empty())
3366 if (Relative.consume_front(CompDir))
3367 Relative.consume_front(llvm::sys::path::get_separator());
3369 return Relative.str();
3372 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3379 Signature = ModSig.truncatedValue();
3383 llvm::DIBuilder DIB(CGM.getModule());
3385 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3386 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3387 PCM = getCurrentDirname();
3391 llvm::sys::path::append(PCM, Mod.
getASTFile());
3392 DIB.createCompileUnit(
3393 TheCU->getSourceLanguage(),
3396 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3397 llvm::DICompileUnit::FullDebug, Signature);
3401 llvm::DIModule *Parent =
3403 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3405 std::string IncludePath = Mod.
getPath().str();
3406 llvm::DIModule *DIMod =
3407 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3408 RemapPath(IncludePath));
3409 ModuleCache[M].reset(DIMod);
3413llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3414 llvm::DIFile *Unit) {
3416 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3417 unsigned Line = getLineNumber(
ID->getLocation());
3419 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3425 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3426 if (
ID->getImplementation())
3427 Flags |= llvm::DINode::FlagObjcClassComplete;
3429 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3430 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3431 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3432 nullptr, llvm::DINodeArray(), RuntimeLang);
3434 QualType QTy(Ty, 0);
3435 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3438 LexicalBlockStack.emplace_back(RealDecl);
3439 RegionMap[Ty->
getDecl()].reset(RealDecl);
3442 SmallVector<llvm::Metadata *, 16> EltTys;
3444 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3446 llvm::DIType *SClassTy =
3447 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3451 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3452 llvm::DINode::FlagZero);
3453 EltTys.push_back(InhTag);
3457 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3458 SourceLocation Loc = PD->getLocation();
3459 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3460 unsigned PLine = getLineNumber(Loc);
3461 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3462 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3463 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3464 PD->getName(), PUnit, PLine,
3466 : getSelectorName(PD->getGetterName()),
3468 : getSelectorName(PD->getSetterName()),
3469 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3470 EltTys.push_back(PropertyNode);
3475 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3479 llvm::DenseSet<IsClassAndIdent> PropertySet;
3481 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3482 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3484 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3485 for (
auto *PD : ClassExt->properties()) {
3486 PropertySet.insert(GetIsClassAndIdent(PD));
3489 for (
const auto *PD :
ID->properties()) {
3492 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3498 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3499 unsigned FieldNo = 0;
3500 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3501 Field =
Field->getNextIvar(), ++FieldNo) {
3502 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3506 StringRef FieldName =
Field->getName();
3509 if (FieldName.empty())
3513 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3514 unsigned FieldLine = getLineNumber(
Field->getLocation());
3515 QualType FType =
Field->getType();
3522 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3523 : CGM.getContext().getTypeSize(FType);
3528 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3532 if (
Field->isBitField()) {
3534 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3535 FieldOffset %= CGM.getContext().getCharWidth();
3543 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3545 Flags = llvm::DINode::FlagProtected;
3547 Flags = llvm::DINode::FlagPrivate;
3549 Flags = llvm::DINode::FlagPublic;
3551 if (
Field->isBitField())
3552 Flags |= llvm::DINode::FlagBitField;
3554 llvm::MDNode *PropertyNode =
nullptr;
3555 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3556 if (ObjCPropertyImplDecl *PImpD =
3557 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3558 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3559 SourceLocation Loc = PD->getLocation();
3560 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3561 unsigned PLine = getLineNumber(Loc);
3562 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3563 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3564 PropertyNode = DBuilder.createObjCProperty(
3565 PD->getName(), PUnit, PLine,
3568 : getSelectorName(PD->getGetterName()),
3571 : getSelectorName(PD->getSetterName()),
3572 PD->getPropertyAttributes(),
3573 getOrCreateType(PD->getType(), PUnit));
3577 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3578 FieldSize, FieldAlign, FieldOffset, Flags,
3579 FieldTy, PropertyNode);
3580 EltTys.push_back(FieldTy);
3583 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3584 DBuilder.replaceArrays(RealDecl, Elements);
3586 LexicalBlockStack.pop_back();
3590llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3591 llvm::DIFile *Unit) {
3599 auto &Ctx = CGM.getContext();
3604 QualType CharVecTy =
3606 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3609 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3612 llvm::Metadata *Subscript;
3613 QualType QTy(Ty, 0);
3614 auto SizeExpr = SizeExprCache.find(QTy);
3615 if (SizeExpr != SizeExprCache.end())
3616 Subscript = DBuilder.getOrCreateSubrange(
3617 SizeExpr->getSecond() ,
nullptr ,
3618 nullptr ,
nullptr );
3621 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3622 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3623 Subscript = DBuilder.getOrCreateSubrange(
3624 CountNode ,
nullptr ,
nullptr ,
3627 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3632 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3635llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3636 llvm::DIFile *Unit) {
3640 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3645 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3646 auto *ColumnCountNode =
3647 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3648 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3649 auto *RowCountNode =
3650 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3651 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3652 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3653 ColumnCountNode ,
nullptr ,
nullptr ,
3655 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3656 RowCountNode ,
nullptr ,
nullptr ,
3658 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3659 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3662llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3667 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3682 Size = CGM.getContext().getTypeSize(Ty);
3689 SmallVector<llvm::Metadata *, 8> Subscripts;
3690 QualType EltTy(Ty, 0);
3691 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3700 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3701 Count = CAT->getZExtSize();
3702 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3703 if (Expr *Size = VAT->getSizeExpr()) {
3705 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3706 Count =
Result.Val.getInt().getExtValue();
3710 auto SizeNode = SizeExprCache.find(EltTy);
3711 if (SizeNode != SizeExprCache.end())
3712 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3713 SizeNode->getSecond() ,
nullptr ,
3714 nullptr ,
nullptr ));
3717 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3718 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3719 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3720 CountNode ,
nullptr ,
nullptr ,
3726 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3728 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3732llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3733 llvm::DIFile *Unit) {
3734 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3738llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3739 llvm::DIFile *Unit) {
3740 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3742 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3743 CGM.getCodeGenOpts().DwarfVersion < 4)
3744 Tag = llvm::dwarf::DW_TAG_reference_type;
3746 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3749llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3751 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3755 Size = CGM.getContext().getTypeSize(Ty);
3758 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3761 Flags |= llvm::DINode::FlagSingleInheritance;
3764 Flags |= llvm::DINode::FlagMultipleInheritance;
3767 Flags |= llvm::DINode::FlagVirtualInheritance;
3777 llvm::DIType *ClassType = getOrCreateType(
T, U);
3779 return DBuilder.createMemberPointerType(
3783 const FunctionProtoType *FPT =
3785 return DBuilder.createMemberPointerType(
3786 getOrCreateInstanceMethodType(
3789 ClassType, Size, 0, Flags);
3792llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3794 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3797llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3801llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3803 return getOrCreateType(Ty->getWrappedType(), U);
3806llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3813 const EnumType *Ty) {
3825llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3828 bool isImportedFromModule =
3829 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3833 if (isImportedFromModule || !ED->getDefinition()) {
3840 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3841 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3842 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3843 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3845 unsigned Line = getLineNumber(ED->getLocation());
3846 StringRef EDName = ED->getName();
3847 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3848 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3849 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3851 ReplaceMap.emplace_back(
3852 std::piecewise_construct, std::make_tuple(Ty),
3853 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3857 return CreateTypeDefinition(Ty);
3860llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3863 SmallVector<llvm::Metadata *, 16> Enumerators;
3864 ED = ED->getDefinition();
3865 assert(ED &&
"An enumeration definition is required");
3866 for (
const auto *
Enum : ED->enumerators()) {
3867 Enumerators.push_back(
3868 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3871 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3872 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3873 EnumKind = Attr->getExtensibility();
3876 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3878 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3879 unsigned Line = getLineNumber(ED->getLocation());
3880 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3881 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3882 return DBuilder.createEnumerationType(
3883 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3884 0, Identifier, ED->isScoped(), EnumKind);
3889 StringRef Name, StringRef
Value) {
3890 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3891 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3897 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3898 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3899 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3903 StringRef FuncName) {
3904 llvm::DISubprogram *SP =
3905 createInlinedSubprogram(FuncName, Location->getFile());
3906 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3911 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3917 FuncName += Category;
3919 FuncName += FailureMsg;
3931 Quals += InnerQuals;
3933 switch (
T->getTypeClass()) {
3935 return C.getQualifiedType(
T.getTypePtr(), Quals);
3938 case Type::InjectedClassName:
3939 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3941 case Type::TemplateSpecialization: {
3943 if (Spec->isTypeAlias())
3944 return C.getQualifiedType(
T.getTypePtr(), Quals);
3945 T = Spec->desugar();
3948 case Type::TypeOfExpr:
3954 case Type::Decltype:
3957 case Type::UnaryTransform:
3960 case Type::Attributed:
3963 case Type::BTFTagAttributed:
3966 case Type::CountAttributed:
3975 case Type::MacroQualified:
3978 case Type::SubstTemplateTypeParm:
3982 case Type::DeducedTemplateSpecialization: {
3984 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3988 case Type::PackIndexing: {
3992 case Type::Adjusted:
3999 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4004llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4007 if (It != TypeCache.end()) {
4009 if (llvm::Metadata *
V = It->second)
4022 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4029 RetainedTypes.push_back(
4030 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4033llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4037 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4039 llvm::raw_string_ostream OS(Name);
4040 Ty.
print(OS, getPrintingPolicy());
4047 if (
auto *
T = getTypeOrNull(Ty))
4050 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4051 void *TyPtr = Ty.getAsOpaquePtr();
4054 TypeCache[TyPtr].reset(Res);
4059llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4067 auto Info = Reader->getSourceDescriptor(Idx);
4069 return getOrCreateModuleRef(*Info,
true);
4070 }
else if (ClangModuleMap) {
4083 auto Info = ASTSourceDescriptor(*M);
4084 return getOrCreateModuleRef(Info,
false);
4087 return getOrCreateModuleRef(PCHDescriptor,
false);
4094llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4097 return CreateQualifiedType(Ty, Unit);
4101#define TYPE(Class, Base)
4102#define ABSTRACT_TYPE(Class, Base)
4103#define NON_CANONICAL_TYPE(Class, Base)
4104#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4105#include "clang/AST/TypeNodes.inc"
4106 llvm_unreachable(
"Dependent types cannot show up in debug information");
4108 case Type::ExtVector:
4111 case Type::ConstantMatrix:
4113 case Type::ObjCObjectPointer:
4115 case Type::ObjCObject:
4117 case Type::ObjCTypeParam:
4119 case Type::ObjCInterface:
4127 case Type::BlockPointer:
4135 case Type::FunctionProto:
4136 case Type::FunctionNoProto:
4138 case Type::ConstantArray:
4139 case Type::VariableArray:
4140 case Type::IncompleteArray:
4141 case Type::ArrayParameter:
4144 case Type::LValueReference:
4146 case Type::RValueReference:
4149 case Type::MemberPointer:
4160 case Type::TemplateSpecialization:
4162 case Type::HLSLAttributedResource:
4164 case Type::HLSLInlineSpirv:
4166 case Type::PredefinedSugar:
4168 case Type::CountAttributed:
4170 case Type::Attributed:
4171 case Type::BTFTagAttributed:
4172 case Type::Adjusted:
4174 case Type::DeducedTemplateSpecialization:
4177 case Type::MacroQualified:
4178 case Type::SubstTemplateTypeParm:
4179 case Type::TypeOfExpr:
4181 case Type::Decltype:
4182 case Type::PackIndexing:
4183 case Type::UnaryTransform:
4187 llvm_unreachable(
"type should have been unwrapped!");
4190llvm::DICompositeType *
4191CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4192 QualType QTy(Ty, 0);
4194 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4199 if (
T && !
T->isForwardDecl())
4203 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4208 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4211 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4216llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4217 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4220 StringRef RDName = getClassName(RD);
4222 llvm::DIFile *DefUnit =
nullptr;
4225 DefUnit = getOrCreateFile(Loc);
4226 Line = getLineNumber(Loc);
4229 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4233 auto *
T = cast_or_null<llvm::DICompositeType>(
4234 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4242 return getOrCreateRecordFwdDecl(Ty, RDContext);
4255 auto Flags = llvm::DINode::FlagZero;
4256 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4258 Flags |= llvm::DINode::FlagTypePassByReference;
4260 Flags |= llvm::DINode::FlagTypePassByValue;
4263 if (!CXXRD->isTrivial())
4264 Flags |= llvm::DINode::FlagNonTrivial;
4267 if (CXXRD->isAnonymousStructOrUnion())
4268 Flags |= llvm::DINode::FlagExportSymbols;
4271 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4274 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4275 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4277 Flags, Identifier, Annotations);
4281 switch (RealDecl->getTag()) {
4283 llvm_unreachable(
"invalid composite type tag");
4285 case llvm::dwarf::DW_TAG_array_type:
4286 case llvm::dwarf::DW_TAG_enumeration_type:
4291 if (Identifier.empty())
4295 case llvm::dwarf::DW_TAG_structure_type:
4296 case llvm::dwarf::DW_TAG_union_type:
4297 case llvm::dwarf::DW_TAG_class_type:
4300 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4304 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4305 CXXRecordDecl *TemplateDecl =
4306 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4307 RegionMap[TemplateDecl].reset(RealDecl);
4309 RegionMap[RD].reset(RealDecl);
4311 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4313 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4314 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4315 CollectCXXTemplateParams(TSpecial, DefUnit));
4319void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4320 llvm::DICompositeType *RealDecl) {
4322 llvm::DIType *ContainingType =
nullptr;
4323 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4327 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4334 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4335 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4337 ContainingType = RealDecl;
4339 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4342llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4343 StringRef Name, uint64_t *Offset) {
4344 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4345 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4348 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4349 *Offset, llvm::DINode::FlagZero, FieldTy);
4350 *Offset += FieldSize;
4354void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4356 StringRef &LinkageName,
4357 llvm::DIScope *&FDContext,
4358 llvm::DINodeArray &TParamsArray,
4359 llvm::DINode::DIFlags &Flags) {
4361 Name = getFunctionName(FD);
4364 LinkageName = CGM.getMangledName(GD);
4366 Flags |= llvm::DINode::FlagPrototyped;
4370 if (LinkageName == Name ||
4371 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4372 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4373 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4374 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4375 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4376 LinkageName = StringRef();
4380 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4381 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4382 CGM.getCodeGenOpts().EmitCodeView)) {
4383 if (
const NamespaceDecl *NSDecl =
4385 FDContext = getOrCreateNamespace(NSDecl);
4386 else if (
const RecordDecl *RDecl =
4388 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4389 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4392 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4395 Flags |= llvm::DINode::FlagNoReturn;
4397 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4401void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4402 unsigned &LineNo, QualType &
T,
4403 StringRef &Name, StringRef &LinkageName,
4404 llvm::MDTuple *&TemplateParameters,
4405 llvm::DIScope *&VDContext) {
4414 llvm::APInt ConstVal(32, 1);
4415 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4417 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4424 LinkageName = CGM.getMangledName(VD);
4425 if (LinkageName == Name)
4426 LinkageName = StringRef();
4429 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4430 TemplateParameters = parameterNodes.get();
4432 TemplateParameters =
nullptr;
4450 DC = CGM.getContext().getTranslationUnitDecl();
4452 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4453 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4456llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4458 llvm::DINodeArray TParamsArray;
4459 StringRef Name, LinkageName;
4460 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4461 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4463 llvm::DIFile *Unit = getOrCreateFile(Loc);
4464 llvm::DIScope *DContext = Unit;
4465 unsigned Line = getLineNumber(Loc);
4466 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4471 SmallVector<QualType, 16> ArgTypes;
4472 for (
const ParmVarDecl *Parm : FD->
parameters())
4473 ArgTypes.push_back(Parm->getType());
4476 QualType FnType = CGM.getContext().getFunctionType(
4477 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4479 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4480 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4481 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4484 Flags |= getCallSiteRelatedAttrs();
4485 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4486 return DBuilder.createFunction(
4487 DContext, Name, LinkageName, Unit,
Line,
4488 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4489 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4491 CGM.getCodeGenOpts().DebugKeyInstructions);
4494 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4495 DContext, Name, LinkageName, Unit,
Line,
4496 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4497 TParamsArray.get(), getFunctionDeclaration(FD));
4499 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4500 std::make_tuple(CanonDecl),
4501 std::make_tuple(SP));
4505llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4506 return getFunctionFwdDeclOrStub(GD,
false);
4509llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4510 return getFunctionFwdDeclOrStub(GD,
true);
4513llvm::DIGlobalVariable *
4514CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4516 StringRef Name, LinkageName;
4518 llvm::DIFile *Unit = getOrCreateFile(Loc);
4519 llvm::DIScope *DContext = Unit;
4520 unsigned Line = getLineNumber(Loc);
4521 llvm::MDTuple *TemplateParameters =
nullptr;
4523 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4526 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4527 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4529 FwdDeclReplaceMap.emplace_back(
4530 std::piecewise_construct,
4532 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4536llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4541 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4542 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4543 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4547 if (I != DeclCache.end()) {
4549 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4550 return GVE->getVariable();
4558 if (IE != ImportedDeclCache.end()) {
4559 auto N = IE->second;
4560 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4562 return dyn_cast_or_null<llvm::DINode>(N);
4567 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4568 return getFunctionForwardDeclaration(FD);
4569 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4570 return getGlobalVariableForwardDeclaration(VD);
4575llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4576 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4579 const auto *FD = dyn_cast<FunctionDecl>(D);
4584 auto *S = getDeclContextDescriptor(D);
4587 if (MI == SPCache.end()) {
4589 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4593 if (MI != SPCache.end()) {
4594 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4595 if (SP && !SP->isDefinition())
4599 for (
auto *NextFD : FD->
redecls()) {
4600 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4601 if (MI != SPCache.end()) {
4602 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4603 if (SP && !SP->isDefinition())
4610llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4611 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4612 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4613 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4616 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4620 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4624 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4633 QualType QTy(
ID->getTypeForDecl(), 0);
4634 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4635 if (It == TypeCache.end())
4638 llvm::DISubprogram *FD = DBuilder.createFunction(
4639 InterfaceType, getObjCMethodName(OMD), StringRef(),
4640 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4641 DBuilder.finalizeSubprogram(FD);
4648llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4653 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4654 !CGM.getCodeGenOpts().EmitCodeView))
4657 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4659 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4662 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4665 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4666 return getOrCreateMethodType(
Method, F);
4668 const auto *FTy = FnType->
getAs<FunctionType>();
4671 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4673 SmallVector<llvm::Metadata *, 16> Elts;
4676 QualType ResultTy = OMethod->getReturnType();
4679 if (ResultTy == CGM.getContext().getObjCInstanceType())
4680 ResultTy = CGM.getContext().getPointerType(
4681 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4683 Elts.push_back(getOrCreateType(ResultTy, F));
4685 QualType SelfDeclTy;
4686 if (
auto *SelfDecl = OMethod->getSelfDecl())
4687 SelfDeclTy = SelfDecl->getType();
4688 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4691 if (!SelfDeclTy.
isNull())
4693 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4695 Elts.push_back(DBuilder.createArtificialType(
4696 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4698 for (
const auto *PI : OMethod->parameters())
4699 Elts.push_back(getOrCreateType(PI->getType(), F));
4701 if (OMethod->isVariadic())
4702 Elts.push_back(DBuilder.createUnspecifiedParameter());
4704 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4705 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4711 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4712 if (FD->isVariadic()) {
4713 SmallVector<llvm::Metadata *, 16> EltTys;
4714 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4715 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4717 EltTys.push_back(getOrCreateType(ParamType, F));
4718 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4719 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4720 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4733 CC = SrcFnTy->getCallConv();
4735 for (
const VarDecl *VD : Args)
4736 ArgTypes.push_back(VD->
getType());
4737 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4743 llvm::Function *Fn,
bool CurFuncIsThunk) {
4745 StringRef LinkageName;
4747 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4750 bool HasDecl = (D !=
nullptr);
4752 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4753 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4754 llvm::DIFile *Unit = getOrCreateFile(Loc);
4755 llvm::DIScope *FDContext = Unit;
4756 llvm::DINodeArray TParamsArray;
4757 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4760 LinkageName = Fn->getName();
4761 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4763 auto FI = SPCache.find(FD->getCanonicalDecl());
4764 if (FI != SPCache.end()) {
4765 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4766 if (SP && SP->isDefinition()) {
4767 LexicalBlockStack.emplace_back(SP);
4768 RegionMap[D].reset(SP);
4772 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4773 TParamsArray, Flags);
4776 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4777 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4778 Name = getObjCMethodName(OMD);
4779 Flags |= llvm::DINode::FlagPrototyped;
4786 Name = Fn->getName();
4791 Flags |= llvm::DINode::FlagPrototyped;
4793 Name.consume_front(
"\01");
4797 "Unexpected DynamicInitKind !");
4801 Flags |= llvm::DINode::FlagArtificial;
4807 Flags |= llvm::DINode::FlagThunk;
4809 if (Fn->hasLocalLinkage())
4810 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4811 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4812 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4814 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4815 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4816 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4818 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4819 unsigned ScopeLine = getLineNumber(ScopeLoc);
4820 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4821 llvm::DISubprogram *
Decl =
nullptr;
4822 llvm::DINodeArray Annotations =
nullptr;
4825 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4826 : getFunctionDeclaration(D);
4827 Annotations = CollectBTFDeclTagAnnotations(D);
4835 llvm::DISubprogram *SP = DBuilder.createFunction(
4836 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4837 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4838 Annotations,
"", KeyInstructions);
4839 Fn->setSubprogram(SP);
4848 LexicalBlockStack.emplace_back(SP);
4851 RegionMap[D].reset(SP);
4855 QualType FnType, llvm::Function *Fn) {
4857 StringRef LinkageName;
4863 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4864 return GetName(D,
true);
4867 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4868 llvm::DIFile *Unit = getOrCreateFile(Loc);
4869 bool IsDeclForCallSite = Fn ?
true :
false;
4870 llvm::DIScope *FDContext =
4871 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4872 llvm::DINodeArray TParamsArray;
4875 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4876 TParamsArray, Flags);
4877 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4878 Name = getObjCMethodName(OMD);
4879 Flags |= llvm::DINode::FlagPrototyped;
4881 llvm_unreachable(
"not a function or ObjC method");
4883 Name.consume_front(
"\01");
4886 Flags |= llvm::DINode::FlagArtificial;
4891 unsigned LineNo = getLineNumber(Loc);
4892 unsigned ScopeLine = 0;
4893 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4894 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4895 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4897 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4898 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4900 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4901 llvm::DISubprogram *SP = DBuilder.createFunction(
4902 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4903 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4909 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4910 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4911 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4914 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4915 DBuilder.createParameterVariable(
4916 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4917 llvm::DINode::FlagZero, ParamAnnotations);
4923 if (IsDeclForCallSite)
4924 Fn->setSubprogram(SP);
4932 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4935 if (
Func->getSubprogram())
4940 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4941 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4954 auto FI = SPCache.find(FD->getCanonicalDecl());
4955 llvm::DISubprogram *SP =
nullptr;
4956 if (FI != SPCache.end())
4957 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4958 if (!SP || !SP->isDefinition())
4959 SP = getFunctionStub(GD);
4960 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4961 LexicalBlockStack.emplace_back(SP);
4967 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4976 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4979 llvm::MDNode *
Scope = LexicalBlockStack.back();
4980 Builder.SetCurrentDebugLocation(
4981 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
4982 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4986 llvm::MDNode *Back =
nullptr;
4987 if (!LexicalBlockStack.empty())
4988 Back = LexicalBlockStack.back().get();
4989 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4991 getColumnNumber(CurLoc)));
4994void CGDebugInfo::AppendAddressSpaceXDeref(
4996 std::optional<unsigned> DWARFAddressSpace =
4998 if (!DWARFAddressSpace)
5001 Expr.push_back(llvm::dwarf::DW_OP_constu);
5002 Expr.push_back(*DWARFAddressSpace);
5003 Expr.push_back(llvm::dwarf::DW_OP_swap);
5004 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5013 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5014 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5015 LexicalBlockStack.back(), CurInlinedAt));
5017 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5021 CreateLexicalBlock(Loc);
5026 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5031 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5034 LexicalBlockStack.pop_back();
5038 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5039 unsigned RCount = FnBeginRegionCount.back();
5040 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5043 while (LexicalBlockStack.size() != RCount) {
5046 LexicalBlockStack.pop_back();
5048 FnBeginRegionCount.pop_back();
5050 if (Fn && Fn->getSubprogram())
5051 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5054CGDebugInfo::BlockByRefType
5055CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5056 uint64_t *XOffset) {
5059 uint64_t FieldSize, FieldOffset;
5060 uint32_t FieldAlign;
5062 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5067 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5068 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5070 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5071 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5074 if (HasCopyAndDispose) {
5077 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5079 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5081 bool HasByrefExtendedLayout;
5084 HasByrefExtendedLayout) &&
5085 HasByrefExtendedLayout) {
5088 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5097 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5100 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5103 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5108 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5109 FieldSize = CGM.getContext().getTypeSize(FType);
5110 FieldAlign = CGM.getContext().toBits(Align);
5112 *XOffset = FieldOffset;
5113 llvm::DIType *FieldTy = DBuilder.createMemberType(
5114 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5115 llvm::DINode::FlagZero, WrappedTy);
5116 EltTys.push_back(FieldTy);
5117 FieldOffset += FieldSize;
5119 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5120 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5121 llvm::DINode::FlagZero,
nullptr, Elements),
5125llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5126 llvm::Value *Storage,
5127 std::optional<unsigned> ArgNo,
5129 const bool UsePointerValue) {
5130 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5131 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5132 if (VD->
hasAttr<NoDebugAttr>())
5137 llvm::DIFile *Unit =
nullptr;
5138 if (!VarIsArtificial)
5142 if (VD->
hasAttr<BlocksAttr>())
5143 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5145 Ty = getOrCreateType(VD->
getType(), Unit);
5155 if (!VarIsArtificial) {
5159 SmallVector<uint64_t, 13> Expr;
5160 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5161 if (VarIsArtificial)
5162 Flags |= llvm::DINode::FlagArtificial;
5166 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5167 AppendAddressSpaceXDeref(AddressSpace, Expr);
5171 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5174 Flags |= llvm::DINode::FlagObjectPointer;
5175 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5176 if (PVD->isExplicitObjectParameter())
5177 Flags |= llvm::DINode::FlagObjectPointer;
5185 StringRef Name = VD->
getName();
5186 if (!Name.empty()) {
5192 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5194 offset = CGM.getContext().toCharUnitsFromBits(
5197 Expr.push_back(llvm::dwarf::DW_OP_deref);
5198 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5200 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5203 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5215 for (
const auto *Field : RD->
fields()) {
5216 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5217 StringRef FieldName =
Field->getName();
5225 auto *D = DBuilder.createAutoVariable(
5226 Scope, FieldName, Unit,
Line, FieldTy,
5227 CGM.getCodeGenOpts().OptimizationLevel != 0,
5228 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5231 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5232 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5235 Builder.GetInsertBlock());
5243 if (UsePointerValue) {
5244 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5245 "Debug info already contains DW_OP_deref.");
5246 Expr.push_back(llvm::dwarf::DW_OP_deref);
5250 llvm::DILocalVariable *D =
nullptr;
5252 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5253 D = DBuilder.createParameterVariable(
5254 Scope, Name, *ArgNo, Unit,
Line, Ty,
5255 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5264 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5270 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5271 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5272 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5273 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5275 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5281 if (Iter != CoroutineParameterMappings.end()) {
5282 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5283 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5284 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5286 if (Iter2 != ParamDbgMappings.end())
5287 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5293 D = RemapCoroArgToLocalVar();
5296 D = DBuilder.createAutoVariable(
5297 Scope, Name, Unit,
Line, Ty,
5298 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5301 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5302 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5303 Column, Scope, CurInlinedAt),
5304 Builder.GetInsertBlock());
5309llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5310 llvm::Value *Storage,
5311 std::optional<unsigned> ArgNo,
5313 const bool UsePointerValue) {
5314 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5315 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5316 if (BD->
hasAttr<NoDebugAttr>())
5323 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5324 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5332 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5334 SmallVector<uint64_t, 3> Expr;
5335 AppendAddressSpaceXDeref(AddressSpace, Expr);
5340 if (UsePointerValue) {
5341 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5342 "Debug info already contains DW_OP_deref.");
5343 Expr.push_back(llvm::dwarf::DW_OP_deref);
5348 StringRef Name = BD->
getName();
5351 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5352 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5353 llvm::DINode::FlagZero, Align);
5355 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5356 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5357 const unsigned fieldIndex = FD->getFieldIndex();
5358 const clang::CXXRecordDecl *parent =
5359 (
const CXXRecordDecl *)FD->getParent();
5360 const ASTRecordLayout &layout =
5361 CGM.getContext().getASTRecordLayout(parent);
5363 if (FD->isBitField()) {
5364 const CGRecordLayout &RL =
5365 CGM.getTypes().getCGRecordLayout(FD->getParent());
5370 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5376 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5377 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5378 Expr.push_back(Info.
Offset);
5381 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5382 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5383 }
else if (fieldOffset != 0) {
5384 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5385 "Unexpected non-bitfield with non-byte-aligned offset");
5386 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5388 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5391 }
else if (
const ArraySubscriptExpr *ASE =
5392 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5393 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5394 const uint64_t value = IL->getValue().getZExtValue();
5395 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5398 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5399 Expr.push_back(CGM.getContext()
5400 .toCharUnitsFromBits(value * typeSize)
5407 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5408 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5409 Column, Scope, CurInlinedAt),
5410 Builder.GetInsertBlock());
5415llvm::DILocalVariable *
5418 const bool UsePointerValue) {
5419 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5421 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5423 EmitDeclare(B, Storage, std::nullopt, Builder,
5430 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5434 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5435 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5437 if (D->
hasAttr<NoDebugAttr>())
5441 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5447 StringRef Name = D->
getName();
5453 CGM.getCodeGenOpts().OptimizationLevel != 0);
5456 DBuilder.insertLabel(L,
5457 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5458 Scope, CurInlinedAt),
5459 Builder.GetInsertBlock()->end());
5462llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5464 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5467 return DBuilder.createObjectPointerType(Ty,
true);
5472 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5473 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5474 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5476 if (Builder.GetInsertBlock() ==
nullptr)
5478 if (VD->
hasAttr<NoDebugAttr>())
5481 bool isByRef = VD->
hasAttr<BlocksAttr>();
5483 uint64_t XOffset = 0;
5484 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5487 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5489 Ty = getOrCreateType(VD->
getType(), Unit);
5493 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5495 Ty = CreateSelfType(VD->
getType(), Ty);
5498 const unsigned Line =
5502 const llvm::DataLayout &target = CGM.getDataLayout();
5509 addr.push_back(llvm::dwarf::DW_OP_deref);
5510 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5513 addr.push_back(llvm::dwarf::DW_OP_deref);
5514 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5517 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5519 addr.push_back(llvm::dwarf::DW_OP_deref);
5520 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5522 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5528 auto *D = DBuilder.createAutoVariable(
5530 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5533 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5534 LexicalBlockStack.back(), CurInlinedAt);
5535 auto *
Expr = DBuilder.createExpression(addr);
5537 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5539 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5542llvm::DILocalVariable *
5545 bool UsePointerValue) {
5546 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5547 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5551struct BlockLayoutChunk {
5552 uint64_t OffsetInBits;
5555bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5556 return l.OffsetInBits < r.OffsetInBits;
5560void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5562 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5563 SmallVectorImpl<llvm::Metadata *> &Fields) {
5567 if (CGM.getLangOpts().OpenCL) {
5568 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5569 BlockLayout.getElementOffsetInBits(0),
5571 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5572 BlockLayout.getElementOffsetInBits(1),
5576 BlockLayout.getElementOffsetInBits(0),
5578 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5579 BlockLayout.getElementOffsetInBits(1),
5583 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5584 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5585 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5586 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5587 BlockLayout.getElementOffsetInBits(3),
5589 Fields.push_back(createFieldType(
5594 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5601 llvm::AllocaInst *Alloca,
5603 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5609 llvm::DIFile *tunit = getOrCreateFile(loc);
5610 unsigned line = getLineNumber(loc);
5611 unsigned column = getColumnNumber(loc);
5616 const llvm::StructLayout *blockLayout =
5620 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5629 BlockLayoutChunk chunk;
5630 chunk.OffsetInBits =
5631 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5632 chunk.Capture =
nullptr;
5633 chunks.push_back(chunk);
5637 for (
const auto &capture :
blockDecl->captures()) {
5638 const VarDecl *variable = capture.getVariable();
5645 BlockLayoutChunk chunk;
5646 chunk.OffsetInBits =
5647 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5648 chunk.Capture = &capture;
5649 chunks.push_back(chunk);
5653 llvm::array_pod_sort(chunks.begin(), chunks.end());
5655 for (
const BlockLayoutChunk &Chunk : chunks) {
5656 uint64_t offsetInBits = Chunk.OffsetInBits;
5663 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5665 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5666 type = CGM.getContext().getCanonicalTagType(RDecl);
5668 llvm_unreachable(
"unexpected block declcontext");
5670 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5671 offsetInBits, tunit, tunit));
5676 StringRef name = variable->
getName();
5678 llvm::DIType *fieldType;
5680 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5685 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5686 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5687 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5688 PtrInfo.
Width, Align, offsetInBits,
5689 llvm::DINode::FlagZero, fieldType);
5693 offsetInBits, Align, tunit, tunit);
5695 fields.push_back(fieldType);
5699 llvm::raw_svector_ostream(typeName)
5700 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5702 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5704 llvm::DIType *
type =
5705 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5706 CGM.getContext().toBits(block.
BlockSize), 0,
5707 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5708 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5711 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5715 auto *debugVar = DBuilder.createParameterVariable(
5716 scope, Name, ArgNo, tunit, line,
type,
5717 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5720 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5721 llvm::DILocation::get(CGM.getLLVMContext(), line,
5722 column, scope, CurInlinedAt),
5723 Builder.GetInsertBlock());
5726llvm::DIDerivedType *
5727CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5732 if (MI != StaticDataMemberCache.end()) {
5733 assert(MI->second &&
"Static data member declaration should still exist");
5744llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5745 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5746 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5747 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5749 for (
const auto *Field : RD->
fields()) {
5750 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5751 StringRef FieldName = Field->getName();
5754 if (FieldName.empty()) {
5755 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5756 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5757 LineNo, LinkageName, Var, DContext);
5761 GVE = DBuilder.createGlobalVariableExpression(
5762 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5763 Var->hasLocalLinkage());
5764 Var->addDebugInfo(GVE);
5776 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5781 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5792 struct ReferencesAnonymous
5794 bool RefAnon =
false;
5795 bool VisitRecordType(RecordType *RT) {
5803 ReferencesAnonymous RT;
5816struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5817 bool Reconstitutable =
true;
5818 bool VisitVectorType(VectorType *FT) {
5819 Reconstitutable =
false;
5822 bool VisitAtomicType(AtomicType *FT) {
5823 Reconstitutable =
false;
5826 bool VisitType(
Type *
T) {
5830 Reconstitutable =
false;
5835 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5838 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5839 if (!ED->getIdentifier()) {
5840 Reconstitutable =
false;
5843 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5844 Reconstitutable =
false;
5850 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5854 return Reconstitutable;
5856 bool VisitRecordType(RecordType *RT,
bool =
false) {
5858 Reconstitutable =
false;
5868 ReconstitutableType
T;
5870 return T.Reconstitutable;
5873bool CGDebugInfo::HasReconstitutableArgs(
5874 ArrayRef<TemplateArgument> Args)
const {
5875 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5915 llvm_unreachable(
"Other, unresolved, template arguments should "
5916 "not be seen here");
5921std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5923 llvm::raw_string_ostream
OS(Name);
5924 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5927 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5928 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5930 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5931 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5933 std::optional<TemplateArgs> Args;
5935 bool IsOperatorOverload =
false;
5936 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5937 Args = GetTemplateArgs(RD);
5938 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5939 Args = GetTemplateArgs(FD);
5941 IsOperatorOverload |=
5944 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5945 Args = GetTemplateArgs(VD);
5969 bool Reconstitutable =
5970 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5972 PrintingPolicy PP = getPrintingPolicy();
5974 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5978 bool Mangled = TemplateNamesKind ==
5979 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5985 std::string EncodedOriginalName;
5986 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5991 printTemplateArgumentList(OS, Args->Args, PP);
5992 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
5994 std::string CanonicalOriginalName;
5995 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5997 assert(EncodedOriginalName == CanonicalOriginalName);
6006 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6007 if (D->
hasAttr<NoDebugAttr>())
6010 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6011 return GetName(D,
true);
6017 if (Cached != DeclCache.end())
6018 return Var->addDebugInfo(
6022 llvm::DIFile *Unit =
nullptr;
6023 llvm::DIScope *DContext =
nullptr;
6025 StringRef DeclName, LinkageName;
6027 llvm::MDTuple *TemplateParameters =
nullptr;
6028 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6029 TemplateParameters, DContext);
6033 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6038 if (
T->isUnionType() && DeclName.empty()) {
6039 const auto *RD =
T->castAsRecordDecl();
6041 "unnamed non-anonymous struct or union?");
6042 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6047 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6048 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6049 if (D->
hasAttr<CUDASharedAttr>())
6052 else if (D->
hasAttr<CUDAConstantAttr>())
6056 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6058 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6059 GVE = DBuilder.createGlobalVariableExpression(
6060 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6061 Var->hasLocalLinkage(),
true,
6062 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6063 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6064 Align, Annotations);
6065 Var->addDebugInfo(GVE);
6071 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6072 if (VD->
hasAttr<NoDebugAttr>())
6074 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6075 return GetName(VD,
true);
6080 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6081 StringRef Name = VD->
getName();
6082 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6084 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6086 if (CGM.getCodeGenOpts().EmitCodeView) {
6097 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6098 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6099 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6109 auto *VarD = dyn_cast<VarDecl>(VD);
6110 if (VarD && VarD->isStaticDataMember()) {
6112 getDeclContextDescriptor(VarD);
6117 RetainedTypes.push_back(
6118 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6122 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6124 auto &GV = DeclCache[VD];
6128 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6129 llvm::MDTuple *TemplateParameters =
nullptr;
6133 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6134 TemplateParameters = parameterNodes.get();
6137 GV.reset(DBuilder.createGlobalVariableExpression(
6138 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6139 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6140 TemplateParameters, Align));
6145 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6146 if (D->
hasAttr<NoDebugAttr>())
6150 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6151 StringRef Name = D->
getName();
6152 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6154 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6155 llvm::DIGlobalVariableExpression *GVE =
6156 DBuilder.createGlobalVariableExpression(
6157 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6158 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6159 Var->addDebugInfo(GVE);
6166 if (CGM.getCodeGenOpts().getDebugInfo() <=
6167 llvm::codegenoptions::DebugLineTablesOnly)
6170 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6174 llvm::DIFile *Unit = DIL->getFile();
6175 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6180 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6181 llvm::Value *Var = Load->getPointerOperand();
6186 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6187 return DbgDeclare->getVariable()->getType() ==
Type;
6189 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6193 llvm::DILocalVariable *D =
6194 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6195 Type,
false, llvm::DINode::FlagArtificial);
6197 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6198 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6208 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6212 if (D->
hasAttr<NoDebugAttr>())
6215 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6230 if (!(DI = getDeclarationOrDefinition(
6231 AliaseeDecl.getCanonicalDecl().getDecl())))
6234 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6237 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6238 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6247 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
6251 llvm::DIFile *
File = getOrCreateFile(Loc);
6252 llvm::DIGlobalVariableExpression *Debug =
6253 DBuilder.createGlobalVariableExpression(
6254 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6255 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6256 GV->addDebugInfo(Debug);
6259llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6260 if (!LexicalBlockStack.empty())
6261 return LexicalBlockStack.back();
6262 llvm::DIScope *Mod = getParentModuleOrNull(D);
6263 return getContextDescriptor(D, Mod ? Mod : TheCU);
6267 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6271 CGM.getCodeGenOpts().DebugExplicitImport) {
6275 DBuilder.createImportedModule(
6277 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6282 if (llvm::DINode *
Target =
6285 DBuilder.createImportedDeclaration(
6287 getOrCreateFile(Loc), getLineNumber(Loc));
6292 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6295 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6297 for (
const auto *USD : UD.
shadows()) {
6302 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6303 if (
const auto *AT = FD->getType()
6306 if (AT->getDeducedType().isNull())
6317 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6320 "We shouldn't be codegening an invalid UsingEnumDecl"
6321 " containing no decls");
6323 for (
const auto *USD : UD.
shadows())
6328 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6330 if (
Module *M = ID.getImportedModule()) {
6332 auto Loc = ID.getLocation();
6333 DBuilder.createImportedDeclaration(
6334 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6335 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6336 getLineNumber(Loc));
6340llvm::DIImportedEntity *
6342 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6344 auto &VH = NamespaceAliasCache[&NA];
6347 llvm::DIImportedEntity *R;
6349 if (
const auto *Underlying =
6352 R = DBuilder.createImportedDeclaration(
6355 getLineNumber(Loc), NA.
getName());
6357 R = DBuilder.createImportedDeclaration(
6360 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6366CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6370 auto I = NamespaceCache.find(NSDecl);
6371 if (I != NamespaceCache.end())
6374 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6376 llvm::DINamespace *NS =
6377 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6378 NamespaceCache[NSDecl].reset(NS);
6383 assert(TheCU &&
"no main compile unit");
6384 TheCU->setDWOId(Signature);
6390 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6391 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6393 ? CreateTypeDefinition(E.Type, E.Unit)
6395 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6399 for (
const auto &P : ObjCMethodCache) {
6400 if (P.second.empty())
6403 QualType QTy(P.first->getTypeForDecl(), 0);
6405 assert(It != TypeCache.end());
6407 llvm::DICompositeType *InterfaceDecl =
6410 auto CurElts = InterfaceDecl->getElements();
6414 for (
auto &SubprogramDirect : P.second)
6415 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6416 EltTys.push_back(SubprogramDirect.getPointer());
6418 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6419 DBuilder.replaceArrays(InterfaceDecl, Elements);
6422 for (
const auto &P : ReplaceMap) {
6425 assert(Ty->isForwardDecl());
6427 auto It = TypeCache.find(P.first);
6428 assert(It != TypeCache.end());
6431 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6435 for (
const auto &P : FwdDeclReplaceMap) {
6438 llvm::Metadata *Repl;
6440 auto It = DeclCache.find(P.first);
6444 if (It == DeclCache.end())
6449 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6450 Repl = GVE->getVariable();
6456 for (
auto &RT : RetainedTypes)
6457 if (
auto MD = TypeCache[RT])
6460 DBuilder.finalize();
6465 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6466 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6467 DBuilder.retainType(DieTy);
6471 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6472 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6473 DBuilder.retainType(DieTy);
6477 if (LexicalBlockStack.empty())
6478 return llvm::DebugLoc();
6480 llvm::MDNode *
Scope = LexicalBlockStack.back();
6481 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6482 getColumnNumber(Loc),
Scope);
6485llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6489 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6490 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6491 return llvm::DINode::FlagZero;
6496 bool SupportsDWARFv4Ext =
6498 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6499 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6501 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6502 return llvm::DINode::FlagZero;
6504 return llvm::DINode::FlagAllCallsDescribed;
6515 return DBuilder.createConstantValueExpression(
6516 Val.
getFloat().bitcastToAPInt().getZExtValue());
6521 llvm::APSInt
const &ValInt = Val.
getInt();
6522 std::optional<uint64_t> ValIntOpt;
6523 if (ValInt.isUnsigned())
6524 ValIntOpt = ValInt.tryZExtValue();
6525 else if (
auto tmp = ValInt.trySExtValue())
6528 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6531 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6536CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6538 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6539 CGF.CurLexicalScope =
this;
6541 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6546 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6559#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6561 Label = "__ubsan_check_" #Name; \
6565#undef SANITIZER_CHECK
6576#define SANITIZER(NAME, ID) \
6577 case SanitizerKind::SO_##ID: \
6578 Label = "__ubsan_check_" NAME; \
6580#include "clang/Basic/Sanitizers.def"
6582 llvm_unreachable(
"unexpected sanitizer kind");
6587 for (
unsigned int i = 0; i < Label.length(); i++)
6588 if (!std::isalpha(Label[i]))
6597 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6599 if (!DI || !CheckDebugLoc)
6600 return CheckDebugLoc;
6601 const auto &AnnotateDebugInfo =
6602 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6603 if (AnnotateDebugInfo.empty())
6604 return CheckDebugLoc;
6607 if (Ordinals.size() == 1)
6612 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6613 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6615 return CheckDebugLoc;
6623 assert(!CGF->IsSanitizerScope);
6624 CGF->IsSanitizerScope =
true;
6628 assert(CGF->IsSanitizerScope);
6629 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 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 bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
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 llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
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)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
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...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
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...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
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.