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"
71 if (TI.isAlignRequired())
99 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
103 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
127 if (!llvm::isa<ParmVarDecl>(VD))
137 if (!Method->isImplicit() || !Method->isPropertyAccessor())
148 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
149 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
150 DBuilder(CGM.getModule()) {
155 assert(LexicalBlockStack.empty() &&
156 "Region stack mismatch, stack not empty!");
159void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
160 uint64_t Group, uint8_t Rank) {
161 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
165 Rank = std::min<uint8_t>(Rank, 7);
167 const llvm::DebugLoc &DL = I->getDebugLoc();
172 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
173 Group = DL->getAtomGroup();
174 Rank = DL->getAtomRank();
179 KeyInstructionsInfo.HighestEmittedAtom =
180 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
183 llvm::DILocation *NewDL = llvm::DILocation::get(
184 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
185 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
186 I->setDebugLoc(NewDL);
190 llvm::Value *Backup) {
192 KeyInstructionsInfo.CurrentAtom);
198 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
201 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
202 if (!SP || !SP->getKeyInstructionsEnabled())
205 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
207 llvm::Instruction *BackupI =
208 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
213 addInstSourceAtomMetadata(BackupI, Group, 2);
219 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
220 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
223 addInstSourceAtomMetadata(BackupI, Group, Rank++);
229 KeyInstructionsInfo.NextAtom = 1;
230 KeyInstructionsInfo.HighestEmittedAtom = 0;
231 KeyInstructionsInfo.CurrentAtom = 0;
237 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
238 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
246 DI->KeyInstructionsInfo.NextAtom =
247 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
248 DI->KeyInstructionsInfo.NextAtom);
250 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
256 init(TemporaryLocation);
263 init(TemporaryLocation, DefaultToEmpty);
267 bool DefaultToEmpty) {
274 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
276 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
279 if (TemporaryLocation.
isValid()) {
280 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
284 if (DefaultToEmpty) {
285 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
290 assert(!DI->LexicalBlockStack.empty());
291 CGF->Builder.SetCurrentDebugLocation(
292 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
293 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
303 if (!CGF.getDebugInfo()) {
307 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
311 if (Loc->getAtomGroup())
312 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
313 Loc->getColumn(), Loc->getScope(),
314 Loc->getInlinedAt(), Loc.isImplicitCode());
315 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
323 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
329 if (!CGF.getDebugInfo()) {
333 auto &DI = *CGF.getDebugInfo();
334 SavedLocation = DI.getLocation();
335 assert((DI.getInlinedAt() ==
336 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
337 "CGDebugInfo and IRBuilder are out of sync");
339 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
345 auto &DI = *CGF->getDebugInfo();
346 DI.EmitInlineFunctionEnd(CGF->Builder);
347 DI.EmitLocation(CGF->Builder, SavedLocation);
357 if (CurLoc != NewLoc) {
359 CurLocFile =
nullptr;
368 if (CGM.getCodeGenOpts().DebugColumnInfo)
370 CurLocFile = getOrCreateFile(CurLoc);
376 if (LexicalBlockStack.empty())
380 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
383 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
384 LexicalBlockStack.pop_back();
385 LexicalBlockStack.emplace_back(
386 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
389 LexicalBlockStack.pop_back();
390 LexicalBlockStack.emplace_back(
391 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
395llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
396 llvm::DIScope *Mod = getParentModuleOrNull(D);
401llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
406 auto I = RegionMap.find(Context);
407 if (I != RegionMap.end()) {
408 llvm::Metadata *
V = I->second;
409 return dyn_cast_or_null<llvm::DIScope>(
V);
413 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
414 return getOrCreateNamespace(NSDecl);
416 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
417 if (!RDecl->isDependentType())
423PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
424 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
431 if (CGM.getCodeGenOpts().EmitCodeView) {
452StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
453 bool *NameIsSimplified) {
454 return internString(GetName(FD,
false, NameIsSimplified));
457StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
458 SmallString<256> MethodName;
459 llvm::raw_svector_ostream
OS(MethodName);
462 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
463 OS << OID->getName();
464 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
465 OS << OID->getName();
466 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
467 if (OC->IsClassExtension()) {
468 OS << OC->getClassInterface()->getName();
470 OS << OC->getIdentifier()->getNameStart() <<
'('
471 << OC->getIdentifier()->getNameStart() <<
')';
473 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
474 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
478 return internString(
OS.str());
481StringRef CGDebugInfo::getSelectorName(Selector S) {
485StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
486 bool *NameIsSimplified) {
489 return internString(GetName(RD,
false, NameIsSimplified));
495 return II->getName();
500 if (CGM.getCodeGenOpts().EmitCodeView) {
503 "Typedef should not be in another decl context!");
504 assert(D->getDeclName().getAsIdentifierInfo() &&
505 "Typedef was not named!");
506 return D->getDeclName().getAsIdentifierInfo()->getName();
509 if (CGM.getLangOpts().CPlusPlus) {
512 ASTContext &Context = CGM.getContext();
516 Name = DD->getName();
517 else if (
const TypedefNameDecl *TND =
521 Name = TND->getName();
524 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
525 if (CXXRD->isLambda())
527 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
530 SmallString<256> UnnamedType(
"<unnamed-type-");
533 return internString(UnnamedType);
541std::optional<llvm::DIFile::ChecksumKind>
542CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
545 if (!CGM.getCodeGenOpts().EmitCodeView &&
546 CGM.getCodeGenOpts().DwarfVersion < 5)
549 SourceManager &
SM = CGM.getContext().getSourceManager();
550 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
554 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
555 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
557 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
558 return llvm::DIFile::CSK_MD5;
560 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
561 return llvm::DIFile::CSK_SHA1;
563 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
564 return llvm::DIFile::CSK_SHA256;
568 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
571std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
573 if (!CGM.getCodeGenOpts().EmbedSource)
576 bool SourceInvalid =
false;
577 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
585llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
586 SourceManager &
SM = CGM.getContext().getSourceManager();
589 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
595 FileName = TheCU->getFile()->getFilename();
596 CSInfo = TheCU->getFile()->getChecksum();
599 if (Loc == CurLoc && CurLocFile)
602 PresumedLoc PLoc =
SM.getPresumedLoc(Loc);
606 FileName = TheCU->getFile()->getFilename();
614 auto It = DIFileCache.find(
FileName.data());
615 if (It != DIFileCache.end()) {
617 if (llvm::Metadata *
V = It->second)
622 SmallString<64> Checksum;
624 std::optional<llvm::DIFile::ChecksumKind> CSKind =
625 computeChecksum(FID, Checksum);
627 CSInfo.emplace(*CSKind, Checksum);
633llvm::DIFile *CGDebugInfo::createFile(
635 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
636 std::optional<StringRef> Source) {
640 std::string CurDir =
remapDIPath(getCurrentDirname());
641 SmallString<128> DirBuf;
642 SmallString<128> FileBuf;
643 if (llvm::sys::path::is_absolute(RemappedFile)) {
646 auto FileIt = llvm::sys::path::begin(RemappedFile);
647 auto FileE = llvm::sys::path::end(RemappedFile);
648 auto CurDirIt = llvm::sys::path::begin(CurDir);
649 auto CurDirE = llvm::sys::path::end(CurDir);
650 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
651 llvm::sys::path::append(DirBuf, *CurDirIt);
652 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
658 for (; FileIt != FileE; ++FileIt)
659 llvm::sys::path::append(FileBuf, *FileIt);
664 if (!llvm::sys::path::is_absolute(
FileName))
668 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
669 DIFileCache[
FileName.data()].reset(F);
675 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
676 if (llvm::sys::path::replace_path_prefix(P, From, To))
678 return P.str().str();
686 if (DebugLoc == CurLoc)
688 return SM.getPresumedLoc(DebugLoc).getLine();
701 if (DebugLoc == CurLoc)
707StringRef CGDebugInfo::getCurrentDirname() {
715 assert(CGO.DwarfVersion <= 5);
717 llvm::dwarf::SourceLanguage LangTag;
720 LangTag = llvm::dwarf::DW_LANG_HLSL;
722 LangTag = llvm::dwarf::DW_LANG_HIP;
724 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
725 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
726 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
727 else if (LO.CPlusPlus14)
728 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
729 else if (LO.CPlusPlus11)
730 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
732 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
733 }
else if (LO.ObjC) {
734 LangTag = llvm::dwarf::DW_LANG_ObjC;
735 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
736 LangTag = llvm::dwarf::DW_LANG_OpenCL;
737 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
738 LangTag = llvm::dwarf::DW_LANG_C11;
740 LangTag = llvm::dwarf::DW_LANG_C99;
742 LangTag = llvm::dwarf::DW_LANG_C89;
748static llvm::DISourceLanguageName
756 uint32_t LangVersion = 0;
757 llvm::dwarf::SourceLanguageName LangTag;
760 LangTag = llvm::dwarf::DW_LNAME_HLSL;
762 LangTag = llvm::dwarf::DW_LNAME_HIP;
763 }
else if (LO.ObjC) {
764 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
766 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
769 }
else if (LO.ObjC) {
770 LangTag = llvm::dwarf::DW_LNAME_ObjC;
771 }
else if (LO.OpenCL) {
772 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
774 LangTag = llvm::dwarf::DW_LNAME_C;
778 return llvm::DISourceLanguageName(LangTag, LangVersion);
781void CGDebugInfo::CreateCompileUnit() {
782 SmallString<64> Checksum;
783 std::optional<llvm::DIFile::ChecksumKind> CSKind;
784 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
794 SourceManager &
SM = CGM.getContext().getSourceManager();
795 auto &CGO = CGM.getCodeGenOpts();
796 const LangOptions &LO = CGM.getLangOpts();
797 std::string MainFileName = CGO.MainFileName;
798 if (MainFileName.empty())
799 MainFileName =
"<stdin>";
805 std::string MainFileDir;
807 SM.getFileEntryRefForID(
SM.getMainFileID())) {
808 MainFileDir = std::string(MainFile->getDir().getName());
809 if (!llvm::sys::path::is_absolute(MainFileName)) {
810 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
811 llvm::sys::path::Style Style =
813 ? (CGM.getTarget().
getTriple().isOSWindows()
814 ? llvm::sys::path::Style::windows_backslash
815 : llvm::sys::path::Style::posix)
816 : llvm::sys::path::Style::native;
817 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
818 MainFileName = std::string(
819 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
826 if (MainFile->getName() == MainFileName &&
828 MainFile->getName().rsplit(
'.').second)
830 MainFileName = CGM.getModule().getName().str();
832 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
839 unsigned RuntimeVers = 0;
843 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
845 case llvm::codegenoptions::NoDebugInfo:
846 case llvm::codegenoptions::LocTrackingOnly:
847 EmissionKind = llvm::DICompileUnit::NoDebug;
849 case llvm::codegenoptions::DebugLineTablesOnly:
850 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
852 case llvm::codegenoptions::DebugDirectivesOnly:
853 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
855 case llvm::codegenoptions::DebugInfoConstructor:
856 case llvm::codegenoptions::LimitedDebugInfo:
857 case llvm::codegenoptions::FullDebugInfo:
858 case llvm::codegenoptions::UnusedTypeInfo:
859 EmissionKind = llvm::DICompileUnit::FullDebug;
864 auto &CGOpts = CGM.getCodeGenOpts();
870 CSInfo.emplace(*CSKind, Checksum);
871 llvm::DIFile *CUFile = DBuilder.createFile(
873 getSource(
SM,
SM.getMainFileID()));
875 StringRef Sysroot, SDK;
876 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
877 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
878 auto B = llvm::sys::path::rbegin(Sysroot);
879 auto E = llvm::sys::path::rend(Sysroot);
881 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
886 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
887 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
888 CGOpts.DebugNameTable);
889 if (CGM.getTarget().getTriple().isNVPTX())
890 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
891 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
892 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
895 TheCU = DBuilder.createCompileUnit(
897 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
898 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
899 CGOpts.PrepareForThinLTO,
900 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
901 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
902 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
905llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
909#define BUILTIN_TYPE(Id, SingletonId)
910#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
911#include "clang/AST/BuiltinTypes.def"
912 case BuiltinType::Dependent:
913 llvm_unreachable(
"Unexpected builtin type");
914 case BuiltinType::NullPtr:
915 return DBuilder.createNullPtrType();
916 case BuiltinType::Void:
918 case BuiltinType::ObjCClass:
921 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
922 "objc_class", TheCU, TheCU->getFile(), 0);
924 case BuiltinType::ObjCId: {
935 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
936 "objc_class", TheCU, TheCU->getFile(), 0);
938 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
940 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
942 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
943 (uint64_t)0, 0, llvm::DINode::FlagZero,
944 nullptr, llvm::DINodeArray());
946 DBuilder.replaceArrays(
947 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
948 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
949 llvm::DINode::FlagZero, ISATy)));
952 case BuiltinType::ObjCSel: {
954 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
955 "objc_selector", TheCU,
956 TheCU->getFile(), 0);
960#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
961 case BuiltinType::Id: \
962 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
964#include "clang/Basic/OpenCLImageTypes.def"
965 case BuiltinType::OCLSampler:
966 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
967 case BuiltinType::OCLEvent:
968 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
969 case BuiltinType::OCLClkEvent:
970 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
971 case BuiltinType::OCLQueue:
972 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
973 case BuiltinType::OCLReserveID:
974 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
975#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
976 case BuiltinType::Id: \
977 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
978#include "clang/Basic/OpenCLExtensionTypes.def"
979#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
980 case BuiltinType::Id: \
981 return getOrCreateStructPtrType(#Name, SingletonId);
982#include "clang/Basic/HLSLIntangibleTypes.def"
984#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
985#include "clang/Basic/AArch64ACLETypes.def"
987 if (BT->
getKind() == BuiltinType::MFloat8) {
988 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
989 BTName = BT->
getName(CGM.getLangOpts());
992 return DBuilder.createBasicType(BTName, Size, Encoding);
994 ASTContext::BuiltinVectorTypeInfo Info =
996 BT->
getKind() == BuiltinType::SveCount
997 ? ASTContext::BuiltinVectorTypeInfo(
998 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1000 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1007 "Unsupported number of vectors for svcount_t");
1009 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1010 llvm::Metadata *BitStride =
nullptr;
1011 if (BT->
getKind() == BuiltinType::SveBool) {
1012 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1013 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1014 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1015 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1017 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1020 llvm::Metadata *LowerBound, *UpperBound;
1021 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1022 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1023 if (Info.
EC.isScalable()) {
1024 unsigned NumElemsPerVG = NumElems / 2;
1025 SmallVector<uint64_t, 9> Expr(
1026 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1027 46, 0, llvm::dwarf::DW_OP_mul,
1028 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1029 UpperBound = DBuilder.createExpression(Expr);
1031 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1032 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1034 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1035 nullptr, LowerBound, UpperBound,
nullptr);
1036 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1037 llvm::DIType *ElemTy =
1038 getOrCreateType(Info.
ElementType, TheCU->getFile());
1040 return DBuilder.createVectorType( 0, Align, ElemTy,
1041 SubscriptArray, BitStride);
1045#define PPC_VECTOR_TYPE(Name, Id, size) \
1046 case BuiltinType::Id:
1047#include "clang/Basic/PPCTypes.def"
1050#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1051#include "clang/Basic/RISCVVTypes.def"
1053 ASTContext::BuiltinVectorTypeInfo Info =
1054 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1056 unsigned ElementCount = Info.
EC.getKnownMinValue();
1057 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1059 bool Fractional =
false;
1062 unsigned FixedSize = ElementCount * SEW;
1063 if (Info.
ElementType == CGM.getContext().BoolTy) {
1066 }
else if (FixedSize < 64) {
1069 LMUL = 64 / FixedSize;
1071 LMUL = FixedSize / 64;
1075 SmallVector<uint64_t, 12> Expr(
1079 {llvm::dwarf::DW_OP_bregx,
1082 llvm::dwarf::DW_OP_constu,
1084 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1086 Expr.push_back(llvm::dwarf::DW_OP_div);
1088 Expr.push_back(llvm::dwarf::DW_OP_mul);
1091 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1093 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1096 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1097 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1098 auto *UpperBound = DBuilder.createExpression(Expr);
1099 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1100 nullptr, LowerBound, UpperBound,
nullptr);
1101 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1102 llvm::DIType *ElemTy =
1103 getOrCreateType(Info.
ElementType, TheCU->getFile());
1106 return DBuilder.createVectorType(0, Align, ElemTy,
1110#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1111 case BuiltinType::Id: { \
1114 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1115 MangledName, TheCU, TheCU->getFile(), 0); \
1116 return SingletonId; \
1118#include "clang/Basic/WebAssemblyReferenceTypes.def"
1119#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1120 case BuiltinType::Id: { \
1123 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1124 TheCU, TheCU->getFile(), 0); \
1125 return SingletonId; \
1127#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1128 case BuiltinType::Id: { \
1131 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1132 return SingletonId; \
1134#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1135 case BuiltinType::Id: { \
1138 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1139 return SingletonId; \
1141#include "clang/Basic/AMDGPUTypes.def"
1142 case BuiltinType::UChar:
1143 case BuiltinType::Char_U:
1144 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1146 case BuiltinType::Char_S:
1147 case BuiltinType::SChar:
1148 Encoding = llvm::dwarf::DW_ATE_signed_char;
1150 case BuiltinType::Char8:
1151 case BuiltinType::Char16:
1152 case BuiltinType::Char32:
1153 Encoding = llvm::dwarf::DW_ATE_UTF;
1155 case BuiltinType::UShort:
1156 case BuiltinType::UInt:
1157 case BuiltinType::UInt128:
1158 case BuiltinType::ULong:
1159 case BuiltinType::WChar_U:
1160 case BuiltinType::ULongLong:
1161 Encoding = llvm::dwarf::DW_ATE_unsigned;
1163 case BuiltinType::Short:
1164 case BuiltinType::Int:
1165 case BuiltinType::Int128:
1166 case BuiltinType::Long:
1167 case BuiltinType::WChar_S:
1168 case BuiltinType::LongLong:
1169 Encoding = llvm::dwarf::DW_ATE_signed;
1171 case BuiltinType::Bool:
1172 Encoding = llvm::dwarf::DW_ATE_boolean;
1174 case BuiltinType::Half:
1175 case BuiltinType::Float:
1176 case BuiltinType::LongDouble:
1177 case BuiltinType::Float16:
1178 case BuiltinType::BFloat16:
1179 case BuiltinType::Float128:
1180 case BuiltinType::Double:
1181 case BuiltinType::Ibm128:
1187 Encoding = llvm::dwarf::DW_ATE_float;
1189 case BuiltinType::ShortAccum:
1190 case BuiltinType::Accum:
1191 case BuiltinType::LongAccum:
1192 case BuiltinType::ShortFract:
1193 case BuiltinType::Fract:
1194 case BuiltinType::LongFract:
1195 case BuiltinType::SatShortFract:
1196 case BuiltinType::SatFract:
1197 case BuiltinType::SatLongFract:
1198 case BuiltinType::SatShortAccum:
1199 case BuiltinType::SatAccum:
1200 case BuiltinType::SatLongAccum:
1201 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1203 case BuiltinType::UShortAccum:
1204 case BuiltinType::UAccum:
1205 case BuiltinType::ULongAccum:
1206 case BuiltinType::UShortFract:
1207 case BuiltinType::UFract:
1208 case BuiltinType::ULongFract:
1209 case BuiltinType::SatUShortAccum:
1210 case BuiltinType::SatUAccum:
1211 case BuiltinType::SatULongAccum:
1212 case BuiltinType::SatUShortFract:
1213 case BuiltinType::SatUFract:
1214 case BuiltinType::SatULongFract:
1215 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1219 BTName = BT->
getName(CGM.getLangOpts());
1222 return DBuilder.createBasicType(BTName, Size, Encoding);
1225llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1226 SmallString<32> Name;
1227 llvm::raw_svector_ostream
OS(Name);
1228 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1231 ? llvm::dwarf::DW_ATE_unsigned
1232 : llvm::dwarf::DW_ATE_signed;
1233 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1234 Encoding, llvm::DINode::FlagZero, 0,
1238llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1240 return getOrCreateType(Ty->getUnderlyingType(), U);
1243llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1245 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1247 Encoding = llvm::dwarf::DW_ATE_lo_user;
1250 return DBuilder.createBasicType(
"complex", Size, Encoding);
1264 return llvm::dwarf::DW_TAG_const_type;
1268 return llvm::dwarf::DW_TAG_volatile_type;
1272 return llvm::dwarf::DW_TAG_restrict_type;
1274 return (llvm::dwarf::Tag)0;
1277llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1278 llvm::DIFile *Unit) {
1279 QualifierCollector Qc;
1293 bool AuthenticatesNullValues =
1296 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1297 llvm::DIType *FromTy = getOrCreateType(QualType(T, 0), Unit);
1298 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1299 ExtraDiscr, IsaPointer,
1300 AuthenticatesNullValues);
1302 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1303 return getOrCreateType(QualType(T, 0), Unit);
1307 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
1311 return DBuilder.createQualifiedType(Tag, FromTy);
1314llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1315 llvm::DIFile *Unit) {
1324 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1329 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1335 return DBuilder.createQualifiedType(Tag, FromTy);
1338llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1339 llvm::DIFile *Unit) {
1345 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1347 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1351llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1352 llvm::DIFile *Unit) {
1353 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1359 case llvm::dwarf::DW_LANG_C_plus_plus:
1360 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1361 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1362 case llvm::dwarf::DW_LANG_HIP:
1364 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1374 case llvm::dwarf::DW_LNAME_C_plus_plus:
1375 case llvm::dwarf::DW_LNAME_HIP:
1377 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1388 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1389 SourceLang.hasVersionedName())
1391 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1395 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1421 llvm::DICompileUnit *TheCU) {
1439 llvm::DICompileUnit *TheCU) {
1445 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1447 if (RD->isDynamicClass() &&
1453 llvm::raw_svector_ostream Out(Identifier);
1460 llvm::dwarf::Tag Tag;
1462 Tag = llvm::dwarf::DW_TAG_structure_type;
1464 Tag = llvm::dwarf::DW_TAG_union_type;
1469 Tag = llvm::dwarf::DW_TAG_class_type;
1474llvm::DICompositeType *
1475CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1476 llvm::DIScope *Ctx) {
1477 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1478 if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
1480 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1481 const unsigned Line =
1483 StringRef RDName = getClassName(RD);
1490 Size = CGM.getContext().getTypeSize(Ty);
1492 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1497 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1498 if (!CXXRD->hasDefinition() ||
1499 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1500 Flags |= llvm::DINode::FlagNonTrivial;
1503 SmallString<256> Identifier;
1505 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1507 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1510 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1511 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1512 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1513 CollectCXXTemplateParams(TSpecial, DefUnit));
1514 ReplaceMap.emplace_back(
1515 std::piecewise_construct, std::make_tuple(Ty),
1516 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1520llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1523 llvm::DIFile *Unit) {
1528 std::optional<unsigned> DWARFAddressSpace =
1529 CGM.getTarget().getDWARFAddressSpace(
1530 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1532 const BTFTagAttributedType *BTFAttrTy;
1533 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1534 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1536 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1537 SmallVector<llvm::Metadata *, 4> Annots;
1539 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1541 llvm::Metadata *Ops[2] = {
1542 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1543 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1544 Annots.insert(Annots.begin(),
1545 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1547 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1550 llvm::DINodeArray Annotations =
nullptr;
1551 if (Annots.size() > 0)
1552 Annotations = DBuilder.getOrCreateArray(Annots);
1554 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1555 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1556 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1557 Size, Align, DWARFAddressSpace);
1559 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1560 Align, DWARFAddressSpace, StringRef(),
1564llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1565 llvm::DIType *&
Cache) {
1568 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1569 TheCU, TheCU->getFile(), 0);
1570 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1571 Cache = DBuilder.createPointerType(
Cache, Size);
1575uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1576 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1577 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1587 if (CGM.getLangOpts().OpenCL) {
1588 FType = CGM.getContext().IntTy;
1589 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1590 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1592 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1593 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1594 FType = CGM.getContext().IntTy;
1595 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1596 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1598 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1599 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1600 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1601 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1602 EltTys.push_back(DBuilder.createMemberType(
1603 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1604 FieldOffset, llvm::DINode::FlagZero, DescTy));
1605 FieldOffset += FieldSize;
1611llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1612 llvm::DIFile *Unit) {
1613 SmallVector<llvm::Metadata *, 8> EltTys;
1616 llvm::DINodeArray Elements;
1619 FType = CGM.getContext().UnsignedLongTy;
1620 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1621 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1623 Elements = DBuilder.getOrCreateArray(EltTys);
1626 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1629 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1630 FieldOffset, 0, Flags,
nullptr, Elements);
1635 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1637 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1640 Elements = DBuilder.getOrCreateArray(EltTys);
1646 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1647 Flags,
nullptr, Elements);
1649 return DBuilder.createPointerType(EltTy, Size);
1652static llvm::SmallVector<TemplateArgument>
1654 assert(Ty->isTypeAlias());
1663 ArrayRef SubstArgs = Ty->template_arguments();
1666 if (Param->isParameterPack()) {
1675 if (SubstArgs.empty()) {
1684 SpecArgs.push_back(SubstArgs.front());
1685 SubstArgs = SubstArgs.drop_front();
1690llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1691 llvm::DIFile *Unit) {
1692 assert(Ty->isTypeAlias());
1693 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1695 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1703 SmallString<128> NS;
1704 llvm::raw_svector_ostream
OS(NS);
1706 auto PP = getPrintingPolicy();
1709 SourceLocation Loc =
AliasDecl->getLocation();
1711 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1712 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1721 llvm::raw_string_ostream
OS(Name);
1723 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1724 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1725 !HasReconstitutableArgs(Args.Args))
1726 printTemplateArgumentList(OS, Args.Args, PP);
1728 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1729 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1730 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1734 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1736 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1753 return llvm::DINode::FlagZero;
1757 return llvm::DINode::FlagPrivate;
1759 return llvm::DINode::FlagProtected;
1761 return llvm::DINode::FlagPublic;
1763 return llvm::DINode::FlagZero;
1765 llvm_unreachable(
"unexpected access enumerator");
1768llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1769 llvm::DIFile *Unit) {
1770 llvm::DIType *Underlying =
1782 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1784 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1789 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1790 getOrCreateFile(Loc), getLineNumber(Loc),
1791 getDeclContextDescriptor(Ty->
getDecl()), Align,
1792 Flags, Annotations);
1802 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1804 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1806 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1808 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1810 return llvm::dwarf::DW_CC_BORLAND_pascal;
1812 return llvm::dwarf::DW_CC_LLVM_Win64;
1814 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1818 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1820 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1822 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1824 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1826 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1828 return llvm::dwarf::DW_CC_LLVM_Swift;
1830 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1832 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1834 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1836 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1838 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1840 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1842 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1843#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1857 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1863 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1865 Flags |= llvm::DINode::FlagLValueReference;
1867 Flags |= llvm::DINode::FlagRValueReference;
1871llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1872 llvm::DIFile *Unit) {
1873 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1875 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1881 SmallVector<llvm::Metadata *, 16> EltTys;
1884 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1886 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1890 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1893 for (
const QualType &ParamType : FPT->param_types())
1894 EltTys.push_back(getOrCreateType(ParamType, Unit));
1895 if (FPT->isVariadic())
1896 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1899 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1900 llvm::DIType *F = DBuilder.createSubroutineType(
1905llvm::DIDerivedType *
1906CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1907 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1908 StringRef Name = BitFieldDecl->
getName();
1909 QualType Ty = BitFieldDecl->
getType();
1910 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1913 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1914 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1917 llvm::DIFile *
File = getOrCreateFile(Loc);
1918 unsigned Line = getLineNumber(Loc);
1920 const CGBitFieldInfo &BitFieldInfo =
1921 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1923 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1930 if (CGM.getDataLayout().isBigEndian())
1932 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1934 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1935 return DBuilder.createBitFieldMemberType(
1936 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1937 Flags, DebugType, Annotations);
1940llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1941 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1942 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1944 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1969 if (PreviousFieldsDI.empty())
1973 auto *PreviousMDEntry =
1974 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1975 auto *PreviousMDField =
1976 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1977 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1978 PreviousMDField->getSizeInBits() == 0)
1982 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1984 assert(PreviousBitfield->isBitField());
1986 if (!PreviousBitfield->isZeroLengthBitField())
1989 QualType Ty = PreviousBitfield->getType();
1990 SourceLocation Loc = PreviousBitfield->getLocation();
1991 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1992 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1993 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1995 llvm::DIFile *
File = getOrCreateFile(Loc);
1996 unsigned Line = getLineNumber(Loc);
2002 llvm::DINode::DIFlags Flags =
2004 llvm::DINodeArray Annotations =
2005 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2006 return DBuilder.createBitFieldMemberType(
2007 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2008 Flags, DebugType, Annotations);
2011llvm::DIType *CGDebugInfo::createFieldType(
2013 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
2014 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2015 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2018 llvm::DIFile *file = getOrCreateFile(loc);
2019 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2022 auto Align = AlignInBits;
2023 if (!
type->isIncompleteArrayType()) {
2024 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2025 SizeInBits = TI.
Width;
2031 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2032 offsetInBits, flags, debugType, Annotations);
2036CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2037 llvm::DIFile *FileScope) {
2041 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2044 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2045 SP = DBuilder.createFunction(
2046 FileScope, FuncName, StringRef(),
2047 FileScope, 0, DIFnTy,
2049 llvm::DINode::FlagArtificial,
2050 llvm::DISubprogram::SPFlagDefinition,
2051 nullptr,
nullptr,
nullptr,
2052 nullptr, StringRef(),
2053 CGM.getCodeGenOpts().DebugKeyInstructions);
2060CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2062 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2064 assert(
Capture.capturesVariable());
2066 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2067 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2069 return CaptureDecl->
getName();
2072void CGDebugInfo::CollectRecordLambdaFields(
2073 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2074 llvm::DIType *RecordTy) {
2079 unsigned fieldno = 0;
2082 I != E; ++I, ++Field, ++fieldno) {
2083 const LambdaCapture &
Capture = *I;
2085 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2087 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2097 Loc =
Field->getLocation();
2098 }
else if (
Capture.capturesVariable()) {
2101 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2102 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2109 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2111 elements.push_back(createFieldType(
2113 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2119template <
typename T>
2120static llvm::Constant *
2131 return llvm::ConstantDataArray::get(Ctx, Vals);
2144 const QualType ElemQTy = ArrayTy->getElementType();
2151 switch (ElemBitWidth) {
2167llvm::DIDerivedType *
2168CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2169 const RecordDecl *RD) {
2173 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2174 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2176 unsigned LineNumber = getLineNumber(Var->
getLocation());
2177 StringRef VName = Var->
getName();
2181 llvm::Constant *
C =
nullptr;
2186 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2187 if (
Value->isFloat())
2188 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2189 if (
Value->isArray())
2195 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2196 ? llvm::dwarf::DW_TAG_variable
2197 : llvm::dwarf::DW_TAG_member;
2199 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2200 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2205void CGDebugInfo::CollectRecordNormalField(
2206 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2207 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2208 const RecordDecl *RD) {
2213 if (
name.empty() && !
type->isRecordType())
2216 llvm::DIType *FieldType;
2218 llvm::DIDerivedType *BitFieldType;
2219 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2220 if (llvm::DIType *Separator =
2221 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2222 elements.push_back(Separator);
2225 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2228 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2231 elements.push_back(FieldType);
2234void CGDebugInfo::CollectRecordNestedType(
2235 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2236 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2243 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2244 elements.push_back(nestedType);
2247void CGDebugInfo::CollectRecordFields(
2248 const RecordDecl *record, llvm::DIFile *tunit,
2249 SmallVectorImpl<llvm::Metadata *> &elements,
2250 llvm::DICompositeType *RecordTy) {
2251 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2253 if (CXXDecl && CXXDecl->
isLambda())
2254 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2256 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2259 unsigned fieldNo = 0;
2263 for (
const auto *I : record->
decls())
2264 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2265 if (
V->hasAttr<NoDebugAttr>())
2270 if (CGM.getCodeGenOpts().EmitCodeView &&
2278 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2279 if (MI != StaticDataMemberCache.end()) {
2280 assert(MI->second &&
2281 "Static data member declaration should still exist");
2282 elements.push_back(MI->second);
2284 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2285 elements.push_back(Field);
2287 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2288 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2289 elements, RecordTy, record);
2293 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2296 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2301 if (!nestedType->isImplicit() &&
2302 nestedType->getDeclContext() == record)
2303 CollectRecordNestedType(nestedType, elements);
2309llvm::DISubroutineType *
2310CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2311 llvm::DIFile *Unit) {
2312 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2314 return cast_or_null<llvm::DISubroutineType>(
2315 getOrCreateType(QualType(
Func, 0), Unit));
2318 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2319 ThisType =
Method->getThisType();
2321 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2324llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2325 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2326 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2328 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2331llvm::DISubroutineType *
2332CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2333 const FunctionProtoType *
Func,
2334 llvm::DIFile *Unit,
bool SkipFirst) {
2335 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2350 getOrCreateType(CGM.getContext().getFunctionType(
2351 Func->getReturnType(),
Func->getParamTypes(), EPI),
2353 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2354 assert(Args.size() &&
"Invalid number of arguments!");
2356 SmallVector<llvm::Metadata *, 16> Elts;
2359 Elts.push_back(Args[0]);
2361 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2365 if (!HasExplicitObjectParameter) {
2366 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2369 DBuilder.createObjectPointerType(ThisPtrType,
true);
2370 Elts.push_back(ThisPtrType);
2374 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2375 Elts.push_back(Args[i]);
2378 if (HasExplicitObjectParameter) {
2379 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2380 "Expected at least return type and object parameter.");
2381 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2384 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2386 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2393 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2401CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2404 const bool IsCtorOrDtor =
2407 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2414 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2417 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2420 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2423 return CGM.getMangledName(
Method);
2426bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2429 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2432llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2433 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2436 StringRef MethodName = getFunctionName(
Method);
2437 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2439 StringRef MethodLinkageName;
2446 MethodLinkageName = GetMethodLinkageName(
Method);
2449 llvm::DIFile *MethodDefUnit =
nullptr;
2450 unsigned MethodLine = 0;
2451 if (!
Method->isImplicit()) {
2452 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2453 MethodLine = getLineNumber(
Method->getLocation());
2457 llvm::DIType *ContainingType =
nullptr;
2458 unsigned VIndex = 0;
2459 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2460 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2461 int ThisAdjustment = 0;
2464 if (
Method->isPureVirtual())
2465 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2467 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2469 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2473 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2477 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2480 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2481 CGM.getContext().getLangOpts())
2485 MethodVFTableLocation ML =
2486 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2494 if (
Method->size_overridden_methods() == 0)
2495 Flags |= llvm::DINode::FlagIntroducedVirtual;
2500 ThisAdjustment = CGM.getCXXABI()
2501 .getVirtualFunctionPrologueThisAdjustment(GD)
2504 ContainingType = RecordTy;
2507 if (
Method->getCanonicalDecl()->isDeleted())
2508 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2510 if (
Method->isNoReturn())
2511 Flags |= llvm::DINode::FlagNoReturn;
2514 Flags |= llvm::DINode::FlagStaticMember;
2515 if (
Method->isImplicit())
2516 Flags |= llvm::DINode::FlagArtificial;
2518 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2519 if (CXXC->isExplicit())
2520 Flags |= llvm::DINode::FlagExplicit;
2521 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2522 if (CXXC->isExplicit())
2523 Flags |= llvm::DINode::FlagExplicit;
2525 if (
Method->hasPrototype())
2526 Flags |= llvm::DINode::FlagPrototyped;
2528 Flags |= llvm::DINode::FlagLValueReference;
2530 Flags |= llvm::DINode::FlagRValueReference;
2531 if (!
Method->isExternallyVisible())
2532 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2533 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2534 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2538 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2539 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2542 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2543 llvm::DISubprogram *SP = DBuilder.createMethod(
2544 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2545 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2546 TParamsArray.get(),
nullptr,
2547 CGM.getCodeGenOpts().DebugKeyInstructions);
2549 SPCache[
Method->getCanonicalDecl()].reset(SP);
2554void CGDebugInfo::CollectCXXMemberFunctions(
2555 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2556 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2561 for (
const auto *I : RD->
decls()) {
2562 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2576 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2585 auto MI = SPCache.find(
Method->getCanonicalDecl());
2586 EltTys.push_back(MI == SPCache.end()
2587 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2588 :
static_cast<llvm::Metadata *
>(MI->second));
2592void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2593 SmallVectorImpl<llvm::Metadata *> &EltTys,
2594 llvm::DIType *RecordTy) {
2595 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2596 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2597 llvm::DINode::FlagZero);
2601 if (CGM.getCodeGenOpts().EmitCodeView) {
2602 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2603 llvm::DINode::FlagIndirectVirtualBase);
2607void CGDebugInfo::CollectCXXBasesAux(
2608 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2609 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2611 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2612 llvm::DINode::DIFlags StartingFlags) {
2613 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2614 for (
const auto &BI : Bases) {
2617 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2619 if (!SeenTypes.insert(Base).second)
2621 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2622 llvm::DINode::DIFlags BFlags = StartingFlags;
2626 if (BI.isVirtual()) {
2627 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2630 BaseOffset = 0 - CGM.getItaniumVTableContext()
2631 .getVirtualBaseOffsetOffset(RD, Base)
2637 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2638 VBPtrOffset = CGM.getContext()
2639 .getASTRecordLayout(RD)
2643 BFlags |= llvm::DINode::FlagVirtual;
2650 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2651 VBPtrOffset, BFlags);
2652 EltTys.push_back(DTy);
2657CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2658 llvm::DIFile *Unit) {
2660 return llvm::DINodeArray();
2661 TemplateArgs &Args = *OArgs;
2662 SmallVector<llvm::Metadata *, 16> TemplateParams;
2663 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2664 const TemplateArgument &TA = Args.Args[i];
2668 Name = Args.TList->getParam(i)->getName();
2672 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2673 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2674 TheCU, Name, TTy, defaultParameter));
2679 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2680 TheCU, Name, TTy, defaultParameter,
2681 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2686 llvm::DIType *TTy = getOrCreateType(T, Unit);
2687 llvm::Constant *
V =
nullptr;
2690 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2691 !D->
hasAttr<CUDADeviceAttr>()) {
2694 if (
const auto *VD = dyn_cast<VarDecl>(D))
2695 V = CGM.GetAddrOfGlobalVar(VD);
2698 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2699 MD && MD->isImplicitObjectMemberFunction())
2700 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2701 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2702 V = CGM.GetAddrOfFunction(FD);
2705 else if (
const auto *MPT =
2706 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2710 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2712 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2713 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2714 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2715 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2716 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2718 V = ConstantEmitter(CGM).emitAbstract(
2719 SourceLocation(), TPO->getValue(), TPO->getType());
2721 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2723 assert(
V &&
"Failed to find template parameter pointer");
2724 V =
V->stripPointerCasts();
2726 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2727 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2731 llvm::DIType *TTy = getOrCreateType(T, Unit);
2732 llvm::Constant *
V =
nullptr;
2735 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2741 if (MPT->isMemberDataPointer())
2742 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2744 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2745 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2746 TheCU, Name, TTy, defaultParameter,
V));
2750 llvm::DIType *TTy = getOrCreateType(T, Unit);
2751 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2753 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2754 TheCU, Name, TTy, defaultParameter,
V));
2757 std::string QualName;
2758 llvm::raw_string_ostream
OS(QualName);
2760 OS, getPrintingPolicy());
2761 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2762 TheCU, Name,
nullptr, QualName, defaultParameter));
2766 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2767 TheCU, Name,
nullptr,
2774 T = CGM.getContext().getLValueReferenceType(T);
2775 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2776 assert(
V &&
"Expression in template argument isn't constant");
2777 llvm::DIType *TTy = getOrCreateType(T, Unit);
2778 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2779 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2785 "These argument types shouldn't exist in concrete types");
2788 return DBuilder.getOrCreateArray(TemplateParams);
2791std::optional<CGDebugInfo::TemplateArgs>
2792CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2800 return std::nullopt;
2802std::optional<CGDebugInfo::TemplateArgs>
2803CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2807 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2809 return std::nullopt;
2810 VarTemplateDecl *T = TS->getSpecializedTemplate();
2812 auto TA = TS->getTemplateArgs().asArray();
2813 return {{TList, TA}};
2815std::optional<CGDebugInfo::TemplateArgs>
2816CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2817 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2821 TemplateParameterList *TPList =
2822 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2823 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2824 return {{TPList, TAList.
asArray()}};
2826 return std::nullopt;
2830CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2831 llvm::DIFile *Unit) {
2832 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2835llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2836 llvm::DIFile *Unit) {
2837 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2840llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2841 llvm::DIFile *Unit) {
2842 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2845llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2846 if (!D->
hasAttr<BTFDeclTagAttr>())
2849 SmallVector<llvm::Metadata *, 4> Annotations;
2851 llvm::Metadata *Ops[2] = {
2852 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2853 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2854 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2856 return DBuilder.getOrCreateArray(Annotations);
2859llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2861 return VTablePtrType;
2863 ASTContext &Context = CGM.getContext();
2866 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2867 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2868 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2870 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2871 std::optional<unsigned> DWARFAddressSpace =
2872 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2874 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2875 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2876 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2877 return VTablePtrType;
2880StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2892 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2894 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2904 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2905 VTable->isDeclarationForLinker())
2909 StringRef SymbolName =
"__clang_vtable";
2911 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2920 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2922 llvm::DIFile *Unit = getOrCreateFile(Loc);
2923 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2925 llvm::DINode::FlagArtificial;
2926 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2927 ? llvm::dwarf::DW_TAG_variable
2928 : llvm::dwarf::DW_TAG_member;
2929 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2930 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2934 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2938 llvm::DIGlobalVariableExpression *GVE =
2939 DBuilder.createGlobalVariableExpression(
2940 TheCU, SymbolName, VTable->getName(), Unit, 0,
2941 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2942 true,
nullptr, DT,
nullptr,
2944 VTable->addDebugInfo(GVE);
2947StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2949 llvm::Function *InitFn) {
2954 return InitFn->getName();
2964 llvm::raw_svector_ostream OS(QualifiedGV);
2966 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2968 std::swap(Quals, GVName);
2972 llvm::raw_svector_ostream OS(InitName);
2974 OS << Quals <<
"::";
2979 llvm_unreachable(
"not an initializer");
2981 OS <<
"`dynamic initializer for '";
2984 OS <<
"`dynamic atexit destructor for '";
2991 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2992 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2993 getPrintingPolicy());
2998 return internString(
OS.str());
3001void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3002 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3011 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3018 llvm::DIType *VPtrTy =
nullptr;
3019 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3020 CGM.getTarget().getCXXABI().isMicrosoft();
3021 if (NeedVTableShape) {
3023 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3024 const VTableLayout &VFTLayout =
3025 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3026 unsigned VSlotCount =
3028 unsigned VTableWidth = PtrWidth * VSlotCount;
3029 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3030 std::optional<unsigned> DWARFAddressSpace =
3031 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3034 llvm::DIType *VTableType = DBuilder.createPointerType(
3035 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3036 EltTys.push_back(VTableType);
3039 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3047 VPtrTy = getOrCreateVTablePtrType(Unit);
3049 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3050 llvm::DIType *VPtrMember =
3051 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3052 llvm::DINode::FlagArtificial, VPtrTy);
3053 EltTys.push_back(VPtrMember);
3058 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3059 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3070 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3071 assert(!D.
isNull() &&
"null type");
3072 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3073 assert(T &&
"could not create debug info for type");
3082 if (CGM.getCodeGenOpts().getDebugInfo() <=
3083 llvm::codegenoptions::DebugLineTablesOnly)
3087 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3089 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3091 CI->setMetadata(
"heapallocsite", node);
3095 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3097 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3099 auto I = TypeCache.find(TyPtr);
3102 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3103 assert(!Res->isForwardDecl());
3104 TypeCache[TyPtr].reset(Res);
3108 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3109 !CGM.getLangOpts().CPlusPlus)
3115 if (RD->
hasAttr<DLLImportAttr>())
3118 if (MD->hasAttr<DLLImportAttr>())
3131 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3141 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3142 Explicit = TD->isExplicitInstantiationOrSpecialization();
3146 if (CXXDecl->
fields().empty())
3156 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3157 if (CXXRD->isDynamicClass() &&
3158 CGM.getVTableLinkage(CXXRD) ==
3159 llvm::GlobalValue::AvailableExternallyLinkage &&
3170 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3172 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3174 auto I = TypeCache.find(TyPtr);
3181 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3182 assert(!Res->isForwardDecl());
3183 TypeCache[TyPtr].reset(Res);
3190 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3191 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3214 if (Ctor->isCopyOrMoveConstructor())
3216 if (!Ctor->isDeleted())
3235 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3238 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3239 RD->
hasAttr<StandaloneDebugAttr>())
3242 if (!LangOpts.CPlusPlus)
3248 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3264 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3265 Spec = SD->getSpecializationKind();
3274 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3285 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3286 llvm::DIType *T = getTypeOrNull(Ty);
3287 if (T && T->isForwardDecl())
3291llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3292 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3293 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3297 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3301 auto [Def, Pref] = CreateTypeDefinition(Ty);
3303 return Pref ? Pref : Def;
3306llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3307 llvm::DIFile *Unit) {
3311 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3315 return getOrCreateType(PNA->getTypedefType(), Unit);
3318std::pair<llvm::DIType *, llvm::DIType *>
3319CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3320 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3323 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3331 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3335 return {FwdDecl,
nullptr};
3337 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3338 CollectContainingType(CXXDecl, FwdDecl);
3341 LexicalBlockStack.emplace_back(&*FwdDecl);
3342 RegionMap[RD].reset(FwdDecl);
3345 SmallVector<llvm::Metadata *, 16> EltTys;
3352 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3354 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3355 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3359 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3360 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3361 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3363 LexicalBlockStack.pop_back();
3364 RegionMap.erase(RD);
3366 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3367 DBuilder.replaceArrays(FwdDecl, Elements);
3369 if (FwdDecl->isTemporary())
3371 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3373 RegionMap[RD].reset(FwdDecl);
3375 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3376 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3377 return {FwdDecl, PrefDI};
3379 return {FwdDecl,
nullptr};
3382llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3383 llvm::DIFile *Unit) {
3385 return getOrCreateType(Ty->getBaseType(), Unit);
3388llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3389 llvm::DIFile *Unit) {
3391 SourceLocation Loc = Ty->getDecl()->getLocation();
3394 return DBuilder.createTypedef(
3395 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3396 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3397 getDeclContextDescriptor(Ty->getDecl()));
3424llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3425 llvm::DIFile *Unit) {
3430 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3431 TheCU->getSourceLanguage().getUnversionedName());
3436 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3437 !
ID->getImplementation())
3438 return DBuilder.createForwardDecl(
3439 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3440 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3443 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3444 unsigned Line = getLineNumber(
ID->getLocation());
3448 ObjCInterfaceDecl *Def =
ID->getDefinition();
3450 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3451 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3452 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3453 DefUnit,
Line, RuntimeLang);
3454 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3458 return CreateTypeDefinition(Ty, Unit);
3461llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3462 bool CreateSkeletonCU) {
3467 auto ModRef = ModuleCache.find(M);
3468 if (ModRef != ModuleCache.end())
3472 SmallString<128> ConfigMacros;
3474 llvm::raw_svector_ostream
OS(ConfigMacros);
3475 const auto &PPOpts = CGM.getPreprocessorOpts();
3478 for (
auto &M : PPOpts.Macros) {
3481 const std::string &
Macro = M.first;
3482 bool Undef = M.second;
3483 OS <<
"\"-" << (Undef ?
'U' :
'D');
3499 bool IsRootModule = M ? !M->
Parent :
true;
3503 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3504 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3505 "clang module without ASTFile must be specified by -fmodule-name");
3508 auto RemapPath = [
this](StringRef Path) -> std::string {
3510 StringRef Relative(Remapped);
3511 StringRef CompDir = TheCU->getDirectory();
3512 if (CompDir.empty())
3515 if (Relative.consume_front(CompDir))
3516 Relative.consume_front(llvm::sys::path::get_separator());
3518 return Relative.str();
3521 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3528 Signature = ModSig.truncatedValue();
3532 llvm::DIBuilder DIB(CGM.getModule());
3534 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3535 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3536 PCM = getCurrentDirname();
3540 llvm::sys::path::append(PCM, Mod.
getASTFile());
3541 DIB.createCompileUnit(
3542 TheCU->getSourceLanguage(),
3545 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3546 llvm::DICompileUnit::FullDebug, Signature);
3550 llvm::DIModule *Parent =
3552 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3554 std::string IncludePath = Mod.
getPath().str();
3555 llvm::DIModule *DIMod =
3556 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3557 RemapPath(IncludePath));
3558 ModuleCache[M].reset(DIMod);
3562llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3563 llvm::DIFile *Unit) {
3565 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3566 unsigned Line = getLineNumber(
ID->getLocation());
3568 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3574 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3575 if (
ID->getImplementation())
3576 Flags |= llvm::DINode::FlagObjcClassComplete;
3578 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3579 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3580 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3581 nullptr, llvm::DINodeArray(), RuntimeLang);
3583 QualType QTy(Ty, 0);
3584 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3587 LexicalBlockStack.emplace_back(RealDecl);
3588 RegionMap[Ty->
getDecl()].reset(RealDecl);
3591 SmallVector<llvm::Metadata *, 16> EltTys;
3593 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3595 llvm::DIType *SClassTy =
3596 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3600 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3601 llvm::DINode::FlagZero);
3602 EltTys.push_back(InhTag);
3606 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3607 SourceLocation Loc = PD->getLocation();
3608 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3609 unsigned PLine = getLineNumber(Loc);
3610 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3611 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3612 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3613 PD->getName(), PUnit, PLine,
3615 : getSelectorName(PD->getGetterName()),
3617 : getSelectorName(PD->getSetterName()),
3618 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3619 EltTys.push_back(PropertyNode);
3624 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3628 llvm::DenseSet<IsClassAndIdent> PropertySet;
3630 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3631 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3633 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3634 for (
auto *PD : ClassExt->properties()) {
3635 PropertySet.insert(GetIsClassAndIdent(PD));
3638 for (
const auto *PD :
ID->properties()) {
3641 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3647 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3648 unsigned FieldNo = 0;
3649 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3650 Field =
Field->getNextIvar(), ++FieldNo) {
3651 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3655 StringRef FieldName =
Field->getName();
3658 if (FieldName.empty())
3662 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3663 unsigned FieldLine = getLineNumber(
Field->getLocation());
3664 QualType FType =
Field->getType();
3671 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3672 : CGM.getContext().getTypeSize(FType);
3677 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3681 if (
Field->isBitField()) {
3683 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3684 FieldOffset %= CGM.getContext().getCharWidth();
3692 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3694 Flags = llvm::DINode::FlagProtected;
3696 Flags = llvm::DINode::FlagPrivate;
3698 Flags = llvm::DINode::FlagPublic;
3700 if (
Field->isBitField())
3701 Flags |= llvm::DINode::FlagBitField;
3703 llvm::MDNode *PropertyNode =
nullptr;
3704 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3705 if (ObjCPropertyImplDecl *PImpD =
3706 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3707 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3708 SourceLocation Loc = PD->getLocation();
3709 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3710 unsigned PLine = getLineNumber(Loc);
3711 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3712 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3713 PropertyNode = DBuilder.createObjCProperty(
3714 PD->getName(), PUnit, PLine,
3717 : getSelectorName(PD->getGetterName()),
3720 : getSelectorName(PD->getSetterName()),
3721 PD->getPropertyAttributes(),
3722 getOrCreateType(PD->getType(), PUnit));
3726 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3727 FieldSize, FieldAlign, FieldOffset, Flags,
3728 FieldTy, PropertyNode);
3729 EltTys.push_back(FieldTy);
3732 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3733 DBuilder.replaceArrays(RealDecl, Elements);
3735 LexicalBlockStack.pop_back();
3739llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3740 llvm::DIFile *Unit) {
3748 auto &Ctx = CGM.getContext();
3753 QualType CharVecTy =
3755 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3758 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3761 llvm::Metadata *Subscript;
3762 QualType QTy(Ty, 0);
3763 auto SizeExpr = SizeExprCache.find(QTy);
3764 if (SizeExpr != SizeExprCache.end())
3765 Subscript = DBuilder.getOrCreateSubrange(
3766 SizeExpr->getSecond() ,
nullptr ,
3767 nullptr ,
nullptr );
3770 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3771 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3772 Subscript = DBuilder.getOrCreateSubrange(
3773 CountNode ,
nullptr ,
nullptr ,
3776 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3781 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3784llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3785 llvm::DIFile *Unit) {
3789 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3794 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3795 auto *ColumnCountNode =
3796 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3797 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3798 auto *RowCountNode =
3799 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3800 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3801 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3802 ColumnCountNode ,
nullptr ,
nullptr ,
3804 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3805 RowCountNode ,
nullptr ,
nullptr ,
3807 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3808 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3811llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3816 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3831 Size = CGM.getContext().getTypeSize(Ty);
3838 SmallVector<llvm::Metadata *, 8> Subscripts;
3839 QualType EltTy(Ty, 0);
3840 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3849 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3850 Count = CAT->getZExtSize();
3851 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3852 if (Expr *Size = VAT->getSizeExpr()) {
3854 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3855 Count =
Result.Val.getInt().getExtValue();
3859 auto SizeNode = SizeExprCache.find(EltTy);
3860 if (SizeNode != SizeExprCache.end())
3861 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3862 SizeNode->getSecond() ,
nullptr ,
3863 nullptr ,
nullptr ));
3866 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3867 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3868 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3869 CountNode ,
nullptr ,
nullptr ,
3875 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3877 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3881llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3882 llvm::DIFile *Unit) {
3883 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3887llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3888 llvm::DIFile *Unit) {
3889 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3891 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3892 CGM.getCodeGenOpts().DwarfVersion < 4)
3893 Tag = llvm::dwarf::DW_TAG_reference_type;
3895 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3898llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3900 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3904 Size = CGM.getContext().getTypeSize(Ty);
3907 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3910 Flags |= llvm::DINode::FlagSingleInheritance;
3913 Flags |= llvm::DINode::FlagMultipleInheritance;
3916 Flags |= llvm::DINode::FlagVirtualInheritance;
3926 llvm::DIType *ClassType = getOrCreateType(T, U);
3928 return DBuilder.createMemberPointerType(
3932 const FunctionProtoType *FPT =
3934 return DBuilder.createMemberPointerType(
3935 getOrCreateInstanceMethodType(
3938 ClassType, Size, 0, Flags);
3941llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3943 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3946llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3950llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3952 return getOrCreateType(Ty->getWrappedType(), U);
3955llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3962 const EnumType *Ty) {
3974llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3977 bool isImportedFromModule =
3978 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3982 if (isImportedFromModule || !ED->getDefinition()) {
3989 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3990 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3991 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3992 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3994 unsigned Line = getLineNumber(ED->getLocation());
3995 StringRef EDName = ED->getName();
3996 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3997 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3998 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4000 ReplaceMap.emplace_back(
4001 std::piecewise_construct, std::make_tuple(Ty),
4002 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4006 return CreateTypeDefinition(Ty);
4009llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4012 SmallVector<llvm::Metadata *, 16> Enumerators;
4013 ED = ED->getDefinition();
4014 assert(ED &&
"An enumeration definition is required");
4015 for (
const auto *
Enum : ED->enumerators()) {
4016 Enumerators.push_back(
4017 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4020 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4021 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4022 EnumKind = Attr->getExtensibility();
4025 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4027 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4028 unsigned Line = getLineNumber(ED->getLocation());
4029 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4030 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4031 return DBuilder.createEnumerationType(
4032 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4033 0, Identifier, ED->isScoped(), EnumKind);
4038 StringRef Name, StringRef
Value) {
4039 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4040 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4046 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4047 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4048 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4053 llvm::DISubprogram *SynthSubprogram) {
4054 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4055 SynthSubprogram, ParentLocation);
4060 StringRef SynthFuncName,
4061 llvm::DIFile *SynthFile) {
4062 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4067 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4073 FuncName += Category;
4075 FuncName += FailureMsg;
4078 TrapLocation->getFile());
4084 Qualifiers InnerQuals = T.getLocalQualifiers();
4088 Quals += InnerQuals;
4090 switch (T->getTypeClass()) {
4092 return C.getQualifiedType(T.getTypePtr(), Quals);
4095 case Type::InjectedClassName:
4096 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4098 case Type::TemplateSpecialization: {
4100 if (Spec->isTypeAlias())
4101 return C.getQualifiedType(T.getTypePtr(), Quals);
4102 T = Spec->desugar();
4105 case Type::TypeOfExpr:
4111 case Type::Decltype:
4114 case Type::UnaryTransform:
4117 case Type::Attributed:
4120 case Type::BTFTagAttributed:
4123 case Type::CountAttributed:
4132 case Type::MacroQualified:
4135 case Type::SubstTemplateTypeParm:
4139 case Type::DeducedTemplateSpecialization: {
4141 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4145 case Type::PackIndexing: {
4149 case Type::Adjusted:
4156 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4161llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4164 if (It != TypeCache.end()) {
4166 if (llvm::Metadata *
V = It->second)
4179 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4186 RetainedTypes.push_back(
4187 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4190llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4194 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4196 llvm::raw_string_ostream OS(Name);
4197 Ty.
print(OS, getPrintingPolicy());
4204 if (
auto *T = getTypeOrNull(Ty))
4207 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4208 void *TyPtr = Ty.getAsOpaquePtr();
4211 TypeCache[TyPtr].reset(Res);
4216llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4224 auto Info = Reader->getSourceDescriptor(Idx);
4226 return getOrCreateModuleRef(*Info,
true);
4227 }
else if (ClangModuleMap) {
4240 auto Info = ASTSourceDescriptor(*M);
4241 return getOrCreateModuleRef(Info,
false);
4244 return getOrCreateModuleRef(PCHDescriptor,
false);
4251llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4254 return CreateQualifiedType(Ty, Unit);
4258#define TYPE(Class, Base)
4259#define ABSTRACT_TYPE(Class, Base)
4260#define NON_CANONICAL_TYPE(Class, Base)
4261#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4262#include "clang/AST/TypeNodes.inc"
4263 llvm_unreachable(
"Dependent types cannot show up in debug information");
4265 case Type::ExtVector:
4268 case Type::ConstantMatrix:
4270 case Type::ObjCObjectPointer:
4272 case Type::ObjCObject:
4274 case Type::ObjCTypeParam:
4276 case Type::ObjCInterface:
4284 case Type::BlockPointer:
4292 case Type::FunctionProto:
4293 case Type::FunctionNoProto:
4295 case Type::ConstantArray:
4296 case Type::VariableArray:
4297 case Type::IncompleteArray:
4298 case Type::ArrayParameter:
4301 case Type::LValueReference:
4303 case Type::RValueReference:
4306 case Type::MemberPointer:
4314 case Type::OverflowBehavior:
4319 case Type::TemplateSpecialization:
4321 case Type::HLSLAttributedResource:
4323 case Type::HLSLInlineSpirv:
4325 case Type::PredefinedSugar:
4327 case Type::CountAttributed:
4329 case Type::Attributed:
4330 case Type::BTFTagAttributed:
4331 case Type::Adjusted:
4333 case Type::DeducedTemplateSpecialization:
4336 case Type::MacroQualified:
4337 case Type::SubstTemplateTypeParm:
4338 case Type::TypeOfExpr:
4340 case Type::Decltype:
4341 case Type::PackIndexing:
4342 case Type::UnaryTransform:
4346 llvm_unreachable(
"type should have been unwrapped!");
4349llvm::DICompositeType *
4350CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4351 QualType QTy(Ty, 0);
4353 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4358 if (T && !T->isForwardDecl())
4362 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4367 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4370 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4375llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4376 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4377 bool NameIsSimplified =
false;
4380 StringRef RDName = getClassName(RD, &NameIsSimplified);
4382 llvm::DIFile *DefUnit =
nullptr;
4385 DefUnit = getOrCreateFile(Loc);
4386 Line = getLineNumber(Loc);
4389 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4393 auto *T = cast_or_null<llvm::DICompositeType>(
4394 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4402 return getOrCreateRecordFwdDecl(Ty, RDContext);
4415 auto Flags = llvm::DINode::FlagZero;
4416 if (NameIsSimplified)
4417 Flags |= llvm::DINode::FlagNameIsSimplified;
4418 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4420 Flags |= llvm::DINode::FlagTypePassByReference;
4422 Flags |= llvm::DINode::FlagTypePassByValue;
4425 if (!CXXRD->isTrivial())
4426 Flags |= llvm::DINode::FlagNonTrivial;
4429 if (CXXRD->isAnonymousStructOrUnion())
4430 Flags |= llvm::DINode::FlagExportSymbols;
4433 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4436 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4437 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4439 Flags, Identifier, Annotations);
4443 switch (RealDecl->getTag()) {
4445 llvm_unreachable(
"invalid composite type tag");
4447 case llvm::dwarf::DW_TAG_array_type:
4448 case llvm::dwarf::DW_TAG_enumeration_type:
4453 if (Identifier.empty())
4457 case llvm::dwarf::DW_TAG_structure_type:
4458 case llvm::dwarf::DW_TAG_union_type:
4459 case llvm::dwarf::DW_TAG_class_type:
4462 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4466 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4467 CXXRecordDecl *TemplateDecl =
4468 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4469 RegionMap[TemplateDecl].reset(RealDecl);
4471 RegionMap[RD].reset(RealDecl);
4473 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4475 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4476 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4477 CollectCXXTemplateParams(TSpecial, DefUnit));
4481void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4482 llvm::DICompositeType *RealDecl) {
4484 llvm::DIType *ContainingType =
nullptr;
4485 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4489 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4496 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4497 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4499 ContainingType = RealDecl;
4501 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4504llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4505 StringRef Name, uint64_t *Offset) {
4506 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4507 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4510 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4511 *Offset, llvm::DINode::FlagZero, FieldTy);
4512 *Offset += FieldSize;
4516void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4518 StringRef &LinkageName,
4519 llvm::DIScope *&FDContext,
4520 llvm::DINodeArray &TParamsArray,
4521 llvm::DINode::DIFlags &Flags) {
4523 bool NameIsSimplified =
false;
4524 Name = getFunctionName(FD, &NameIsSimplified);
4525 if (NameIsSimplified)
4526 Flags |= llvm::DINode::FlagNameIsSimplified;
4527 Name = getFunctionName(FD);
4530 LinkageName = CGM.getMangledName(GD);
4532 Flags |= llvm::DINode::FlagPrototyped;
4536 if (LinkageName == Name ||
4537 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4538 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4539 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4540 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4541 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4542 LinkageName = StringRef();
4546 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4547 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4548 CGM.getCodeGenOpts().EmitCodeView)) {
4549 if (
const NamespaceDecl *NSDecl =
4551 FDContext = getOrCreateNamespace(NSDecl);
4552 else if (
const RecordDecl *RDecl =
4554 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4555 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4558 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4561 Flags |= llvm::DINode::FlagNoReturn;
4563 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4567void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4568 unsigned &LineNo, QualType &T,
4569 StringRef &Name, StringRef &LinkageName,
4570 llvm::MDTuple *&TemplateParameters,
4571 llvm::DIScope *&VDContext) {
4580 llvm::APInt ConstVal(32, 1);
4581 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4583 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4590 LinkageName = CGM.getMangledName(VD);
4591 if (LinkageName == Name)
4592 LinkageName = StringRef();
4595 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4596 TemplateParameters = parameterNodes.get();
4598 TemplateParameters =
nullptr;
4616 DC = CGM.getContext().getTranslationUnitDecl();
4618 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4619 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4622llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4624 llvm::DINodeArray TParamsArray;
4625 StringRef Name, LinkageName;
4626 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4627 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4629 llvm::DIFile *Unit = getOrCreateFile(Loc);
4630 llvm::DIScope *DContext = Unit;
4631 unsigned Line = getLineNumber(Loc);
4632 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4637 SmallVector<QualType, 16> ArgTypes;
4638 for (
const ParmVarDecl *Parm : FD->
parameters())
4639 ArgTypes.push_back(Parm->getType());
4642 QualType FnType = CGM.getContext().getFunctionType(
4643 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4645 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4646 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4647 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4651 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4652 return DBuilder.createFunction(
4653 DContext, Name, LinkageName, Unit,
Line,
4654 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4655 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4657 CGM.getCodeGenOpts().DebugKeyInstructions);
4660 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4661 DContext, Name, LinkageName, Unit,
Line,
4662 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4663 TParamsArray.get(), getFunctionDeclaration(FD));
4665 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4666 std::make_tuple(CanonDecl),
4667 std::make_tuple(SP));
4671llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4672 return getFunctionFwdDeclOrStub(GD,
false);
4675llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4676 return getFunctionFwdDeclOrStub(GD,
true);
4679llvm::DIGlobalVariable *
4680CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4682 StringRef Name, LinkageName;
4684 llvm::DIFile *Unit = getOrCreateFile(Loc);
4685 llvm::DIScope *DContext = Unit;
4686 unsigned Line = getLineNumber(Loc);
4687 llvm::MDTuple *TemplateParameters =
nullptr;
4689 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4692 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4693 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4695 FwdDeclReplaceMap.emplace_back(
4696 std::piecewise_construct,
4698 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4702llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4707 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4708 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4709 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4713 if (I != DeclCache.end()) {
4715 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4716 return GVE->getVariable();
4724 if (IE != ImportedDeclCache.end()) {
4725 auto N = IE->second;
4726 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4728 return dyn_cast_or_null<llvm::DINode>(N);
4733 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4734 return getFunctionForwardDeclaration(FD);
4735 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4736 return getGlobalVariableForwardDeclaration(VD);
4741llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4742 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4745 const auto *FD = dyn_cast<FunctionDecl>(D);
4750 auto *S = getDeclContextDescriptor(D);
4753 if (MI == SPCache.end()) {
4755 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4759 if (MI != SPCache.end()) {
4760 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4761 if (SP && !SP->isDefinition())
4765 for (
auto *NextFD : FD->
redecls()) {
4766 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4767 if (MI != SPCache.end()) {
4768 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4769 if (SP && !SP->isDefinition())
4776llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4777 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4778 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4779 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4782 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4786 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4790 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4799 QualType QTy(
ID->getTypeForDecl(), 0);
4800 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4801 if (It == TypeCache.end())
4804 llvm::DISubprogram *FD = DBuilder.createFunction(
4805 InterfaceType, getObjCMethodName(OMD), StringRef(),
4806 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4807 DBuilder.finalizeSubprogram(FD);
4814llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4819 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4820 !CGM.getCodeGenOpts().EmitCodeView))
4823 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4825 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4828 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4831 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4832 return getOrCreateMethodType(
Method, F);
4834 const auto *FTy = FnType->
getAs<FunctionType>();
4837 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4839 SmallVector<llvm::Metadata *, 16> Elts;
4842 QualType ResultTy = OMethod->getReturnType();
4845 if (ResultTy == CGM.getContext().getObjCInstanceType())
4846 ResultTy = CGM.getContext().getPointerType(
4847 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4849 Elts.push_back(getOrCreateType(ResultTy, F));
4851 QualType SelfDeclTy;
4852 if (
auto *SelfDecl = OMethod->getSelfDecl())
4853 SelfDeclTy = SelfDecl->getType();
4854 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4857 if (!SelfDeclTy.
isNull())
4859 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4861 Elts.push_back(DBuilder.createArtificialType(
4862 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4864 for (
const auto *PI : OMethod->parameters())
4865 Elts.push_back(getOrCreateType(PI->getType(), F));
4867 if (OMethod->isVariadic())
4868 Elts.push_back(DBuilder.createUnspecifiedParameter());
4870 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4871 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4877 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4878 if (FD->isVariadic()) {
4879 SmallVector<llvm::Metadata *, 16> EltTys;
4880 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4881 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4883 EltTys.push_back(getOrCreateType(ParamType, F));
4884 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4885 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4886 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4899 CC = SrcFnTy->getCallConv();
4901 for (
const VarDecl *VD : Args)
4902 ArgTypes.push_back(VD->
getType());
4903 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4909 llvm::Function *Fn,
bool CurFuncIsThunk) {
4911 StringRef LinkageName;
4913 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4916 bool HasDecl = (D !=
nullptr);
4918 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4919 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4920 llvm::DIFile *Unit = getOrCreateFile(Loc);
4921 llvm::DIScope *FDContext = Unit;
4922 llvm::DINodeArray TParamsArray;
4923 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4926 LinkageName = Fn->getName();
4927 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4929 auto FI = SPCache.find(FD->getCanonicalDecl());
4930 if (FI != SPCache.end()) {
4931 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4932 if (SP && SP->isDefinition()) {
4933 LexicalBlockStack.emplace_back(SP);
4934 RegionMap[D].reset(SP);
4938 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4939 TParamsArray, Flags);
4942 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4943 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4944 Name = getObjCMethodName(OMD);
4945 Flags |= llvm::DINode::FlagPrototyped;
4951 if (Name != Fn->getName())
4952 LinkageName = Fn->getName();
4954 Name = Fn->getName();
4959 Flags |= llvm::DINode::FlagPrototyped;
4961 Name.consume_front(
"\01");
4965 "Unexpected DynamicInitKind !");
4969 Flags |= llvm::DINode::FlagArtificial;
4975 Flags |= llvm::DINode::FlagThunk;
4977 if (Fn->hasLocalLinkage())
4978 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4979 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4980 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4983 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4984 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4986 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4987 unsigned ScopeLine = getLineNumber(ScopeLoc);
4988 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4989 llvm::DISubprogram *
Decl =
nullptr;
4990 llvm::DINodeArray Annotations =
nullptr;
4993 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4994 : getFunctionDeclaration(D);
4995 Annotations = CollectBTFDeclTagAnnotations(D);
5003 llvm::DISubprogram *SP = DBuilder.createFunction(
5004 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5005 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5006 Annotations,
"", KeyInstructions);
5007 Fn->setSubprogram(SP);
5016 LexicalBlockStack.emplace_back(SP);
5019 RegionMap[D].reset(SP);
5023 QualType FnType, llvm::Function *Fn) {
5025 StringRef LinkageName;
5031 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5032 return GetName(D,
true);
5035 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5036 llvm::DIFile *Unit = getOrCreateFile(Loc);
5037 bool IsDeclForCallSite = Fn ?
true :
false;
5038 llvm::DIScope *FDContext =
5039 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5040 llvm::DINodeArray TParamsArray;
5043 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5044 TParamsArray, Flags);
5045 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5046 Name = getObjCMethodName(OMD);
5047 Flags |= llvm::DINode::FlagPrototyped;
5049 llvm_unreachable(
"not a function or ObjC method");
5051 Name.consume_front(
"\01");
5054 Flags |= llvm::DINode::FlagArtificial;
5059 unsigned LineNo = getLineNumber(Loc);
5060 unsigned ScopeLine = 0;
5061 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5062 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5063 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5065 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5066 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5068 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5069 llvm::DISubprogram *SP = DBuilder.createFunction(
5070 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5071 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5077 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5078 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5079 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5082 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5083 DBuilder.createParameterVariable(
5084 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5085 llvm::DINode::FlagZero, ParamAnnotations);
5091 if (IsDeclForCallSite)
5092 Fn->setSubprogram(SP);
5096 llvm::CallBase *CI) {
5097 if (!shouldGenerateVirtualCallSite())
5103 assert(CI &&
"Invalid Call Instruction.");
5104 if (!CI->isIndirectCall())
5108 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5109 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5117 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5120 if (
Func->getSubprogram())
5128 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5143 auto FI = SPCache.find(FD->getCanonicalDecl());
5144 llvm::DISubprogram *SP =
nullptr;
5145 if (FI != SPCache.end())
5146 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5147 if (!SP || !SP->isDefinition())
5148 SP = getFunctionStub(GD);
5149 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5150 LexicalBlockStack.emplace_back(SP);
5156 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5165 if (CurLoc.isInvalid() ||
5166 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5167 LexicalBlockStack.empty())
5170 llvm::MDNode *
Scope = LexicalBlockStack.back();
5171 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5172 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5176 llvm::MDNode *Back =
nullptr;
5177 if (!LexicalBlockStack.empty())
5178 Back = LexicalBlockStack.back().get();
5179 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5181 getColumnNumber(CurLoc)));
5184void CGDebugInfo::AppendAddressSpaceXDeref(
5186 std::optional<unsigned> DWARFAddressSpace =
5188 if (!DWARFAddressSpace)
5191 Expr.push_back(llvm::dwarf::DW_OP_constu);
5192 Expr.push_back(*DWARFAddressSpace);
5193 Expr.push_back(llvm::dwarf::DW_OP_swap);
5194 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5203 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5204 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5205 LexicalBlockStack.back(), CurInlinedAt));
5207 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5211 CreateLexicalBlock(Loc);
5216 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5221 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5224 LexicalBlockStack.pop_back();
5228 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5229 unsigned RCount = FnBeginRegionCount.back();
5230 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5233 while (LexicalBlockStack.size() != RCount) {
5236 LexicalBlockStack.pop_back();
5238 FnBeginRegionCount.pop_back();
5240 if (Fn && Fn->getSubprogram())
5241 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5244CGDebugInfo::BlockByRefType
5245CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5246 uint64_t *XOffset) {
5249 uint64_t FieldSize, FieldOffset;
5250 uint32_t FieldAlign;
5252 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5257 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5258 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5260 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5261 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5264 if (HasCopyAndDispose) {
5267 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5269 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5271 bool HasByrefExtendedLayout;
5274 HasByrefExtendedLayout) &&
5275 HasByrefExtendedLayout) {
5278 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5287 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5290 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5293 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5298 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5299 FieldSize = CGM.getContext().getTypeSize(FType);
5300 FieldAlign = CGM.getContext().toBits(Align);
5302 *XOffset = FieldOffset;
5303 llvm::DIType *FieldTy = DBuilder.createMemberType(
5304 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5305 llvm::DINode::FlagZero, WrappedTy);
5306 EltTys.push_back(FieldTy);
5307 FieldOffset += FieldSize;
5309 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5310 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5311 llvm::DINode::FlagZero,
nullptr, Elements),
5315llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5316 llvm::Value *Storage,
5317 std::optional<unsigned> ArgNo,
5319 const bool UsePointerValue) {
5320 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5321 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5322 if (VD->
hasAttr<NoDebugAttr>())
5327 llvm::DIFile *Unit =
nullptr;
5328 if (!VarIsArtificial)
5332 if (VD->
hasAttr<BlocksAttr>())
5333 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5335 Ty = getOrCreateType(VD->
getType(), Unit);
5345 if (!VarIsArtificial) {
5349 SmallVector<uint64_t, 13> Expr;
5350 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5357 Flags |= llvm::DINode::FlagArtificial;
5361 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5362 AppendAddressSpaceXDeref(AddressSpace, Expr);
5366 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5369 Flags |= llvm::DINode::FlagObjectPointer;
5370 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5371 if (PVD->isExplicitObjectParameter())
5372 Flags |= llvm::DINode::FlagObjectPointer;
5380 StringRef Name = VD->
getName();
5381 if (!Name.empty()) {
5387 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5389 offset = CGM.getContext().toCharUnitsFromBits(
5392 Expr.push_back(llvm::dwarf::DW_OP_deref);
5393 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5395 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5398 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5410 for (
const auto *Field : RD->
fields()) {
5411 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5412 StringRef FieldName =
Field->getName();
5420 auto *D = DBuilder.createAutoVariable(
5421 Scope, FieldName, Unit,
Line, FieldTy,
5422 CGM.getCodeGenOpts().OptimizationLevel != 0,
5423 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5426 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5427 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5430 Builder.GetInsertBlock());
5438 if (UsePointerValue) {
5439 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5440 "Debug info already contains DW_OP_deref.");
5441 Expr.push_back(llvm::dwarf::DW_OP_deref);
5445 llvm::DILocalVariable *D =
nullptr;
5447 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5448 D = DBuilder.createParameterVariable(
5449 Scope, Name, *ArgNo, Unit,
Line, Ty,
5450 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5459 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5465 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5466 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5467 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5468 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5470 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5476 if (Iter != CoroutineParameterMappings.end()) {
5477 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5478 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5479 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5481 if (Iter2 != ParamDbgMappings.end())
5482 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5488 D = RemapCoroArgToLocalVar();
5491 D = DBuilder.createAutoVariable(
5492 Scope, Name, Unit,
Line, Ty,
5493 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5496 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5497 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5498 Column, Scope, CurInlinedAt),
5499 Builder.GetInsertBlock());
5504llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5505 llvm::Value *Storage,
5506 std::optional<unsigned> ArgNo,
5508 const bool UsePointerValue) {
5509 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5510 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5511 if (BD->
hasAttr<NoDebugAttr>())
5518 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5519 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5527 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5529 SmallVector<uint64_t, 3> Expr;
5530 AppendAddressSpaceXDeref(AddressSpace, Expr);
5535 if (UsePointerValue) {
5536 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5537 "Debug info already contains DW_OP_deref.");
5538 Expr.push_back(llvm::dwarf::DW_OP_deref);
5543 StringRef Name = BD->
getName();
5546 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5547 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5548 llvm::DINode::FlagZero, Align);
5550 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5551 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5552 const unsigned fieldIndex = FD->getFieldIndex();
5553 const clang::CXXRecordDecl *parent =
5554 (
const CXXRecordDecl *)FD->getParent();
5555 const ASTRecordLayout &layout =
5556 CGM.getContext().getASTRecordLayout(parent);
5558 if (FD->isBitField()) {
5559 const CGRecordLayout &RL =
5560 CGM.getTypes().getCGRecordLayout(FD->getParent());
5565 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5571 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5572 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5573 Expr.push_back(Info.
Offset);
5576 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5577 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5578 }
else if (fieldOffset != 0) {
5579 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5580 "Unexpected non-bitfield with non-byte-aligned offset");
5581 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5583 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5586 }
else if (
const ArraySubscriptExpr *ASE =
5587 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5588 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5589 const uint64_t value = IL->getValue().getZExtValue();
5590 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5593 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5594 Expr.push_back(CGM.getContext()
5595 .toCharUnitsFromBits(value * typeSize)
5602 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5603 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5604 Column, Scope, CurInlinedAt),
5605 Builder.GetInsertBlock());
5610llvm::DILocalVariable *
5613 const bool UsePointerValue) {
5614 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5616 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5618 EmitDeclare(B, Storage, std::nullopt, Builder,
5625 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5629 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5630 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5632 if (D->
hasAttr<NoDebugAttr>())
5636 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5642 StringRef Name = D->
getName();
5648 CGM.getCodeGenOpts().OptimizationLevel != 0);
5651 DBuilder.insertLabel(L,
5652 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5653 Scope, CurInlinedAt),
5654 Builder.GetInsertBlock()->end());
5657llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5659 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5662 return DBuilder.createObjectPointerType(Ty,
true);
5667 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5668 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5669 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5671 if (Builder.GetInsertBlock() ==
nullptr)
5673 if (VD->
hasAttr<NoDebugAttr>())
5676 bool isByRef = VD->
hasAttr<BlocksAttr>();
5678 uint64_t XOffset = 0;
5679 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5682 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5684 Ty = getOrCreateType(VD->
getType(), Unit);
5688 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5690 Ty = CreateSelfType(VD->
getType(), Ty);
5693 const unsigned Line =
5697 const llvm::DataLayout &target = CGM.getDataLayout();
5704 addr.push_back(llvm::dwarf::DW_OP_deref);
5705 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5708 addr.push_back(llvm::dwarf::DW_OP_deref);
5709 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5712 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5714 addr.push_back(llvm::dwarf::DW_OP_deref);
5715 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5717 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5723 auto *D = DBuilder.createAutoVariable(
5725 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5728 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5729 LexicalBlockStack.back(), CurInlinedAt);
5730 auto *
Expr = DBuilder.createExpression(addr);
5732 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5734 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5737llvm::DILocalVariable *
5740 bool UsePointerValue) {
5741 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5742 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5746struct BlockLayoutChunk {
5747 uint64_t OffsetInBits;
5750bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5751 return l.OffsetInBits < r.OffsetInBits;
5755void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5757 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5758 SmallVectorImpl<llvm::Metadata *> &Fields) {
5762 if (CGM.getLangOpts().OpenCL) {
5763 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5764 BlockLayout.getElementOffsetInBits(0),
5766 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5767 BlockLayout.getElementOffsetInBits(1),
5771 BlockLayout.getElementOffsetInBits(0),
5773 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5774 BlockLayout.getElementOffsetInBits(1),
5778 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5779 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5780 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5781 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5782 BlockLayout.getElementOffsetInBits(3),
5784 Fields.push_back(createFieldType(
5789 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5796 llvm::AllocaInst *Alloca,
5798 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5804 llvm::DIFile *tunit = getOrCreateFile(loc);
5805 unsigned line = getLineNumber(loc);
5806 unsigned column = getColumnNumber(loc);
5811 const llvm::StructLayout *blockLayout =
5815 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5824 BlockLayoutChunk chunk;
5825 chunk.OffsetInBits =
5826 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5827 chunk.Capture =
nullptr;
5828 chunks.push_back(chunk);
5832 for (
const auto &capture :
blockDecl->captures()) {
5833 const VarDecl *variable = capture.getVariable();
5840 BlockLayoutChunk chunk;
5841 chunk.OffsetInBits =
5842 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5843 chunk.Capture = &capture;
5844 chunks.push_back(chunk);
5848 llvm::array_pod_sort(chunks.begin(), chunks.end());
5850 for (
const BlockLayoutChunk &Chunk : chunks) {
5851 uint64_t offsetInBits = Chunk.OffsetInBits;
5858 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5860 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5861 type = CGM.getContext().getCanonicalTagType(RDecl);
5863 llvm_unreachable(
"unexpected block declcontext");
5865 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5866 offsetInBits, tunit, tunit));
5871 StringRef name = variable->
getName();
5873 llvm::DIType *fieldType;
5875 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5880 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5881 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5882 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5883 PtrInfo.
Width, Align, offsetInBits,
5884 llvm::DINode::FlagZero, fieldType);
5888 offsetInBits, Align, tunit, tunit);
5890 fields.push_back(fieldType);
5894 llvm::raw_svector_ostream(typeName)
5895 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5897 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5899 llvm::DIType *
type =
5900 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5901 CGM.getContext().toBits(block.
BlockSize), 0,
5902 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5903 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5906 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5910 auto *debugVar = DBuilder.createParameterVariable(
5911 scope, Name, ArgNo, tunit, line,
type,
5912 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5915 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5916 llvm::DILocation::get(CGM.getLLVMContext(), line,
5917 column, scope, CurInlinedAt),
5918 Builder.GetInsertBlock());
5921llvm::DIDerivedType *
5922CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5927 if (MI != StaticDataMemberCache.end()) {
5928 assert(MI->second &&
"Static data member declaration should still exist");
5939llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5940 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5941 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5942 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5944 for (
const auto *Field : RD->
fields()) {
5945 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5946 StringRef FieldName = Field->getName();
5949 if (FieldName.empty()) {
5950 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5951 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5952 LineNo, LinkageName, Var, DContext);
5956 GVE = DBuilder.createGlobalVariableExpression(
5957 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5958 Var->hasLocalLinkage());
5959 Var->addDebugInfo(GVE);
5971 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5976 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5987 struct ReferencesAnonymous
5989 bool RefAnon =
false;
5990 bool VisitRecordType(RecordType *RT) {
5998 ReferencesAnonymous RT;
6011struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6012 bool Reconstitutable =
true;
6013 bool VisitVectorType(VectorType *FT) {
6014 Reconstitutable =
false;
6017 bool VisitAtomicType(AtomicType *FT) {
6018 Reconstitutable =
false;
6021 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6024 const EnumDecl *ED = ET->getDecl();
6026 Reconstitutable =
false;
6030 Reconstitutable =
false;
6035 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6039 return Reconstitutable;
6041 bool VisitRecordType(RecordType *RT,
bool =
false) {
6043 Reconstitutable =
false;
6053 ReconstitutableType T;
6055 return T.Reconstitutable;
6058bool CGDebugInfo::HasReconstitutableArgs(
6059 ArrayRef<TemplateArgument> Args)
const {
6060 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6100 llvm_unreachable(
"Other, unresolved, template arguments should "
6101 "not be seen here");
6106std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6107 bool *NameIsSimplified)
const {
6109 llvm::raw_string_ostream
OS(Name);
6110 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6113 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6114 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6116 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6117 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6119 std::optional<TemplateArgs> Args;
6121 bool IsOperatorOverload =
false;
6122 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6123 Args = GetTemplateArgs(RD);
6124 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6125 Args = GetTemplateArgs(FD);
6127 IsOperatorOverload |=
6130 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6131 Args = GetTemplateArgs(VD);
6155 bool Reconstitutable =
6156 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6158 PrintingPolicy PP = getPrintingPolicy();
6160 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6165 if (NameIsSimplified)
6166 *NameIsSimplified =
true;
6167 bool Mangled = TemplateNamesKind ==
6168 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6174 std::string EncodedOriginalName;
6175 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6180 printTemplateArgumentList(OS, Args->Args, PP);
6181 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6183 std::string CanonicalOriginalName;
6184 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6186 assert(EncodedOriginalName == CanonicalOriginalName);
6195 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6196 if (D->
hasAttr<NoDebugAttr>())
6199 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6200 return GetName(D,
true);
6206 if (Cached != DeclCache.end())
6207 return Var->addDebugInfo(
6211 llvm::DIFile *Unit =
nullptr;
6212 llvm::DIScope *DContext =
nullptr;
6214 StringRef DeclName, LinkageName;
6216 llvm::MDTuple *TemplateParameters =
nullptr;
6217 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6218 TemplateParameters, DContext);
6222 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6227 if (T->isUnionType() && DeclName.empty()) {
6228 const auto *RD = T->castAsRecordDecl();
6230 "unnamed non-anonymous struct or union?");
6231 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6236 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6237 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6238 if (D->
hasAttr<CUDASharedAttr>())
6241 else if (D->
hasAttr<CUDAConstantAttr>())
6245 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6247 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6248 GVE = DBuilder.createGlobalVariableExpression(
6249 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6250 Var->hasLocalLinkage(),
true,
6251 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6252 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6253 Align, Annotations);
6254 Var->addDebugInfo(GVE);
6260 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6261 if (VD->
hasAttr<NoDebugAttr>())
6263 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6264 return GetName(VD,
true);
6269 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6270 StringRef Name = VD->
getName();
6271 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6273 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6275 if (CGM.getCodeGenOpts().EmitCodeView) {
6286 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6287 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6288 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6298 auto *VarD = dyn_cast<VarDecl>(VD);
6299 if (VarD && VarD->isStaticDataMember()) {
6301 getDeclContextDescriptor(VarD);
6306 RetainedTypes.push_back(
6307 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6311 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6313 auto &GV = DeclCache[VD];
6317 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6318 llvm::MDTuple *TemplateParameters =
nullptr;
6322 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6323 TemplateParameters = parameterNodes.get();
6326 GV.reset(DBuilder.createGlobalVariableExpression(
6327 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6328 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6329 TemplateParameters, Align));
6334 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6335 if (D->
hasAttr<NoDebugAttr>())
6339 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6340 StringRef Name = D->
getName();
6341 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6343 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6344 llvm::DIGlobalVariableExpression *GVE =
6345 DBuilder.createGlobalVariableExpression(
6346 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6347 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6348 Var->addDebugInfo(GVE);
6355 if (CGM.getCodeGenOpts().getDebugInfo() <=
6356 llvm::codegenoptions::DebugLineTablesOnly)
6359 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6363 llvm::DIFile *Unit = DIL->getFile();
6364 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6369 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6370 llvm::Value *Var = Load->getPointerOperand();
6375 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6376 return DbgDeclare->getVariable()->getType() ==
Type;
6378 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6382 llvm::DILocalVariable *D =
6383 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6384 Type,
false, llvm::DINode::FlagArtificial);
6386 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6387 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6397 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6401 if (D->
hasAttr<NoDebugAttr>())
6404 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6419 if (!(DI = getDeclarationOrDefinition(
6420 AliaseeDecl.getCanonicalDecl().getDecl())))
6423 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6426 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6427 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6441 llvm::DIFile *
File = getOrCreateFile(Loc);
6442 llvm::DIGlobalVariableExpression *Debug =
6443 DBuilder.createGlobalVariableExpression(
6444 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6445 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6446 GV->addDebugInfo(Debug);
6449llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6450 if (!LexicalBlockStack.empty())
6451 return LexicalBlockStack.back();
6452 llvm::DIScope *Mod = getParentModuleOrNull(D);
6453 return getContextDescriptor(D, Mod ? Mod : TheCU);
6457 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6461 CGM.getCodeGenOpts().DebugExplicitImport) {
6465 DBuilder.createImportedModule(
6467 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6472 if (llvm::DINode *
Target =
6475 DBuilder.createImportedDeclaration(
6477 getOrCreateFile(Loc), getLineNumber(Loc));
6482 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6485 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6487 for (
const auto *USD : UD.
shadows()) {
6492 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6493 if (
const auto *AT = FD->getType()
6496 if (AT->getDeducedType().isNull())
6507 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6510 "We shouldn't be codegening an invalid UsingEnumDecl"
6511 " containing no decls");
6513 for (
const auto *USD : UD.
shadows())
6518 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6520 if (
Module *M = ID.getImportedModule()) {
6522 auto Loc = ID.getLocation();
6523 DBuilder.createImportedDeclaration(
6524 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6525 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6526 getLineNumber(Loc));
6530llvm::DIImportedEntity *
6532 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6534 auto &VH = NamespaceAliasCache[&NA];
6537 llvm::DIImportedEntity *R;
6539 if (
const auto *Underlying =
6542 R = DBuilder.createImportedDeclaration(
6545 getLineNumber(Loc), NA.
getName());
6547 R = DBuilder.createImportedDeclaration(
6550 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6556CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6560 auto I = NamespaceCache.find(NSDecl);
6561 if (I != NamespaceCache.end())
6564 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6566 llvm::DINamespace *NS =
6567 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6568 NamespaceCache[NSDecl].reset(NS);
6573 assert(TheCU &&
"no main compile unit");
6574 TheCU->setDWOId(Signature);
6580 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6581 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6583 ? CreateTypeDefinition(E.Type, E.Unit)
6585 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6589 for (
const auto &P : ObjCMethodCache) {
6590 if (P.second.empty())
6593 QualType QTy(P.first->getTypeForDecl(), 0);
6595 assert(It != TypeCache.end());
6597 llvm::DICompositeType *InterfaceDecl =
6600 auto CurElts = InterfaceDecl->getElements();
6604 for (
auto &SubprogramDirect : P.second)
6605 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6606 EltTys.push_back(SubprogramDirect.getPointer());
6608 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6609 DBuilder.replaceArrays(InterfaceDecl, Elements);
6612 for (
const auto &P : ReplaceMap) {
6615 assert(Ty->isForwardDecl());
6617 auto It = TypeCache.find(P.first);
6618 assert(It != TypeCache.end());
6621 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6625 for (
const auto &P : FwdDeclReplaceMap) {
6628 llvm::Metadata *Repl;
6630 auto It = DeclCache.find(P.first);
6634 if (It == DeclCache.end())
6639 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6640 Repl = GVE->getVariable();
6646 for (
auto &RT : RetainedTypes)
6647 if (
auto MD = TypeCache[RT])
6650 DBuilder.finalize();
6655 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6656 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6657 DBuilder.retainType(DieTy);
6661 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6662 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6663 DBuilder.retainType(DieTy);
6667 if (LexicalBlockStack.empty())
6668 return llvm::DebugLoc();
6670 llvm::MDNode *
Scope = LexicalBlockStack.back();
6671 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6672 getColumnNumber(Loc),
Scope);
6678 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6679 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6680 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6681 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6682 return llvm::DINode::FlagZero;
6687 bool SupportsDWARFv4Ext =
6688 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6689 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6690 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6692 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6693 return llvm::DINode::FlagZero;
6695 return llvm::DINode::FlagAllCallsDescribed;
6706 return DBuilder.createConstantValueExpression(
6707 Val.
getFloat().bitcastToAPInt().getZExtValue());
6712 llvm::APSInt
const &ValInt = Val.
getInt();
6713 std::optional<uint64_t> ValIntOpt;
6714 if (ValInt.isUnsigned())
6715 ValIntOpt = ValInt.tryZExtValue();
6716 else if (
auto tmp = ValInt.trySExtValue())
6719 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6722 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6727CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6729 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6730 CGF.CurLexicalScope =
this;
6732 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6737 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6750#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6752 Label = "__ubsan_check_" #Name; \
6756#undef SANITIZER_CHECK
6767#define SANITIZER(NAME, ID) \
6768 case SanitizerKind::SO_##ID: \
6769 Label = "__ubsan_check_" NAME; \
6771#include "clang/Basic/Sanitizers.def"
6773 llvm_unreachable(
"unexpected sanitizer kind");
6778 for (
unsigned int i = 0; i < Label.length(); i++)
6779 if (!std::isalpha(Label[i]))
6788 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6790 if (!DI || !CheckDebugLoc)
6791 return CheckDebugLoc;
6792 const auto &AnnotateDebugInfo =
6793 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6794 if (AnnotateDebugInfo.empty())
6795 return CheckDebugLoc;
6798 if (Ordinals.size() == 1)
6803 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6807 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6808 "ubsan_interface.h",
6810 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6813 return CheckDebugLoc;
6821 assert(!CGF->IsSanitizerScope);
6822 CGF->IsSanitizerScope =
true;
6826 assert(CGF->IsSanitizerScope);
6827 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 llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
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 SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
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 llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
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
static StringRef getTriple(const Command &Job)
#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],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
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()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
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.
unsigned getNumBits() const
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)
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 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.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
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 EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
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...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
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.
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc ParentLocation, llvm::DISubprogram *SynthSubprogram)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
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::LLVMContext & getLLVMContext()
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.
unsigned getLine() const
Return the presumed line number 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.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
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.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
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 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.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
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.