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 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
878 if (CGM.getCodeGenOpts().DebugRecordSysroot)
879 Sysroot = FullSysroot;
880 auto B = llvm::sys::path::rbegin(FullSysroot);
881 auto E = llvm::sys::path::rend(FullSysroot);
883 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
888 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
889 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
890 CGOpts.DebugNameTable);
891 if (CGM.getTarget().getTriple().isNVPTX())
892 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
893 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
894 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
897 TheCU = DBuilder.createCompileUnit(
899 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
900 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
901 CGOpts.PrepareForThinLTO,
902 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
903 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
904 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
907llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
911#define BUILTIN_TYPE(Id, SingletonId)
912#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
913#include "clang/AST/BuiltinTypes.def"
914 case BuiltinType::Dependent:
915 llvm_unreachable(
"Unexpected builtin type");
916 case BuiltinType::NullPtr:
917 return DBuilder.createNullPtrType();
918 case BuiltinType::Void:
920 case BuiltinType::ObjCClass:
923 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
924 "objc_class", TheCU, TheCU->getFile(), 0);
926 case BuiltinType::ObjCId: {
937 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
938 "objc_class", TheCU, TheCU->getFile(), 0);
940 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
942 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
944 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
945 (uint64_t)0, 0, llvm::DINode::FlagZero,
946 nullptr, llvm::DINodeArray());
948 DBuilder.replaceArrays(
949 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
950 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
951 llvm::DINode::FlagZero, ISATy)));
954 case BuiltinType::ObjCSel: {
956 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
957 "objc_selector", TheCU,
958 TheCU->getFile(), 0);
962#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
963 case BuiltinType::Id: \
964 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
966#include "clang/Basic/OpenCLImageTypes.def"
967 case BuiltinType::OCLSampler:
968 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
969 case BuiltinType::OCLEvent:
970 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
971 case BuiltinType::OCLClkEvent:
972 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
973 case BuiltinType::OCLQueue:
974 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
975 case BuiltinType::OCLReserveID:
976 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
977#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
978 case BuiltinType::Id: \
979 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
980#include "clang/Basic/OpenCLExtensionTypes.def"
981#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
982 case BuiltinType::Id: \
983 return getOrCreateStructPtrType(#Name, SingletonId);
984#include "clang/Basic/HLSLIntangibleTypes.def"
986#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
987#include "clang/Basic/AArch64ACLETypes.def"
989 if (BT->
getKind() == BuiltinType::MFloat8) {
990 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
991 BTName = BT->
getName(CGM.getLangOpts());
994 return DBuilder.createBasicType(BTName, Size, Encoding);
996 ASTContext::BuiltinVectorTypeInfo Info =
998 BT->
getKind() == BuiltinType::SveCount
999 ? ASTContext::BuiltinVectorTypeInfo(
1000 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1002 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1009 "Unsupported number of vectors for svcount_t");
1011 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1012 llvm::Metadata *BitStride =
nullptr;
1013 if (BT->
getKind() == BuiltinType::SveBool) {
1014 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1015 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1016 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1017 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1019 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1022 llvm::Metadata *LowerBound, *UpperBound;
1023 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1024 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1025 if (Info.
EC.isScalable()) {
1026 unsigned NumElemsPerVG = NumElems / 2;
1027 SmallVector<uint64_t, 9> Expr(
1028 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1029 46, 0, llvm::dwarf::DW_OP_mul,
1030 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1031 UpperBound = DBuilder.createExpression(Expr);
1033 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1034 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1036 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1037 nullptr, LowerBound, UpperBound,
nullptr);
1038 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1039 llvm::DIType *ElemTy =
1040 getOrCreateType(Info.
ElementType, TheCU->getFile());
1042 return DBuilder.createVectorType( 0, Align, ElemTy,
1043 SubscriptArray, BitStride);
1047#define PPC_VECTOR_TYPE(Name, Id, size) \
1048 case BuiltinType::Id:
1049#include "clang/Basic/PPCTypes.def"
1052#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1053#include "clang/Basic/RISCVVTypes.def"
1055 ASTContext::BuiltinVectorTypeInfo Info =
1056 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1058 unsigned ElementCount = Info.
EC.getKnownMinValue();
1059 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1061 bool Fractional =
false;
1064 unsigned FixedSize = ElementCount * SEW;
1065 if (Info.
ElementType == CGM.getContext().BoolTy) {
1068 }
else if (FixedSize < 64) {
1071 LMUL = 64 / FixedSize;
1073 LMUL = FixedSize / 64;
1077 SmallVector<uint64_t, 12> Expr(
1081 {llvm::dwarf::DW_OP_bregx,
1084 llvm::dwarf::DW_OP_constu,
1086 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1088 Expr.push_back(llvm::dwarf::DW_OP_div);
1090 Expr.push_back(llvm::dwarf::DW_OP_mul);
1093 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1095 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1098 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1099 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1100 auto *UpperBound = DBuilder.createExpression(Expr);
1101 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1102 nullptr, LowerBound, UpperBound,
nullptr);
1103 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1104 llvm::DIType *ElemTy =
1105 getOrCreateType(Info.
ElementType, TheCU->getFile());
1108 return DBuilder.createVectorType(0, Align, ElemTy,
1112#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1113 case BuiltinType::Id: { \
1116 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1117 MangledName, TheCU, TheCU->getFile(), 0); \
1118 return SingletonId; \
1120#include "clang/Basic/WebAssemblyReferenceTypes.def"
1121#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1122 case BuiltinType::Id: { \
1125 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1126 TheCU, TheCU->getFile(), 0); \
1127 return SingletonId; \
1129#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1130 case BuiltinType::Id: { \
1133 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1134 return SingletonId; \
1136#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1137 case BuiltinType::Id: { \
1140 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1141 return SingletonId; \
1143#include "clang/Basic/AMDGPUTypes.def"
1144 case BuiltinType::UChar:
1145 case BuiltinType::Char_U:
1146 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1148 case BuiltinType::Char_S:
1149 case BuiltinType::SChar:
1150 Encoding = llvm::dwarf::DW_ATE_signed_char;
1152 case BuiltinType::Char8:
1153 case BuiltinType::Char16:
1154 case BuiltinType::Char32:
1155 Encoding = llvm::dwarf::DW_ATE_UTF;
1157 case BuiltinType::UShort:
1158 case BuiltinType::UInt:
1159 case BuiltinType::UInt128:
1160 case BuiltinType::ULong:
1161 case BuiltinType::WChar_U:
1162 case BuiltinType::ULongLong:
1163 Encoding = llvm::dwarf::DW_ATE_unsigned;
1165 case BuiltinType::Short:
1166 case BuiltinType::Int:
1167 case BuiltinType::Int128:
1168 case BuiltinType::Long:
1169 case BuiltinType::WChar_S:
1170 case BuiltinType::LongLong:
1171 Encoding = llvm::dwarf::DW_ATE_signed;
1173 case BuiltinType::Bool:
1174 Encoding = llvm::dwarf::DW_ATE_boolean;
1176 case BuiltinType::Half:
1177 case BuiltinType::Float:
1178 case BuiltinType::LongDouble:
1179 case BuiltinType::Float16:
1180 case BuiltinType::BFloat16:
1181 case BuiltinType::Float128:
1182 case BuiltinType::Double:
1183 case BuiltinType::Ibm128:
1189 Encoding = llvm::dwarf::DW_ATE_float;
1191 case BuiltinType::ShortAccum:
1192 case BuiltinType::Accum:
1193 case BuiltinType::LongAccum:
1194 case BuiltinType::ShortFract:
1195 case BuiltinType::Fract:
1196 case BuiltinType::LongFract:
1197 case BuiltinType::SatShortFract:
1198 case BuiltinType::SatFract:
1199 case BuiltinType::SatLongFract:
1200 case BuiltinType::SatShortAccum:
1201 case BuiltinType::SatAccum:
1202 case BuiltinType::SatLongAccum:
1203 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1205 case BuiltinType::UShortAccum:
1206 case BuiltinType::UAccum:
1207 case BuiltinType::ULongAccum:
1208 case BuiltinType::UShortFract:
1209 case BuiltinType::UFract:
1210 case BuiltinType::ULongFract:
1211 case BuiltinType::SatUShortAccum:
1212 case BuiltinType::SatUAccum:
1213 case BuiltinType::SatULongAccum:
1214 case BuiltinType::SatUShortFract:
1215 case BuiltinType::SatUFract:
1216 case BuiltinType::SatULongFract:
1217 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1221 BTName = BT->
getName(CGM.getLangOpts());
1224 return DBuilder.createBasicType(BTName, Size, Encoding);
1227llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1228 SmallString<32> Name;
1229 llvm::raw_svector_ostream
OS(Name);
1230 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1233 ? llvm::dwarf::DW_ATE_unsigned
1234 : llvm::dwarf::DW_ATE_signed;
1235 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1236 Encoding, llvm::DINode::FlagZero, 0,
1240llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1242 return getOrCreateType(Ty->getUnderlyingType(), U);
1245llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1247 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1249 Encoding = llvm::dwarf::DW_ATE_lo_user;
1252 return DBuilder.createBasicType(
"complex", Size, Encoding);
1266 return llvm::dwarf::DW_TAG_const_type;
1270 return llvm::dwarf::DW_TAG_volatile_type;
1274 return llvm::dwarf::DW_TAG_restrict_type;
1276 return (llvm::dwarf::Tag)0;
1279llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1280 llvm::DIFile *Unit) {
1281 QualifierCollector Qc;
1295 bool AuthenticatesNullValues =
1298 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1299 llvm::DIType *FromTy = getOrCreateType(QualType(T, 0), Unit);
1300 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1301 ExtraDiscr, IsaPointer,
1302 AuthenticatesNullValues);
1304 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1305 return getOrCreateType(QualType(T, 0), Unit);
1309 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
1313 return DBuilder.createQualifiedType(Tag, FromTy);
1316llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1317 llvm::DIFile *Unit) {
1326 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1331 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1337 return DBuilder.createQualifiedType(Tag, FromTy);
1340llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1341 llvm::DIFile *Unit) {
1347 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1349 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1353llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1354 llvm::DIFile *Unit) {
1355 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1361 case llvm::dwarf::DW_LANG_C_plus_plus:
1362 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1363 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1364 case llvm::dwarf::DW_LANG_HIP:
1366 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1376 case llvm::dwarf::DW_LNAME_C_plus_plus:
1377 case llvm::dwarf::DW_LNAME_HIP:
1379 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1390 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1391 SourceLang.hasVersionedName())
1393 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1397 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1423 llvm::DICompileUnit *TheCU) {
1441 llvm::DICompileUnit *TheCU) {
1447 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1449 if (RD->isDynamicClass() &&
1455 llvm::raw_svector_ostream Out(Identifier);
1462 llvm::dwarf::Tag Tag;
1464 Tag = llvm::dwarf::DW_TAG_structure_type;
1466 Tag = llvm::dwarf::DW_TAG_union_type;
1471 Tag = llvm::dwarf::DW_TAG_class_type;
1476llvm::DICompositeType *
1477CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1478 llvm::DIScope *Ctx) {
1479 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1480 if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
1482 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1483 const unsigned Line =
1485 StringRef RDName = getClassName(RD);
1492 Size = CGM.getContext().getTypeSize(Ty);
1494 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1499 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1500 if (!CXXRD->hasDefinition() ||
1501 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1502 Flags |= llvm::DINode::FlagNonTrivial;
1505 SmallString<256> Identifier;
1507 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1509 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1512 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1513 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1514 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1515 CollectCXXTemplateParams(TSpecial, DefUnit));
1516 ReplaceMap.emplace_back(
1517 std::piecewise_construct, std::make_tuple(Ty),
1518 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1522llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1525 llvm::DIFile *Unit) {
1530 std::optional<unsigned> DWARFAddressSpace =
1531 CGM.getTarget().getDWARFAddressSpace(
1532 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1534 const BTFTagAttributedType *BTFAttrTy;
1535 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1536 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1538 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1539 SmallVector<llvm::Metadata *, 4> Annots;
1541 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1543 llvm::Metadata *Ops[2] = {
1544 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1545 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1546 Annots.insert(Annots.begin(),
1547 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1549 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1552 llvm::DINodeArray Annotations =
nullptr;
1553 if (Annots.size() > 0)
1554 Annotations = DBuilder.getOrCreateArray(Annots);
1556 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1557 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1558 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1559 Size, Align, DWARFAddressSpace);
1561 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1562 Align, DWARFAddressSpace, StringRef(),
1566llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1567 llvm::DIType *&
Cache) {
1570 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1571 TheCU, TheCU->getFile(), 0);
1572 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1573 Cache = DBuilder.createPointerType(
Cache, Size);
1577uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1578 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1579 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1589 if (CGM.getLangOpts().OpenCL) {
1590 FType = CGM.getContext().IntTy;
1591 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1592 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1594 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1595 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1596 FType = CGM.getContext().IntTy;
1597 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1598 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1600 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1601 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1602 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1603 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1604 EltTys.push_back(DBuilder.createMemberType(
1605 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1606 FieldOffset, llvm::DINode::FlagZero, DescTy));
1607 FieldOffset += FieldSize;
1613llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1614 llvm::DIFile *Unit) {
1615 SmallVector<llvm::Metadata *, 8> EltTys;
1618 llvm::DINodeArray Elements;
1621 FType = CGM.getContext().UnsignedLongTy;
1622 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1623 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1625 Elements = DBuilder.getOrCreateArray(EltTys);
1628 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1631 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1632 FieldOffset, 0, Flags,
nullptr, Elements);
1637 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1639 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1642 Elements = DBuilder.getOrCreateArray(EltTys);
1648 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1649 Flags,
nullptr, Elements);
1651 return DBuilder.createPointerType(EltTy, Size);
1654static llvm::SmallVector<TemplateArgument>
1656 assert(Ty->isTypeAlias());
1665 ArrayRef SubstArgs = Ty->template_arguments();
1668 if (Param->isParameterPack()) {
1677 if (SubstArgs.empty()) {
1686 SpecArgs.push_back(SubstArgs.front());
1687 SubstArgs = SubstArgs.drop_front();
1692llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1693 llvm::DIFile *Unit) {
1694 assert(Ty->isTypeAlias());
1695 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1697 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1705 SmallString<128> NS;
1706 llvm::raw_svector_ostream
OS(NS);
1708 auto PP = getPrintingPolicy();
1711 SourceLocation Loc =
AliasDecl->getLocation();
1713 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1714 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1723 llvm::raw_string_ostream
OS(Name);
1725 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1726 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1727 !HasReconstitutableArgs(Args.Args))
1728 printTemplateArgumentList(OS, Args.Args, PP);
1730 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1731 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1732 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1736 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1738 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1755 return llvm::DINode::FlagZero;
1759 return llvm::DINode::FlagPrivate;
1761 return llvm::DINode::FlagProtected;
1763 return llvm::DINode::FlagPublic;
1765 return llvm::DINode::FlagZero;
1767 llvm_unreachable(
"unexpected access enumerator");
1770llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1771 llvm::DIFile *Unit) {
1772 llvm::DIType *Underlying =
1784 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1786 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1791 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1792 getOrCreateFile(Loc), getLineNumber(Loc),
1793 getDeclContextDescriptor(Ty->
getDecl()), Align,
1794 Flags, Annotations);
1804 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1806 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1808 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1810 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1812 return llvm::dwarf::DW_CC_BORLAND_pascal;
1814 return llvm::dwarf::DW_CC_LLVM_Win64;
1816 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1820 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1822 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1824 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1826 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1828 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1830 return llvm::dwarf::DW_CC_LLVM_Swift;
1832 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1834 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1836 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1838 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1840 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1842 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1844 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1845#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1859 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1865 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1867 Flags |= llvm::DINode::FlagLValueReference;
1869 Flags |= llvm::DINode::FlagRValueReference;
1873llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1874 llvm::DIFile *Unit) {
1875 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1877 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1883 SmallVector<llvm::Metadata *, 16> EltTys;
1886 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1888 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1892 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1895 for (
const QualType &ParamType : FPT->param_types())
1896 EltTys.push_back(getOrCreateType(ParamType, Unit));
1897 if (FPT->isVariadic())
1898 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1901 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1902 llvm::DIType *F = DBuilder.createSubroutineType(
1907llvm::DIDerivedType *
1908CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1909 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1910 StringRef Name = BitFieldDecl->
getName();
1911 QualType Ty = BitFieldDecl->
getType();
1912 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1915 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1916 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1919 llvm::DIFile *
File = getOrCreateFile(Loc);
1920 unsigned Line = getLineNumber(Loc);
1922 const CGBitFieldInfo &BitFieldInfo =
1923 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1925 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1932 if (CGM.getDataLayout().isBigEndian())
1934 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1936 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1937 return DBuilder.createBitFieldMemberType(
1938 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1939 Flags, DebugType, Annotations);
1942llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1943 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1944 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1946 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1971 if (PreviousFieldsDI.empty())
1975 auto *PreviousMDEntry =
1976 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1977 auto *PreviousMDField =
1978 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1979 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1980 PreviousMDField->getSizeInBits() == 0)
1984 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1986 assert(PreviousBitfield->isBitField());
1988 if (!PreviousBitfield->isZeroLengthBitField())
1991 QualType Ty = PreviousBitfield->getType();
1992 SourceLocation Loc = PreviousBitfield->getLocation();
1993 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1994 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1995 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1997 llvm::DIFile *
File = getOrCreateFile(Loc);
1998 unsigned Line = getLineNumber(Loc);
2004 llvm::DINode::DIFlags Flags =
2006 llvm::DINodeArray Annotations =
2007 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2008 return DBuilder.createBitFieldMemberType(
2009 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2010 Flags, DebugType, Annotations);
2013llvm::DIType *CGDebugInfo::createFieldType(
2015 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
2016 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2017 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2020 llvm::DIFile *file = getOrCreateFile(loc);
2021 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2024 auto Align = AlignInBits;
2025 if (!
type->isIncompleteArrayType()) {
2026 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2027 SizeInBits = TI.
Width;
2033 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2034 offsetInBits, flags, debugType, Annotations);
2038CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2039 llvm::DIFile *FileScope) {
2043 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2046 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2047 SP = DBuilder.createFunction(
2048 FileScope, FuncName, StringRef(),
2049 FileScope, 0, DIFnTy,
2051 llvm::DINode::FlagArtificial,
2052 llvm::DISubprogram::SPFlagDefinition,
2053 nullptr,
nullptr,
nullptr,
2054 nullptr, StringRef(),
2055 CGM.getCodeGenOpts().DebugKeyInstructions);
2062CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2064 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2066 assert(
Capture.capturesVariable());
2068 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2069 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2071 return CaptureDecl->
getName();
2074void CGDebugInfo::CollectRecordLambdaFields(
2075 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2076 llvm::DIType *RecordTy) {
2081 unsigned fieldno = 0;
2084 I != E; ++I, ++Field, ++fieldno) {
2085 const LambdaCapture &
Capture = *I;
2087 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2089 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2099 Loc =
Field->getLocation();
2100 }
else if (
Capture.capturesVariable()) {
2103 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2104 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2111 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2113 elements.push_back(createFieldType(
2115 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2121template <
typename T>
2122static llvm::Constant *
2133 return llvm::ConstantDataArray::get(Ctx, Vals);
2146 const QualType ElemQTy = ArrayTy->getElementType();
2153 switch (ElemBitWidth) {
2169llvm::DIDerivedType *
2170CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2171 const RecordDecl *RD) {
2175 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2176 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2178 unsigned LineNumber = getLineNumber(Var->
getLocation());
2179 StringRef VName = Var->
getName();
2183 llvm::Constant *
C =
nullptr;
2188 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2189 if (
Value->isFloat())
2190 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2191 if (
Value->isArray())
2197 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2198 ? llvm::dwarf::DW_TAG_variable
2199 : llvm::dwarf::DW_TAG_member;
2201 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2202 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2207void CGDebugInfo::CollectRecordNormalField(
2208 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2209 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2210 const RecordDecl *RD) {
2215 if (
name.empty() && !
type->isRecordType())
2218 llvm::DIType *FieldType;
2220 llvm::DIDerivedType *BitFieldType;
2221 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2222 if (llvm::DIType *Separator =
2223 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2224 elements.push_back(Separator);
2227 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2230 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2233 elements.push_back(FieldType);
2236void CGDebugInfo::CollectRecordNestedType(
2237 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2238 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2245 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2246 elements.push_back(nestedType);
2249void CGDebugInfo::CollectRecordFields(
2250 const RecordDecl *record, llvm::DIFile *tunit,
2251 SmallVectorImpl<llvm::Metadata *> &elements,
2252 llvm::DICompositeType *RecordTy) {
2253 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2255 if (CXXDecl && CXXDecl->
isLambda())
2256 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2258 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2261 unsigned fieldNo = 0;
2265 for (
const auto *I : record->
decls())
2266 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2267 if (
V->hasAttr<NoDebugAttr>())
2272 if (CGM.getCodeGenOpts().EmitCodeView &&
2280 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2281 if (MI != StaticDataMemberCache.end()) {
2282 assert(MI->second &&
2283 "Static data member declaration should still exist");
2284 elements.push_back(MI->second);
2286 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2287 elements.push_back(Field);
2289 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2290 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2291 elements, RecordTy, record);
2295 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2298 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2303 if (!nestedType->isImplicit() &&
2304 nestedType->getDeclContext() == record)
2305 CollectRecordNestedType(nestedType, elements);
2311llvm::DISubroutineType *
2312CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2313 llvm::DIFile *Unit) {
2314 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2316 return cast_or_null<llvm::DISubroutineType>(
2317 getOrCreateType(QualType(
Func, 0), Unit));
2320 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2321 ThisType =
Method->getThisType();
2323 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2326llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2327 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2328 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2330 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2333llvm::DISubroutineType *
2334CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2335 const FunctionProtoType *
Func,
2336 llvm::DIFile *Unit,
bool SkipFirst) {
2337 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2352 getOrCreateType(CGM.getContext().getFunctionType(
2353 Func->getReturnType(),
Func->getParamTypes(), EPI),
2355 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2356 assert(Args.size() &&
"Invalid number of arguments!");
2358 SmallVector<llvm::Metadata *, 16> Elts;
2361 Elts.push_back(Args[0]);
2363 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2367 if (!HasExplicitObjectParameter) {
2368 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2371 DBuilder.createObjectPointerType(ThisPtrType,
true);
2372 Elts.push_back(ThisPtrType);
2376 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2377 Elts.push_back(Args[i]);
2380 if (HasExplicitObjectParameter) {
2381 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2382 "Expected at least return type and object parameter.");
2383 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2386 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2388 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2395 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2403CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2406 const bool IsCtorOrDtor =
2409 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2416 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2419 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2422 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2425 return CGM.getMangledName(
Method);
2428bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2431 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2434llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2435 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2438 StringRef MethodName = getFunctionName(
Method);
2439 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2441 StringRef MethodLinkageName;
2448 MethodLinkageName = GetMethodLinkageName(
Method);
2451 llvm::DIFile *MethodDefUnit =
nullptr;
2452 unsigned MethodLine = 0;
2453 if (!
Method->isImplicit()) {
2454 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2455 MethodLine = getLineNumber(
Method->getLocation());
2459 llvm::DIType *ContainingType =
nullptr;
2460 unsigned VIndex = 0;
2461 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2462 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2463 int ThisAdjustment = 0;
2466 if (
Method->isPureVirtual())
2467 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2469 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2471 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2475 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2479 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2482 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2483 CGM.getContext().getLangOpts())
2487 MethodVFTableLocation ML =
2488 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2496 if (
Method->size_overridden_methods() == 0)
2497 Flags |= llvm::DINode::FlagIntroducedVirtual;
2502 ThisAdjustment = CGM.getCXXABI()
2503 .getVirtualFunctionPrologueThisAdjustment(GD)
2506 ContainingType = RecordTy;
2509 if (
Method->getCanonicalDecl()->isDeleted())
2510 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2512 if (
Method->isNoReturn())
2513 Flags |= llvm::DINode::FlagNoReturn;
2516 Flags |= llvm::DINode::FlagStaticMember;
2517 if (
Method->isImplicit())
2518 Flags |= llvm::DINode::FlagArtificial;
2520 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2521 if (CXXC->isExplicit())
2522 Flags |= llvm::DINode::FlagExplicit;
2523 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2524 if (CXXC->isExplicit())
2525 Flags |= llvm::DINode::FlagExplicit;
2527 if (
Method->hasPrototype())
2528 Flags |= llvm::DINode::FlagPrototyped;
2530 Flags |= llvm::DINode::FlagLValueReference;
2532 Flags |= llvm::DINode::FlagRValueReference;
2533 if (!
Method->isExternallyVisible())
2534 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2535 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2536 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2540 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2541 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2544 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2545 llvm::DISubprogram *SP = DBuilder.createMethod(
2546 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2547 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2548 TParamsArray.get(),
nullptr,
2549 CGM.getCodeGenOpts().DebugKeyInstructions);
2551 SPCache[
Method->getCanonicalDecl()].reset(SP);
2556void CGDebugInfo::CollectCXXMemberFunctions(
2557 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2558 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2563 for (
const auto *I : RD->
decls()) {
2564 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2578 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2587 auto MI = SPCache.find(
Method->getCanonicalDecl());
2588 EltTys.push_back(MI == SPCache.end()
2589 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2590 :
static_cast<llvm::Metadata *
>(MI->second));
2594void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2595 SmallVectorImpl<llvm::Metadata *> &EltTys,
2596 llvm::DIType *RecordTy) {
2597 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2598 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2599 llvm::DINode::FlagZero);
2603 if (CGM.getCodeGenOpts().EmitCodeView) {
2604 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2605 llvm::DINode::FlagIndirectVirtualBase);
2609void CGDebugInfo::CollectCXXBasesAux(
2610 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2611 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2613 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2614 llvm::DINode::DIFlags StartingFlags) {
2615 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2616 for (
const auto &BI : Bases) {
2619 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2621 if (!SeenTypes.insert(Base).second)
2623 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2624 llvm::DINode::DIFlags BFlags = StartingFlags;
2628 if (BI.isVirtual()) {
2629 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2632 BaseOffset = 0 - CGM.getItaniumVTableContext()
2633 .getVirtualBaseOffsetOffset(RD, Base)
2639 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2640 VBPtrOffset = CGM.getContext()
2641 .getASTRecordLayout(RD)
2645 BFlags |= llvm::DINode::FlagVirtual;
2652 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2653 VBPtrOffset, BFlags);
2654 EltTys.push_back(DTy);
2659CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2660 llvm::DIFile *Unit) {
2662 return llvm::DINodeArray();
2663 TemplateArgs &Args = *OArgs;
2664 SmallVector<llvm::Metadata *, 16> TemplateParams;
2665 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2666 const TemplateArgument &TA = Args.Args[i];
2670 Name = Args.TList->getParam(i)->getName();
2674 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2675 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2676 TheCU, Name, TTy, defaultParameter));
2681 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2682 TheCU, Name, TTy, defaultParameter,
2683 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2688 llvm::DIType *TTy = getOrCreateType(T, Unit);
2689 llvm::Constant *
V =
nullptr;
2692 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2693 !D->
hasAttr<CUDADeviceAttr>()) {
2696 if (
const auto *VD = dyn_cast<VarDecl>(D))
2697 V = CGM.GetAddrOfGlobalVar(VD);
2700 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2701 MD && MD->isImplicitObjectMemberFunction())
2702 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2703 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2704 V = CGM.GetAddrOfFunction(FD);
2707 else if (
const auto *MPT =
2708 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2712 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2714 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2715 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2716 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2717 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2718 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2720 V = ConstantEmitter(CGM).emitAbstract(
2721 SourceLocation(), TPO->getValue(), TPO->getType());
2723 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2725 assert(
V &&
"Failed to find template parameter pointer");
2726 V =
V->stripPointerCasts();
2728 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2729 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2733 llvm::DIType *TTy = getOrCreateType(T, Unit);
2734 llvm::Constant *
V =
nullptr;
2737 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2743 if (MPT->isMemberDataPointer())
2744 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2746 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2747 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2748 TheCU, Name, TTy, defaultParameter,
V));
2752 llvm::DIType *TTy = getOrCreateType(T, Unit);
2753 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2755 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2756 TheCU, Name, TTy, defaultParameter,
V));
2759 std::string QualName;
2760 llvm::raw_string_ostream
OS(QualName);
2762 OS, getPrintingPolicy());
2763 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2764 TheCU, Name,
nullptr, QualName, defaultParameter));
2768 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2769 TheCU, Name,
nullptr,
2776 T = CGM.getContext().getLValueReferenceType(T);
2777 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2778 assert(
V &&
"Expression in template argument isn't constant");
2779 llvm::DIType *TTy = getOrCreateType(T, Unit);
2780 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2781 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2787 "These argument types shouldn't exist in concrete types");
2790 return DBuilder.getOrCreateArray(TemplateParams);
2793std::optional<CGDebugInfo::TemplateArgs>
2794CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2802 return std::nullopt;
2804std::optional<CGDebugInfo::TemplateArgs>
2805CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2809 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2811 return std::nullopt;
2812 VarTemplateDecl *T = TS->getSpecializedTemplate();
2814 auto TA = TS->getTemplateArgs().asArray();
2815 return {{TList, TA}};
2817std::optional<CGDebugInfo::TemplateArgs>
2818CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2819 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2823 TemplateParameterList *TPList =
2824 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2825 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2826 return {{TPList, TAList.
asArray()}};
2828 return std::nullopt;
2832CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2833 llvm::DIFile *Unit) {
2834 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2837llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2838 llvm::DIFile *Unit) {
2839 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2842llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2843 llvm::DIFile *Unit) {
2844 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2847llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2848 if (!D->
hasAttr<BTFDeclTagAttr>())
2851 SmallVector<llvm::Metadata *, 4> Annotations;
2853 llvm::Metadata *Ops[2] = {
2854 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2855 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2856 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2858 return DBuilder.getOrCreateArray(Annotations);
2861llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2863 return VTablePtrType;
2865 ASTContext &Context = CGM.getContext();
2868 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2869 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2870 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2872 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2873 std::optional<unsigned> DWARFAddressSpace =
2874 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2876 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2877 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2878 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2879 return VTablePtrType;
2882StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2894 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2896 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2906 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2907 VTable->isDeclarationForLinker())
2911 StringRef SymbolName =
"__clang_vtable";
2913 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2922 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2924 llvm::DIFile *Unit = getOrCreateFile(Loc);
2925 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2927 llvm::DINode::FlagArtificial;
2928 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2929 ? llvm::dwarf::DW_TAG_variable
2930 : llvm::dwarf::DW_TAG_member;
2931 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2932 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2936 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2940 llvm::DIGlobalVariableExpression *GVE =
2941 DBuilder.createGlobalVariableExpression(
2942 TheCU, SymbolName, VTable->getName(), Unit, 0,
2943 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2944 true,
nullptr, DT,
nullptr,
2946 VTable->addDebugInfo(GVE);
2949StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2951 llvm::Function *InitFn) {
2956 return InitFn->getName();
2966 llvm::raw_svector_ostream OS(QualifiedGV);
2968 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2970 std::swap(Quals, GVName);
2974 llvm::raw_svector_ostream OS(InitName);
2976 OS << Quals <<
"::";
2981 llvm_unreachable(
"not an initializer");
2983 OS <<
"`dynamic initializer for '";
2986 OS <<
"`dynamic atexit destructor for '";
2993 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2994 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2995 getPrintingPolicy());
3000 return internString(
OS.str());
3003void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3004 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3013 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3020 llvm::DIType *VPtrTy =
nullptr;
3021 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3022 CGM.getTarget().getCXXABI().isMicrosoft();
3023 if (NeedVTableShape) {
3025 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3026 const VTableLayout &VFTLayout =
3027 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3028 unsigned VSlotCount =
3030 unsigned VTableWidth = PtrWidth * VSlotCount;
3031 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3032 std::optional<unsigned> DWARFAddressSpace =
3033 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3036 llvm::DIType *VTableType = DBuilder.createPointerType(
3037 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3038 EltTys.push_back(VTableType);
3041 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3049 VPtrTy = getOrCreateVTablePtrType(Unit);
3051 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3052 llvm::DIType *VPtrMember =
3053 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3054 llvm::DINode::FlagArtificial, VPtrTy);
3055 EltTys.push_back(VPtrMember);
3060 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3061 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3072 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3073 assert(!D.
isNull() &&
"null type");
3074 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3075 assert(T &&
"could not create debug info for type");
3084 if (CGM.getCodeGenOpts().getDebugInfo() <=
3085 llvm::codegenoptions::DebugLineTablesOnly)
3089 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3091 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3093 CI->setMetadata(
"heapallocsite", node);
3097 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3099 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3101 auto I = TypeCache.find(TyPtr);
3104 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3105 assert(!Res->isForwardDecl());
3106 TypeCache[TyPtr].reset(Res);
3110 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3111 !CGM.getLangOpts().CPlusPlus)
3117 if (RD->
hasAttr<DLLImportAttr>())
3120 if (MD->hasAttr<DLLImportAttr>())
3133 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3143 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3144 Explicit = TD->isExplicitInstantiationOrSpecialization();
3148 if (CXXDecl->
fields().empty())
3158 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3159 if (CXXRD->isDynamicClass() &&
3160 CGM.getVTableLinkage(CXXRD) ==
3161 llvm::GlobalValue::AvailableExternallyLinkage &&
3172 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3174 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3176 auto I = TypeCache.find(TyPtr);
3183 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3184 assert(!Res->isForwardDecl());
3185 TypeCache[TyPtr].reset(Res);
3192 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3193 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3216 if (Ctor->isCopyOrMoveConstructor())
3218 if (!Ctor->isDeleted())
3237 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3240 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3241 RD->
hasAttr<StandaloneDebugAttr>())
3244 if (!LangOpts.CPlusPlus)
3250 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3266 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3267 Spec = SD->getSpecializationKind();
3276 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3287 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3288 llvm::DIType *T = getTypeOrNull(Ty);
3289 if (T && T->isForwardDecl())
3293llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3294 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3295 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3299 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3303 auto [Def, Pref] = CreateTypeDefinition(Ty);
3305 return Pref ? Pref : Def;
3308llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3309 llvm::DIFile *Unit) {
3313 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3317 return getOrCreateType(PNA->getTypedefType(), Unit);
3320std::pair<llvm::DIType *, llvm::DIType *>
3321CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3322 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3325 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3333 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3337 return {FwdDecl,
nullptr};
3339 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3340 CollectContainingType(CXXDecl, FwdDecl);
3343 LexicalBlockStack.emplace_back(&*FwdDecl);
3344 RegionMap[RD].reset(FwdDecl);
3347 SmallVector<llvm::Metadata *, 16> EltTys;
3354 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3356 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3357 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3361 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3362 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3363 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3365 LexicalBlockStack.pop_back();
3366 RegionMap.erase(RD);
3368 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3369 DBuilder.replaceArrays(FwdDecl, Elements);
3371 if (FwdDecl->isTemporary())
3373 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3375 RegionMap[RD].reset(FwdDecl);
3377 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3378 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3379 return {FwdDecl, PrefDI};
3381 return {FwdDecl,
nullptr};
3384llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3385 llvm::DIFile *Unit) {
3387 return getOrCreateType(Ty->getBaseType(), Unit);
3390llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3391 llvm::DIFile *Unit) {
3393 SourceLocation Loc = Ty->getDecl()->getLocation();
3396 return DBuilder.createTypedef(
3397 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3398 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3399 getDeclContextDescriptor(Ty->getDecl()));
3426llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3427 llvm::DIFile *Unit) {
3432 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3433 TheCU->getSourceLanguage().getUnversionedName());
3438 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3439 !
ID->getImplementation())
3440 return DBuilder.createForwardDecl(
3441 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3442 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3445 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3446 unsigned Line = getLineNumber(
ID->getLocation());
3450 ObjCInterfaceDecl *Def =
ID->getDefinition();
3452 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3453 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3454 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3455 DefUnit,
Line, RuntimeLang);
3456 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3460 return CreateTypeDefinition(Ty, Unit);
3463llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3464 bool CreateSkeletonCU) {
3469 auto ModRef = ModuleCache.find(M);
3470 if (ModRef != ModuleCache.end())
3474 SmallString<128> ConfigMacros;
3476 llvm::raw_svector_ostream
OS(ConfigMacros);
3477 const auto &PPOpts = CGM.getPreprocessorOpts();
3480 for (
auto &M : PPOpts.Macros) {
3483 const std::string &
Macro = M.first;
3484 bool Undef = M.second;
3485 OS <<
"\"-" << (Undef ?
'U' :
'D');
3501 bool IsRootModule = M ? !M->
Parent :
true;
3505 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3506 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3507 "clang module without ASTFile must be specified by -fmodule-name");
3510 auto RemapPath = [
this](StringRef Path) -> std::string {
3512 StringRef Relative(Remapped);
3513 StringRef CompDir = TheCU->getDirectory();
3514 if (CompDir.empty())
3517 if (Relative.consume_front(CompDir))
3518 Relative.consume_front(llvm::sys::path::get_separator());
3520 return Relative.str();
3523 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3530 Signature = ModSig.truncatedValue();
3534 llvm::DIBuilder DIB(CGM.getModule());
3536 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3537 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3538 PCM = getCurrentDirname();
3542 llvm::sys::path::append(PCM, Mod.
getASTFile());
3543 DIB.createCompileUnit(
3544 TheCU->getSourceLanguage(),
3547 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3548 llvm::DICompileUnit::FullDebug, Signature);
3552 llvm::DIModule *Parent =
3554 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3556 StringRef IncludePath = Mod.
getPath();
3557 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3558 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3559 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3562 llvm::DIModule *DIMod =
3563 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3564 RemapPath(IncludePath));
3565 ModuleCache[M].reset(DIMod);
3569llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3570 llvm::DIFile *Unit) {
3572 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3573 unsigned Line = getLineNumber(
ID->getLocation());
3575 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3581 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3582 if (
ID->getImplementation())
3583 Flags |= llvm::DINode::FlagObjcClassComplete;
3585 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3586 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3587 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3588 nullptr, llvm::DINodeArray(), RuntimeLang);
3590 QualType QTy(Ty, 0);
3591 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3594 LexicalBlockStack.emplace_back(RealDecl);
3595 RegionMap[Ty->
getDecl()].reset(RealDecl);
3598 SmallVector<llvm::Metadata *, 16> EltTys;
3600 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3602 llvm::DIType *SClassTy =
3603 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3607 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3608 llvm::DINode::FlagZero);
3609 EltTys.push_back(InhTag);
3613 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3614 SourceLocation Loc = PD->getLocation();
3615 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3616 unsigned PLine = getLineNumber(Loc);
3617 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3618 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3619 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3620 PD->getName(), PUnit, PLine,
3622 : getSelectorName(PD->getGetterName()),
3624 : getSelectorName(PD->getSetterName()),
3625 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3626 EltTys.push_back(PropertyNode);
3631 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3635 llvm::DenseSet<IsClassAndIdent> PropertySet;
3637 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3638 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3640 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3641 for (
auto *PD : ClassExt->properties()) {
3642 PropertySet.insert(GetIsClassAndIdent(PD));
3645 for (
const auto *PD :
ID->properties()) {
3648 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3654 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3655 unsigned FieldNo = 0;
3656 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3657 Field =
Field->getNextIvar(), ++FieldNo) {
3658 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3662 StringRef FieldName =
Field->getName();
3665 if (FieldName.empty())
3669 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3670 unsigned FieldLine = getLineNumber(
Field->getLocation());
3671 QualType FType =
Field->getType();
3678 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3679 : CGM.getContext().getTypeSize(FType);
3684 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3688 if (
Field->isBitField()) {
3690 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3691 FieldOffset %= CGM.getContext().getCharWidth();
3699 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3701 Flags = llvm::DINode::FlagProtected;
3703 Flags = llvm::DINode::FlagPrivate;
3705 Flags = llvm::DINode::FlagPublic;
3707 if (
Field->isBitField())
3708 Flags |= llvm::DINode::FlagBitField;
3710 llvm::MDNode *PropertyNode =
nullptr;
3711 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3712 if (ObjCPropertyImplDecl *PImpD =
3713 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3714 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3715 SourceLocation Loc = PD->getLocation();
3716 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3717 unsigned PLine = getLineNumber(Loc);
3718 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3719 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3720 PropertyNode = DBuilder.createObjCProperty(
3721 PD->getName(), PUnit, PLine,
3724 : getSelectorName(PD->getGetterName()),
3727 : getSelectorName(PD->getSetterName()),
3728 PD->getPropertyAttributes(),
3729 getOrCreateType(PD->getType(), PUnit));
3733 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3734 FieldSize, FieldAlign, FieldOffset, Flags,
3735 FieldTy, PropertyNode);
3736 EltTys.push_back(FieldTy);
3739 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3740 DBuilder.replaceArrays(RealDecl, Elements);
3742 LexicalBlockStack.pop_back();
3746llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3747 llvm::DIFile *Unit) {
3755 auto &Ctx = CGM.getContext();
3760 QualType CharVecTy =
3762 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3765 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3768 llvm::Metadata *Subscript;
3769 QualType QTy(Ty, 0);
3770 auto SizeExpr = SizeExprCache.find(QTy);
3771 if (SizeExpr != SizeExprCache.end())
3772 Subscript = DBuilder.getOrCreateSubrange(
3773 SizeExpr->getSecond() ,
nullptr ,
3774 nullptr ,
nullptr );
3777 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3778 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3779 Subscript = DBuilder.getOrCreateSubrange(
3780 CountNode ,
nullptr ,
nullptr ,
3783 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3788 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3791llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3792 llvm::DIFile *Unit) {
3796 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3801 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3802 auto *ColumnCountNode =
3803 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3804 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3805 auto *RowCountNode =
3806 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3807 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3808 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3809 ColumnCountNode ,
nullptr ,
nullptr ,
3811 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3812 RowCountNode ,
nullptr ,
nullptr ,
3814 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3815 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3818llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3823 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3838 Size = CGM.getContext().getTypeSize(Ty);
3845 SmallVector<llvm::Metadata *, 8> Subscripts;
3846 QualType EltTy(Ty, 0);
3847 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3856 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3857 Count = CAT->getZExtSize();
3858 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3859 if (Expr *Size = VAT->getSizeExpr()) {
3861 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3862 Count =
Result.Val.getInt().getExtValue();
3866 auto SizeNode = SizeExprCache.find(EltTy);
3867 if (SizeNode != SizeExprCache.end())
3868 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3869 SizeNode->getSecond() ,
nullptr ,
3870 nullptr ,
nullptr ));
3873 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3874 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3875 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3876 CountNode ,
nullptr ,
nullptr ,
3882 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3884 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3888llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3889 llvm::DIFile *Unit) {
3890 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3894llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3895 llvm::DIFile *Unit) {
3896 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3898 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3899 CGM.getCodeGenOpts().DwarfVersion < 4)
3900 Tag = llvm::dwarf::DW_TAG_reference_type;
3902 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3905llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3907 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3911 Size = CGM.getContext().getTypeSize(Ty);
3914 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3917 Flags |= llvm::DINode::FlagSingleInheritance;
3920 Flags |= llvm::DINode::FlagMultipleInheritance;
3923 Flags |= llvm::DINode::FlagVirtualInheritance;
3933 llvm::DIType *ClassType = getOrCreateType(T, U);
3935 return DBuilder.createMemberPointerType(
3939 const FunctionProtoType *FPT =
3941 return DBuilder.createMemberPointerType(
3942 getOrCreateInstanceMethodType(
3945 ClassType, Size, 0, Flags);
3948llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3950 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3953llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3957llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3959 return getOrCreateType(Ty->getWrappedType(), U);
3962llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3969 const EnumType *Ty) {
3981llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3984 bool isImportedFromModule =
3985 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3989 if (isImportedFromModule || !ED->getDefinition()) {
3996 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3997 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3998 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3999 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4001 unsigned Line = getLineNumber(ED->getLocation());
4002 StringRef EDName = ED->getName();
4003 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4004 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4005 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4007 ReplaceMap.emplace_back(
4008 std::piecewise_construct, std::make_tuple(Ty),
4009 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4013 return CreateTypeDefinition(Ty);
4016llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4019 SmallVector<llvm::Metadata *, 16> Enumerators;
4020 ED = ED->getDefinition();
4021 assert(ED &&
"An enumeration definition is required");
4022 for (
const auto *
Enum : ED->enumerators()) {
4023 Enumerators.push_back(
4024 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4027 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4028 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4029 EnumKind = Attr->getExtensibility();
4032 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4034 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4035 unsigned Line = getLineNumber(ED->getLocation());
4036 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4037 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4038 return DBuilder.createEnumerationType(
4039 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4040 0, Identifier, ED->isScoped(), EnumKind);
4045 StringRef Name, StringRef
Value) {
4046 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4047 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4053 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4054 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4055 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4060 llvm::DISubprogram *SynthSubprogram) {
4061 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4062 SynthSubprogram, ParentLocation);
4067 StringRef SynthFuncName,
4068 llvm::DIFile *SynthFile) {
4069 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4074 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4080 FuncName += Category;
4082 FuncName += FailureMsg;
4085 TrapLocation->getFile());
4091 Qualifiers InnerQuals = T.getLocalQualifiers();
4095 Quals += InnerQuals;
4097 switch (T->getTypeClass()) {
4099 return C.getQualifiedType(T.getTypePtr(), Quals);
4102 case Type::InjectedClassName:
4103 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4105 case Type::TemplateSpecialization: {
4107 if (Spec->isTypeAlias())
4108 return C.getQualifiedType(T.getTypePtr(), Quals);
4109 T = Spec->desugar();
4112 case Type::TypeOfExpr:
4118 case Type::Decltype:
4121 case Type::UnaryTransform:
4124 case Type::Attributed:
4127 case Type::BTFTagAttributed:
4130 case Type::CountAttributed:
4139 case Type::MacroQualified:
4142 case Type::SubstTemplateTypeParm:
4146 case Type::DeducedTemplateSpecialization: {
4148 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4152 case Type::PackIndexing: {
4156 case Type::Adjusted:
4163 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4168llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4171 if (It != TypeCache.end()) {
4173 if (llvm::Metadata *
V = It->second)
4186 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4193 RetainedTypes.push_back(
4194 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4197llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4201 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4203 llvm::raw_string_ostream OS(Name);
4204 Ty.
print(OS, getPrintingPolicy());
4211 if (
auto *T = getTypeOrNull(Ty))
4214 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4215 void *TyPtr = Ty.getAsOpaquePtr();
4218 TypeCache[TyPtr].reset(Res);
4223llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4231 auto Info = Reader->getSourceDescriptor(Idx);
4233 return getOrCreateModuleRef(*Info,
true);
4234 }
else if (ClangModuleMap) {
4247 auto Info = ASTSourceDescriptor(*M);
4248 return getOrCreateModuleRef(Info,
false);
4251 return getOrCreateModuleRef(PCHDescriptor,
false);
4258llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4261 return CreateQualifiedType(Ty, Unit);
4265#define TYPE(Class, Base)
4266#define ABSTRACT_TYPE(Class, Base)
4267#define NON_CANONICAL_TYPE(Class, Base)
4268#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4269#include "clang/AST/TypeNodes.inc"
4270 llvm_unreachable(
"Dependent types cannot show up in debug information");
4272 case Type::ExtVector:
4275 case Type::ConstantMatrix:
4277 case Type::ObjCObjectPointer:
4279 case Type::ObjCObject:
4281 case Type::ObjCTypeParam:
4283 case Type::ObjCInterface:
4291 case Type::BlockPointer:
4299 case Type::FunctionProto:
4300 case Type::FunctionNoProto:
4302 case Type::ConstantArray:
4303 case Type::VariableArray:
4304 case Type::IncompleteArray:
4305 case Type::ArrayParameter:
4308 case Type::LValueReference:
4310 case Type::RValueReference:
4313 case Type::MemberPointer:
4321 case Type::OverflowBehavior:
4326 case Type::TemplateSpecialization:
4328 case Type::HLSLAttributedResource:
4330 case Type::HLSLInlineSpirv:
4332 case Type::PredefinedSugar:
4334 case Type::CountAttributed:
4336 case Type::Attributed:
4337 case Type::BTFTagAttributed:
4338 case Type::Adjusted:
4340 case Type::DeducedTemplateSpecialization:
4343 case Type::MacroQualified:
4344 case Type::SubstTemplateTypeParm:
4345 case Type::TypeOfExpr:
4347 case Type::Decltype:
4348 case Type::PackIndexing:
4349 case Type::UnaryTransform:
4353 llvm_unreachable(
"type should have been unwrapped!");
4356llvm::DICompositeType *
4357CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4358 QualType QTy(Ty, 0);
4360 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4365 if (T && !T->isForwardDecl())
4369 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4374 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4377 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4382llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4383 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4384 bool NameIsSimplified =
false;
4387 StringRef RDName = getClassName(RD, &NameIsSimplified);
4389 llvm::DIFile *DefUnit =
nullptr;
4392 DefUnit = getOrCreateFile(Loc);
4393 Line = getLineNumber(Loc);
4396 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4400 auto *T = cast_or_null<llvm::DICompositeType>(
4401 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4409 return getOrCreateRecordFwdDecl(Ty, RDContext);
4422 auto Flags = llvm::DINode::FlagZero;
4423 if (NameIsSimplified)
4424 Flags |= llvm::DINode::FlagNameIsSimplified;
4425 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4427 Flags |= llvm::DINode::FlagTypePassByReference;
4429 Flags |= llvm::DINode::FlagTypePassByValue;
4432 if (!CXXRD->isTrivial())
4433 Flags |= llvm::DINode::FlagNonTrivial;
4436 if (CXXRD->isAnonymousStructOrUnion())
4437 Flags |= llvm::DINode::FlagExportSymbols;
4440 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4443 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4444 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4446 Flags, Identifier, Annotations);
4450 switch (RealDecl->getTag()) {
4452 llvm_unreachable(
"invalid composite type tag");
4454 case llvm::dwarf::DW_TAG_array_type:
4455 case llvm::dwarf::DW_TAG_enumeration_type:
4460 if (Identifier.empty())
4464 case llvm::dwarf::DW_TAG_structure_type:
4465 case llvm::dwarf::DW_TAG_union_type:
4466 case llvm::dwarf::DW_TAG_class_type:
4469 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4473 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4474 CXXRecordDecl *TemplateDecl =
4475 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4476 RegionMap[TemplateDecl].reset(RealDecl);
4478 RegionMap[RD].reset(RealDecl);
4480 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4482 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4483 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4484 CollectCXXTemplateParams(TSpecial, DefUnit));
4488void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4489 llvm::DICompositeType *RealDecl) {
4491 llvm::DIType *ContainingType =
nullptr;
4492 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4496 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4503 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4504 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4506 ContainingType = RealDecl;
4508 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4511llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4512 StringRef Name, uint64_t *Offset) {
4513 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4514 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4517 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4518 *Offset, llvm::DINode::FlagZero, FieldTy);
4519 *Offset += FieldSize;
4523void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4525 StringRef &LinkageName,
4526 llvm::DIScope *&FDContext,
4527 llvm::DINodeArray &TParamsArray,
4528 llvm::DINode::DIFlags &Flags) {
4530 bool NameIsSimplified =
false;
4531 Name = getFunctionName(FD, &NameIsSimplified);
4532 if (NameIsSimplified)
4533 Flags |= llvm::DINode::FlagNameIsSimplified;
4534 Name = getFunctionName(FD);
4537 LinkageName = CGM.getMangledName(GD);
4539 Flags |= llvm::DINode::FlagPrototyped;
4543 if (LinkageName == Name ||
4544 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4545 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4546 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4547 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4548 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4549 LinkageName = StringRef();
4553 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4554 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4555 CGM.getCodeGenOpts().EmitCodeView)) {
4556 if (
const NamespaceDecl *NSDecl =
4558 FDContext = getOrCreateNamespace(NSDecl);
4559 else if (
const RecordDecl *RDecl =
4561 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4562 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4565 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4568 Flags |= llvm::DINode::FlagNoReturn;
4570 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4574void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4575 unsigned &LineNo, QualType &T,
4576 StringRef &Name, StringRef &LinkageName,
4577 llvm::MDTuple *&TemplateParameters,
4578 llvm::DIScope *&VDContext) {
4587 llvm::APInt ConstVal(32, 1);
4588 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4590 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4597 LinkageName = CGM.getMangledName(VD);
4598 if (LinkageName == Name)
4599 LinkageName = StringRef();
4602 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4603 TemplateParameters = parameterNodes.get();
4605 TemplateParameters =
nullptr;
4623 DC = CGM.getContext().getTranslationUnitDecl();
4625 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4626 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4629llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4631 llvm::DINodeArray TParamsArray;
4632 StringRef Name, LinkageName;
4633 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4634 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4636 llvm::DIFile *Unit = getOrCreateFile(Loc);
4637 llvm::DIScope *DContext = Unit;
4638 unsigned Line = getLineNumber(Loc);
4639 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4644 SmallVector<QualType, 16> ArgTypes;
4645 for (
const ParmVarDecl *Parm : FD->
parameters())
4646 ArgTypes.push_back(Parm->getType());
4649 QualType FnType = CGM.getContext().getFunctionType(
4650 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4652 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4653 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4654 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4658 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4659 return DBuilder.createFunction(
4660 DContext, Name, LinkageName, Unit,
Line,
4661 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4662 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4664 CGM.getCodeGenOpts().DebugKeyInstructions);
4667 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4668 DContext, Name, LinkageName, Unit,
Line,
4669 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4670 TParamsArray.get(), getFunctionDeclaration(FD));
4672 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4673 std::make_tuple(CanonDecl),
4674 std::make_tuple(SP));
4678llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4679 return getFunctionFwdDeclOrStub(GD,
false);
4682llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4683 return getFunctionFwdDeclOrStub(GD,
true);
4686llvm::DIGlobalVariable *
4687CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4689 StringRef Name, LinkageName;
4691 llvm::DIFile *Unit = getOrCreateFile(Loc);
4692 llvm::DIScope *DContext = Unit;
4693 unsigned Line = getLineNumber(Loc);
4694 llvm::MDTuple *TemplateParameters =
nullptr;
4696 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4699 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4700 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4702 FwdDeclReplaceMap.emplace_back(
4703 std::piecewise_construct,
4705 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4709llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4714 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4715 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4716 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4720 if (I != DeclCache.end()) {
4722 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4723 return GVE->getVariable();
4731 if (IE != ImportedDeclCache.end()) {
4732 auto N = IE->second;
4733 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4735 return dyn_cast_or_null<llvm::DINode>(N);
4740 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4741 return getFunctionForwardDeclaration(FD);
4742 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4743 return getGlobalVariableForwardDeclaration(VD);
4748llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4749 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4752 const auto *FD = dyn_cast<FunctionDecl>(D);
4757 auto *S = getDeclContextDescriptor(D);
4760 if (MI == SPCache.end()) {
4762 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4766 if (MI != SPCache.end()) {
4767 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4768 if (SP && !SP->isDefinition())
4772 for (
auto *NextFD : FD->
redecls()) {
4773 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4774 if (MI != SPCache.end()) {
4775 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4776 if (SP && !SP->isDefinition())
4783llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4784 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4785 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4786 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4789 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4793 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4797 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4806 QualType QTy(
ID->getTypeForDecl(), 0);
4807 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4808 if (It == TypeCache.end())
4811 llvm::DISubprogram *FD = DBuilder.createFunction(
4812 InterfaceType, getObjCMethodName(OMD), StringRef(),
4813 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4814 DBuilder.finalizeSubprogram(FD);
4821llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4826 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4827 !CGM.getCodeGenOpts().EmitCodeView))
4830 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4832 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4835 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4838 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4839 return getOrCreateMethodType(
Method, F);
4841 const auto *FTy = FnType->
getAs<FunctionType>();
4844 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4846 SmallVector<llvm::Metadata *, 16> Elts;
4849 QualType ResultTy = OMethod->getReturnType();
4852 if (ResultTy == CGM.getContext().getObjCInstanceType())
4853 ResultTy = CGM.getContext().getPointerType(
4854 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4856 Elts.push_back(getOrCreateType(ResultTy, F));
4858 QualType SelfDeclTy;
4859 if (
auto *SelfDecl = OMethod->getSelfDecl())
4860 SelfDeclTy = SelfDecl->getType();
4861 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4864 if (!SelfDeclTy.
isNull())
4866 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4868 Elts.push_back(DBuilder.createArtificialType(
4869 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4871 for (
const auto *PI : OMethod->parameters())
4872 Elts.push_back(getOrCreateType(PI->getType(), F));
4874 if (OMethod->isVariadic())
4875 Elts.push_back(DBuilder.createUnspecifiedParameter());
4877 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4878 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4884 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4885 if (FD->isVariadic()) {
4886 SmallVector<llvm::Metadata *, 16> EltTys;
4887 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4888 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4890 EltTys.push_back(getOrCreateType(ParamType, F));
4891 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4892 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4893 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4906 CC = SrcFnTy->getCallConv();
4908 for (
const VarDecl *VD : Args)
4909 ArgTypes.push_back(VD->
getType());
4910 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4916 llvm::Function *Fn,
bool CurFuncIsThunk) {
4918 StringRef LinkageName;
4920 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4923 bool HasDecl = (D !=
nullptr);
4925 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4926 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4927 llvm::DIFile *Unit = getOrCreateFile(Loc);
4928 llvm::DIScope *FDContext = Unit;
4929 llvm::DINodeArray TParamsArray;
4930 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4933 LinkageName = Fn->getName();
4934 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4936 auto FI = SPCache.find(FD->getCanonicalDecl());
4937 if (FI != SPCache.end()) {
4938 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4939 if (SP && SP->isDefinition()) {
4940 LexicalBlockStack.emplace_back(SP);
4941 RegionMap[D].reset(SP);
4945 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4946 TParamsArray, Flags);
4949 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4950 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4951 Name = getObjCMethodName(OMD);
4952 Flags |= llvm::DINode::FlagPrototyped;
4958 if (Name != Fn->getName())
4959 LinkageName = Fn->getName();
4961 Name = Fn->getName();
4966 Flags |= llvm::DINode::FlagPrototyped;
4968 Name.consume_front(
"\01");
4972 "Unexpected DynamicInitKind !");
4976 Flags |= llvm::DINode::FlagArtificial;
4982 Flags |= llvm::DINode::FlagThunk;
4984 if (Fn->hasLocalLinkage())
4985 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4986 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4987 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4990 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4991 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4993 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4994 unsigned ScopeLine = getLineNumber(ScopeLoc);
4995 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4996 llvm::DISubprogram *
Decl =
nullptr;
4997 llvm::DINodeArray Annotations =
nullptr;
5000 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5001 : getFunctionDeclaration(D);
5002 Annotations = CollectBTFDeclTagAnnotations(D);
5010 llvm::DISubprogram *SP = DBuilder.createFunction(
5011 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5012 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5013 Annotations,
"", KeyInstructions);
5014 Fn->setSubprogram(SP);
5023 LexicalBlockStack.emplace_back(SP);
5026 RegionMap[D].reset(SP);
5030 QualType FnType, llvm::Function *Fn) {
5032 StringRef LinkageName;
5038 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5039 return GetName(D,
true);
5042 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5043 llvm::DIFile *Unit = getOrCreateFile(Loc);
5044 bool IsDeclForCallSite = Fn ?
true :
false;
5045 llvm::DIScope *FDContext =
5046 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5047 llvm::DINodeArray TParamsArray;
5050 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5051 TParamsArray, Flags);
5052 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5053 Name = getObjCMethodName(OMD);
5054 Flags |= llvm::DINode::FlagPrototyped;
5056 llvm_unreachable(
"not a function or ObjC method");
5058 Name.consume_front(
"\01");
5061 Flags |= llvm::DINode::FlagArtificial;
5066 unsigned LineNo = getLineNumber(Loc);
5067 unsigned ScopeLine = 0;
5068 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5069 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5070 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5072 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5073 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5075 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5076 llvm::DISubprogram *SP = DBuilder.createFunction(
5077 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5078 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5084 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5085 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5086 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5089 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5090 DBuilder.createParameterVariable(
5091 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5092 llvm::DINode::FlagZero, ParamAnnotations);
5098 if (IsDeclForCallSite)
5099 Fn->setSubprogram(SP);
5103 llvm::CallBase *CI) {
5104 if (!shouldGenerateVirtualCallSite())
5110 assert(CI &&
"Invalid Call Instruction.");
5111 if (!CI->isIndirectCall())
5115 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5116 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5124 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5127 if (
Func->getSubprogram())
5135 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5150 auto FI = SPCache.find(FD->getCanonicalDecl());
5151 llvm::DISubprogram *SP =
nullptr;
5152 if (FI != SPCache.end())
5153 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5154 if (!SP || !SP->isDefinition())
5155 SP = getFunctionStub(GD);
5156 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5157 LexicalBlockStack.emplace_back(SP);
5163 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5172 if (CurLoc.isInvalid() ||
5173 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5174 LexicalBlockStack.empty())
5177 llvm::MDNode *
Scope = LexicalBlockStack.back();
5178 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5179 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5183 llvm::MDNode *Back =
nullptr;
5184 if (!LexicalBlockStack.empty())
5185 Back = LexicalBlockStack.back().get();
5186 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5188 getColumnNumber(CurLoc)));
5191void CGDebugInfo::AppendAddressSpaceXDeref(
5193 std::optional<unsigned> DWARFAddressSpace =
5195 if (!DWARFAddressSpace)
5198 Expr.push_back(llvm::dwarf::DW_OP_constu);
5199 Expr.push_back(*DWARFAddressSpace);
5200 Expr.push_back(llvm::dwarf::DW_OP_swap);
5201 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5210 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5211 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5212 LexicalBlockStack.back(), CurInlinedAt));
5214 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5218 CreateLexicalBlock(Loc);
5223 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5228 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5231 LexicalBlockStack.pop_back();
5235 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5236 unsigned RCount = FnBeginRegionCount.back();
5237 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5240 while (LexicalBlockStack.size() != RCount) {
5243 LexicalBlockStack.pop_back();
5245 FnBeginRegionCount.pop_back();
5247 if (Fn && Fn->getSubprogram())
5248 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5251CGDebugInfo::BlockByRefType
5252CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5253 uint64_t *XOffset) {
5256 uint64_t FieldSize, FieldOffset;
5257 uint32_t FieldAlign;
5259 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5264 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5265 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5267 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5268 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5271 if (HasCopyAndDispose) {
5274 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5276 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5278 bool HasByrefExtendedLayout;
5281 HasByrefExtendedLayout) &&
5282 HasByrefExtendedLayout) {
5285 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5294 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5297 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5300 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5305 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5306 FieldSize = CGM.getContext().getTypeSize(FType);
5307 FieldAlign = CGM.getContext().toBits(Align);
5309 *XOffset = FieldOffset;
5310 llvm::DIType *FieldTy = DBuilder.createMemberType(
5311 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5312 llvm::DINode::FlagZero, WrappedTy);
5313 EltTys.push_back(FieldTy);
5314 FieldOffset += FieldSize;
5316 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5317 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5318 llvm::DINode::FlagZero,
nullptr, Elements),
5322llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5323 llvm::Value *Storage,
5324 std::optional<unsigned> ArgNo,
5326 const bool UsePointerValue) {
5327 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5328 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5329 if (VD->
hasAttr<NoDebugAttr>())
5334 llvm::DIFile *Unit =
nullptr;
5335 if (!VarIsArtificial)
5339 if (VD->
hasAttr<BlocksAttr>())
5340 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5342 Ty = getOrCreateType(VD->
getType(), Unit);
5352 if (!VarIsArtificial) {
5356 SmallVector<uint64_t, 13> Expr;
5357 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5364 Flags |= llvm::DINode::FlagArtificial;
5368 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5369 AppendAddressSpaceXDeref(AddressSpace, Expr);
5373 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5376 Flags |= llvm::DINode::FlagObjectPointer;
5377 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5378 if (PVD->isExplicitObjectParameter())
5379 Flags |= llvm::DINode::FlagObjectPointer;
5387 StringRef Name = VD->
getName();
5388 if (!Name.empty()) {
5394 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5396 offset = CGM.getContext().toCharUnitsFromBits(
5399 Expr.push_back(llvm::dwarf::DW_OP_deref);
5400 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5402 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5405 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5417 for (
const auto *Field : RD->
fields()) {
5418 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5419 StringRef FieldName =
Field->getName();
5427 auto *D = DBuilder.createAutoVariable(
5428 Scope, FieldName, Unit,
Line, FieldTy,
5429 CGM.getCodeGenOpts().OptimizationLevel != 0,
5430 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5433 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5434 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5437 Builder.GetInsertBlock());
5445 if (UsePointerValue) {
5446 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5447 "Debug info already contains DW_OP_deref.");
5448 Expr.push_back(llvm::dwarf::DW_OP_deref);
5452 llvm::DILocalVariable *D =
nullptr;
5454 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5455 D = DBuilder.createParameterVariable(
5456 Scope, Name, *ArgNo, Unit,
Line, Ty,
5457 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5466 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5472 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5473 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5474 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5475 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5477 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5483 if (Iter != CoroutineParameterMappings.end()) {
5484 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5485 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5486 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5488 if (Iter2 != ParamDbgMappings.end())
5489 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5495 D = RemapCoroArgToLocalVar();
5498 D = DBuilder.createAutoVariable(
5499 Scope, Name, Unit,
Line, Ty,
5500 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5503 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5504 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5505 Column, Scope, CurInlinedAt),
5506 Builder.GetInsertBlock());
5511llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5512 llvm::Value *Storage,
5513 std::optional<unsigned> ArgNo,
5515 const bool UsePointerValue) {
5516 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5517 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5518 if (BD->
hasAttr<NoDebugAttr>())
5525 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5526 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5534 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5536 SmallVector<uint64_t, 3> Expr;
5537 AppendAddressSpaceXDeref(AddressSpace, Expr);
5542 if (UsePointerValue) {
5543 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5544 "Debug info already contains DW_OP_deref.");
5545 Expr.push_back(llvm::dwarf::DW_OP_deref);
5550 StringRef Name = BD->
getName();
5553 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5554 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5555 llvm::DINode::FlagZero, Align);
5557 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5558 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5559 const unsigned fieldIndex = FD->getFieldIndex();
5560 const clang::CXXRecordDecl *parent =
5561 (
const CXXRecordDecl *)FD->getParent();
5562 const ASTRecordLayout &layout =
5563 CGM.getContext().getASTRecordLayout(parent);
5565 if (FD->isBitField()) {
5566 const CGRecordLayout &RL =
5567 CGM.getTypes().getCGRecordLayout(FD->getParent());
5572 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5578 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5579 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5580 Expr.push_back(Info.
Offset);
5583 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5584 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5585 }
else if (fieldOffset != 0) {
5586 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5587 "Unexpected non-bitfield with non-byte-aligned offset");
5588 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5590 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5593 }
else if (
const ArraySubscriptExpr *ASE =
5594 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5595 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5596 const uint64_t value = IL->getValue().getZExtValue();
5597 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5600 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5601 Expr.push_back(CGM.getContext()
5602 .toCharUnitsFromBits(value * typeSize)
5609 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5610 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5611 Column, Scope, CurInlinedAt),
5612 Builder.GetInsertBlock());
5617llvm::DILocalVariable *
5620 const bool UsePointerValue) {
5621 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5623 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5625 EmitDeclare(B, Storage, std::nullopt, Builder,
5632 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5636 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5637 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5639 if (D->
hasAttr<NoDebugAttr>())
5643 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5649 StringRef Name = D->
getName();
5655 CGM.getCodeGenOpts().OptimizationLevel != 0);
5658 DBuilder.insertLabel(L,
5659 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5660 Scope, CurInlinedAt),
5661 Builder.GetInsertBlock()->end());
5664llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5666 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5669 return DBuilder.createObjectPointerType(Ty,
true);
5674 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5675 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5676 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5678 if (Builder.GetInsertBlock() ==
nullptr)
5680 if (VD->
hasAttr<NoDebugAttr>())
5683 bool isByRef = VD->
hasAttr<BlocksAttr>();
5685 uint64_t XOffset = 0;
5686 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5689 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5691 Ty = getOrCreateType(VD->
getType(), Unit);
5695 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5697 Ty = CreateSelfType(VD->
getType(), Ty);
5700 const unsigned Line =
5704 const llvm::DataLayout &target = CGM.getDataLayout();
5711 addr.push_back(llvm::dwarf::DW_OP_deref);
5712 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5715 addr.push_back(llvm::dwarf::DW_OP_deref);
5716 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5719 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5721 addr.push_back(llvm::dwarf::DW_OP_deref);
5722 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5724 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5730 auto *D = DBuilder.createAutoVariable(
5732 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5735 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5736 LexicalBlockStack.back(), CurInlinedAt);
5737 auto *
Expr = DBuilder.createExpression(addr);
5739 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5741 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5744llvm::DILocalVariable *
5747 bool UsePointerValue) {
5748 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5749 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5753struct BlockLayoutChunk {
5754 uint64_t OffsetInBits;
5757bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5758 return l.OffsetInBits < r.OffsetInBits;
5762void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5764 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5765 SmallVectorImpl<llvm::Metadata *> &Fields) {
5769 if (CGM.getLangOpts().OpenCL) {
5770 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5771 BlockLayout.getElementOffsetInBits(0),
5773 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5774 BlockLayout.getElementOffsetInBits(1),
5778 BlockLayout.getElementOffsetInBits(0),
5780 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5781 BlockLayout.getElementOffsetInBits(1),
5785 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5786 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5787 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5788 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5789 BlockLayout.getElementOffsetInBits(3),
5791 Fields.push_back(createFieldType(
5796 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5803 llvm::AllocaInst *Alloca,
5805 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5811 llvm::DIFile *tunit = getOrCreateFile(loc);
5812 unsigned line = getLineNumber(loc);
5813 unsigned column = getColumnNumber(loc);
5818 const llvm::StructLayout *blockLayout =
5822 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5831 BlockLayoutChunk chunk;
5832 chunk.OffsetInBits =
5833 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5834 chunk.Capture =
nullptr;
5835 chunks.push_back(chunk);
5839 for (
const auto &capture :
blockDecl->captures()) {
5840 const VarDecl *variable = capture.getVariable();
5847 BlockLayoutChunk chunk;
5848 chunk.OffsetInBits =
5849 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5850 chunk.Capture = &capture;
5851 chunks.push_back(chunk);
5855 llvm::array_pod_sort(chunks.begin(), chunks.end());
5857 for (
const BlockLayoutChunk &Chunk : chunks) {
5858 uint64_t offsetInBits = Chunk.OffsetInBits;
5865 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5867 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5868 type = CGM.getContext().getCanonicalTagType(RDecl);
5870 llvm_unreachable(
"unexpected block declcontext");
5872 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5873 offsetInBits, tunit, tunit));
5878 StringRef name = variable->
getName();
5880 llvm::DIType *fieldType;
5882 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5887 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5888 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5889 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5890 PtrInfo.
Width, Align, offsetInBits,
5891 llvm::DINode::FlagZero, fieldType);
5895 offsetInBits, Align, tunit, tunit);
5897 fields.push_back(fieldType);
5901 llvm::raw_svector_ostream(typeName)
5902 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5904 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5906 llvm::DIType *
type =
5907 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5908 CGM.getContext().toBits(block.
BlockSize), 0,
5909 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5910 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5913 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5917 auto *debugVar = DBuilder.createParameterVariable(
5918 scope, Name, ArgNo, tunit, line,
type,
5919 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5922 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5923 llvm::DILocation::get(CGM.getLLVMContext(), line,
5924 column, scope, CurInlinedAt),
5925 Builder.GetInsertBlock());
5928llvm::DIDerivedType *
5929CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5934 if (MI != StaticDataMemberCache.end()) {
5935 assert(MI->second &&
"Static data member declaration should still exist");
5946llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5947 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5948 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5949 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5951 for (
const auto *Field : RD->
fields()) {
5952 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5953 StringRef FieldName = Field->getName();
5956 if (FieldName.empty()) {
5957 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5958 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5959 LineNo, LinkageName, Var, DContext);
5963 GVE = DBuilder.createGlobalVariableExpression(
5964 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5965 Var->hasLocalLinkage());
5966 Var->addDebugInfo(GVE);
5978 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5983 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5994 struct ReferencesAnonymous
5996 bool RefAnon =
false;
5997 bool VisitRecordType(RecordType *RT) {
6005 ReferencesAnonymous RT;
6018struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6019 bool Reconstitutable =
true;
6020 bool VisitVectorType(VectorType *FT) {
6021 Reconstitutable =
false;
6024 bool VisitAtomicType(AtomicType *FT) {
6025 Reconstitutable =
false;
6028 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6031 const EnumDecl *ED = ET->getDecl();
6033 Reconstitutable =
false;
6037 Reconstitutable =
false;
6042 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6046 return Reconstitutable;
6048 bool VisitRecordType(RecordType *RT,
bool =
false) {
6050 Reconstitutable =
false;
6060 ReconstitutableType T;
6062 return T.Reconstitutable;
6065bool CGDebugInfo::HasReconstitutableArgs(
6066 ArrayRef<TemplateArgument> Args)
const {
6067 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6107 llvm_unreachable(
"Other, unresolved, template arguments should "
6108 "not be seen here");
6113std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6114 bool *NameIsSimplified)
const {
6116 llvm::raw_string_ostream
OS(Name);
6117 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6120 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6121 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6123 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6124 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6126 std::optional<TemplateArgs> Args;
6128 bool IsOperatorOverload =
false;
6129 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6130 Args = GetTemplateArgs(RD);
6131 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6132 Args = GetTemplateArgs(FD);
6134 IsOperatorOverload |=
6137 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6138 Args = GetTemplateArgs(VD);
6162 bool Reconstitutable =
6163 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6165 PrintingPolicy PP = getPrintingPolicy();
6167 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6172 if (NameIsSimplified)
6173 *NameIsSimplified =
true;
6174 bool Mangled = TemplateNamesKind ==
6175 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6181 std::string EncodedOriginalName;
6182 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6187 printTemplateArgumentList(OS, Args->Args, PP);
6188 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6190 std::string CanonicalOriginalName;
6191 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6193 assert(EncodedOriginalName == CanonicalOriginalName);
6202 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6203 if (D->
hasAttr<NoDebugAttr>())
6206 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6207 return GetName(D,
true);
6213 if (Cached != DeclCache.end())
6214 return Var->addDebugInfo(
6218 llvm::DIFile *Unit =
nullptr;
6219 llvm::DIScope *DContext =
nullptr;
6221 StringRef DeclName, LinkageName;
6223 llvm::MDTuple *TemplateParameters =
nullptr;
6224 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6225 TemplateParameters, DContext);
6229 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6234 if (T->isUnionType() && DeclName.empty()) {
6235 const auto *RD = T->castAsRecordDecl();
6237 "unnamed non-anonymous struct or union?");
6238 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6243 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6244 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6245 if (D->
hasAttr<CUDASharedAttr>())
6248 else if (D->
hasAttr<CUDAConstantAttr>())
6252 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6254 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6255 GVE = DBuilder.createGlobalVariableExpression(
6256 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6257 Var->hasLocalLinkage(),
true,
6258 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6259 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6260 Align, Annotations);
6261 Var->addDebugInfo(GVE);
6267 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6268 if (VD->
hasAttr<NoDebugAttr>())
6270 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6271 return GetName(VD,
true);
6276 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6277 StringRef Name = VD->
getName();
6278 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6280 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6282 if (CGM.getCodeGenOpts().EmitCodeView) {
6293 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6294 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6295 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6305 auto *VarD = dyn_cast<VarDecl>(VD);
6306 if (VarD && VarD->isStaticDataMember()) {
6308 getDeclContextDescriptor(VarD);
6313 RetainedTypes.push_back(
6314 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6318 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6320 auto &GV = DeclCache[VD];
6324 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6325 llvm::MDTuple *TemplateParameters =
nullptr;
6329 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6330 TemplateParameters = parameterNodes.get();
6333 GV.reset(DBuilder.createGlobalVariableExpression(
6334 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6335 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6336 TemplateParameters, Align));
6341 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6342 if (D->
hasAttr<NoDebugAttr>())
6346 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6347 StringRef Name = D->
getName();
6348 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6350 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6351 llvm::DIGlobalVariableExpression *GVE =
6352 DBuilder.createGlobalVariableExpression(
6353 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6354 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6355 Var->addDebugInfo(GVE);
6362 if (CGM.getCodeGenOpts().getDebugInfo() <=
6363 llvm::codegenoptions::DebugLineTablesOnly)
6366 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6370 llvm::DIFile *Unit = DIL->getFile();
6371 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6376 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6377 llvm::Value *Var = Load->getPointerOperand();
6382 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6383 return DbgDeclare->getVariable()->getType() ==
Type;
6385 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6389 llvm::DILocalVariable *D =
6390 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6391 Type,
false, llvm::DINode::FlagArtificial);
6393 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6394 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6404 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6408 if (D->
hasAttr<NoDebugAttr>())
6411 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6426 if (!(DI = getDeclarationOrDefinition(
6427 AliaseeDecl.getCanonicalDecl().getDecl())))
6430 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6433 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6434 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6448 llvm::DIFile *
File = getOrCreateFile(Loc);
6449 llvm::DIGlobalVariableExpression *Debug =
6450 DBuilder.createGlobalVariableExpression(
6451 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6452 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6453 GV->addDebugInfo(Debug);
6456llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6457 if (!LexicalBlockStack.empty())
6458 return LexicalBlockStack.back();
6459 llvm::DIScope *Mod = getParentModuleOrNull(D);
6460 return getContextDescriptor(D, Mod ? Mod : TheCU);
6464 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6468 CGM.getCodeGenOpts().DebugExplicitImport) {
6472 DBuilder.createImportedModule(
6474 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6479 if (llvm::DINode *
Target =
6482 DBuilder.createImportedDeclaration(
6484 getOrCreateFile(Loc), getLineNumber(Loc));
6489 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6492 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6494 for (
const auto *USD : UD.
shadows()) {
6499 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6500 if (
const auto *AT = FD->getType()
6503 if (AT->getDeducedType().isNull())
6514 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6517 "We shouldn't be codegening an invalid UsingEnumDecl"
6518 " containing no decls");
6520 for (
const auto *USD : UD.
shadows())
6525 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6527 if (
Module *M = ID.getImportedModule()) {
6529 auto Loc = ID.getLocation();
6530 DBuilder.createImportedDeclaration(
6531 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6532 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6533 getLineNumber(Loc));
6537llvm::DIImportedEntity *
6539 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6541 auto &VH = NamespaceAliasCache[&NA];
6544 llvm::DIImportedEntity *R;
6546 if (
const auto *Underlying =
6549 R = DBuilder.createImportedDeclaration(
6552 getLineNumber(Loc), NA.
getName());
6554 R = DBuilder.createImportedDeclaration(
6557 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6563CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6567 auto I = NamespaceCache.find(NSDecl);
6568 if (I != NamespaceCache.end())
6571 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6573 llvm::DINamespace *NS =
6574 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6575 NamespaceCache[NSDecl].reset(NS);
6580 assert(TheCU &&
"no main compile unit");
6581 TheCU->setDWOId(Signature);
6587 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6588 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6590 ? CreateTypeDefinition(E.Type, E.Unit)
6592 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6596 for (
const auto &P : ObjCMethodCache) {
6597 if (P.second.empty())
6600 QualType QTy(P.first->getTypeForDecl(), 0);
6602 assert(It != TypeCache.end());
6604 llvm::DICompositeType *InterfaceDecl =
6607 auto CurElts = InterfaceDecl->getElements();
6611 for (
auto &SubprogramDirect : P.second)
6612 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6613 EltTys.push_back(SubprogramDirect.getPointer());
6615 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6616 DBuilder.replaceArrays(InterfaceDecl, Elements);
6619 for (
const auto &P : ReplaceMap) {
6622 assert(Ty->isForwardDecl());
6624 auto It = TypeCache.find(P.first);
6625 assert(It != TypeCache.end());
6628 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6632 for (
const auto &P : FwdDeclReplaceMap) {
6635 llvm::Metadata *Repl;
6637 auto It = DeclCache.find(P.first);
6641 if (It == DeclCache.end())
6646 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6647 Repl = GVE->getVariable();
6653 for (
auto &RT : RetainedTypes)
6654 if (
auto MD = TypeCache[RT])
6657 DBuilder.finalize();
6662 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6663 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6664 DBuilder.retainType(DieTy);
6668 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6669 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6670 DBuilder.retainType(DieTy);
6674 if (LexicalBlockStack.empty())
6675 return llvm::DebugLoc();
6677 llvm::MDNode *
Scope = LexicalBlockStack.back();
6678 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6679 getColumnNumber(Loc),
Scope);
6685 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6686 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6687 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6688 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6689 return llvm::DINode::FlagZero;
6694 bool SupportsDWARFv4Ext =
6695 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6696 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6697 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6699 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6700 return llvm::DINode::FlagZero;
6702 return llvm::DINode::FlagAllCallsDescribed;
6713 return DBuilder.createConstantValueExpression(
6714 Val.
getFloat().bitcastToAPInt().getZExtValue());
6719 llvm::APSInt
const &ValInt = Val.
getInt();
6720 std::optional<uint64_t> ValIntOpt;
6721 if (ValInt.isUnsigned())
6722 ValIntOpt = ValInt.tryZExtValue();
6723 else if (
auto tmp = ValInt.trySExtValue())
6726 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6729 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6734CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6736 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6737 CGF.CurLexicalScope =
this;
6739 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6744 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6757#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6759 Label = "__ubsan_check_" #Name; \
6763#undef SANITIZER_CHECK
6774#define SANITIZER(NAME, ID) \
6775 case SanitizerKind::SO_##ID: \
6776 Label = "__ubsan_check_" NAME; \
6778#include "clang/Basic/Sanitizers.def"
6780 llvm_unreachable(
"unexpected sanitizer kind");
6785 for (
unsigned int i = 0; i < Label.length(); i++)
6786 if (!std::isalpha(Label[i]))
6795 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6797 if (!DI || !CheckDebugLoc)
6798 return CheckDebugLoc;
6799 const auto &AnnotateDebugInfo =
6800 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6801 if (AnnotateDebugInfo.empty())
6802 return CheckDebugLoc;
6805 if (Ordinals.size() == 1)
6810 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6814 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6815 "ubsan_interface.h",
6817 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6820 return CheckDebugLoc;
6828 assert(!CGF->IsSanitizerScope);
6829 CGF->IsSanitizerScope =
true;
6833 assert(CGF->IsSanitizerScope);
6834 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.