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
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) {
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 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1535 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1536 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1537 Size, Align, DWARFAddressSpace);
1539 SmallVector<llvm::Metadata *, 4> Annots;
1540 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1542 llvm::DINodeArray Annotations =
nullptr;
1543 if (Annots.size() > 0)
1544 Annotations = DBuilder.getOrCreateArray(Annots);
1545 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1546 Align, DWARFAddressSpace, StringRef(),
1551llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1552 llvm::DIType *&
Cache) {
1555 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1556 TheCU, TheCU->getFile(), 0);
1557 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1558 Cache = DBuilder.createPointerType(
Cache, Size);
1562uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1563 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1564 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1574 if (CGM.getLangOpts().OpenCL) {
1575 FType = CGM.getContext().IntTy;
1576 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1579 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1580 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1581 FType = CGM.getContext().IntTy;
1582 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1583 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1585 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1586 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1587 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1588 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1589 EltTys.push_back(DBuilder.createMemberType(
1590 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1591 FieldOffset, llvm::DINode::FlagZero, DescTy));
1592 FieldOffset += FieldSize;
1598llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1599 llvm::DIFile *Unit) {
1600 SmallVector<llvm::Metadata *, 8> EltTys;
1603 llvm::DINodeArray Elements;
1606 FType = CGM.getContext().UnsignedLongTy;
1607 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1608 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1610 Elements = DBuilder.getOrCreateArray(EltTys);
1613 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1616 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1617 FieldOffset, 0, Flags,
nullptr, Elements);
1622 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1624 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1627 Elements = DBuilder.getOrCreateArray(EltTys);
1633 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1634 Flags,
nullptr, Elements);
1636 return DBuilder.createPointerType(EltTy, Size);
1639static llvm::SmallVector<TemplateArgument>
1641 assert(Ty->isTypeAlias());
1650 ArrayRef SubstArgs = Ty->template_arguments();
1653 if (Param->isParameterPack()) {
1662 if (SubstArgs.empty()) {
1671 SpecArgs.push_back(SubstArgs.front());
1672 SubstArgs = SubstArgs.drop_front();
1677llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1678 llvm::DIFile *Unit) {
1679 assert(Ty->isTypeAlias());
1680 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1682 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1690 SmallString<128> NS;
1691 llvm::raw_svector_ostream
OS(NS);
1693 auto PP = getPrintingPolicy();
1696 SourceLocation Loc =
AliasDecl->getLocation();
1698 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1699 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1708 llvm::raw_string_ostream
OS(Name);
1710 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1711 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1712 !HasReconstitutableArgs(Args.Args))
1713 printTemplateArgumentList(OS, Args.Args, PP);
1715 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1716 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1717 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1721 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1723 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1740 return llvm::DINode::FlagZero;
1744 return llvm::DINode::FlagPrivate;
1746 return llvm::DINode::FlagProtected;
1748 return llvm::DINode::FlagPublic;
1750 return llvm::DINode::FlagZero;
1752 llvm_unreachable(
"unexpected access enumerator");
1755llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1756 llvm::DIFile *Unit) {
1757 llvm::DIType *Underlying =
1773 SmallVector<llvm::Metadata *, 4> Annots;
1774 llvm::DINodeArray Annotations;
1776 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1777 if (!Annots.empty())
1778 Annotations = DBuilder.getOrCreateArray(Annots);
1780 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1785 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1786 getOrCreateFile(Loc), getLineNumber(Loc),
1787 getDeclContextDescriptor(Ty->
getDecl()), Align,
1788 Flags, Annotations);
1798 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1800 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1802 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1804 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1806 return llvm::dwarf::DW_CC_BORLAND_pascal;
1808 return llvm::dwarf::DW_CC_LLVM_Win64;
1810 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1814 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1816 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1818 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1820 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1822 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1824 return llvm::dwarf::DW_CC_LLVM_Swift;
1826 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1828 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1830 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1832 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1834 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1836 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1838 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1839#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1853 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1859 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1861 Flags |= llvm::DINode::FlagLValueReference;
1863 Flags |= llvm::DINode::FlagRValueReference;
1867llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1868 llvm::DIFile *Unit) {
1869 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1871 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1877 SmallVector<llvm::Metadata *, 16> EltTys;
1880 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1882 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1886 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1889 for (
const QualType &ParamType : FPT->param_types())
1890 EltTys.push_back(getOrCreateType(ParamType, Unit));
1891 if (FPT->isVariadic())
1892 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1895 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1896 llvm::DIType *F = DBuilder.createSubroutineType(
1901llvm::DIDerivedType *
1902CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1903 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1904 StringRef Name = BitFieldDecl->
getName();
1905 QualType Ty = BitFieldDecl->
getType();
1906 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1909 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1910 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1913 llvm::DIFile *
File = getOrCreateFile(Loc);
1914 unsigned Line = getLineNumber(Loc);
1916 const CGBitFieldInfo &BitFieldInfo =
1917 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1919 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1926 if (CGM.getDataLayout().isBigEndian())
1928 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1930 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1931 return DBuilder.createBitFieldMemberType(
1932 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1933 Flags, DebugType, Annotations);
1936llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1937 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1938 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1940 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1965 if (PreviousFieldsDI.empty())
1969 auto *PreviousMDEntry =
1970 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1971 auto *PreviousMDField =
1972 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1973 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1974 PreviousMDField->getSizeInBits() == 0)
1978 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1980 assert(PreviousBitfield->isBitField());
1982 if (!PreviousBitfield->isZeroLengthBitField())
1985 QualType Ty = PreviousBitfield->getType();
1986 SourceLocation Loc = PreviousBitfield->getLocation();
1987 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1988 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1989 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1991 llvm::DIFile *
File = getOrCreateFile(Loc);
1992 unsigned Line = getLineNumber(Loc);
1998 llvm::DINode::DIFlags Flags =
2000 llvm::DINodeArray Annotations =
2001 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2002 return DBuilder.createBitFieldMemberType(
2003 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2004 Flags, DebugType, Annotations);
2007llvm::DIType *CGDebugInfo::createFieldType(
2009 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2010 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2011 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2014 llvm::DIFile *file = getOrCreateFile(loc);
2015 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2018 auto Align = AlignInBits;
2019 if (!
type->isIncompleteArrayType()) {
2020 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2021 SizeInBits = TI.
Width;
2027 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2028 offsetInBits, flags, debugType, Annotations);
2032CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2033 llvm::DIFile *FileScope) {
2037 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2040 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2041 SP = DBuilder.createFunction(
2042 FileScope, FuncName, StringRef(),
2043 FileScope, 0, DIFnTy,
2045 llvm::DINode::FlagArtificial,
2046 llvm::DISubprogram::SPFlagDefinition,
2047 nullptr,
nullptr,
nullptr,
2048 nullptr, StringRef(),
2049 CGM.getCodeGenOpts().DebugKeyInstructions);
2056CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2058 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2060 assert(
Capture.capturesVariable());
2062 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2063 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2065 return CaptureDecl->
getName();
2068void CGDebugInfo::CollectRecordLambdaFields(
2069 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2070 llvm::DIType *RecordTy) {
2075 unsigned fieldno = 0;
2078 I != E; ++I, ++Field, ++fieldno) {
2079 const LambdaCapture &
Capture = *I;
2081 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2083 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2093 Loc =
Field->getLocation();
2094 }
else if (
Capture.capturesVariable()) {
2097 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2098 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2105 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2107 elements.push_back(createFieldType(
2109 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2115template <
typename T>
2116static llvm::Constant *
2127 return llvm::ConstantDataArray::get(Ctx, Vals);
2140 const QualType ElemQTy = ArrayTy->getElementType();
2147 switch (ElemBitWidth) {
2163llvm::DIDerivedType *
2164CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2165 const RecordDecl *RD) {
2169 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2170 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2172 unsigned LineNumber = getLineNumber(Var->
getLocation());
2173 StringRef VName = Var->
getName();
2177 llvm::Constant *
C =
nullptr;
2182 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2183 if (
Value->isFloat())
2184 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2185 if (
Value->isArray())
2191 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2192 ? llvm::dwarf::DW_TAG_variable
2193 : llvm::dwarf::DW_TAG_member;
2195 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2196 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2201void CGDebugInfo::CollectRecordNormalField(
2202 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2203 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2204 const RecordDecl *RD) {
2209 if (
name.empty() && !
type->isRecordType())
2212 llvm::DIType *FieldType;
2214 llvm::DIDerivedType *BitFieldType;
2215 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2216 if (llvm::DIType *Separator =
2217 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2218 elements.push_back(Separator);
2221 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2224 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2227 elements.push_back(FieldType);
2230void CGDebugInfo::CollectRecordNestedType(
2231 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2232 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2239 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2240 elements.push_back(nestedType);
2243void CGDebugInfo::CollectRecordFields(
2244 const RecordDecl *record, llvm::DIFile *tunit,
2245 SmallVectorImpl<llvm::Metadata *> &elements,
2246 llvm::DICompositeType *RecordTy) {
2247 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2249 if (CXXDecl && CXXDecl->
isLambda())
2250 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2252 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2255 unsigned fieldNo = 0;
2259 for (
const auto *I : record->
decls())
2260 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2261 if (
V->hasAttr<NoDebugAttr>())
2266 if (CGM.getCodeGenOpts().EmitCodeView &&
2274 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2275 if (MI != StaticDataMemberCache.end()) {
2276 assert(MI->second &&
2277 "Static data member declaration should still exist");
2278 elements.push_back(MI->second);
2280 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2281 elements.push_back(Field);
2283 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2284 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2285 elements, RecordTy, record);
2289 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2292 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2297 if (!nestedType->isImplicit() &&
2298 nestedType->getDeclContext() == record)
2299 CollectRecordNestedType(nestedType, elements);
2305llvm::DISubroutineType *
2306CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2307 llvm::DIFile *Unit) {
2308 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2310 return cast_or_null<llvm::DISubroutineType>(
2311 getOrCreateType(QualType(
Func, 0), Unit));
2314 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2315 ThisType =
Method->getThisType();
2317 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2320llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2321 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2322 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2324 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2327llvm::DISubroutineType *
2328CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2329 const FunctionProtoType *
Func,
2330 llvm::DIFile *Unit,
bool SkipFirst) {
2331 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2346 getOrCreateType(CGM.getContext().getFunctionType(
2347 Func->getReturnType(),
Func->getParamTypes(), EPI),
2349 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2350 assert(Args.size() &&
"Invalid number of arguments!");
2352 SmallVector<llvm::Metadata *, 16> Elts;
2355 Elts.push_back(Args[0]);
2357 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2361 if (!HasExplicitObjectParameter) {
2362 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2365 DBuilder.createObjectPointerType(ThisPtrType,
true);
2366 Elts.push_back(ThisPtrType);
2370 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2371 Elts.push_back(Args[i]);
2374 if (HasExplicitObjectParameter) {
2375 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2376 "Expected at least return type and object parameter.");
2377 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2380 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2382 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2389 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2397CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2400 const bool IsCtorOrDtor =
2403 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2410 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2413 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2416 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2419 return CGM.getMangledName(
Method);
2422bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2425 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2428llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2429 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2432 StringRef MethodName = getFunctionName(
Method);
2433 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2435 StringRef MethodLinkageName;
2442 MethodLinkageName = GetMethodLinkageName(
Method);
2445 llvm::DIFile *MethodDefUnit =
nullptr;
2446 unsigned MethodLine = 0;
2447 if (!
Method->isImplicit()) {
2448 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2449 MethodLine = getLineNumber(
Method->getLocation());
2453 llvm::DIType *ContainingType =
nullptr;
2454 unsigned VIndex = 0;
2455 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2456 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2457 int ThisAdjustment = 0;
2460 if (
Method->isPureVirtual())
2461 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2463 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2465 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2469 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2473 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2476 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2477 CGM.getContext().getLangOpts())
2481 MethodVFTableLocation ML =
2482 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2490 if (
Method->size_overridden_methods() == 0)
2491 Flags |= llvm::DINode::FlagIntroducedVirtual;
2496 ThisAdjustment = CGM.getCXXABI()
2497 .getVirtualFunctionPrologueThisAdjustment(GD)
2500 ContainingType = RecordTy;
2503 if (
Method->getCanonicalDecl()->isDeleted())
2504 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2506 if (
Method->isNoReturn())
2507 Flags |= llvm::DINode::FlagNoReturn;
2510 Flags |= llvm::DINode::FlagStaticMember;
2511 if (
Method->isImplicit())
2512 Flags |= llvm::DINode::FlagArtificial;
2514 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2515 if (CXXC->isExplicit())
2516 Flags |= llvm::DINode::FlagExplicit;
2517 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2518 if (CXXC->isExplicit())
2519 Flags |= llvm::DINode::FlagExplicit;
2521 if (
Method->hasPrototype())
2522 Flags |= llvm::DINode::FlagPrototyped;
2524 Flags |= llvm::DINode::FlagLValueReference;
2526 Flags |= llvm::DINode::FlagRValueReference;
2527 if (!
Method->isExternallyVisible())
2528 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2529 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2530 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2534 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2535 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2538 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2539 llvm::DISubprogram *SP = DBuilder.createMethod(
2540 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2541 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2542 TParamsArray.get(),
nullptr,
2543 CGM.getCodeGenOpts().DebugKeyInstructions);
2545 SPCache[
Method->getCanonicalDecl()].reset(SP);
2550void CGDebugInfo::CollectCXXMemberFunctions(
2551 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2552 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2557 for (
const auto *I : RD->
decls()) {
2558 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2572 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2581 auto MI = SPCache.find(
Method->getCanonicalDecl());
2582 EltTys.push_back(MI == SPCache.end()
2583 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2584 :
static_cast<llvm::Metadata *
>(MI->second));
2588void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2589 SmallVectorImpl<llvm::Metadata *> &EltTys,
2590 llvm::DIType *RecordTy) {
2591 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2592 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2593 llvm::DINode::FlagZero);
2597 if (CGM.getCodeGenOpts().EmitCodeView) {
2598 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2599 llvm::DINode::FlagIndirectVirtualBase);
2603void CGDebugInfo::CollectCXXBasesAux(
2604 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2605 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2607 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2608 llvm::DINode::DIFlags StartingFlags) {
2609 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2610 for (
const auto &BI : Bases) {
2613 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2615 if (!SeenTypes.insert(Base).second)
2617 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2618 llvm::DINode::DIFlags BFlags = StartingFlags;
2622 if (BI.isVirtual()) {
2623 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2626 BaseOffset = 0 - CGM.getItaniumVTableContext()
2627 .getVirtualBaseOffsetOffset(RD, Base)
2633 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2634 VBPtrOffset = CGM.getContext()
2635 .getASTRecordLayout(RD)
2639 BFlags |= llvm::DINode::FlagVirtual;
2646 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2647 VBPtrOffset, BFlags);
2648 EltTys.push_back(DTy);
2653CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2654 llvm::DIFile *Unit) {
2656 return llvm::DINodeArray();
2657 TemplateArgs &Args = *OArgs;
2658 SmallVector<llvm::Metadata *, 16> TemplateParams;
2659 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2660 const TemplateArgument &TA = Args.Args[i];
2664 Name = Args.TList->getParam(i)->getName();
2668 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2669 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2670 TheCU, Name, TTy, defaultParameter));
2675 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2676 TheCU, Name, TTy, defaultParameter,
2677 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2682 llvm::DIType *TTy = getOrCreateType(T, Unit);
2683 llvm::Constant *
V =
nullptr;
2686 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2687 !D->
hasAttr<CUDADeviceAttr>()) {
2690 if (
const auto *VD = dyn_cast<VarDecl>(D))
2691 V = CGM.GetAddrOfGlobalVar(VD);
2694 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2695 MD && MD->isImplicitObjectMemberFunction())
2696 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2697 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2698 V = CGM.GetAddrOfFunction(FD);
2701 else if (
const auto *MPT =
2702 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2706 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2708 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2709 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2710 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2711 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2712 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2714 V = ConstantEmitter(CGM).emitAbstract(
2715 SourceLocation(), TPO->getValue(), TPO->getType());
2717 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2719 assert(
V &&
"Failed to find template parameter pointer");
2720 V =
V->stripPointerCasts();
2722 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2723 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2727 llvm::DIType *TTy = getOrCreateType(T, Unit);
2728 llvm::Constant *
V =
nullptr;
2731 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2737 if (MPT->isMemberDataPointer())
2738 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2740 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2741 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2742 TheCU, Name, TTy, defaultParameter,
V));
2746 llvm::DIType *TTy = getOrCreateType(T, Unit);
2747 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2749 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2750 TheCU, Name, TTy, defaultParameter,
V));
2753 std::string QualName;
2754 llvm::raw_string_ostream
OS(QualName);
2756 OS, getPrintingPolicy());
2757 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2758 TheCU, Name,
nullptr, QualName, defaultParameter));
2762 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2763 TheCU, Name,
nullptr,
2770 T = CGM.getContext().getLValueReferenceType(T);
2771 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2772 assert(
V &&
"Expression in template argument isn't constant");
2773 llvm::DIType *TTy = getOrCreateType(T, Unit);
2774 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2775 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2781 "These argument types shouldn't exist in concrete types");
2784 return DBuilder.getOrCreateArray(TemplateParams);
2787std::optional<CGDebugInfo::TemplateArgs>
2788CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2796 return std::nullopt;
2798std::optional<CGDebugInfo::TemplateArgs>
2799CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2803 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2805 return std::nullopt;
2806 VarTemplateDecl *T = TS->getSpecializedTemplate();
2808 auto TA = TS->getTemplateArgs().asArray();
2809 return {{TList, TA}};
2811std::optional<CGDebugInfo::TemplateArgs>
2812CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2813 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2817 TemplateParameterList *TPList =
2818 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2819 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2820 return {{TPList, TAList.
asArray()}};
2822 return std::nullopt;
2826CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2827 llvm::DIFile *Unit) {
2828 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2831llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2832 llvm::DIFile *Unit) {
2833 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2836llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2837 llvm::DIFile *Unit) {
2838 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2841void CGDebugInfo::CollectBTFDeclTagAnnotations(
2842 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2844 llvm::Metadata *Ops[2] = {
2845 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2846 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2847 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2851llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2852 if (!D->
hasAttr<BTFDeclTagAttr>())
2855 SmallVector<llvm::Metadata *, 4> Annotations;
2856 CollectBTFDeclTagAnnotations(D, Annotations);
2857 return DBuilder.getOrCreateArray(Annotations);
2860void CGDebugInfo::CollectBTFTypeTagAnnotations(
2861 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2862 const BTFTagAttributedType *BTFAttrTy;
2864 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2866 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2869 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2871 llvm::Metadata *Ops[2] = {
2872 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2873 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2874 Annotations.insert(Annotations.begin(),
2875 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2877 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2881llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2883 return VTablePtrType;
2885 ASTContext &Context = CGM.getContext();
2888 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2889 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2890 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2892 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2893 std::optional<unsigned> DWARFAddressSpace =
2894 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2896 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2897 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2898 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2899 return VTablePtrType;
2902StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2914 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2916 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2926 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2927 VTable->isDeclarationForLinker())
2931 StringRef SymbolName =
"__clang_vtable";
2933 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2942 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2944 llvm::DIFile *Unit = getOrCreateFile(Loc);
2945 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2947 llvm::DINode::FlagArtificial;
2948 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2949 ? llvm::dwarf::DW_TAG_variable
2950 : llvm::dwarf::DW_TAG_member;
2951 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2952 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2956 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2960 llvm::DIGlobalVariableExpression *GVE =
2961 DBuilder.createGlobalVariableExpression(
2962 TheCU, SymbolName, VTable->getName(), Unit, 0,
2963 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2964 true,
nullptr, DT,
nullptr,
2966 VTable->addDebugInfo(GVE);
2969StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2971 llvm::Function *InitFn) {
2976 return InitFn->getName();
2986 llvm::raw_svector_ostream OS(QualifiedGV);
2988 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2990 std::swap(Quals, GVName);
2994 llvm::raw_svector_ostream OS(InitName);
2996 OS << Quals <<
"::";
3001 llvm_unreachable(
"not an initializer");
3003 OS <<
"`dynamic initializer for '";
3006 OS <<
"`dynamic atexit destructor for '";
3013 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3014 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3015 getPrintingPolicy());
3020 return internString(
OS.str());
3023void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3024 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3033 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3040 llvm::DIType *VPtrTy =
nullptr;
3041 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3042 CGM.getTarget().getCXXABI().isMicrosoft();
3043 if (NeedVTableShape) {
3045 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3046 const VTableLayout &VFTLayout =
3047 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3048 unsigned VSlotCount =
3050 unsigned VTableWidth = PtrWidth * VSlotCount;
3051 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3052 std::optional<unsigned> DWARFAddressSpace =
3053 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3056 llvm::DIType *VTableType = DBuilder.createPointerType(
3057 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3058 EltTys.push_back(VTableType);
3061 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3069 VPtrTy = getOrCreateVTablePtrType(Unit);
3071 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3072 llvm::DIType *VPtrMember =
3073 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3074 llvm::DINode::FlagArtificial, VPtrTy);
3075 EltTys.push_back(VPtrMember);
3080 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3081 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3092 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3093 assert(!D.
isNull() &&
"null type");
3094 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3095 assert(T &&
"could not create debug info for type");
3104 if (CGM.getCodeGenOpts().getDebugInfo() <=
3105 llvm::codegenoptions::DebugLineTablesOnly)
3109 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3111 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3113 CI->setMetadata(
"heapallocsite", node);
3117 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3119 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3121 auto I = TypeCache.find(TyPtr);
3124 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3125 assert(!Res->isForwardDecl());
3126 TypeCache[TyPtr].reset(Res);
3130 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3131 !CGM.getLangOpts().CPlusPlus)
3137 if (RD->
hasAttr<DLLImportAttr>())
3140 if (MD->hasAttr<DLLImportAttr>())
3153 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3163 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3164 Explicit = TD->isExplicitInstantiationOrSpecialization();
3168 if (CXXDecl->
fields().empty())
3178 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3179 if (CXXRD->isDynamicClass() &&
3180 CGM.getVTableLinkage(CXXRD) ==
3181 llvm::GlobalValue::AvailableExternallyLinkage &&
3192 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3194 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3196 auto I = TypeCache.find(TyPtr);
3203 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3204 assert(!Res->isForwardDecl());
3205 TypeCache[TyPtr].reset(Res);
3212 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3213 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3236 if (Ctor->isCopyOrMoveConstructor())
3238 if (!Ctor->isDeleted())
3257 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3260 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3261 RD->
hasAttr<StandaloneDebugAttr>())
3264 if (!LangOpts.CPlusPlus)
3270 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3286 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3287 Spec = SD->getSpecializationKind();
3296 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3307 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3308 llvm::DIType *T = getTypeOrNull(Ty);
3309 if (T && T->isForwardDecl())
3313llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3315 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3319 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3323 auto [Def, Pref] = CreateTypeDefinition(Ty);
3325 return Pref ? Pref : Def;
3328llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3329 llvm::DIFile *Unit) {
3333 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3337 return getOrCreateType(PNA->getTypedefType(), Unit);
3340std::pair<llvm::DIType *, llvm::DIType *>
3341CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3345 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3353 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3357 return {FwdDecl,
nullptr};
3359 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3360 CollectContainingType(CXXDecl, FwdDecl);
3363 LexicalBlockStack.emplace_back(&*FwdDecl);
3364 RegionMap[RD].reset(FwdDecl);
3367 SmallVector<llvm::Metadata *, 16> EltTys;
3374 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3376 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3377 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3381 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3382 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3383 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3385 LexicalBlockStack.pop_back();
3386 RegionMap.erase(RD);
3388 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3389 DBuilder.replaceArrays(FwdDecl, Elements);
3391 if (FwdDecl->isTemporary())
3393 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3395 RegionMap[RD].reset(FwdDecl);
3397 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3398 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3399 return {FwdDecl, PrefDI};
3401 return {FwdDecl,
nullptr};
3404llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3405 llvm::DIFile *Unit) {
3407 return getOrCreateType(Ty->getBaseType(), Unit);
3410llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3411 llvm::DIFile *Unit) {
3413 SourceLocation Loc = Ty->getDecl()->getLocation();
3416 return DBuilder.createTypedef(
3417 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3418 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3419 getDeclContextDescriptor(Ty->getDecl()));
3446llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3447 llvm::DIFile *Unit) {
3452 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3453 TheCU->getSourceLanguage().getUnversionedName());
3458 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3459 !
ID->getImplementation())
3460 return DBuilder.createForwardDecl(
3461 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3462 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3465 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3466 unsigned Line = getLineNumber(
ID->getLocation());
3470 ObjCInterfaceDecl *Def =
ID->getDefinition();
3472 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3473 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3474 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3475 DefUnit,
Line, RuntimeLang);
3476 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3480 return CreateTypeDefinition(Ty, Unit);
3483llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3484 bool CreateSkeletonCU) {
3489 auto ModRef = ModuleCache.find(M);
3490 if (ModRef != ModuleCache.end())
3494 SmallString<128> ConfigMacros;
3496 llvm::raw_svector_ostream
OS(ConfigMacros);
3497 const auto &PPOpts = CGM.getPreprocessorOpts();
3500 for (
auto &M : PPOpts.Macros) {
3503 const std::string &
Macro = M.first;
3504 bool Undef = M.second;
3505 OS <<
"\"-" << (Undef ?
'U' :
'D');
3506 for (
char c :
Macro)
3521 bool IsRootModule = M ? !M->
Parent :
true;
3525 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3526 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3527 "clang module without ASTFile must be specified by -fmodule-name");
3530 auto RemapPath = [
this](StringRef Path) -> std::string {
3532 StringRef Relative(Remapped);
3533 StringRef CompDir = TheCU->getDirectory();
3534 if (CompDir.empty())
3537 if (Relative.consume_front(CompDir))
3538 Relative.consume_front(llvm::sys::path::get_separator());
3540 return Relative.str();
3543 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3550 Signature = ModSig.truncatedValue();
3554 llvm::DIBuilder DIB(CGM.getModule());
3556 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3557 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3558 PCM = getCurrentDirname();
3562 llvm::sys::path::append(PCM, Mod.
getASTFile());
3563 DIB.createCompileUnit(
3564 TheCU->getSourceLanguage(),
3567 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3568 llvm::DICompileUnit::FullDebug, Signature);
3572 llvm::DIModule *Parent =
3574 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3576 StringRef IncludePath = Mod.
getPath();
3577 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3578 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3579 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3582 llvm::DIModule *DIMod =
3583 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3584 RemapPath(IncludePath));
3585 ModuleCache[M].reset(DIMod);
3589llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3590 llvm::DIFile *Unit) {
3592 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3593 unsigned Line = getLineNumber(
ID->getLocation());
3595 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3601 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3602 if (
ID->getImplementation())
3603 Flags |= llvm::DINode::FlagObjcClassComplete;
3605 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3606 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3607 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3608 nullptr, llvm::DINodeArray(), RuntimeLang);
3610 QualType QTy(Ty, 0);
3611 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3614 LexicalBlockStack.emplace_back(RealDecl);
3615 RegionMap[Ty->
getDecl()].reset(RealDecl);
3618 SmallVector<llvm::Metadata *, 16> EltTys;
3620 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3622 llvm::DIType *SClassTy =
3623 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3627 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3628 llvm::DINode::FlagZero);
3629 EltTys.push_back(InhTag);
3633 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3634 SourceLocation Loc = PD->getLocation();
3635 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3636 unsigned PLine = getLineNumber(Loc);
3637 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3638 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3639 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3640 PD->getName(), PUnit, PLine,
3642 : getSelectorName(PD->getGetterName()),
3644 : getSelectorName(PD->getSetterName()),
3645 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3646 EltTys.push_back(PropertyNode);
3651 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3655 llvm::DenseSet<IsClassAndIdent> PropertySet;
3657 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3658 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3660 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3661 for (
auto *PD : ClassExt->properties()) {
3662 PropertySet.insert(GetIsClassAndIdent(PD));
3665 for (
const auto *PD :
ID->properties()) {
3668 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3674 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3675 unsigned FieldNo = 0;
3676 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3677 Field =
Field->getNextIvar(), ++FieldNo) {
3678 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3682 StringRef FieldName =
Field->getName();
3685 if (FieldName.empty())
3689 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3690 unsigned FieldLine = getLineNumber(
Field->getLocation());
3691 QualType FType =
Field->getType();
3698 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3699 : CGM.getContext().getTypeSize(FType);
3704 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3708 if (
Field->isBitField()) {
3710 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3711 FieldOffset %= CGM.getContext().getCharWidth();
3719 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3721 Flags = llvm::DINode::FlagProtected;
3723 Flags = llvm::DINode::FlagPrivate;
3725 Flags = llvm::DINode::FlagPublic;
3727 if (
Field->isBitField())
3728 Flags |= llvm::DINode::FlagBitField;
3730 llvm::MDNode *PropertyNode =
nullptr;
3731 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3732 if (ObjCPropertyImplDecl *PImpD =
3733 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3734 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3735 SourceLocation Loc = PD->getLocation();
3736 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3737 unsigned PLine = getLineNumber(Loc);
3738 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3739 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3740 PropertyNode = DBuilder.createObjCProperty(
3741 PD->getName(), PUnit, PLine,
3744 : getSelectorName(PD->getGetterName()),
3747 : getSelectorName(PD->getSetterName()),
3748 PD->getPropertyAttributes(),
3749 getOrCreateType(PD->getType(), PUnit));
3753 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3754 FieldSize, FieldAlign, FieldOffset, Flags,
3755 FieldTy, PropertyNode);
3756 EltTys.push_back(FieldTy);
3759 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3760 DBuilder.replaceArrays(RealDecl, Elements);
3762 LexicalBlockStack.pop_back();
3766llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3767 llvm::DIFile *Unit) {
3775 auto &Ctx = CGM.getContext();
3780 QualType CharVecTy =
3782 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3785 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3788 llvm::Metadata *Subscript;
3789 QualType QTy(Ty, 0);
3790 auto SizeExpr = SizeExprCache.find(QTy);
3791 if (SizeExpr != SizeExprCache.end())
3792 Subscript = DBuilder.getOrCreateSubrange(
3793 SizeExpr->getSecond() ,
nullptr ,
3794 nullptr ,
nullptr );
3797 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3798 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3799 Subscript = DBuilder.getOrCreateSubrange(
3800 CountNode ,
nullptr ,
nullptr ,
3803 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3808 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3811llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3812 llvm::DIFile *Unit) {
3816 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3821 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3822 auto *ColumnCountNode =
3823 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3824 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3825 auto *RowCountNode =
3826 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3827 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3828 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3829 ColumnCountNode ,
nullptr ,
nullptr ,
3831 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3832 RowCountNode ,
nullptr ,
nullptr ,
3834 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3835 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3838llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3843 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3858 Size = CGM.getContext().getTypeSize(Ty);
3865 SmallVector<llvm::Metadata *, 8> Subscripts;
3866 QualType EltTy(Ty, 0);
3867 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3876 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3877 Count = CAT->getZExtSize();
3878 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3879 if (Expr *Size = VAT->getSizeExpr()) {
3881 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3882 Count =
Result.Val.getInt().getExtValue();
3886 auto SizeNode = SizeExprCache.find(EltTy);
3887 if (SizeNode != SizeExprCache.end())
3888 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3889 SizeNode->getSecond() ,
nullptr ,
3890 nullptr ,
nullptr ));
3893 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3894 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3895 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3896 CountNode ,
nullptr ,
nullptr ,
3902 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3904 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3908llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3909 llvm::DIFile *Unit) {
3910 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3914llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3915 llvm::DIFile *Unit) {
3916 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3918 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3919 CGM.getCodeGenOpts().DwarfVersion < 4)
3920 Tag = llvm::dwarf::DW_TAG_reference_type;
3922 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3925llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3927 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3931 Size = CGM.getContext().getTypeSize(Ty);
3934 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3937 Flags |= llvm::DINode::FlagSingleInheritance;
3940 Flags |= llvm::DINode::FlagMultipleInheritance;
3943 Flags |= llvm::DINode::FlagVirtualInheritance;
3953 llvm::DIType *ClassType = getOrCreateType(T, U);
3955 return DBuilder.createMemberPointerType(
3959 const FunctionProtoType *FPT =
3961 return DBuilder.createMemberPointerType(
3962 getOrCreateInstanceMethodType(
3965 ClassType, Size, 0, Flags);
3968llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3970 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3973llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3977llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3979 return getOrCreateType(Ty->getWrappedType(), U);
3982llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3989 const EnumType *Ty) {
4001llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4004 bool isImportedFromModule =
4005 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4009 if (isImportedFromModule || !ED->getDefinition()) {
4016 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4017 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4018 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4019 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4021 unsigned Line = getLineNumber(ED->getLocation());
4022 StringRef EDName = ED->getName();
4023 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4024 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4025 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4027 ReplaceMap.emplace_back(
4028 std::piecewise_construct, std::make_tuple(Ty),
4029 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4033 return CreateTypeDefinition(Ty);
4036llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4039 SmallVector<llvm::Metadata *, 16> Enumerators;
4040 ED = ED->getDefinition();
4041 assert(ED &&
"An enumeration definition is required");
4042 for (
const auto *
Enum : ED->enumerators()) {
4043 Enumerators.push_back(
4044 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4047 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4048 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4049 EnumKind = Attr->getExtensibility();
4052 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4054 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4055 unsigned Line = getLineNumber(ED->getLocation());
4056 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4057 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4058 return DBuilder.createEnumerationType(
4059 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4060 0, Identifier, ED->isScoped(), EnumKind);
4065 StringRef Name, StringRef
Value) {
4066 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4067 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4073 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4074 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4075 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4080 llvm::DISubprogram *SynthSubprogram) {
4081 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4082 SynthSubprogram, ParentLocation);
4087 StringRef SynthFuncName,
4088 llvm::DIFile *SynthFile) {
4089 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4094 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4100 FuncName += Category;
4102 FuncName += FailureMsg;
4105 TrapLocation->getFile());
4111 Qualifiers InnerQuals = T.getLocalQualifiers();
4115 Quals += InnerQuals;
4117 switch (T->getTypeClass()) {
4119 return C.getQualifiedType(T.getTypePtr(), Quals);
4122 case Type::InjectedClassName:
4123 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4125 case Type::TemplateSpecialization: {
4127 if (Spec->isTypeAlias())
4128 return C.getQualifiedType(T.getTypePtr(), Quals);
4129 T = Spec->desugar();
4132 case Type::TypeOfExpr:
4138 case Type::Decltype:
4141 case Type::UnaryTransform:
4144 case Type::Attributed:
4147 case Type::BTFTagAttributed:
4150 case Type::CountAttributed:
4159 case Type::MacroQualified:
4162 case Type::SubstTemplateTypeParm:
4166 case Type::DeducedTemplateSpecialization: {
4168 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4172 case Type::PackIndexing: {
4176 case Type::Adjusted:
4183 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4188llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4191 if (It != TypeCache.end()) {
4193 if (llvm::Metadata *
V = It->second)
4206 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4213 RetainedTypes.push_back(
4214 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4217llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4221 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4223 llvm::raw_string_ostream OS(Name);
4224 Ty.
print(OS, getPrintingPolicy());
4231 if (
auto *T = getTypeOrNull(Ty))
4234 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4235 void *TyPtr = Ty.getAsOpaquePtr();
4238 TypeCache[TyPtr].reset(Res);
4243llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4251 auto Info = Reader->getSourceDescriptor(Idx);
4253 return getOrCreateModuleRef(*Info,
true);
4254 }
else if (ClangModuleMap) {
4267 auto Info = ASTSourceDescriptor(*M);
4268 return getOrCreateModuleRef(Info,
false);
4271 return getOrCreateModuleRef(PCHDescriptor,
false);
4278llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4281 return CreateQualifiedType(Ty, Unit);
4285#define TYPE(Class, Base)
4286#define ABSTRACT_TYPE(Class, Base)
4287#define NON_CANONICAL_TYPE(Class, Base)
4288#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4289#include "clang/AST/TypeNodes.inc"
4290 llvm_unreachable(
"Dependent types cannot show up in debug information");
4292 case Type::ExtVector:
4295 case Type::ConstantMatrix:
4297 case Type::ObjCObjectPointer:
4299 case Type::ObjCObject:
4301 case Type::ObjCTypeParam:
4303 case Type::ObjCInterface:
4311 case Type::BlockPointer:
4319 case Type::FunctionProto:
4320 case Type::FunctionNoProto:
4322 case Type::ConstantArray:
4323 case Type::VariableArray:
4324 case Type::IncompleteArray:
4325 case Type::ArrayParameter:
4328 case Type::LValueReference:
4330 case Type::RValueReference:
4333 case Type::MemberPointer:
4341 case Type::OverflowBehavior:
4346 case Type::TemplateSpecialization:
4348 case Type::HLSLAttributedResource:
4350 case Type::HLSLInlineSpirv:
4352 case Type::PredefinedSugar:
4354 case Type::CountAttributed:
4356 case Type::Attributed:
4357 case Type::BTFTagAttributed:
4358 case Type::Adjusted:
4360 case Type::DeducedTemplateSpecialization:
4363 case Type::MacroQualified:
4364 case Type::SubstTemplateTypeParm:
4365 case Type::TypeOfExpr:
4367 case Type::Decltype:
4368 case Type::PackIndexing:
4369 case Type::UnaryTransform:
4373 llvm_unreachable(
"type should have been unwrapped!");
4376llvm::DICompositeType *
4377CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4378 QualType QTy(Ty, 0);
4380 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4385 if (T && !T->isForwardDecl())
4389 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4394 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4397 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4402llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4404 bool NameIsSimplified =
false;
4407 StringRef RDName = getClassName(RD, &NameIsSimplified);
4409 llvm::DIFile *DefUnit =
nullptr;
4412 DefUnit = getOrCreateFile(Loc);
4413 Line = getLineNumber(Loc);
4416 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4420 auto *T = cast_or_null<llvm::DICompositeType>(
4421 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4429 return getOrCreateRecordFwdDecl(Ty, RDContext);
4442 auto Flags = llvm::DINode::FlagZero;
4443 if (NameIsSimplified)
4444 Flags |= llvm::DINode::FlagNameIsSimplified;
4445 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4447 Flags |= llvm::DINode::FlagTypePassByReference;
4449 Flags |= llvm::DINode::FlagTypePassByValue;
4452 if (!CXXRD->isTrivial())
4453 Flags |= llvm::DINode::FlagNonTrivial;
4456 if (CXXRD->isAnonymousStructOrUnion())
4457 Flags |= llvm::DINode::FlagExportSymbols;
4460 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4463 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4464 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4466 Flags, Identifier, Annotations);
4470 switch (RealDecl->getTag()) {
4472 llvm_unreachable(
"invalid composite type tag");
4474 case llvm::dwarf::DW_TAG_array_type:
4475 case llvm::dwarf::DW_TAG_enumeration_type:
4480 if (Identifier.empty())
4484 case llvm::dwarf::DW_TAG_structure_type:
4485 case llvm::dwarf::DW_TAG_union_type:
4486 case llvm::dwarf::DW_TAG_class_type:
4489 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4493 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4494 CXXRecordDecl *TemplateDecl =
4495 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4496 RegionMap[TemplateDecl].reset(RealDecl);
4498 RegionMap[RD].reset(RealDecl);
4500 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4502 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4503 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4504 CollectCXXTemplateParams(TSpecial, DefUnit));
4508void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4509 llvm::DICompositeType *RealDecl) {
4511 llvm::DIType *ContainingType =
nullptr;
4512 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4516 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4523 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4524 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4526 ContainingType = RealDecl;
4528 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4531llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4532 StringRef Name, uint64_t *Offset) {
4533 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4534 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4537 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4538 *Offset, llvm::DINode::FlagZero, FieldTy);
4539 *Offset += FieldSize;
4543void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4545 StringRef &LinkageName,
4546 llvm::DIScope *&FDContext,
4547 llvm::DINodeArray &TParamsArray,
4548 llvm::DINode::DIFlags &Flags) {
4550 bool NameIsSimplified =
false;
4551 Name = getFunctionName(FD, &NameIsSimplified);
4552 if (NameIsSimplified)
4553 Flags |= llvm::DINode::FlagNameIsSimplified;
4554 Name = getFunctionName(FD);
4557 LinkageName = CGM.getMangledName(GD);
4559 Flags |= llvm::DINode::FlagPrototyped;
4563 if (LinkageName == Name ||
4564 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4565 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4566 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4567 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4568 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4569 LinkageName = StringRef();
4573 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4574 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4575 CGM.getCodeGenOpts().EmitCodeView)) {
4576 if (
const NamespaceDecl *NSDecl =
4578 FDContext = getOrCreateNamespace(NSDecl);
4579 else if (
const RecordDecl *RDecl =
4581 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4582 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4585 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4588 Flags |= llvm::DINode::FlagNoReturn;
4590 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4594void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4595 unsigned &LineNo, QualType &T,
4596 StringRef &Name, StringRef &LinkageName,
4597 llvm::MDTuple *&TemplateParameters,
4598 llvm::DIScope *&VDContext) {
4607 llvm::APInt ConstVal(32, 1);
4608 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4610 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4617 LinkageName = CGM.getMangledName(VD);
4618 if (LinkageName == Name)
4619 LinkageName = StringRef();
4622 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4623 TemplateParameters = parameterNodes.get();
4625 TemplateParameters =
nullptr;
4643 DC = CGM.getContext().getTranslationUnitDecl();
4645 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4646 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4649llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4651 llvm::DINodeArray TParamsArray;
4652 StringRef Name, LinkageName;
4653 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4654 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4656 llvm::DIFile *Unit = getOrCreateFile(Loc);
4657 llvm::DIScope *DContext = Unit;
4658 unsigned Line = getLineNumber(Loc);
4659 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4664 SmallVector<QualType, 16> ArgTypes;
4665 for (
const ParmVarDecl *Parm : FD->
parameters())
4666 ArgTypes.push_back(Parm->getType());
4669 QualType FnType = CGM.getContext().getFunctionType(
4670 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4672 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4673 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4674 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4678 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4679 return DBuilder.createFunction(
4680 DContext, Name, LinkageName, Unit,
Line,
4681 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4682 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4684 CGM.getCodeGenOpts().DebugKeyInstructions);
4687 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4688 DContext, Name, LinkageName, Unit,
Line,
4689 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4690 TParamsArray.get(), getFunctionDeclaration(FD));
4692 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4693 std::make_tuple(CanonDecl),
4694 std::make_tuple(SP));
4698llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4699 return getFunctionFwdDeclOrStub(GD,
false);
4702llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4703 return getFunctionFwdDeclOrStub(GD,
true);
4706llvm::DIGlobalVariable *
4707CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4709 StringRef Name, LinkageName;
4711 llvm::DIFile *Unit = getOrCreateFile(Loc);
4712 llvm::DIScope *DContext = Unit;
4713 unsigned Line = getLineNumber(Loc);
4714 llvm::MDTuple *TemplateParameters =
nullptr;
4716 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4719 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4720 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4722 FwdDeclReplaceMap.emplace_back(
4723 std::piecewise_construct,
4725 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4729llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4734 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4735 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4736 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4740 if (I != DeclCache.end()) {
4742 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4743 return GVE->getVariable();
4751 if (IE != ImportedDeclCache.end()) {
4752 auto N = IE->second;
4753 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4755 return dyn_cast_or_null<llvm::DINode>(N);
4760 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4761 return getFunctionForwardDeclaration(FD);
4762 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4763 return getGlobalVariableForwardDeclaration(VD);
4768llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4769 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4772 const auto *FD = dyn_cast<FunctionDecl>(D);
4777 auto *S = getDeclContextDescriptor(D);
4780 if (MI == SPCache.end()) {
4782 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4786 if (MI != SPCache.end()) {
4787 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4788 if (SP && !SP->isDefinition())
4792 for (
auto *NextFD : FD->
redecls()) {
4793 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4794 if (MI != SPCache.end()) {
4795 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4796 if (SP && !SP->isDefinition())
4803llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4804 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4805 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4806 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4809 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4813 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4817 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4826 QualType QTy(
ID->getTypeForDecl(), 0);
4827 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4828 if (It == TypeCache.end())
4831 llvm::DISubprogram *FD = DBuilder.createFunction(
4832 InterfaceType, getObjCMethodName(OMD), StringRef(),
4833 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4834 DBuilder.finalizeSubprogram(FD);
4841llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4846 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4847 !CGM.getCodeGenOpts().EmitCodeView))
4850 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4852 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4855 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4858 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4859 return getOrCreateMethodType(
Method, F);
4861 const auto *FTy = FnType->
getAs<FunctionType>();
4864 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4866 SmallVector<llvm::Metadata *, 16> Elts;
4869 QualType ResultTy = OMethod->getReturnType();
4872 if (ResultTy == CGM.getContext().getObjCInstanceType())
4873 ResultTy = CGM.getContext().getPointerType(
4874 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4876 Elts.push_back(getOrCreateType(ResultTy, F));
4878 QualType SelfDeclTy;
4879 if (
auto *SelfDecl = OMethod->getSelfDecl())
4880 SelfDeclTy = SelfDecl->getType();
4881 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4884 if (!SelfDeclTy.
isNull())
4886 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4888 Elts.push_back(DBuilder.createArtificialType(
4889 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4891 for (
const auto *PI : OMethod->parameters())
4892 Elts.push_back(getOrCreateType(PI->getType(), F));
4894 if (OMethod->isVariadic())
4895 Elts.push_back(DBuilder.createUnspecifiedParameter());
4897 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4898 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4904 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4905 if (FD->isVariadic()) {
4906 SmallVector<llvm::Metadata *, 16> EltTys;
4907 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4908 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4910 EltTys.push_back(getOrCreateType(ParamType, F));
4911 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4912 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4913 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4926 CC = SrcFnTy->getCallConv();
4928 for (
const VarDecl *VD : Args)
4929 ArgTypes.push_back(VD->
getType());
4930 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4936 llvm::Function *Fn,
bool CurFuncIsThunk) {
4938 StringRef LinkageName;
4940 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4943 bool HasDecl = (D !=
nullptr);
4945 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4946 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4947 llvm::DIFile *Unit = getOrCreateFile(Loc);
4948 llvm::DIScope *FDContext = Unit;
4949 llvm::DINodeArray TParamsArray;
4950 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4953 LinkageName = Fn->getName();
4954 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4956 auto FI = SPCache.find(FD->getCanonicalDecl());
4957 if (FI != SPCache.end()) {
4958 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4959 if (SP && SP->isDefinition()) {
4960 LexicalBlockStack.emplace_back(SP);
4961 RegionMap[D].reset(SP);
4965 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4966 TParamsArray, Flags);
4969 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4970 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4971 Name = getObjCMethodName(OMD);
4972 Flags |= llvm::DINode::FlagPrototyped;
4978 if (Name != Fn->getName())
4979 LinkageName = Fn->getName();
4981 Name = Fn->getName();
4986 Flags |= llvm::DINode::FlagPrototyped;
4988 Name.consume_front(
"\01");
4992 "Unexpected DynamicInitKind !");
4996 Flags |= llvm::DINode::FlagArtificial;
5002 Flags |= llvm::DINode::FlagThunk;
5004 if (Fn->hasLocalLinkage())
5005 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5006 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5007 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5010 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5011 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5013 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5014 unsigned ScopeLine = getLineNumber(ScopeLoc);
5015 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5016 llvm::DISubprogram *
Decl =
nullptr;
5017 llvm::DINodeArray Annotations =
nullptr;
5020 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5021 : getFunctionDeclaration(D);
5022 Annotations = CollectBTFDeclTagAnnotations(D);
5030 llvm::DISubprogram *SP = DBuilder.createFunction(
5031 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5032 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5033 Annotations,
"", KeyInstructions);
5034 Fn->setSubprogram(SP);
5043 LexicalBlockStack.emplace_back(SP);
5046 RegionMap[D].reset(SP);
5050 QualType FnType, llvm::Function *Fn) {
5052 StringRef LinkageName;
5058 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5059 return GetName(D,
true);
5062 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5063 llvm::DIFile *Unit = getOrCreateFile(Loc);
5064 bool IsDeclForCallSite = Fn ?
true :
false;
5065 llvm::DIScope *FDContext =
5066 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5067 llvm::DINodeArray TParamsArray;
5070 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5071 TParamsArray, Flags);
5072 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5073 Name = getObjCMethodName(OMD);
5074 Flags |= llvm::DINode::FlagPrototyped;
5076 llvm_unreachable(
"not a function or ObjC method");
5078 Name.consume_front(
"\01");
5081 Flags |= llvm::DINode::FlagArtificial;
5086 unsigned LineNo = getLineNumber(Loc);
5087 unsigned ScopeLine = 0;
5088 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5089 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5090 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5092 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5093 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5095 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5096 llvm::DISubprogram *SP = DBuilder.createFunction(
5097 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5098 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5104 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5105 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5106 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5109 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5110 DBuilder.createParameterVariable(
5111 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5112 llvm::DINode::FlagZero, ParamAnnotations);
5118 if (IsDeclForCallSite)
5119 Fn->setSubprogram(SP);
5123 llvm::CallBase *CI) {
5124 if (!shouldGenerateVirtualCallSite())
5130 assert(CI &&
"Invalid Call Instruction.");
5131 if (!CI->isIndirectCall())
5135 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5136 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5144 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5147 if (
Func->getSubprogram())
5155 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5170 auto FI = SPCache.find(FD->getCanonicalDecl());
5171 llvm::DISubprogram *SP =
nullptr;
5172 if (FI != SPCache.end())
5173 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5174 if (!SP || !SP->isDefinition())
5175 SP = getFunctionStub(GD);
5176 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5177 LexicalBlockStack.emplace_back(SP);
5183 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5192 if (CurLoc.isInvalid() ||
5193 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5194 LexicalBlockStack.empty())
5197 llvm::MDNode *
Scope = LexicalBlockStack.back();
5198 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5199 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5203 llvm::MDNode *Back =
nullptr;
5204 if (!LexicalBlockStack.empty())
5205 Back = LexicalBlockStack.back().get();
5206 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5208 getColumnNumber(CurLoc)));
5211void CGDebugInfo::AppendAddressSpaceXDeref(
5213 std::optional<unsigned> DWARFAddressSpace =
5215 if (!DWARFAddressSpace)
5218 Expr.push_back(llvm::dwarf::DW_OP_constu);
5219 Expr.push_back(*DWARFAddressSpace);
5220 Expr.push_back(llvm::dwarf::DW_OP_swap);
5221 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5230 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5231 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5232 LexicalBlockStack.back(), CurInlinedAt));
5234 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5238 CreateLexicalBlock(Loc);
5243 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5248 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5251 LexicalBlockStack.pop_back();
5255 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5256 unsigned RCount = FnBeginRegionCount.back();
5257 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5260 while (LexicalBlockStack.size() != RCount) {
5263 LexicalBlockStack.pop_back();
5265 FnBeginRegionCount.pop_back();
5267 if (Fn && Fn->getSubprogram())
5268 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5271CGDebugInfo::BlockByRefType
5272CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5273 uint64_t *XOffset) {
5276 uint64_t FieldSize, FieldOffset;
5277 uint32_t FieldAlign;
5279 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5284 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5285 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5287 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5288 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5291 if (HasCopyAndDispose) {
5294 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5296 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5298 bool HasByrefExtendedLayout;
5301 HasByrefExtendedLayout) &&
5302 HasByrefExtendedLayout) {
5305 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5314 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5317 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5320 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5325 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5326 FieldSize = CGM.getContext().getTypeSize(FType);
5327 FieldAlign = CGM.getContext().toBits(Align);
5329 *XOffset = FieldOffset;
5330 llvm::DIType *FieldTy = DBuilder.createMemberType(
5331 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5332 llvm::DINode::FlagZero, WrappedTy);
5333 EltTys.push_back(FieldTy);
5334 FieldOffset += FieldSize;
5336 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5337 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5338 llvm::DINode::FlagZero,
nullptr, Elements),
5342llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5343 llvm::Value *Storage,
5344 std::optional<unsigned> ArgNo,
5346 const bool UsePointerValue) {
5347 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5348 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5349 if (VD->
hasAttr<NoDebugAttr>())
5354 llvm::DIFile *Unit =
nullptr;
5355 if (!VarIsArtificial)
5359 if (VD->
hasAttr<BlocksAttr>())
5360 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5362 Ty = getOrCreateType(VD->
getType(), Unit);
5372 if (!VarIsArtificial) {
5376 SmallVector<uint64_t, 13> Expr;
5377 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5384 Flags |= llvm::DINode::FlagArtificial;
5388 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5389 AppendAddressSpaceXDeref(AddressSpace, Expr);
5393 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5396 Flags |= llvm::DINode::FlagObjectPointer;
5397 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5398 if (PVD->isExplicitObjectParameter())
5399 Flags |= llvm::DINode::FlagObjectPointer;
5407 StringRef Name = VD->
getName();
5408 if (!Name.empty()) {
5414 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5416 offset = CGM.getContext().toCharUnitsFromBits(
5419 Expr.push_back(llvm::dwarf::DW_OP_deref);
5420 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5422 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5425 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5437 for (
const auto *Field : RD->
fields()) {
5438 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5439 StringRef FieldName =
Field->getName();
5447 auto *D = DBuilder.createAutoVariable(
5448 Scope, FieldName, Unit,
Line, FieldTy,
5449 CGM.getCodeGenOpts().OptimizationLevel != 0,
5450 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5453 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5454 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5457 Builder.GetInsertBlock());
5465 if (UsePointerValue) {
5466 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5467 "Debug info already contains DW_OP_deref.");
5468 Expr.push_back(llvm::dwarf::DW_OP_deref);
5472 llvm::DILocalVariable *D =
nullptr;
5474 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5475 D = DBuilder.createParameterVariable(
5476 Scope, Name, *ArgNo, Unit,
Line, Ty,
5477 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5486 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5492 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5493 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5494 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5495 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5497 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5503 if (Iter != CoroutineParameterMappings.end()) {
5504 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5505 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5506 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5508 if (Iter2 != ParamDbgMappings.end())
5509 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5515 D = RemapCoroArgToLocalVar();
5518 D = DBuilder.createAutoVariable(
5519 Scope, Name, Unit,
Line, Ty,
5520 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5523 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5524 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5525 Column, Scope, CurInlinedAt),
5526 Builder.GetInsertBlock());
5531llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5532 llvm::Value *Storage,
5533 std::optional<unsigned> ArgNo,
5535 const bool UsePointerValue) {
5536 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5537 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5538 if (BD->
hasAttr<NoDebugAttr>())
5545 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5546 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5554 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5556 SmallVector<uint64_t, 3> Expr;
5557 AppendAddressSpaceXDeref(AddressSpace, Expr);
5562 if (UsePointerValue) {
5563 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5564 "Debug info already contains DW_OP_deref.");
5565 Expr.push_back(llvm::dwarf::DW_OP_deref);
5570 StringRef Name = BD->
getName();
5573 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5574 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5575 llvm::DINode::FlagZero, Align);
5577 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5578 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5579 const unsigned fieldIndex = FD->getFieldIndex();
5580 const clang::CXXRecordDecl *parent =
5581 (
const CXXRecordDecl *)FD->getParent();
5582 const ASTRecordLayout &layout =
5583 CGM.getContext().getASTRecordLayout(parent);
5585 if (FD->isBitField()) {
5586 const CGRecordLayout &RL =
5587 CGM.getTypes().getCGRecordLayout(FD->getParent());
5592 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5598 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5599 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5600 Expr.push_back(Info.
Offset);
5603 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5604 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5605 }
else if (fieldOffset != 0) {
5606 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5607 "Unexpected non-bitfield with non-byte-aligned offset");
5608 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5610 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5613 }
else if (
const ArraySubscriptExpr *ASE =
5614 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5615 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5616 const uint64_t value = IL->getValue().getZExtValue();
5617 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5620 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5621 Expr.push_back(CGM.getContext()
5622 .toCharUnitsFromBits(value * typeSize)
5629 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5630 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5631 Column, Scope, CurInlinedAt),
5632 Builder.GetInsertBlock());
5637llvm::DILocalVariable *
5640 const bool UsePointerValue) {
5641 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5643 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5645 EmitDeclare(B, Storage, std::nullopt, Builder,
5652 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5656 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5657 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5659 if (D->
hasAttr<NoDebugAttr>())
5663 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5669 StringRef Name = D->
getName();
5675 CGM.getCodeGenOpts().OptimizationLevel != 0);
5678 DBuilder.insertLabel(L,
5679 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5680 Scope, CurInlinedAt),
5681 Builder.GetInsertBlock()->end());
5684llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5686 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5689 return DBuilder.createObjectPointerType(Ty,
true);
5694 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5695 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5696 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5698 if (Builder.GetInsertBlock() ==
nullptr)
5700 if (VD->
hasAttr<NoDebugAttr>())
5703 bool isByRef = VD->
hasAttr<BlocksAttr>();
5705 uint64_t XOffset = 0;
5706 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5709 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5711 Ty = getOrCreateType(VD->
getType(), Unit);
5715 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5717 Ty = CreateSelfType(VD->
getType(), Ty);
5720 const unsigned Line =
5724 const llvm::DataLayout &target = CGM.getDataLayout();
5731 addr.push_back(llvm::dwarf::DW_OP_deref);
5732 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5735 addr.push_back(llvm::dwarf::DW_OP_deref);
5736 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5739 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5741 addr.push_back(llvm::dwarf::DW_OP_deref);
5742 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5744 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5750 auto *D = DBuilder.createAutoVariable(
5752 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5755 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5756 LexicalBlockStack.back(), CurInlinedAt);
5757 auto *
Expr = DBuilder.createExpression(addr);
5759 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5761 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5764llvm::DILocalVariable *
5767 bool UsePointerValue) {
5768 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5769 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5773struct BlockLayoutChunk {
5774 uint64_t OffsetInBits;
5777bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5778 return l.OffsetInBits < r.OffsetInBits;
5782void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5784 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5785 SmallVectorImpl<llvm::Metadata *> &Fields) {
5789 if (CGM.getLangOpts().OpenCL) {
5790 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5791 BlockLayout.getElementOffsetInBits(0),
5793 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5794 BlockLayout.getElementOffsetInBits(1),
5798 BlockLayout.getElementOffsetInBits(0),
5800 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5801 BlockLayout.getElementOffsetInBits(1),
5805 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5806 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5807 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5808 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5809 BlockLayout.getElementOffsetInBits(3),
5811 Fields.push_back(createFieldType(
5816 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5823 llvm::AllocaInst *Alloca,
5825 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5831 llvm::DIFile *tunit = getOrCreateFile(loc);
5832 unsigned line = getLineNumber(loc);
5833 unsigned column = getColumnNumber(loc);
5838 const llvm::StructLayout *blockLayout =
5842 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5851 BlockLayoutChunk chunk;
5852 chunk.OffsetInBits =
5853 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5854 chunk.Capture =
nullptr;
5855 chunks.push_back(chunk);
5859 for (
const auto &capture :
blockDecl->captures()) {
5860 const VarDecl *variable = capture.getVariable();
5867 BlockLayoutChunk chunk;
5868 chunk.OffsetInBits =
5869 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5870 chunk.Capture = &capture;
5871 chunks.push_back(chunk);
5875 llvm::array_pod_sort(chunks.begin(), chunks.end());
5877 for (
const BlockLayoutChunk &Chunk : chunks) {
5878 uint64_t offsetInBits = Chunk.OffsetInBits;
5885 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5887 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5888 type = CGM.getContext().getCanonicalTagType(RDecl);
5890 llvm_unreachable(
"unexpected block declcontext");
5892 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5893 offsetInBits, tunit, tunit));
5898 StringRef name = variable->
getName();
5900 llvm::DIType *fieldType;
5902 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5907 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5908 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5909 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5910 PtrInfo.
Width, Align, offsetInBits,
5911 llvm::DINode::FlagZero, fieldType);
5915 offsetInBits, Align, tunit, tunit);
5917 fields.push_back(fieldType);
5921 llvm::raw_svector_ostream(typeName)
5922 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5924 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5926 llvm::DIType *
type =
5927 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5928 CGM.getContext().toBits(block.
BlockSize), 0,
5929 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5930 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5933 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5937 auto *debugVar = DBuilder.createParameterVariable(
5938 scope, Name, ArgNo, tunit, line,
type,
5939 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5942 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5943 llvm::DILocation::get(CGM.getLLVMContext(), line,
5944 column, scope, CurInlinedAt),
5945 Builder.GetInsertBlock());
5948llvm::DIDerivedType *
5949CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5954 if (MI != StaticDataMemberCache.end()) {
5955 assert(MI->second &&
"Static data member declaration should still exist");
5966llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5967 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5968 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5969 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5971 for (
const auto *Field : RD->
fields()) {
5972 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5973 StringRef FieldName = Field->getName();
5976 if (FieldName.empty()) {
5977 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5978 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5979 LineNo, LinkageName, Var, DContext);
5983 GVE = DBuilder.createGlobalVariableExpression(
5984 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5985 Var->hasLocalLinkage());
5986 Var->addDebugInfo(GVE);
5998 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6003 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6014 struct ReferencesAnonymous
6016 bool RefAnon =
false;
6017 bool VisitRecordType(RecordType *RT) {
6025 ReferencesAnonymous RT;
6038struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6039 bool Reconstitutable =
true;
6040 bool VisitVectorType(VectorType *FT) {
6041 Reconstitutable =
false;
6044 bool VisitAtomicType(AtomicType *FT) {
6045 Reconstitutable =
false;
6048 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6051 const EnumDecl *ED = ET->getDecl();
6053 Reconstitutable =
false;
6057 Reconstitutable =
false;
6062 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6066 return Reconstitutable;
6068 bool VisitRecordType(RecordType *RT,
bool =
false) {
6070 Reconstitutable =
false;
6080 ReconstitutableType T;
6082 return T.Reconstitutable;
6085bool CGDebugInfo::HasReconstitutableArgs(
6086 ArrayRef<TemplateArgument> Args)
const {
6087 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6127 llvm_unreachable(
"Other, unresolved, template arguments should "
6128 "not be seen here");
6133std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6134 bool *NameIsSimplified)
const {
6136 llvm::raw_string_ostream
OS(Name);
6137 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6140 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6141 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6143 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6144 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6146 std::optional<TemplateArgs> Args;
6148 bool IsOperatorOverload =
false;
6149 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6150 Args = GetTemplateArgs(RD);
6151 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6152 Args = GetTemplateArgs(FD);
6154 IsOperatorOverload |=
6157 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6158 Args = GetTemplateArgs(VD);
6182 bool Reconstitutable =
6183 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6185 PrintingPolicy PP = getPrintingPolicy();
6187 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6192 if (NameIsSimplified)
6193 *NameIsSimplified =
true;
6194 bool Mangled = TemplateNamesKind ==
6195 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6201 std::string EncodedOriginalName;
6202 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6207 printTemplateArgumentList(OS, Args->Args, PP);
6208 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6210 std::string CanonicalOriginalName;
6211 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6213 assert(EncodedOriginalName == CanonicalOriginalName);
6222 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6223 if (D->
hasAttr<NoDebugAttr>())
6226 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6227 return GetName(D,
true);
6233 if (Cached != DeclCache.end())
6234 return Var->addDebugInfo(
6238 llvm::DIFile *Unit =
nullptr;
6239 llvm::DIScope *DContext =
nullptr;
6241 StringRef DeclName, LinkageName;
6243 llvm::MDTuple *TemplateParameters =
nullptr;
6244 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6245 TemplateParameters, DContext);
6249 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6254 if (T->isUnionType() && DeclName.empty()) {
6255 const auto *RD = T->castAsRecordDecl();
6257 "unnamed non-anonymous struct or union?");
6258 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6263 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6264 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6265 if (D->
hasAttr<CUDASharedAttr>())
6268 else if (D->
hasAttr<CUDAConstantAttr>())
6272 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6274 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6275 GVE = DBuilder.createGlobalVariableExpression(
6276 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6277 Var->hasLocalLinkage(),
true,
6278 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6279 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6280 Align, Annotations);
6281 Var->addDebugInfo(GVE);
6287 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6288 if (VD->
hasAttr<NoDebugAttr>())
6290 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6291 return GetName(VD,
true);
6296 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6297 StringRef Name = VD->
getName();
6298 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6300 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6302 if (CGM.getCodeGenOpts().EmitCodeView) {
6313 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6314 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6315 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6325 auto *VarD = dyn_cast<VarDecl>(VD);
6326 if (VarD && VarD->isStaticDataMember()) {
6328 getDeclContextDescriptor(VarD);
6333 RetainedTypes.push_back(
6334 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6338 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6340 auto &GV = DeclCache[VD];
6344 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6345 llvm::MDTuple *TemplateParameters =
nullptr;
6349 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6350 TemplateParameters = parameterNodes.get();
6353 GV.reset(DBuilder.createGlobalVariableExpression(
6354 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6355 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6356 TemplateParameters, Align));
6361 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6362 if (D->
hasAttr<NoDebugAttr>())
6366 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6367 StringRef Name = D->
getName();
6368 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6370 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6371 llvm::DIGlobalVariableExpression *GVE =
6372 DBuilder.createGlobalVariableExpression(
6373 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6374 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6375 Var->addDebugInfo(GVE);
6382 if (CGM.getCodeGenOpts().getDebugInfo() <=
6383 llvm::codegenoptions::DebugLineTablesOnly)
6386 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6390 llvm::DIFile *Unit = DIL->getFile();
6391 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6396 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6397 llvm::Value *Var = Load->getPointerOperand();
6402 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6403 return DbgDeclare->getVariable()->getType() ==
Type;
6405 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6409 llvm::DILocalVariable *D =
6410 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6411 Type,
false, llvm::DINode::FlagArtificial);
6413 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6414 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6424 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6428 if (D->
hasAttr<NoDebugAttr>())
6431 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6446 if (!(DI = getDeclarationOrDefinition(
6447 AliaseeDecl.getCanonicalDecl().getDecl())))
6450 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6453 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6454 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6468 llvm::DIFile *
File = getOrCreateFile(Loc);
6469 llvm::DIGlobalVariableExpression *Debug =
6470 DBuilder.createGlobalVariableExpression(
6471 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6472 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6473 GV->addDebugInfo(Debug);
6476llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6477 if (!LexicalBlockStack.empty())
6478 return LexicalBlockStack.back();
6479 llvm::DIScope *Mod = getParentModuleOrNull(D);
6480 return getContextDescriptor(D, Mod ? Mod : TheCU);
6484 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6488 CGM.getCodeGenOpts().DebugExplicitImport) {
6492 DBuilder.createImportedModule(
6494 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6499 if (llvm::DINode *
Target =
6502 DBuilder.createImportedDeclaration(
6504 getOrCreateFile(Loc), getLineNumber(Loc));
6509 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6512 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6514 for (
const auto *USD : UD.
shadows()) {
6519 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6520 if (
const auto *AT = FD->getType()
6523 if (AT->getDeducedType().isNull())
6534 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6537 "We shouldn't be codegening an invalid UsingEnumDecl"
6538 " containing no decls");
6540 for (
const auto *USD : UD.
shadows())
6545 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6547 if (
Module *M = ID.getImportedModule()) {
6549 auto Loc = ID.getLocation();
6550 DBuilder.createImportedDeclaration(
6551 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6552 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6553 getLineNumber(Loc));
6557llvm::DIImportedEntity *
6559 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6561 auto &VH = NamespaceAliasCache[&NA];
6564 llvm::DIImportedEntity *R;
6566 if (
const auto *Underlying =
6569 R = DBuilder.createImportedDeclaration(
6572 getLineNumber(Loc), NA.
getName());
6574 R = DBuilder.createImportedDeclaration(
6577 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6583CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6587 auto I = NamespaceCache.find(NSDecl);
6588 if (I != NamespaceCache.end())
6591 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6593 llvm::DINamespace *NS =
6594 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6595 NamespaceCache[NSDecl].reset(NS);
6600 assert(TheCU &&
"no main compile unit");
6601 TheCU->setDWOId(Signature);
6607 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6608 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6610 ? CreateTypeDefinition(E.Type, E.Unit)
6612 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6616 for (
const auto &P : ObjCMethodCache) {
6617 if (P.second.empty())
6620 QualType QTy(P.first->getTypeForDecl(), 0);
6622 assert(It != TypeCache.end());
6624 llvm::DICompositeType *InterfaceDecl =
6627 auto CurElts = InterfaceDecl->getElements();
6631 for (
auto &SubprogramDirect : P.second)
6632 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6633 EltTys.push_back(SubprogramDirect.getPointer());
6635 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6636 DBuilder.replaceArrays(InterfaceDecl, Elements);
6639 for (
const auto &P : ReplaceMap) {
6642 assert(Ty->isForwardDecl());
6644 auto It = TypeCache.find(P.first);
6645 assert(It != TypeCache.end());
6648 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6652 for (
const auto &P : FwdDeclReplaceMap) {
6655 llvm::Metadata *Repl;
6657 auto It = DeclCache.find(P.first);
6661 if (It == DeclCache.end())
6666 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6667 Repl = GVE->getVariable();
6673 for (
auto &RT : RetainedTypes)
6674 if (
auto MD = TypeCache[RT])
6677 DBuilder.finalize();
6682 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6683 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6684 DBuilder.retainType(DieTy);
6688 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6689 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6690 DBuilder.retainType(DieTy);
6694 if (LexicalBlockStack.empty())
6695 return llvm::DebugLoc();
6697 llvm::MDNode *
Scope = LexicalBlockStack.back();
6698 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6699 getColumnNumber(Loc),
Scope);
6705 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6706 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6707 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6708 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6709 return llvm::DINode::FlagZero;
6714 bool SupportsDWARFv4Ext =
6715 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6716 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6717 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6719 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6720 return llvm::DINode::FlagZero;
6722 return llvm::DINode::FlagAllCallsDescribed;
6733 return DBuilder.createConstantValueExpression(
6734 Val.
getFloat().bitcastToAPInt().getZExtValue());
6739 llvm::APSInt
const &ValInt = Val.
getInt();
6740 std::optional<uint64_t> ValIntOpt;
6741 if (ValInt.isUnsigned())
6742 ValIntOpt = ValInt.tryZExtValue();
6743 else if (
auto tmp = ValInt.trySExtValue())
6746 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6749 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6754CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6756 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6757 CGF.CurLexicalScope =
this;
6759 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6764 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6777#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6779 Label = "__ubsan_check_" #Name; \
6783#undef SANITIZER_CHECK
6794#define SANITIZER(NAME, ID) \
6795 case SanitizerKind::SO_##ID: \
6796 Label = "__ubsan_check_" NAME; \
6798#include "clang/Basic/Sanitizers.def"
6800 llvm_unreachable(
"unexpected sanitizer kind");
6805 for (
unsigned int i = 0; i < Label.length(); i++)
6806 if (!std::isalpha(Label[i]))
6815 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6817 if (!DI || !CheckDebugLoc)
6818 return CheckDebugLoc;
6819 const auto &AnnotateDebugInfo =
6820 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6821 if (AnnotateDebugInfo.empty())
6822 return CheckDebugLoc;
6825 if (Ordinals.size() == 1)
6830 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6834 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6835 "ubsan_interface.h",
6837 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6840 return CheckDebugLoc;
6848 assert(!CGF->IsSanitizerScope);
6849 CGF->IsSanitizerScope =
true;
6853 assert(CGF->IsSanitizerScope);
6854 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.
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...
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 completeUnusedClass(const CXXRecordDecl &D)
void setInlinedAt(llvm::DILocation *InlinedAt)
Update the current inline scope.
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 * getInlinedAt() const
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
RecordDecl * getDefinitionOrSelf() const
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,...
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
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.