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"
76 if (TI.isAlignRequired())
103 auto const *RefExpr =
104 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
108 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
132 if (!llvm::isa<ParmVarDecl>(VD))
142 if (!Method->isImplicit() || !Method->isPropertyAccessor())
153 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
154 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
155 DBuilder(CGM.getModule()) {
160 assert(LexicalBlockStack.empty() &&
161 "Region stack mismatch, stack not empty!");
164void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
165 uint64_t Group, uint8_t Rank) {
166 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
170 Rank = std::min<uint8_t>(Rank, 7);
172 const llvm::DebugLoc &DL = I->getDebugLoc();
177 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
178 Group = DL->getAtomGroup();
179 Rank = DL->getAtomRank();
184 KeyInstructionsInfo.HighestEmittedAtom =
185 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
188 llvm::DILocation *NewDL = llvm::DILocation::get(
189 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
190 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
191 I->setDebugLoc(NewDL);
195 llvm::Value *Backup) {
197 KeyInstructionsInfo.CurrentAtom);
203 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
206 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
207 if (!SP || !SP->getKeyInstructionsEnabled())
210 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
212 llvm::Instruction *BackupI =
213 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
218 addInstSourceAtomMetadata(BackupI, Group, 2);
224 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
225 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
228 addInstSourceAtomMetadata(BackupI, Group, Rank++);
234 KeyInstructionsInfo.NextAtom = 1;
235 KeyInstructionsInfo.HighestEmittedAtom = 0;
236 KeyInstructionsInfo.CurrentAtom = 0;
242 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
243 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
251 DI->KeyInstructionsInfo.NextAtom =
252 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
253 DI->KeyInstructionsInfo.NextAtom);
255 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
261 init(TemporaryLocation);
268 init(TemporaryLocation, DefaultToEmpty);
272 bool DefaultToEmpty) {
279 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
281 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
284 if (TemporaryLocation.
isValid()) {
285 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
289 if (DefaultToEmpty) {
290 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
295 assert(!DI->LexicalBlockStack.empty());
296 CGF->Builder.SetCurrentDebugLocation(
297 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
298 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
308 if (!CGF.getDebugInfo()) {
312 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
316 if (Loc->getAtomGroup())
317 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
318 Loc->getColumn(), Loc->getScope(),
319 Loc->getInlinedAt(), Loc.isImplicitCode());
320 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
328 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
334 if (!CGF.getDebugInfo()) {
338 auto &DI = *CGF.getDebugInfo();
339 SavedLocation = DI.getLocation();
340 assert((DI.getInlinedAt() ==
341 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
342 "CGDebugInfo and IRBuilder are out of sync");
344 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
350 auto &DI = *CGF->getDebugInfo();
351 DI.EmitInlineFunctionEnd(CGF->Builder);
352 DI.EmitLocation(CGF->Builder, SavedLocation);
362 if (CurLoc != NewLoc) {
364 CurLocFile =
nullptr;
373 if (CGM.getCodeGenOpts().DebugColumnInfo)
375 CurLocFile = getOrCreateFile(CurLoc);
381 if (LexicalBlockStack.empty())
385 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
388 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
389 LexicalBlockStack.pop_back();
390 LexicalBlockStack.emplace_back(
391 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
394 LexicalBlockStack.pop_back();
395 LexicalBlockStack.emplace_back(
396 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
400llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
401 llvm::DIScope *Mod = getParentModuleOrNull(D);
406llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
411 auto I = RegionMap.find(Context);
412 if (I != RegionMap.end()) {
413 llvm::Metadata *
V = I->second;
414 return dyn_cast_or_null<llvm::DIScope>(
V);
418 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
419 return getOrCreateNamespace(NSDecl);
421 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
422 if (!RDecl->isDependentType())
428PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
429 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
436 if (CGM.getCodeGenOpts().EmitCodeView) {
437 PP.MSVCFormatting =
true;
447 PP.PrintAsCanonical =
true;
448 PP.UsePreferredNames =
false;
449 PP.AlwaysIncludeTypeForTemplateArgument =
true;
458StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
459 bool *NameIsSimplified) {
460 return internString(GetName(FD,
false, NameIsSimplified));
463StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
464 SmallString<256> MethodName;
465 llvm::raw_svector_ostream
OS(MethodName);
468 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
469 OS << OID->getName();
470 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
471 OS << OID->getName();
472 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
473 if (OC->IsClassExtension()) {
474 OS << OC->getClassInterface()->getName();
476 OS << OC->getIdentifier()->getNameStart() <<
'('
477 << OC->getIdentifier()->getNameStart() <<
')';
479 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
480 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
484 return internString(
OS.str());
487StringRef CGDebugInfo::getSelectorName(Selector S) {
491StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
492 bool *NameIsSimplified) {
495 return internString(GetName(RD,
false, NameIsSimplified));
501 return II->getName();
506 if (CGM.getCodeGenOpts().EmitCodeView) {
509 "Typedef should not be in another decl context!");
510 assert(D->getDeclName().getAsIdentifierInfo() &&
511 "Typedef was not named!");
512 return D->getDeclName().getAsIdentifierInfo()->getName();
515 if (CGM.getLangOpts().CPlusPlus) {
518 ASTContext &Context = CGM.getContext();
522 Name = DD->getName();
523 else if (
const TypedefNameDecl *TND =
527 Name = TND->getName();
530 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
531 if (CXXRD->isLambda())
533 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
536 SmallString<256> UnnamedType(
"<unnamed-type-");
539 return internString(UnnamedType);
547std::optional<llvm::DIFile::ChecksumKind>
548CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
551 if (!CGM.getCodeGenOpts().EmitCodeView &&
552 CGM.getCodeGenOpts().DwarfVersion < 5)
555 SourceManager &SM = CGM.getContext().getSourceManager();
556 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
560 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
561 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
563 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
564 return llvm::DIFile::CSK_MD5;
566 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
567 return llvm::DIFile::CSK_SHA1;
569 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
570 return llvm::DIFile::CSK_SHA256;
574 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
577std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
579 if (!CGM.getCodeGenOpts().EmbedSource)
582 bool SourceInvalid =
false;
591llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
592 SourceManager &SM = CGM.getContext().getSourceManager();
595 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
601 FileName = TheCU->getFile()->getFilename();
602 CSInfo = TheCU->getFile()->getChecksum();
605 if (Loc == CurLoc && CurLocFile)
612 FileName = TheCU->getFile()->getFilename();
620 auto It = DIFileCache.find(
FileName.data());
621 if (It != DIFileCache.end()) {
623 if (llvm::Metadata *
V = It->second)
628 SmallString<64> Checksum;
631 CSInfo = TheCU->getFile()->getChecksum();
633 std::optional<llvm::DIFile::ChecksumKind> CSKind =
634 computeChecksum(FID, Checksum);
636 CSInfo.emplace(*CSKind, Checksum);
642llvm::DIFile *CGDebugInfo::createFile(
644 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
645 std::optional<StringRef> Source) {
649 std::string CurDir =
remapDIPath(getCurrentDirname());
650 SmallString<128> DirBuf;
651 SmallString<128> FileBuf;
652 if (llvm::sys::path::is_absolute(RemappedFile)) {
655 auto FileIt = llvm::sys::path::begin(RemappedFile);
656 auto FileE = llvm::sys::path::end(RemappedFile);
657 auto CurDirIt = llvm::sys::path::begin(CurDir);
658 auto CurDirE = llvm::sys::path::end(CurDir);
659 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
660 llvm::sys::path::append(DirBuf, *CurDirIt);
661 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
667 for (; FileIt != FileE; ++FileIt)
668 llvm::sys::path::append(FileBuf, *FileIt);
673 if (!llvm::sys::path::is_absolute(
FileName))
677 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
678 DIFileCache[
FileName.data()].reset(F);
683 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
691 if (DebugLoc == CurLoc)
706 if (DebugLoc == CurLoc)
712StringRef CGDebugInfo::getCurrentDirname() {
720 assert(CGO.DwarfVersion <= 5);
722 llvm::dwarf::SourceLanguage LangTag;
725 LangTag = llvm::dwarf::DW_LANG_HLSL;
727 LangTag = llvm::dwarf::DW_LANG_HIP;
729 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
730 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
731 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
732 else if (LO.CPlusPlus14)
733 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
734 else if (LO.CPlusPlus11)
735 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
737 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
738 }
else if (LO.ObjC) {
739 LangTag = llvm::dwarf::DW_LANG_ObjC;
740 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
741 LangTag = llvm::dwarf::DW_LANG_OpenCL;
742 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
743 LangTag = llvm::dwarf::DW_LANG_C11;
745 LangTag = llvm::dwarf::DW_LANG_C99;
747 LangTag = llvm::dwarf::DW_LANG_C89;
753static llvm::DISourceLanguageName
762 llvm::dwarf::SourceLanguageName LangTag;
765 LangTag = llvm::dwarf::DW_LNAME_HLSL;
767 LangTag = llvm::dwarf::DW_LNAME_HIP;
768 }
else if (LO.ObjC) {
769 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
771 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
774 }
else if (LO.ObjC) {
775 LangTag = llvm::dwarf::DW_LNAME_ObjC;
776 }
else if (LO.OpenCL) {
777 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
779 LangTag = llvm::dwarf::DW_LNAME_C;
783 return llvm::DISourceLanguageName(LangTag, LangVersion);
786void CGDebugInfo::CreateCompileUnit() {
787 SmallString<64> Checksum;
788 std::optional<llvm::DIFile::ChecksumKind> CSKind;
789 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
799 SourceManager &SM = CGM.getContext().getSourceManager();
800 auto &CGO = CGM.getCodeGenOpts();
801 const LangOptions &LO = CGM.getLangOpts();
802 std::string MainFileName = CGO.MainFileName;
803 if (MainFileName.empty())
804 MainFileName =
"<stdin>";
810 std::string MainFileDir;
813 MainFileDir = std::string(MainFile->getDir().getName());
814 if (!llvm::sys::path::is_absolute(MainFileName)) {
815 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
816 llvm::sys::path::Style Style =
818 ? (CGM.getTarget().
getTriple().isOSWindows()
819 ? llvm::sys::path::Style::windows_backslash
820 : llvm::sys::path::Style::posix)
821 : llvm::sys::path::Style::native;
822 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
823 MainFileName = std::string(
824 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
831 if (MainFile->getName() == MainFileName &&
833 MainFile->getName().rsplit(
'.').second)
835 MainFileName = CGM.getModule().getName().str();
844 unsigned RuntimeVers = 0;
848 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
850 case llvm::codegenoptions::NoDebugInfo:
851 case llvm::codegenoptions::LocTrackingOnly:
852 EmissionKind = llvm::DICompileUnit::NoDebug;
854 case llvm::codegenoptions::DebugLineTablesOnly:
855 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
857 case llvm::codegenoptions::DebugDirectivesOnly:
858 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
860 case llvm::codegenoptions::DebugInfoConstructor:
861 case llvm::codegenoptions::LimitedDebugInfo:
862 case llvm::codegenoptions::FullDebugInfo:
863 case llvm::codegenoptions::UnusedTypeInfo:
864 EmissionKind = llvm::DICompileUnit::FullDebug;
869 auto &CGOpts = CGM.getCodeGenOpts();
875 CSInfo.emplace(*CSKind, Checksum);
876 const llvm::StringRef cwd =
877 !CGOpts.EmitCodeView ||
878 (CGOpts.EmitCodeView && CGOpts.CodeViewEmitCurrentWorkdir)
879 ? getCurrentDirname()
880 : llvm::StringRef(
"");
881 llvm::DIFile *CUFile =
885 StringRef Sysroot, SDK;
886 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
887 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
888 if (CGM.getCodeGenOpts().DebugRecordSysroot)
889 Sysroot = FullSysroot;
890 auto B = llvm::sys::path::rbegin(FullSysroot);
891 auto E = llvm::sys::path::rend(FullSysroot);
893 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
898 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
899 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
900 CGOpts.DebugNameTable);
901 if (CGM.getTarget().getTriple().isNVPTX())
902 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
903 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
904 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
907 TheCU = DBuilder.createCompileUnit(
909 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
910 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
911 CGOpts.PrepareForThinLTO,
912 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
913 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
914 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
917llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
921#define BUILTIN_TYPE(Id, SingletonId)
922#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
923#include "clang/AST/BuiltinTypes.def"
924 case BuiltinType::Dependent:
925 llvm_unreachable(
"Unexpected builtin type");
926 case BuiltinType::NullPtr:
927 return DBuilder.createNullPtrType();
928 case BuiltinType::Void:
930 case BuiltinType::ObjCClass:
933 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
934 "objc_class", TheCU, TheCU->getFile(), 0);
936 case BuiltinType::ObjCId: {
947 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
948 "objc_class", TheCU, TheCU->getFile(), 0);
950 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
952 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
954 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
955 (uint64_t)0, 0, llvm::DINode::FlagZero,
956 nullptr, llvm::DINodeArray());
958 DBuilder.replaceArrays(
959 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
960 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
961 llvm::DINode::FlagZero, ISATy)));
964 case BuiltinType::ObjCSel: {
966 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
967 "objc_selector", TheCU,
968 TheCU->getFile(), 0);
972#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
973 case BuiltinType::Id: \
974 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
976#include "clang/Basic/OpenCLImageTypes.def"
977 case BuiltinType::OCLSampler:
978 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
979 case BuiltinType::OCLEvent:
980 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
981 case BuiltinType::OCLClkEvent:
982 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
983 case BuiltinType::OCLQueue:
984 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
985 case BuiltinType::OCLReserveID:
986 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
987#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
988 case BuiltinType::Id: \
989 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
990#include "clang/Basic/OpenCLExtensionTypes.def"
991#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
992 case BuiltinType::Id: \
993 return getOrCreateStructPtrType(#Name, SingletonId);
994#include "clang/Basic/HLSLIntangibleTypes.def"
995#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
996 case BuiltinType::Id: \
997 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
998#include "clang/Basic/HLSLPackedTypes.def"
1000#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1001#include "clang/Basic/AArch64ACLETypes.def"
1003 if (BT->
getKind() == BuiltinType::MFloat8) {
1004 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1005 BTName = BT->
getName(CGM.getLangOpts());
1008 return DBuilder.createBasicType(BTName, Size, Encoding);
1010 ASTContext::BuiltinVectorTypeInfo Info =
1012 BT->
getKind() == BuiltinType::SveCount
1013 ? ASTContext::BuiltinVectorTypeInfo(
1014 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1016 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1023 "Unsupported number of vectors for svcount_t");
1025 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1026 llvm::Metadata *BitStride =
nullptr;
1027 if (BT->
getKind() == BuiltinType::SveBool) {
1028 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1029 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1030 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1031 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1033 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1036 llvm::Metadata *LowerBound, *UpperBound;
1037 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1038 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1039 if (Info.
EC.isScalable()) {
1040 unsigned NumElemsPerVG = NumElems / 2;
1041 SmallVector<uint64_t, 9> Expr(
1042 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1043 46, 0, llvm::dwarf::DW_OP_mul,
1044 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1045 UpperBound = DBuilder.createExpression(Expr);
1047 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1048 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1050 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1051 nullptr, LowerBound, UpperBound,
nullptr);
1052 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1053 llvm::DIType *ElemTy =
1054 getOrCreateType(Info.
ElementType, TheCU->getFile());
1056 return DBuilder.createVectorType( 0, Align, ElemTy,
1057 SubscriptArray, BitStride);
1061#define PPC_VECTOR_TYPE(Name, Id, size) \
1062 case BuiltinType::Id:
1063#include "clang/Basic/PPCTypes.def"
1066#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1067#include "clang/Basic/RISCVVTypes.def"
1069 ASTContext::BuiltinVectorTypeInfo Info =
1070 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1072 unsigned ElementCount = Info.
EC.getKnownMinValue();
1073 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1075 bool Fractional =
false;
1078 unsigned FixedSize = ElementCount * SEW;
1079 if (Info.
ElementType == CGM.getContext().BoolTy) {
1082 }
else if (FixedSize < 64) {
1085 LMUL = 64 / FixedSize;
1087 LMUL = FixedSize / 64;
1091 SmallVector<uint64_t, 12> Expr(
1095 {llvm::dwarf::DW_OP_bregx,
1098 llvm::dwarf::DW_OP_constu,
1100 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1102 Expr.push_back(llvm::dwarf::DW_OP_div);
1104 Expr.push_back(llvm::dwarf::DW_OP_mul);
1107 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1109 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1112 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1113 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1114 auto *UpperBound = DBuilder.createExpression(Expr);
1115 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1116 nullptr, LowerBound, UpperBound,
nullptr);
1117 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1118 llvm::DIType *ElemTy =
1119 getOrCreateType(Info.
ElementType, TheCU->getFile());
1122 return DBuilder.createVectorType(0, Align, ElemTy,
1126#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1127 case BuiltinType::Id: { \
1130 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1131 MangledName, TheCU, TheCU->getFile(), 0); \
1132 return SingletonId; \
1134#include "clang/Basic/WebAssemblyReferenceTypes.def"
1135#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1136 case BuiltinType::Id: { \
1139 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1140 TheCU, TheCU->getFile(), 0); \
1141 return SingletonId; \
1143#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1144 case BuiltinType::Id: { \
1147 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1148 return SingletonId; \
1150#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1151 case BuiltinType::Id: { \
1154 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1155 return SingletonId; \
1157#include "clang/Basic/AMDGPUTypes.def"
1158#define SPIRV_TYPE(Name, Id, SingletonId) \
1159 case BuiltinType::Id: \
1160 return getOrCreateStructPtrType(Name, SingletonId);
1161#include "clang/Basic/SPIRVTypes.def"
1162 case BuiltinType::UChar:
1163 case BuiltinType::Char_U:
1164 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1166 case BuiltinType::Char_S:
1167 case BuiltinType::SChar:
1168 Encoding = llvm::dwarf::DW_ATE_signed_char;
1170 case BuiltinType::Char8:
1171 case BuiltinType::Char16:
1172 case BuiltinType::Char32:
1173 Encoding = llvm::dwarf::DW_ATE_UTF;
1175 case BuiltinType::UShort:
1176 case BuiltinType::UInt:
1177 case BuiltinType::UInt128:
1178 case BuiltinType::ULong:
1179 case BuiltinType::WChar_U:
1180 case BuiltinType::ULongLong:
1181 Encoding = llvm::dwarf::DW_ATE_unsigned;
1183 case BuiltinType::Short:
1184 case BuiltinType::Int:
1185 case BuiltinType::Int128:
1186 case BuiltinType::Long:
1187 case BuiltinType::WChar_S:
1188 case BuiltinType::LongLong:
1189 Encoding = llvm::dwarf::DW_ATE_signed;
1191 case BuiltinType::Bool:
1192 Encoding = llvm::dwarf::DW_ATE_boolean;
1194 case BuiltinType::Half:
1195 case BuiltinType::Float:
1196 case BuiltinType::LongDouble:
1197 case BuiltinType::Float16:
1198 case BuiltinType::BFloat16:
1199 case BuiltinType::Float128:
1200 case BuiltinType::Double:
1201 case BuiltinType::Ibm128:
1207 Encoding = llvm::dwarf::DW_ATE_float;
1209 case BuiltinType::ShortAccum:
1210 case BuiltinType::Accum:
1211 case BuiltinType::LongAccum:
1212 case BuiltinType::ShortFract:
1213 case BuiltinType::Fract:
1214 case BuiltinType::LongFract:
1215 case BuiltinType::SatShortFract:
1216 case BuiltinType::SatFract:
1217 case BuiltinType::SatLongFract:
1218 case BuiltinType::SatShortAccum:
1219 case BuiltinType::SatAccum:
1220 case BuiltinType::SatLongAccum:
1221 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1223 case BuiltinType::UShortAccum:
1224 case BuiltinType::UAccum:
1225 case BuiltinType::ULongAccum:
1226 case BuiltinType::UShortFract:
1227 case BuiltinType::UFract:
1228 case BuiltinType::ULongFract:
1229 case BuiltinType::SatUShortAccum:
1230 case BuiltinType::SatUAccum:
1231 case BuiltinType::SatULongAccum:
1232 case BuiltinType::SatUShortFract:
1233 case BuiltinType::SatUFract:
1234 case BuiltinType::SatULongFract:
1235 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1237 case BuiltinType::MetaInfo:
1238 llvm_unreachable(
"std::meta::info is consteval-only type");
1241 BTName = BT->
getName(CGM.getLangOpts());
1244 return DBuilder.createBasicType(BTName, Size, Encoding);
1247llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1248 SmallString<32> Name;
1249 llvm::raw_svector_ostream
OS(Name);
1250 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1253 ? llvm::dwarf::DW_ATE_unsigned
1254 : llvm::dwarf::DW_ATE_signed;
1255 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1256 Encoding, llvm::DINode::FlagZero, 0,
1260llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1262 return getOrCreateType(Ty->getUnderlyingType(), U);
1265llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1267 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1269 Encoding = llvm::dwarf::DW_ATE_lo_user;
1272 return DBuilder.createBasicType(
"complex", Size, Encoding);
1286 return llvm::dwarf::DW_TAG_const_type;
1290 return llvm::dwarf::DW_TAG_volatile_type;
1294 return llvm::dwarf::DW_TAG_restrict_type;
1296 return (llvm::dwarf::Tag)0;
1299llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1300 llvm::DIFile *Unit) {
1301 QualifierCollector Qc;
1315 bool AuthenticatesNullValues =
1318 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1319 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1320 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1321 ExtraDiscr, IsaPointer,
1322 AuthenticatesNullValues);
1324 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1325 return getOrCreateType(QualType(
T, 0), Unit);
1329 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1333 return DBuilder.createQualifiedType(Tag, FromTy);
1336llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1337 llvm::DIFile *Unit) {
1346 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1351 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1357 return DBuilder.createQualifiedType(Tag, FromTy);
1360llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1361 llvm::DIFile *Unit) {
1367 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1369 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1373llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1374 llvm::DIFile *Unit) {
1375 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1381 case llvm::dwarf::DW_LANG_C_plus_plus:
1382 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1383 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1384 case llvm::dwarf::DW_LANG_HIP:
1386 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1396 case llvm::dwarf::DW_LNAME_C_plus_plus:
1397 case llvm::dwarf::DW_LNAME_HIP:
1399 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1410 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1411 SourceLang.hasVersionedName())
1413 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1417 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1443 llvm::DICompileUnit *TheCU) {
1461 llvm::DICompileUnit *TheCU) {
1467 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1469 if (RD->isDynamicClass() &&
1475 llvm::raw_svector_ostream Out(Identifier);
1482 llvm::dwarf::Tag Tag;
1484 Tag = llvm::dwarf::DW_TAG_structure_type;
1486 Tag = llvm::dwarf::DW_TAG_union_type;
1491 Tag = llvm::dwarf::DW_TAG_class_type;
1496llvm::DICompositeType *
1497CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1498 llvm::DIScope *Ctx) {
1500 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1502 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1503 const unsigned Line =
1505 StringRef RDName = getClassName(RD);
1512 Size = CGM.getContext().getTypeSize(Ty);
1514 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1519 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1520 if (!CXXRD->hasDefinition() ||
1521 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1522 Flags |= llvm::DINode::FlagNonTrivial;
1525 SmallString<256> Identifier;
1527 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1529 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1532 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1533 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1534 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1535 CollectCXXTemplateParams(TSpecial, DefUnit));
1536 ReplaceMap.emplace_back(
1537 std::piecewise_construct, std::make_tuple(Ty),
1538 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1542llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1545 llvm::DIFile *Unit) {
1550 std::optional<unsigned> DWARFAddressSpace =
1551 CGM.getTarget().getDWARFAddressSpace(
1552 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1554 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1555 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1556 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1557 Size, Align, DWARFAddressSpace);
1559 SmallVector<llvm::Metadata *, 4> Annots;
1560 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1562 llvm::DINodeArray Annotations =
nullptr;
1563 if (Annots.size() > 0)
1564 Annotations = DBuilder.getOrCreateArray(Annots);
1565 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1566 Align, DWARFAddressSpace, StringRef(),
1571llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1572 llvm::DIType *&
Cache) {
1575 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1576 TheCU, TheCU->getFile(), 0);
1577 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1578 Cache = DBuilder.createPointerType(
Cache, Size);
1582uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1583 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1584 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1594 if (CGM.getLangOpts().OpenCL) {
1595 FType = CGM.getContext().IntTy;
1596 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1597 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1599 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1600 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1601 FType = CGM.getContext().IntTy;
1602 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1603 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1605 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1606 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1607 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1608 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1609 EltTys.push_back(DBuilder.createMemberType(
1610 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1611 FieldOffset, llvm::DINode::FlagZero, DescTy));
1612 FieldOffset += FieldSize;
1618llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1619 llvm::DIFile *Unit) {
1620 SmallVector<llvm::Metadata *, 8> EltTys;
1623 llvm::DINodeArray Elements;
1626 FType = CGM.getContext().UnsignedLongTy;
1627 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1628 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1630 Elements = DBuilder.getOrCreateArray(EltTys);
1633 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1636 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1637 FieldOffset, 0, Flags,
nullptr, Elements);
1642 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1644 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1647 Elements = DBuilder.getOrCreateArray(EltTys);
1653 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1654 Flags,
nullptr, Elements);
1656 return DBuilder.createPointerType(EltTy, Size);
1659static llvm::SmallVector<TemplateArgument>
1661 assert(Ty->isTypeAlias());
1670 ArrayRef SubstArgs = Ty->template_arguments();
1673 if (Param->isParameterPack()) {
1682 if (SubstArgs.empty()) {
1691 SpecArgs.push_back(SubstArgs.front());
1692 SubstArgs = SubstArgs.drop_front();
1697llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1698 llvm::DIFile *Unit) {
1699 assert(Ty->isTypeAlias());
1700 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1702 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1710 SmallString<128> NS;
1711 llvm::raw_svector_ostream
OS(NS);
1713 auto PP = getPrintingPolicy();
1716 SourceLocation Loc =
AliasDecl->getLocation();
1718 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1719 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1728 llvm::raw_string_ostream
OS(Name);
1730 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1731 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1732 !HasReconstitutableArgs(Args.Args))
1733 printTemplateArgumentList(OS, Args.Args, PP);
1735 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1736 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1737 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1741 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1743 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1760 return llvm::DINode::FlagZero;
1764 return llvm::DINode::FlagPrivate;
1766 return llvm::DINode::FlagProtected;
1768 return llvm::DINode::FlagPublic;
1770 return llvm::DINode::FlagZero;
1772 llvm_unreachable(
"unexpected access enumerator");
1775llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1776 llvm::DIFile *Unit) {
1777 llvm::DIType *Underlying =
1793 SmallVector<llvm::Metadata *, 4> Annots;
1794 llvm::DINodeArray Annotations;
1796 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1797 if (!Annots.empty())
1798 Annotations = DBuilder.getOrCreateArray(Annots);
1800 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1805 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1806 getOrCreateFile(Loc), getLineNumber(Loc),
1807 getDeclContextDescriptor(Ty->
getDecl()), Align,
1808 Flags, Annotations);
1816 if (
T.isSPIROrSPIRV())
1817 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1822 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1824 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1826 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1828 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1830 return llvm::dwarf::DW_CC_BORLAND_pascal;
1832 return llvm::dwarf::DW_CC_LLVM_Win64;
1834 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1838 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1840 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1842 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1844 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1846 return llvm::dwarf::DW_CC_LLVM_Swift;
1848 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1850 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1852 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1854 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1856 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1858 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1860 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1861#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1875 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1881 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1883 Flags |= llvm::DINode::FlagLValueReference;
1885 Flags |= llvm::DINode::FlagRValueReference;
1889llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1890 llvm::DIFile *Unit) {
1891 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1893 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1899 SmallVector<llvm::Metadata *, 16> EltTys;
1902 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1904 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1908 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1911 for (
const QualType &ParamType : FPT->param_types())
1912 EltTys.push_back(getOrCreateType(ParamType, Unit));
1913 if (FPT->isVariadic())
1914 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1917 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1918 llvm::DIType *F = DBuilder.createSubroutineType(
1919 EltTypeArray, Flags,
1924llvm::DIDerivedType *
1925CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1926 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1927 StringRef Name = BitFieldDecl->
getName();
1928 QualType Ty = BitFieldDecl->
getType();
1929 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1932 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1933 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1936 llvm::DIFile *
File = getOrCreateFile(Loc);
1937 unsigned Line = getLineNumber(Loc);
1939 const CGBitFieldInfo &BitFieldInfo =
1940 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1942 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1949 if (CGM.getDataLayout().isBigEndian())
1951 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1953 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1954 return DBuilder.createBitFieldMemberType(
1955 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1956 Flags, DebugType, Annotations);
1959llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1960 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1961 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1963 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1988 if (PreviousFieldsDI.empty())
1992 auto *PreviousMDEntry =
1993 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1994 auto *PreviousMDField =
1995 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1996 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1997 PreviousMDField->getSizeInBits() == 0)
2001 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
2003 assert(PreviousBitfield->isBitField());
2005 if (!PreviousBitfield->isZeroLengthBitField())
2008 QualType Ty = PreviousBitfield->getType();
2009 SourceLocation Loc = PreviousBitfield->getLocation();
2010 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2011 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
2012 llvm::DIScope *RecordTy = BitFieldDI->getScope();
2014 llvm::DIFile *
File = getOrCreateFile(Loc);
2015 unsigned Line = getLineNumber(Loc);
2021 llvm::DINode::DIFlags Flags =
2023 llvm::DINodeArray Annotations =
2024 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2025 return DBuilder.createBitFieldMemberType(
2026 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2027 Flags, DebugType, Annotations);
2030llvm::DIType *CGDebugInfo::createFieldType(
2032 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2033 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2034 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2037 llvm::DIFile *file = getOrCreateFile(loc);
2038 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2041 auto Align = AlignInBits;
2042 if (!
type->isIncompleteArrayType()) {
2043 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2044 SizeInBits = TI.
Width;
2050 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2051 offsetInBits, flags, debugType, Annotations);
2055CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2056 llvm::DIFile *FileScope) {
2060 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2063 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2064 SP = DBuilder.createFunction(
2065 FileScope, FuncName, StringRef(),
2066 FileScope, 0, DIFnTy,
2068 llvm::DINode::FlagArtificial,
2069 llvm::DISubprogram::SPFlagDefinition,
2070 nullptr,
nullptr,
nullptr,
2071 nullptr, StringRef(),
2072 CGM.getCodeGenOpts().DebugKeyInstructions);
2079CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2081 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2083 assert(
Capture.capturesVariable());
2085 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2086 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2088 return CaptureDecl->
getName();
2091void CGDebugInfo::CollectRecordLambdaFields(
2092 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2093 llvm::DIType *RecordTy) {
2098 unsigned fieldno = 0;
2101 I != E; ++I, ++Field, ++fieldno) {
2102 const LambdaCapture &
Capture = *I;
2104 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2106 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2116 Loc =
Field->getLocation();
2117 }
else if (
Capture.capturesVariable()) {
2120 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2121 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2128 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2130 FieldIndexCache[*
Field] = elements.size();
2131 elements.push_back(createFieldType(
2133 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2139template <
typename T>
2140static llvm::Constant *
2151 return llvm::ConstantDataArray::get(Ctx, Vals);
2164 const QualType ElemQTy = ArrayTy->getElementType();
2171 switch (ElemBitWidth) {
2187llvm::DIDerivedType *
2188CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2189 const RecordDecl *RD) {
2193 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2194 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2196 unsigned LineNumber = getLineNumber(Var->
getLocation());
2197 StringRef VName = Var->
getName();
2201 llvm::Constant *
C =
nullptr;
2206 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2207 if (
Value->isFloat())
2208 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2209 if (
Value->isArray())
2215 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2216 ? llvm::dwarf::DW_TAG_variable
2217 : llvm::dwarf::DW_TAG_member;
2219 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2220 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2225void CGDebugInfo::CollectRecordNormalField(
2226 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2227 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2228 const RecordDecl *RD) {
2233 if (
name.empty() && !
type->isRecordType())
2236 llvm::DIType *FieldType;
2238 llvm::DIDerivedType *BitFieldType;
2239 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2240 if (llvm::DIType *Separator =
2241 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2242 elements.push_back(Separator);
2245 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2248 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2251 FieldIndexCache[field] = elements.size();
2252 elements.push_back(FieldType);
2255void CGDebugInfo::CollectRecordNestedType(
2256 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2257 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2264 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2265 elements.push_back(nestedType);
2268void CGDebugInfo::CollectRecordFields(
2269 const RecordDecl *record, llvm::DIFile *tunit,
2270 SmallVectorImpl<llvm::Metadata *> &elements,
2271 llvm::DICompositeType *RecordTy) {
2272 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2274 if (CXXDecl && CXXDecl->
isLambda())
2275 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2277 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2280 unsigned fieldNo = 0;
2284 for (
const auto *I : record->
decls())
2285 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2286 if (
V->hasAttr<NoDebugAttr>())
2291 if (CGM.getCodeGenOpts().EmitCodeView &&
2299 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2300 if (MI != StaticDataMemberCache.end()) {
2301 assert(MI->second &&
2302 "Static data member declaration should still exist");
2303 elements.push_back(MI->second);
2305 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2306 elements.push_back(Field);
2308 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2309 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2310 elements, RecordTy, record);
2314 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2317 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2322 if (!nestedType->isImplicit() &&
2323 nestedType->getDeclContext() == record)
2324 CollectRecordNestedType(nestedType, elements);
2330llvm::DISubroutineType *
2331CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2332 llvm::DIFile *Unit) {
2333 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2335 return cast_or_null<llvm::DISubroutineType>(
2336 getOrCreateType(QualType(
Func, 0), Unit));
2339 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2340 ThisType =
Method->getThisType();
2342 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2345llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2346 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2347 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2349 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2352llvm::DISubroutineType *
2353CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2354 const FunctionProtoType *
Func,
2355 llvm::DIFile *Unit,
bool SkipFirst) {
2356 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2371 getOrCreateType(CGM.getContext().getFunctionType(
2372 Func->getReturnType(),
Func->getParamTypes(), EPI),
2374 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2375 assert(Args.size() &&
"Invalid number of arguments!");
2377 SmallVector<llvm::Metadata *, 16> Elts;
2380 Elts.push_back(Args[0]);
2382 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2386 if (!HasExplicitObjectParameter) {
2387 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2390 DBuilder.createObjectPointerType(ThisPtrType,
true);
2391 Elts.push_back(ThisPtrType);
2395 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2396 Elts.push_back(Args[i]);
2399 if (HasExplicitObjectParameter) {
2400 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2401 "Expected at least return type and object parameter.");
2402 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2405 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2407 return DBuilder.createSubroutineType(
2408 EltTypeArray, OriginalFunc->getFlags(),
2415 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2423CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2426 const bool IsCtorOrDtor =
2429 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2436 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2439 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2442 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2445 return CGM.getMangledName(
Method);
2448bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2451 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2454llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2455 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2458 StringRef MethodName = getFunctionName(
Method);
2459 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2461 StringRef MethodLinkageName;
2468 MethodLinkageName = GetMethodLinkageName(
Method);
2471 llvm::DIFile *MethodDefUnit =
nullptr;
2472 unsigned MethodLine = 0;
2473 if (!
Method->isImplicit()) {
2474 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2475 MethodLine = getLineNumber(
Method->getLocation());
2479 llvm::DIType *ContainingType =
nullptr;
2480 unsigned VIndex = 0;
2481 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2482 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2483 int ThisAdjustment = 0;
2486 if (
Method->isPureVirtual())
2487 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2489 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2491 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2495 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2499 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2502 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2503 CGM.getContext().getLangOpts())
2507 MethodVFTableLocation ML =
2508 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2516 if (
Method->size_overridden_methods() == 0)
2517 Flags |= llvm::DINode::FlagIntroducedVirtual;
2522 ThisAdjustment = CGM.getCXXABI()
2523 .getVirtualFunctionPrologueThisAdjustment(GD)
2526 ContainingType = RecordTy;
2529 if (
Method->getCanonicalDecl()->isDeleted())
2530 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2532 if (
Method->isNoReturn())
2533 Flags |= llvm::DINode::FlagNoReturn;
2536 Flags |= llvm::DINode::FlagStaticMember;
2537 if (
Method->isImplicit())
2538 Flags |= llvm::DINode::FlagArtificial;
2540 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2541 if (CXXC->isExplicit())
2542 Flags |= llvm::DINode::FlagExplicit;
2543 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2544 if (CXXC->isExplicit())
2545 Flags |= llvm::DINode::FlagExplicit;
2547 if (
Method->hasPrototype())
2548 Flags |= llvm::DINode::FlagPrototyped;
2550 Flags |= llvm::DINode::FlagLValueReference;
2552 Flags |= llvm::DINode::FlagRValueReference;
2553 if (!
Method->isExternallyVisible())
2554 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2555 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2556 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2561 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2562 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2563 if (
const auto *Def =
2564 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2565 Def && !Def->isDelegatingConstructor()) {
2571 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2572 llvm::DISubprogram *SP = DBuilder.createMethod(
2573 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2574 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2575 TParamsArray.get(),
nullptr,
2576 CGM.getCodeGenOpts().DebugKeyInstructions);
2578 SPCache[
Method->getCanonicalDecl()].reset(SP);
2583void CGDebugInfo::CollectCXXMemberFunctions(
2584 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2585 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2590 for (
const auto *I : RD->
decls()) {
2591 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2605 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2614 auto MI = SPCache.find(
Method->getCanonicalDecl());
2615 EltTys.push_back(MI == SPCache.end()
2616 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2617 :
static_cast<llvm::Metadata *
>(MI->second));
2621void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2622 SmallVectorImpl<llvm::Metadata *> &EltTys,
2623 llvm::DIType *RecordTy) {
2624 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2625 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2626 llvm::DINode::FlagZero);
2630 if (CGM.getCodeGenOpts().EmitCodeView) {
2631 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2632 llvm::DINode::FlagIndirectVirtualBase);
2636void CGDebugInfo::CollectCXXBasesAux(
2637 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2638 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2640 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2641 llvm::DINode::DIFlags StartingFlags) {
2642 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2643 for (
const auto &BI : Bases) {
2646 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2648 if (!SeenTypes.insert(Base).second)
2650 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2651 llvm::DINode::DIFlags BFlags = StartingFlags;
2655 if (BI.isVirtual()) {
2656 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2659 BaseOffset = 0 - CGM.getItaniumVTableContext()
2660 .getVirtualBaseOffsetOffset(RD, Base)
2666 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2667 VBPtrOffset = CGM.getContext()
2668 .getASTRecordLayout(RD)
2672 BFlags |= llvm::DINode::FlagVirtual;
2679 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2680 VBPtrOffset, BFlags);
2681 EltTys.push_back(DTy);
2686CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2687 llvm::DIFile *Unit) {
2689 return llvm::DINodeArray();
2690 TemplateArgs &Args = *OArgs;
2691 SmallVector<llvm::Metadata *, 16> TemplateParams;
2692 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2693 const TemplateArgument &TA = Args.Args[i];
2697 Name = Args.TList->getParam(i)->getName();
2701 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2702 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2703 TheCU, Name, TTy, defaultParameter));
2708 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2709 TheCU, Name, TTy, defaultParameter,
2710 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2715 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2716 llvm::Constant *
V =
nullptr;
2719 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2720 !D->
hasAttr<CUDADeviceAttr>()) {
2723 if (
const auto *VD = dyn_cast<VarDecl>(D))
2724 V = CGM.GetAddrOfGlobalVar(VD);
2727 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2728 MD && MD->isImplicitObjectMemberFunction())
2729 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2730 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2731 V = CGM.GetAddrOfFunction(FD);
2734 else if (
const auto *MPT =
2735 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2739 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2741 CGM.getContext().toCharUnitsFromBits((
int64_t)fieldOffset);
2742 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2743 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2744 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2745 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2747 V = ConstantEmitter(CGM).emitAbstract(
2748 SourceLocation(), TPO->getValue(), TPO->getType());
2750 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2752 assert(
V &&
"Failed to find template parameter pointer");
2753 V =
V->stripPointerCasts();
2755 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2756 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2760 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2761 llvm::Constant *
V =
nullptr;
2764 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2770 if (MPT->isMemberDataPointer())
2771 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2773 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2774 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2775 TheCU, Name, TTy, defaultParameter,
V));
2779 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2780 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2782 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2783 TheCU, Name, TTy, defaultParameter,
V));
2786 std::string QualName;
2787 llvm::raw_string_ostream
OS(QualName);
2789 OS, getPrintingPolicy());
2790 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2791 TheCU, Name,
nullptr, QualName, defaultParameter));
2795 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2796 TheCU, Name,
nullptr,
2803 T = CGM.getContext().getLValueReferenceType(
T);
2804 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2805 assert(
V &&
"Expression in template argument isn't constant");
2806 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2807 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2808 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2814 "These argument types shouldn't exist in concrete types");
2817 return DBuilder.getOrCreateArray(TemplateParams);
2820std::optional<CGDebugInfo::TemplateArgs>
2821CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2829 return std::nullopt;
2831std::optional<CGDebugInfo::TemplateArgs>
2832CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2836 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2838 return std::nullopt;
2839 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2840 const TemplateParameterList *TList =
T->getTemplateParameters();
2841 auto TA = TS->getTemplateArgs().asArray();
2842 return {{TList, TA}};
2844std::optional<CGDebugInfo::TemplateArgs>
2845CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2846 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2850 TemplateParameterList *TPList =
2851 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2852 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2853 return {{TPList, TAList.
asArray()}};
2855 return std::nullopt;
2859CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2860 llvm::DIFile *Unit) {
2861 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2864llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2865 llvm::DIFile *Unit) {
2866 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2869llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2870 llvm::DIFile *Unit) {
2871 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2874void CGDebugInfo::CollectBTFDeclTagAnnotations(
2875 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2877 llvm::Metadata *Ops[2] = {
2878 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2879 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2880 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2884llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2885 if (!D->
hasAttr<BTFDeclTagAttr>())
2888 SmallVector<llvm::Metadata *, 4> Annotations;
2889 CollectBTFDeclTagAnnotations(D, Annotations);
2890 return DBuilder.getOrCreateArray(Annotations);
2893void CGDebugInfo::CollectBTFTypeTagAnnotations(
2894 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2895 const BTFTagAttributedType *BTFAttrTy;
2897 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2899 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2902 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2904 llvm::Metadata *Ops[2] = {
2905 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2906 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2907 Annotations.insert(Annotations.begin(),
2908 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2910 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2914llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2916 return VTablePtrType;
2918 ASTContext &Context = CGM.getContext();
2921 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2922 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2923 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2925 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2926 std::optional<unsigned> DWARFAddressSpace =
2927 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2929 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2930 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2931 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2932 return VTablePtrType;
2935StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2947 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2949 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2959 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2960 VTable->isDeclarationForLinker())
2964 StringRef SymbolName =
"__clang_vtable";
2966 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2975 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2977 llvm::DIFile *Unit = getOrCreateFile(Loc);
2978 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2980 llvm::DINode::FlagArtificial;
2981 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2982 ? llvm::dwarf::DW_TAG_variable
2983 : llvm::dwarf::DW_TAG_member;
2984 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2985 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2989 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2993 llvm::DIGlobalVariableExpression *GVE =
2994 DBuilder.createGlobalVariableExpression(
2995 TheCU, SymbolName, VTable->getName(), Unit, 0,
2996 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2997 true,
nullptr, DT,
nullptr,
2999 VTable->addDebugInfo(GVE);
3002StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
3004 llvm::Function *InitFn) {
3009 return InitFn->getName();
3019 llvm::raw_svector_ostream OS(QualifiedGV);
3021 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3023 std::swap(Quals, GVName);
3027 llvm::raw_svector_ostream OS(InitName);
3029 OS << Quals <<
"::";
3034 llvm_unreachable(
"not an initializer");
3036 OS <<
"`dynamic initializer for '";
3039 OS <<
"`dynamic atexit destructor for '";
3046 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3047 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3048 getPrintingPolicy());
3053 return internString(
OS.str());
3056void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3057 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3066 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3073 llvm::DIType *VPtrTy =
nullptr;
3074 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3075 CGM.getTarget().getCXXABI().isMicrosoft();
3076 if (NeedVTableShape) {
3078 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3079 const VTableLayout &VFTLayout =
3080 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3081 unsigned VSlotCount =
3083 unsigned VTableWidth = PtrWidth * VSlotCount;
3084 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3085 std::optional<unsigned> DWARFAddressSpace =
3086 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3089 llvm::DIType *VTableType = DBuilder.createPointerType(
3090 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3091 EltTys.push_back(VTableType);
3094 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3102 VPtrTy = getOrCreateVTablePtrType(Unit);
3104 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3105 llvm::DIType *VPtrMember =
3106 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3107 llvm::DINode::FlagArtificial, VPtrTy);
3108 EltTys.push_back(VPtrMember);
3111std::pair<llvm::DIType *, unsigned>
3116 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3123 auto I = FieldIndexCache.find(Field);
3124 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3125 return {
T, I->second};
3135 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3136 assert(!D.
isNull() &&
"null type");
3137 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3138 assert(
T &&
"could not create debug info for type");
3147 if (CGM.getCodeGenOpts().getDebugInfo() <=
3148 llvm::codegenoptions::DebugLineTablesOnly)
3152 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3154 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3156 CI->setMetadata(
"heapallocsite", node);
3160 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3162 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3164 auto I = TypeCache.find(TyPtr);
3167 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3168 assert(!Res->isForwardDecl());
3169 TypeCache[TyPtr].reset(Res);
3173 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3174 !CGM.getLangOpts().CPlusPlus)
3180 if (RD->
hasAttr<DLLImportAttr>())
3183 if (MD->hasAttr<DLLImportAttr>())
3196 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3206 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3207 Explicit = TD->isExplicitInstantiationOrSpecialization();
3211 if (CXXDecl->
fields().empty())
3221 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3222 if (CXXRD->isDynamicClass() &&
3223 CGM.getVTableLinkage(CXXRD) ==
3224 llvm::GlobalValue::AvailableExternallyLinkage &&
3235 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3237 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3239 auto I = TypeCache.find(TyPtr);
3246 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3247 assert(!Res->isForwardDecl());
3248 TypeCache[TyPtr].reset(Res);
3255 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3256 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3283 bool HasNonDeletedCtor =
false;
3285 if (Ctor->isCopyOrMoveConstructor())
3292 if (CtorDef->isDelegatingConstructor())
3296 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3299 if (!Ctor->isDeleted())
3300 HasNonDeletedCtor =
true;
3302 return HasNonDeletedCtor;
3318 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3321 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3322 RD->
hasAttr<StandaloneDebugAttr>())
3325 if (!LangOpts.CPlusPlus)
3331 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3347 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3348 Spec = SD->getSpecializationKind();
3357 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3368 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3369 llvm::DIType *
T = getTypeOrNull(Ty);
3370 if (
T &&
T->isForwardDecl())
3374llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3376 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3380 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3384 auto [Def, Pref] = CreateTypeDefinition(Ty);
3386 return Pref ? Pref : Def;
3389llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3390 llvm::DIFile *Unit) {
3394 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3398 return getOrCreateType(PNA->getTypedefType(), Unit);
3425 const auto *RT = QT->
getAs<RecordType>();
3429 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3430 if (!CRD || !CRD->hasDefinition())
3435 assert(CRD->isStandardLayout());
3441std::pair<llvm::DIType *, llvm::DIType *>
3442CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3446 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3454 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3458 return {FwdDecl,
nullptr};
3460 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3461 CollectContainingType(CXXDecl, FwdDecl);
3464 LexicalBlockStack.emplace_back(&*FwdDecl);
3465 RegionMap[RD].reset(FwdDecl);
3468 SmallVector<llvm::Metadata *, 16> EltTys;
3475 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3477 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3478 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3482 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3483 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3484 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3486 LexicalBlockStack.pop_back();
3487 RegionMap.erase(RD);
3489 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3490 DBuilder.replaceArrays(FwdDecl, Elements);
3492 if (FwdDecl->isTemporary())
3494 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3496 RegionMap[RD].reset(FwdDecl);
3498 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3513 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3514 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3515 return {FwdDecl, PrefDI};
3517 return {FwdDecl,
nullptr};
3520llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3521 llvm::DIFile *Unit) {
3523 return getOrCreateType(Ty->getBaseType(), Unit);
3526llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3527 llvm::DIFile *Unit) {
3529 SourceLocation Loc = Ty->getDecl()->getLocation();
3532 return DBuilder.createTypedef(
3533 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3534 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3535 getDeclContextDescriptor(Ty->getDecl()));
3562llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3563 llvm::DIFile *Unit) {
3568 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3569 TheCU->getSourceLanguage().getUnversionedName());
3574 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3575 !
ID->getImplementation())
3576 return DBuilder.createForwardDecl(
3577 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3578 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3581 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3582 unsigned Line = getLineNumber(
ID->getLocation());
3586 ObjCInterfaceDecl *Def =
ID->getDefinition();
3588 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3589 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3590 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3591 DefUnit,
Line, RuntimeLang);
3592 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3596 return CreateTypeDefinition(Ty, Unit);
3599llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3600 bool CreateSkeletonCU) {
3605 auto ModRef = ModuleCache.find(M);
3606 if (ModRef != ModuleCache.end())
3610 SmallString<128> ConfigMacros;
3612 llvm::raw_svector_ostream
OS(ConfigMacros);
3613 const auto &PPOpts = CGM.getPreprocessorOpts();
3616 for (
auto &M : PPOpts.Macros) {
3619 const std::string &
Macro = M.first;
3620 bool Undef = M.second;
3621 OS <<
"\"-" << (Undef ?
'U' :
'D');
3622 for (
char c :
Macro)
3637 bool IsRootModule = M ? !M->
Parent :
true;
3641 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3642 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3643 "clang module without ASTFile must be specified by -fmodule-name");
3646 auto RemapPath = [
this](StringRef Path) -> std::string {
3648 StringRef Relative(Remapped);
3649 StringRef CompDir = TheCU->getDirectory();
3650 if (CompDir.empty())
3653 if (Relative.consume_front(CompDir))
3654 Relative.consume_front(llvm::sys::path::get_separator());
3656 return Relative.str();
3659 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3666 Signature = ModSig.truncatedValue();
3670 llvm::DIBuilder DIB(CGM.getModule());
3672 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3673 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3674 PCM = getCurrentDirname();
3678 llvm::sys::path::append(PCM, Mod.
getASTFile());
3679 DIB.createCompileUnit(
3680 TheCU->getSourceLanguage(),
3683 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3684 llvm::DICompileUnit::FullDebug, Signature);
3688 llvm::DIModule *Parent =
3690 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3692 StringRef IncludePath = Mod.
getPath();
3693 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3694 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3695 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3698 llvm::DIModule *DIMod =
3699 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3700 RemapPath(IncludePath));
3701 ModuleCache[M].reset(DIMod);
3705llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3706 llvm::DIFile *Unit) {
3708 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3709 unsigned Line = getLineNumber(
ID->getLocation());
3711 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3717 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3718 if (
ID->getImplementation())
3719 Flags |= llvm::DINode::FlagObjcClassComplete;
3721 llvm::DINodeArray Annotations;
3722 const auto *RuntimeName =
ID->getAttr<ObjCRuntimeNameAttr>();
3723 if (RuntimeName && RuntimeName->getMetadataName() !=
ID->getName()) {
3724 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
3725 llvm::Metadata *Ops[2] = {
3726 llvm::MDString::get(Ctx,
"objc_runtime_name"),
3727 llvm::MDString::get(Ctx, RuntimeName->getMetadataName())};
3728 Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)});
3731 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3732 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3733 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3734 nullptr, llvm::DINodeArray(), RuntimeLang,
nullptr,
3738 QualType QTy(Ty, 0);
3739 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3742 LexicalBlockStack.emplace_back(RealDecl);
3743 RegionMap[Ty->
getDecl()].reset(RealDecl);
3746 SmallVector<llvm::Metadata *, 16> EltTys;
3748 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3750 llvm::DIType *SClassTy =
3751 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3755 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3756 llvm::DINode::FlagZero);
3757 EltTys.push_back(InhTag);
3761 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3762 SourceLocation Loc = PD->getLocation();
3763 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3764 unsigned PLine = getLineNumber(Loc);
3765 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3766 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3767 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3768 PD->getName(), PUnit, PLine,
3770 : getSelectorName(PD->getGetterName()),
3772 : getSelectorName(PD->getSetterName()),
3773 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3774 EltTys.push_back(PropertyNode);
3779 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3783 llvm::DenseSet<IsClassAndIdent> PropertySet;
3785 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3786 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3788 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3789 for (
auto *PD : ClassExt->properties()) {
3790 PropertySet.insert(GetIsClassAndIdent(PD));
3793 for (
const auto *PD :
ID->properties()) {
3796 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3802 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3803 unsigned FieldNo = 0;
3804 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3805 Field =
Field->getNextIvar(), ++FieldNo) {
3806 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3810 StringRef FieldName =
Field->getName();
3813 if (FieldName.empty())
3817 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3818 unsigned FieldLine = getLineNumber(
Field->getLocation());
3819 QualType FType =
Field->getType();
3826 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3827 : CGM.getContext().getTypeSize(FType);
3832 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3836 if (
Field->isBitField()) {
3838 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3839 FieldOffset %= CGM.getContext().getCharWidth();
3847 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3849 Flags = llvm::DINode::FlagProtected;
3851 Flags = llvm::DINode::FlagPrivate;
3853 Flags = llvm::DINode::FlagPublic;
3855 if (
Field->isBitField())
3856 Flags |= llvm::DINode::FlagBitField;
3858 llvm::MDNode *PropertyNode =
nullptr;
3859 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3860 llvm::DIFile *PUnit =
nullptr;
3862 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3863 if (ObjCPropertyImplDecl *PImpD =
3864 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3865 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3866 SynthesizedProperty = PD;
3867 SourceLocation Loc = PD->getLocation();
3868 PUnit = getOrCreateFile(Loc);
3869 PLine = getLineNumber(Loc);
3870 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3871 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3872 PropertyNode = DBuilder.createObjCProperty(
3873 PD->getName(), PUnit, PLine,
3876 : getSelectorName(PD->getGetterName()),
3879 : getSelectorName(PD->getSetterName()),
3880 PD->getPropertyAttributes(),
3881 getOrCreateType(PD->getType(), PUnit));
3885 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3886 FieldSize, FieldAlign, FieldOffset,
3887 Flags, FieldTy, PropertyNode);
3888 EltTys.push_back(IvarTy);
3890 if (SynthesizedProperty) {
3891 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3892 EltTys.push_back(DBuilder.createProperty(
3893 SynthesizedProperty->
getName(), PUnit, PLine,
3894 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3898 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3899 DBuilder.replaceArrays(RealDecl, Elements);
3901 LexicalBlockStack.pop_back();
3905llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3906 llvm::DIFile *Unit) {
3914 auto &Ctx = CGM.getContext();
3919 QualType CharVecTy =
3921 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3924 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3927 llvm::Metadata *Subscript;
3928 QualType QTy(Ty, 0);
3929 auto SizeExpr = SizeExprCache.find(QTy);
3930 if (SizeExpr != SizeExprCache.end())
3931 Subscript = DBuilder.getOrCreateSubrange(
3932 SizeExpr->getSecond() ,
nullptr ,
3933 nullptr ,
nullptr );
3936 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3937 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3938 Subscript = DBuilder.getOrCreateSubrange(
3939 CountNode ,
nullptr ,
nullptr ,
3942 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3947 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3950llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3951 llvm::DIFile *Unit) {
3955 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3960 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3961 auto *ColumnCountNode =
3962 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3963 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3964 auto *RowCountNode =
3965 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3966 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3967 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3968 ColumnCountNode ,
nullptr ,
nullptr ,
3970 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3971 RowCountNode ,
nullptr ,
nullptr ,
3973 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3974 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3977llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3982 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3997 Size = CGM.getContext().getTypeSize(Ty);
4004 SmallVector<llvm::Metadata *, 8> Subscripts;
4005 QualType EltTy(Ty, 0);
4006 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
4015 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
4016 Count = CAT->getZExtSize();
4017 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
4018 if (Expr *Size = VAT->getSizeExpr()) {
4020 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
4021 Count =
Result.Val.getInt().getExtValue();
4025 auto SizeNode = SizeExprCache.find(EltTy);
4026 if (SizeNode != SizeExprCache.end())
4027 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4028 SizeNode->getSecond() ,
nullptr ,
4029 nullptr ,
nullptr ));
4032 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4033 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4034 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4035 CountNode ,
nullptr ,
nullptr ,
4041 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4043 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4047llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4048 llvm::DIFile *Unit) {
4049 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4053llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4054 llvm::DIFile *Unit) {
4055 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4057 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4058 CGM.getCodeGenOpts().DwarfVersion < 4)
4059 Tag = llvm::dwarf::DW_TAG_reference_type;
4061 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4064llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4066 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4070 Size = CGM.getContext().getTypeSize(Ty);
4073 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4076 Flags |= llvm::DINode::FlagSingleInheritance;
4079 Flags |= llvm::DINode::FlagMultipleInheritance;
4082 Flags |= llvm::DINode::FlagVirtualInheritance;
4092 llvm::DIType *ClassType = getOrCreateType(
T, U);
4094 return DBuilder.createMemberPointerType(
4098 const FunctionProtoType *FPT =
4100 return DBuilder.createMemberPointerType(
4101 getOrCreateInstanceMethodType(
4104 ClassType, Size, 0, Flags);
4107llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4109 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4112llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4116llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4118 return getOrCreateType(Ty->getWrappedType(), U);
4121llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4128 const EnumType *Ty) {
4140llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4143 bool isImportedFromModule =
4144 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4148 if (isImportedFromModule || !ED->getDefinition()) {
4155 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4156 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4157 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4158 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4160 unsigned Line = getLineNumber(ED->getLocation());
4161 StringRef EDName = ED->getName();
4162 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4163 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4164 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4166 ReplaceMap.emplace_back(
4167 std::piecewise_construct, std::make_tuple(Ty),
4168 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4172 return CreateTypeDefinition(Ty);
4175llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4178 SmallVector<llvm::Metadata *, 16> Enumerators;
4179 ED = ED->getDefinition();
4180 assert(ED &&
"An enumeration definition is required");
4181 for (
const auto *
Enum : ED->enumerators()) {
4182 Enumerators.push_back(
4183 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4186 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4187 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4188 EnumKind = Attr->getExtensibility();
4191 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4193 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4194 unsigned Line = getLineNumber(ED->getLocation());
4195 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4196 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4197 return DBuilder.createEnumerationType(
4198 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4199 0, Identifier, ED->isScoped(), EnumKind);
4204 StringRef Name, StringRef
Value) {
4205 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4206 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4212 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4213 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4214 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4219 llvm::DISubprogram *SynthSubprogram) {
4220 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4221 SynthSubprogram, ParentLocation);
4226 StringRef SynthFuncName,
4227 llvm::DIFile *SynthFile) {
4228 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4233 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4239 FuncName += Category;
4241 FuncName += FailureMsg;
4244 TrapLocation->getFile());
4254 Quals += InnerQuals;
4256 switch (
T->getTypeClass()) {
4258 return C.getQualifiedType(
T.getTypePtr(), Quals);
4261 case Type::InjectedClassName:
4262 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4264 case Type::TemplateSpecialization: {
4266 if (Spec->isTypeAlias())
4267 return C.getQualifiedType(
T.getTypePtr(), Quals);
4268 T = Spec->desugar();
4271 case Type::TypeOfExpr:
4277 case Type::Decltype:
4280 case Type::UnaryTransform:
4283 case Type::Attributed:
4286 case Type::BTFTagAttributed:
4289 case Type::CountAttributed:
4298 case Type::MacroQualified:
4301 case Type::SubstTemplateTypeParm:
4305 case Type::DeducedTemplateSpecialization: {
4307 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4311 case Type::PackIndexing: {
4315 case Type::Adjusted:
4322 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4327llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4330 if (It != TypeCache.end()) {
4332 if (llvm::Metadata *
V = It->second)
4345 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4352 RetainedTypes.push_back(
4353 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4356llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4360 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4362 llvm::raw_string_ostream OS(Name);
4363 Ty.
print(OS, getPrintingPolicy());
4370 if (
auto *
T = getTypeOrNull(Ty))
4373 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4374 void *TyPtr = Ty.getAsOpaquePtr();
4377 TypeCache[TyPtr].reset(Res);
4382llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4390 auto Info = Reader->getSourceDescriptor(Idx);
4392 return getOrCreateModuleRef(*Info,
true);
4393 }
else if (ClangModuleMap) {
4406 auto Info = ASTSourceDescriptor(*M);
4407 return getOrCreateModuleRef(Info,
false);
4410 return getOrCreateModuleRef(PCHDescriptor,
false);
4417llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4420 return CreateQualifiedType(Ty, Unit);
4424#define TYPE(Class, Base)
4425#define ABSTRACT_TYPE(Class, Base)
4426#define NON_CANONICAL_TYPE(Class, Base)
4427#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4428#include "clang/AST/TypeNodes.inc"
4429 llvm_unreachable(
"Dependent types cannot show up in debug information");
4431 case Type::ExtVector:
4434 case Type::ConstantMatrix:
4436 case Type::ObjCObjectPointer:
4438 case Type::ObjCObject:
4440 case Type::ObjCTypeParam:
4442 case Type::ObjCInterface:
4450 case Type::BlockPointer:
4458 case Type::FunctionProto:
4459 case Type::FunctionNoProto:
4461 case Type::ConstantArray:
4462 case Type::VariableArray:
4463 case Type::IncompleteArray:
4464 case Type::ArrayParameter:
4467 case Type::LValueReference:
4469 case Type::RValueReference:
4472 case Type::MemberPointer:
4480 case Type::OverflowBehavior:
4485 case Type::TemplateSpecialization:
4487 case Type::HLSLAttributedResource:
4489 case Type::HLSLInlineSpirv:
4491 case Type::PredefinedSugar:
4493 case Type::CountAttributed:
4494 case Type::LateParsedAttr:
4496 case Type::Attributed:
4497 case Type::BTFTagAttributed:
4498 case Type::Adjusted:
4500 case Type::DeducedTemplateSpecialization:
4503 case Type::MacroQualified:
4504 case Type::SubstTemplateTypeParm:
4505 case Type::TypeOfExpr:
4507 case Type::Decltype:
4508 case Type::PackIndexing:
4509 case Type::UnaryTransform:
4513 llvm_unreachable(
"type should have been unwrapped!");
4516llvm::DICompositeType *
4517CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4518 QualType QTy(Ty, 0);
4520 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4525 if (
T && !
T->isForwardDecl())
4529 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4534 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4537 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4542llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4544 bool NameIsSimplified =
false;
4547 StringRef RDName = getClassName(RD, &NameIsSimplified);
4549 llvm::DIFile *DefUnit =
nullptr;
4552 DefUnit = getOrCreateFile(Loc);
4553 Line = getLineNumber(Loc);
4556 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4560 auto *
T = cast_or_null<llvm::DICompositeType>(
4561 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4569 return getOrCreateRecordFwdDecl(Ty, RDContext);
4582 auto Flags = llvm::DINode::FlagZero;
4583 if (NameIsSimplified)
4584 Flags |= llvm::DINode::FlagNameIsSimplified;
4585 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4587 Flags |= llvm::DINode::FlagTypePassByReference;
4589 Flags |= llvm::DINode::FlagTypePassByValue;
4592 if (!CXXRD->isTrivial())
4593 Flags |= llvm::DINode::FlagNonTrivial;
4596 if (CXXRD->isAnonymousStructOrUnion())
4597 Flags |= llvm::DINode::FlagExportSymbols;
4600 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4603 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4604 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4606 Flags, Identifier, Annotations);
4610 switch (RealDecl->getTag()) {
4612 llvm_unreachable(
"invalid composite type tag");
4614 case llvm::dwarf::DW_TAG_array_type:
4615 case llvm::dwarf::DW_TAG_enumeration_type:
4620 if (Identifier.empty())
4624 case llvm::dwarf::DW_TAG_structure_type:
4625 case llvm::dwarf::DW_TAG_union_type:
4626 case llvm::dwarf::DW_TAG_class_type:
4629 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4633 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4634 CXXRecordDecl *TemplateDecl =
4635 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4636 RegionMap[TemplateDecl].reset(RealDecl);
4638 RegionMap[RD].reset(RealDecl);
4640 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4642 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4643 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4644 CollectCXXTemplateParams(TSpecial, DefUnit));
4648void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4649 llvm::DICompositeType *RealDecl) {
4651 llvm::DIType *ContainingType =
nullptr;
4652 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4656 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4663 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4664 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4666 ContainingType = RealDecl;
4668 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4671llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4672 StringRef Name, uint64_t *Offset) {
4673 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4674 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4677 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4678 *Offset, llvm::DINode::FlagZero, FieldTy);
4679 *Offset += FieldSize;
4683void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4685 StringRef &LinkageName,
4686 llvm::DIScope *&FDContext,
4687 llvm::DINodeArray &TParamsArray,
4688 llvm::DINode::DIFlags &Flags) {
4690 bool NameIsSimplified =
false;
4691 Name = getFunctionName(FD, &NameIsSimplified);
4692 if (NameIsSimplified)
4693 Flags |= llvm::DINode::FlagNameIsSimplified;
4694 Name = getFunctionName(FD);
4697 LinkageName = CGM.getMangledName(GD);
4699 Flags |= llvm::DINode::FlagPrototyped;
4703 if (LinkageName == Name ||
4704 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4705 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4706 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4707 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4708 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4709 LinkageName = StringRef();
4713 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4714 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4715 CGM.getCodeGenOpts().EmitCodeView)) {
4716 if (
const NamespaceDecl *NSDecl =
4718 FDContext = getOrCreateNamespace(NSDecl);
4719 else if (
const RecordDecl *RDecl =
4721 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4722 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4725 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4728 Flags |= llvm::DINode::FlagNoReturn;
4730 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4734void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4735 unsigned &LineNo, QualType &
T,
4736 StringRef &Name, StringRef &LinkageName,
4737 llvm::MDTuple *&TemplateParameters,
4738 llvm::DIScope *&VDContext) {
4747 llvm::APInt ConstVal(32, 1);
4748 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4750 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4757 LinkageName = CGM.getMangledName(VD);
4758 if (LinkageName == Name)
4759 LinkageName = StringRef();
4762 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4763 TemplateParameters = parameterNodes.get();
4765 TemplateParameters =
nullptr;
4771 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4772 VDContext = LexicalBlockStack.back();
4791 DC = CGM.getContext().getTranslationUnitDecl();
4793 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4794 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4797llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4799 llvm::DINodeArray TParamsArray;
4800 StringRef Name, LinkageName;
4801 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4802 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4804 llvm::DIFile *Unit = getOrCreateFile(Loc);
4805 llvm::DIScope *DContext = Unit;
4806 unsigned Line = getLineNumber(Loc);
4807 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4812 SmallVector<QualType, 16> ArgTypes;
4813 for (
const ParmVarDecl *Parm : FD->
parameters())
4814 ArgTypes.push_back(Parm->getType());
4817 QualType FnType = CGM.getContext().getFunctionType(
4818 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4820 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4821 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4822 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4826 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4827 return DBuilder.createFunction(
4828 DContext, Name, LinkageName, Unit,
Line,
4829 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4830 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4832 CGM.getCodeGenOpts().DebugKeyInstructions);
4835 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4836 DContext, Name, LinkageName, Unit,
Line,
4837 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4838 TParamsArray.get(), getFunctionDeclaration(FD));
4840 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4841 std::make_tuple(CanonDecl),
4842 std::make_tuple(SP));
4846llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4847 return getFunctionFwdDeclOrStub(GD,
false);
4850llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4851 return getFunctionFwdDeclOrStub(GD,
true);
4854llvm::DIGlobalVariable *
4855CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4857 StringRef Name, LinkageName;
4859 llvm::DIFile *Unit = getOrCreateFile(Loc);
4860 llvm::DIScope *DContext = Unit;
4861 unsigned Line = getLineNumber(Loc);
4862 llvm::MDTuple *TemplateParameters =
nullptr;
4864 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4867 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4868 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4870 FwdDeclReplaceMap.emplace_back(
4871 std::piecewise_construct,
4873 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4877llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4882 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4883 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4884 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4888 if (I != DeclCache.end()) {
4890 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4891 return GVE->getVariable();
4899 if (IE != ImportedDeclCache.end()) {
4900 auto N = IE->second;
4901 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4903 return dyn_cast_or_null<llvm::DINode>(N);
4908 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4909 return getFunctionForwardDeclaration(FD);
4910 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4911 return getGlobalVariableForwardDeclaration(VD);
4916llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4917 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4920 const auto *FD = dyn_cast<FunctionDecl>(D);
4925 auto *S = getDeclContextDescriptor(D);
4928 if (MI == SPCache.end()) {
4930 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4934 if (MI != SPCache.end()) {
4935 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4936 if (SP && !SP->isDefinition())
4940 for (
auto *NextFD : FD->
redecls()) {
4941 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4942 if (MI != SPCache.end()) {
4943 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4944 if (SP && !SP->isDefinition())
4951llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4952 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4953 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4954 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4957 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4961 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4965 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4974 QualType QTy(
ID->getTypeForDecl(), 0);
4975 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4976 if (It == TypeCache.end())
4979 llvm::DISubprogram *FD = DBuilder.createFunction(
4980 InterfaceType, getObjCMethodName(OMD), StringRef(),
4981 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4982 DBuilder.finalizeSubprogram(FD);
4989llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4994 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4995 !CGM.getCodeGenOpts().EmitCodeView))
4998 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
5000 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
5003 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
5006 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
5007 return getOrCreateMethodType(
Method, F);
5009 const auto *FTy = FnType->
getAs<FunctionType>();
5012 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
5014 SmallVector<llvm::Metadata *, 16> Elts;
5017 QualType ResultTy = OMethod->getReturnType();
5020 if (ResultTy == CGM.getContext().getObjCInstanceType())
5021 ResultTy = CGM.getContext().getPointerType(
5022 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5024 Elts.push_back(getOrCreateType(ResultTy, F));
5026 QualType SelfDeclTy;
5027 if (
auto *SelfDecl = OMethod->getSelfDecl())
5028 SelfDeclTy = SelfDecl->getType();
5029 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5032 if (!SelfDeclTy.
isNull())
5034 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5036 Elts.push_back(DBuilder.createArtificialType(
5037 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5039 for (
const auto *PI : OMethod->parameters())
5040 Elts.push_back(getOrCreateType(PI->getType(), F));
5042 if (OMethod->isVariadic())
5043 Elts.push_back(DBuilder.createUnspecifiedParameter());
5045 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5046 return DBuilder.createSubroutineType(
5047 EltTypeArray, llvm::DINode::FlagZero,
5048 getDwarfCC(CC, CGM.getTarget().getTriple()));
5053 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5054 if (FD->isVariadic()) {
5055 SmallVector<llvm::Metadata *, 16> EltTys;
5056 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5057 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5059 EltTys.push_back(getOrCreateType(ParamType, F));
5060 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5061 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5062 return DBuilder.createSubroutineType(
5063 EltTypeArray, llvm::DINode::FlagZero,
5064 getDwarfCC(CC, CGM.getTarget().getTriple()));
5076 CC = SrcFnTy->getCallConv();
5078 for (
const VarDecl *VD : Args)
5079 ArgTypes.push_back(VD->
getType());
5080 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5086 llvm::Function *Fn,
bool CurFuncIsThunk) {
5088 StringRef LinkageName;
5090 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5093 bool HasDecl = (D !=
nullptr);
5095 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5096 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5097 llvm::DIFile *Unit = getOrCreateFile(Loc);
5098 llvm::DIScope *FDContext = Unit;
5099 llvm::DINodeArray TParamsArray;
5100 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5103 LinkageName = Fn->getName();
5104 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5106 auto FI = SPCache.find(FD->getCanonicalDecl());
5107 if (FI != SPCache.end()) {
5108 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5109 if (SP && SP->isDefinition()) {
5110 LexicalBlockStack.emplace_back(SP);
5111 RegionMap[D].reset(SP);
5115 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5116 TParamsArray, Flags);
5119 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5120 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5121 Name = getObjCMethodName(OMD);
5122 Flags |= llvm::DINode::FlagPrototyped;
5128 if (Name != Fn->getName())
5129 LinkageName = Fn->getName();
5131 Name = Fn->getName();
5136 Flags |= llvm::DINode::FlagPrototyped;
5138 Name.consume_front(
"\01");
5142 "Unexpected DynamicInitKind !");
5146 Flags |= llvm::DINode::FlagArtificial;
5152 Flags |= llvm::DINode::FlagThunk;
5154 if (Fn->hasLocalLinkage())
5155 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5156 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5157 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5160 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5161 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5163 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5164 unsigned ScopeLine = getLineNumber(ScopeLoc);
5165 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5166 llvm::DISubprogram *
Decl =
nullptr;
5167 llvm::DINodeArray Annotations =
nullptr;
5170 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5171 : getFunctionDeclaration(D);
5172 Annotations = CollectBTFDeclTagAnnotations(D);
5180 llvm::DISubprogram *SP = DBuilder.createFunction(
5181 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5182 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5183 Annotations,
"", KeyInstructions);
5184 Fn->setSubprogram(SP);
5193 LexicalBlockStack.emplace_back(SP);
5196 RegionMap[D].reset(SP);
5200 QualType FnType, llvm::Function *Fn) {
5202 StringRef LinkageName;
5208 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5209 return GetName(D,
true);
5212 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5213 llvm::DIFile *Unit = getOrCreateFile(Loc);
5214 bool IsDeclForCallSite = Fn ?
true :
false;
5215 llvm::DIScope *FDContext =
5216 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5217 llvm::DINodeArray TParamsArray;
5220 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5221 TParamsArray, Flags);
5222 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5223 Name = getObjCMethodName(OMD);
5224 Flags |= llvm::DINode::FlagPrototyped;
5226 llvm_unreachable(
"not a function or ObjC method");
5228 Name.consume_front(
"\01");
5231 Flags |= llvm::DINode::FlagArtificial;
5236 unsigned LineNo = getLineNumber(Loc);
5237 unsigned ScopeLine = 0;
5238 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5239 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5240 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5242 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5243 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5245 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5246 llvm::DISubprogram *SP = DBuilder.createFunction(
5247 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5248 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5254 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5255 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5256 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5259 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5260 DBuilder.createParameterVariable(
5261 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5262 llvm::DINode::FlagZero, ParamAnnotations);
5268 if (IsDeclForCallSite)
5269 Fn->setSubprogram(SP);
5273 llvm::CallBase *CI) {
5274 if (!shouldGenerateVirtualCallSite())
5280 assert(CI &&
"Invalid Call Instruction.");
5281 if (!CI->isIndirectCall())
5285 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5286 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5294 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5297 if (
Func->getSubprogram())
5301 if (!
Func->isDeclaration())
5323 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5324 Func->setSubprogram(SP);
5335 auto FI = SPCache.find(FD->getCanonicalDecl());
5336 llvm::DISubprogram *SP =
nullptr;
5337 if (FI != SPCache.end())
5338 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5339 if (!SP || !SP->isDefinition())
5340 SP = getFunctionStub(GD);
5341 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5342 LexicalBlockStack.emplace_back(SP);
5348 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5357 if (CurLoc.isInvalid() ||
5358 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5359 LexicalBlockStack.empty())
5362 llvm::MDNode *
Scope = LexicalBlockStack.back();
5363 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5364 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5368 llvm::MDNode *Back =
nullptr;
5369 if (!LexicalBlockStack.empty())
5370 Back = LexicalBlockStack.back().get();
5373 unsigned Line = getLineNumber(CurLoc);
5374 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5375 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5379void CGDebugInfo::AppendAddressSpaceXDeref(
5381 std::optional<unsigned> DWARFAddressSpace =
5383 if (!DWARFAddressSpace)
5386 Expr.push_back(llvm::dwarf::DW_OP_constu);
5387 Expr.push_back(*DWARFAddressSpace);
5388 Expr.push_back(llvm::dwarf::DW_OP_swap);
5389 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5398 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5399 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5400 LexicalBlockStack.back(), CurInlinedAt));
5402 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5406 CreateLexicalBlock(Loc);
5411 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5416 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5419 LexicalBlockStack.pop_back();
5423 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5424 unsigned RCount = FnBeginRegionCount.back();
5425 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5428 while (LexicalBlockStack.size() != RCount) {
5431 LexicalBlockStack.pop_back();
5433 FnBeginRegionCount.pop_back();
5435 if (Fn && Fn->getSubprogram())
5436 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5439CGDebugInfo::BlockByRefType
5440CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5441 uint64_t *XOffset) {
5444 uint64_t FieldSize, FieldOffset;
5445 uint32_t FieldAlign;
5447 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5452 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5453 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5455 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5456 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5459 if (HasCopyAndDispose) {
5462 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5464 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5466 bool HasByrefExtendedLayout;
5469 HasByrefExtendedLayout) &&
5470 HasByrefExtendedLayout) {
5473 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5482 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5485 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5488 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5493 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5494 FieldSize = CGM.getContext().getTypeSize(FType);
5495 FieldAlign = CGM.getContext().toBits(Align);
5497 *XOffset = FieldOffset;
5498 llvm::DIType *FieldTy = DBuilder.createMemberType(
5499 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5500 llvm::DINode::FlagZero, WrappedTy);
5501 EltTys.push_back(FieldTy);
5502 FieldOffset += FieldSize;
5504 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5505 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5506 llvm::DINode::FlagZero,
nullptr, Elements),
5510llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5511 llvm::Value *Storage,
5512 std::optional<unsigned> ArgNo,
5514 const bool UsePointerValue) {
5515 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5516 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5517 if (VD->
hasAttr<NoDebugAttr>())
5522 llvm::DIFile *Unit =
nullptr;
5523 if (!VarIsArtificial)
5527 if (VD->
hasAttr<BlocksAttr>())
5528 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5530 Ty = getOrCreateType(VD->
getType(), Unit);
5540 if (!VarIsArtificial) {
5544 SmallVector<uint64_t, 13> Expr;
5545 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5552 Flags |= llvm::DINode::FlagArtificial;
5556 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5557 AppendAddressSpaceXDeref(AddressSpace, Expr);
5561 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5564 Flags |= llvm::DINode::FlagObjectPointer;
5565 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5566 if (PVD->isExplicitObjectParameter())
5567 Flags |= llvm::DINode::FlagObjectPointer;
5575 StringRef Name = VD->
getName();
5576 if (!Name.empty()) {
5582 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5584 offset = CGM.getContext().toCharUnitsFromBits(
5587 Expr.push_back(llvm::dwarf::DW_OP_deref);
5588 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5590 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5593 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5605 for (
const auto *Field : RD->
fields()) {
5606 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5607 StringRef FieldName =
Field->getName();
5615 auto *D = DBuilder.createAutoVariable(
5616 Scope, FieldName, Unit,
Line, FieldTy,
5617 CGM.getCodeGenOpts().OptimizationLevel != 0,
5618 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5621 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5622 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5625 Builder.GetInsertBlock());
5633 if (UsePointerValue) {
5634 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5635 "Debug info already contains DW_OP_deref.");
5636 Expr.push_back(llvm::dwarf::DW_OP_deref);
5640 llvm::DILocalVariable *D =
nullptr;
5642 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5643 D = DBuilder.createParameterVariable(
5644 Scope, Name, *ArgNo, Unit,
Line, Ty,
5645 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5654 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5660 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5661 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5662 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5663 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5665 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5671 if (Iter != CoroutineParameterMappings.end()) {
5672 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5673 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5674 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5676 if (Iter2 != ParamDbgMappings.end())
5677 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5683 D = RemapCoroArgToLocalVar();
5686 D = DBuilder.createAutoVariable(
5687 Scope, Name, Unit,
Line, Ty,
5688 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5691 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5692 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5693 Column, Scope, CurInlinedAt),
5694 Builder.GetInsertBlock());
5699llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5700 llvm::Value *Storage,
5701 std::optional<unsigned> ArgNo,
5703 const bool UsePointerValue) {
5704 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5705 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5706 if (BD->
hasAttr<NoDebugAttr>())
5713 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5714 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5722 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5724 SmallVector<uint64_t, 3> Expr;
5725 AppendAddressSpaceXDeref(AddressSpace, Expr);
5730 if (UsePointerValue) {
5731 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5732 "Debug info already contains DW_OP_deref.");
5733 Expr.push_back(llvm::dwarf::DW_OP_deref);
5738 StringRef Name = BD->
getName();
5741 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5742 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5743 llvm::DINode::FlagZero, Align);
5745 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5746 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5747 const unsigned fieldIndex = FD->getFieldIndex();
5748 const clang::CXXRecordDecl *parent =
5749 (
const CXXRecordDecl *)FD->getParent();
5750 const ASTRecordLayout &layout =
5751 CGM.getContext().getASTRecordLayout(parent);
5753 if (FD->isBitField()) {
5754 const CGRecordLayout &RL =
5755 CGM.getTypes().getCGRecordLayout(FD->getParent());
5760 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5766 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5767 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5768 Expr.push_back(Info.
Offset);
5771 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5772 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5773 }
else if (fieldOffset != 0) {
5774 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5775 "Unexpected non-bitfield with non-byte-aligned offset");
5776 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5778 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5781 }
else if (
const ArraySubscriptExpr *ASE =
5782 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5783 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5784 const uint64_t value = IL->getValue().getZExtValue();
5785 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5788 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5789 Expr.push_back(CGM.getContext()
5790 .toCharUnitsFromBits(value * typeSize)
5797 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5798 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5799 Column, Scope, CurInlinedAt),
5800 Builder.GetInsertBlock());
5805llvm::DILocalVariable *
5808 const bool UsePointerValue) {
5809 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5811 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5813 EmitDeclare(B, Storage, std::nullopt, Builder,
5820 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5824 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5825 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5827 if (D->
hasAttr<NoDebugAttr>())
5831 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5837 StringRef Name = D->
getName();
5843 CGM.getCodeGenOpts().OptimizationLevel != 0);
5846 DBuilder.insertLabel(L,
5847 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5848 Scope, CurInlinedAt),
5849 Builder.GetInsertBlock()->end());
5852llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5854 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5857 return DBuilder.createObjectPointerType(Ty,
true);
5862 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5863 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5864 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5866 if (Builder.GetInsertBlock() ==
nullptr)
5868 if (VD->
hasAttr<NoDebugAttr>())
5871 bool isByRef = VD->
hasAttr<BlocksAttr>();
5873 uint64_t XOffset = 0;
5874 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5877 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5879 Ty = getOrCreateType(VD->
getType(), Unit);
5883 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5885 Ty = CreateSelfType(VD->
getType(), Ty);
5888 const unsigned Line =
5892 const llvm::DataLayout &target = CGM.getDataLayout();
5899 addr.push_back(llvm::dwarf::DW_OP_deref);
5900 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5903 addr.push_back(llvm::dwarf::DW_OP_deref);
5904 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5907 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5909 addr.push_back(llvm::dwarf::DW_OP_deref);
5910 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5912 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5918 auto *D = DBuilder.createAutoVariable(
5920 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5923 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5924 LexicalBlockStack.back(), CurInlinedAt);
5925 auto *
Expr = DBuilder.createExpression(addr);
5927 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5929 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5932llvm::DILocalVariable *
5935 bool UsePointerValue) {
5936 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5937 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5941struct BlockLayoutChunk {
5942 uint64_t OffsetInBits;
5945bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5946 return l.OffsetInBits < r.OffsetInBits;
5950void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5952 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5953 SmallVectorImpl<llvm::Metadata *> &Fields) {
5957 if (CGM.getLangOpts().OpenCL) {
5958 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5959 BlockLayout.getElementOffsetInBits(0),
5961 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5962 BlockLayout.getElementOffsetInBits(1),
5966 BlockLayout.getElementOffsetInBits(0),
5968 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5969 BlockLayout.getElementOffsetInBits(1),
5973 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5974 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5975 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5976 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5977 BlockLayout.getElementOffsetInBits(3),
5979 Fields.push_back(createFieldType(
5984 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5991 llvm::AllocaInst *Alloca,
5993 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5999 llvm::DIFile *tunit = getOrCreateFile(loc);
6000 unsigned line = getLineNumber(loc);
6001 unsigned column = getColumnNumber(loc);
6006 const llvm::StructLayout *blockLayout =
6010 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
6019 BlockLayoutChunk chunk;
6020 chunk.OffsetInBits =
6021 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
6022 chunk.Capture =
nullptr;
6023 chunks.push_back(chunk);
6027 for (
const auto &capture :
blockDecl->captures()) {
6028 const VarDecl *variable = capture.getVariable();
6035 BlockLayoutChunk chunk;
6036 chunk.OffsetInBits =
6037 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6038 chunk.Capture = &capture;
6039 chunks.push_back(chunk);
6043 llvm::array_pod_sort(chunks.begin(), chunks.end());
6045 for (
const BlockLayoutChunk &Chunk : chunks) {
6046 uint64_t offsetInBits = Chunk.OffsetInBits;
6053 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6055 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6056 type = CGM.getContext().getCanonicalTagType(RDecl);
6058 llvm_unreachable(
"unexpected block declcontext");
6060 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6061 offsetInBits, tunit, tunit));
6066 StringRef name = variable->
getName();
6068 llvm::DIType *fieldType;
6070 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6075 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6076 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6077 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6078 PtrInfo.
Width, Align, offsetInBits,
6079 llvm::DINode::FlagZero, fieldType);
6083 offsetInBits, Align, tunit, tunit);
6085 fields.push_back(fieldType);
6089 llvm::raw_svector_ostream(typeName)
6090 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6092 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6094 llvm::DIType *
type =
6095 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6096 CGM.getContext().toBits(block.
BlockSize), 0,
6097 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6098 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6101 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6105 auto *debugVar = DBuilder.createParameterVariable(
6106 scope, Name, ArgNo, tunit, line,
type,
6107 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6110 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6111 llvm::DILocation::get(CGM.getLLVMContext(), line,
6112 column, scope, CurInlinedAt),
6113 Builder.GetInsertBlock());
6116llvm::DIDerivedType *
6117CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6122 if (MI != StaticDataMemberCache.end()) {
6123 assert(MI->second &&
"Static data member declaration should still exist");
6134llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6135 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6136 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6137 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6139 for (
const auto *Field : RD->
fields()) {
6140 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6141 StringRef FieldName = Field->getName();
6144 if (FieldName.empty()) {
6145 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6146 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6147 LineNo, LinkageName, Var, DContext);
6151 GVE = DBuilder.createGlobalVariableExpression(
6152 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6153 Var->hasLocalLinkage());
6154 Var->addDebugInfo(GVE);
6166 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6171 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6182 struct ReferencesAnonymous
6184 bool RefAnon =
false;
6185 bool VisitRecordType(RecordType *RT) {
6193 ReferencesAnonymous RT;
6206struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6207 bool Reconstitutable =
true;
6208 bool VisitVectorType(VectorType *FT) {
6209 Reconstitutable =
false;
6212 bool VisitAtomicType(AtomicType *FT) {
6213 Reconstitutable =
false;
6216 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6219 const EnumDecl *ED = ET->getDecl();
6221 Reconstitutable =
false;
6225 Reconstitutable =
false;
6230 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6234 return Reconstitutable;
6236 bool VisitRecordType(RecordType *RT,
bool =
false) {
6238 Reconstitutable =
false;
6248 ReconstitutableType
T;
6250 return T.Reconstitutable;
6253bool CGDebugInfo::HasReconstitutableArgs(
6254 ArrayRef<TemplateArgument> Args)
const {
6255 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6295 llvm_unreachable(
"Other, unresolved, template arguments should "
6296 "not be seen here");
6301std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6302 bool *NameIsSimplified)
const {
6304 llvm::raw_string_ostream
OS(Name);
6305 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6308 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6309 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6311 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6312 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6314 std::optional<TemplateArgs> Args;
6316 bool IsOperatorOverload =
false;
6317 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6318 Args = GetTemplateArgs(RD);
6319 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6320 Args = GetTemplateArgs(FD);
6322 IsOperatorOverload |=
6325 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6326 Args = GetTemplateArgs(VD);
6350 bool Reconstitutable =
6351 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6353 PrintingPolicy PP = getPrintingPolicy();
6355 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6360 if (NameIsSimplified)
6361 *NameIsSimplified =
true;
6362 bool Mangled = TemplateNamesKind ==
6363 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6369 std::string EncodedOriginalName;
6370 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6375 printTemplateArgumentList(OS, Args->Args, PP);
6376 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6378 std::string CanonicalOriginalName;
6379 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6381 assert(EncodedOriginalName == CanonicalOriginalName);
6390 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6391 if (D->
hasAttr<NoDebugAttr>())
6394 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6395 return GetName(D,
true);
6401 if (Cached != DeclCache.end())
6402 return Var->addDebugInfo(
6406 llvm::DIFile *Unit =
nullptr;
6407 llvm::DIScope *DContext =
nullptr;
6409 StringRef DeclName, LinkageName;
6411 llvm::MDTuple *TemplateParameters =
nullptr;
6412 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6413 TemplateParameters, DContext);
6417 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6422 if (
T->isUnionType() && DeclName.empty()) {
6423 const auto *RD =
T->castAsRecordDecl();
6425 "unnamed non-anonymous struct or union?");
6426 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6431 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6432 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6433 if (D->
hasAttr<CUDASharedAttr>())
6436 else if (D->
hasAttr<CUDAConstantAttr>())
6440 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6442 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6443 GVE = DBuilder.createGlobalVariableExpression(
6444 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6445 Var->hasLocalLinkage(),
true,
6446 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6447 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6448 Align, Annotations);
6449 Var->addDebugInfo(GVE);
6455 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6456 if (VD->
hasAttr<NoDebugAttr>())
6458 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6459 return GetName(VD,
true);
6464 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6465 StringRef Name = VD->
getName();
6466 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6468 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6470 if (CGM.getCodeGenOpts().EmitCodeView) {
6481 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6482 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6483 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6493 auto *VarD = dyn_cast<VarDecl>(VD);
6494 if (VarD && VarD->isStaticDataMember()) {
6496 getDeclContextDescriptor(VarD);
6501 RetainedTypes.push_back(
6502 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6506 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6508 auto &GV = DeclCache[VD];
6512 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6513 llvm::MDTuple *TemplateParameters =
nullptr;
6517 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6518 TemplateParameters = parameterNodes.get();
6521 GV.reset(DBuilder.createGlobalVariableExpression(
6522 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6523 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6524 TemplateParameters, Align));
6529 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6530 if (D->
hasAttr<NoDebugAttr>())
6534 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6535 StringRef Name = D->
getName();
6536 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6538 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6539 llvm::DIGlobalVariableExpression *GVE =
6540 DBuilder.createGlobalVariableExpression(
6541 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6542 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6543 Var->addDebugInfo(GVE);
6550 if (CGM.getCodeGenOpts().getDebugInfo() <=
6551 llvm::codegenoptions::DebugLineTablesOnly)
6554 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6558 llvm::DIFile *Unit = DIL->getFile();
6559 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6564 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6565 llvm::Value *Var = Load->getPointerOperand();
6570 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6571 return DbgDeclare->getVariable()->getType() ==
Type;
6573 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6577 llvm::DILocalVariable *D =
6578 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6579 Type,
false, llvm::DINode::FlagArtificial);
6581 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6582 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6592 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6596 if (D->
hasAttr<NoDebugAttr>())
6599 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6614 if (!(DI = getDeclarationOrDefinition(
6615 AliaseeDecl.getCanonicalDecl().getDecl())))
6618 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6621 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6622 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6636 llvm::DIFile *
File = getOrCreateFile(Loc);
6637 llvm::DIGlobalVariableExpression *Debug =
6638 DBuilder.createGlobalVariableExpression(
6639 nullptr, StringRef(), StringRef(),
File, getLineNumber(Loc),
6641 GV->addDebugInfo(Debug);
6644llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6645 if (!LexicalBlockStack.empty())
6646 return LexicalBlockStack.back();
6647 llvm::DIScope *Mod = getParentModuleOrNull(D);
6648 return getContextDescriptor(D, Mod ? Mod : TheCU);
6652 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6656 CGM.getCodeGenOpts().DebugExplicitImport) {
6660 DBuilder.createImportedModule(
6662 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6667 if (llvm::DINode *
Target =
6670 DBuilder.createImportedDeclaration(
6672 getOrCreateFile(Loc), getLineNumber(Loc));
6677 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6680 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6682 for (
const auto *USD : UD.
shadows()) {
6687 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6688 if (
const auto *AT = FD->getType()
6691 if (AT->getDeducedType().isNull())
6702 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6705 "We shouldn't be codegening an invalid UsingEnumDecl"
6706 " containing no decls");
6708 for (
const auto *USD : UD.
shadows())
6713 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6715 if (
Module *M = ID.getImportedModule()) {
6717 auto Loc = ID.getLocation();
6718 DBuilder.createImportedDeclaration(
6719 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6720 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6721 getLineNumber(Loc));
6725llvm::DIImportedEntity *
6727 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6729 auto &VH = NamespaceAliasCache[&NA];
6732 llvm::DIImportedEntity *R;
6734 if (
const auto *Underlying =
6737 R = DBuilder.createImportedDeclaration(
6740 getLineNumber(Loc), NA.
getName());
6742 R = DBuilder.createImportedDeclaration(
6745 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6751CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6755 auto I = NamespaceCache.find(NSDecl);
6756 if (I != NamespaceCache.end())
6759 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6761 llvm::DINamespace *NS =
6762 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6763 NamespaceCache[NSDecl].reset(NS);
6768 assert(TheCU &&
"no main compile unit");
6769 TheCU->setDWOId(Signature);
6775 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6776 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6778 ? CreateTypeDefinition(E.Type, E.Unit)
6780 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6784 for (
const auto &P : ObjCMethodCache) {
6785 if (P.second.empty())
6788 QualType QTy(P.first->getTypeForDecl(), 0);
6790 assert(It != TypeCache.end());
6792 llvm::DICompositeType *InterfaceDecl =
6795 auto CurElts = InterfaceDecl->getElements();
6799 for (
auto &SubprogramDirect : P.second)
6800 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6801 EltTys.push_back(SubprogramDirect.getPointer());
6803 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6804 DBuilder.replaceArrays(InterfaceDecl, Elements);
6807 for (
const auto &P : ReplaceMap) {
6810 assert(Ty->isForwardDecl());
6812 auto It = TypeCache.find(P.first);
6813 assert(It != TypeCache.end());
6816 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6820 for (
const auto &P : FwdDeclReplaceMap) {
6823 llvm::Metadata *Repl;
6825 auto It = DeclCache.find(P.first);
6829 if (It == DeclCache.end())
6834 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6835 Repl = GVE->getVariable();
6841 for (
auto &RT : RetainedTypes)
6842 if (
auto MD = TypeCache[RT])
6845 DBuilder.finalize();
6850 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6851 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6852 DBuilder.retainType(DieTy);
6856 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6857 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6858 DBuilder.retainType(DieTy);
6862 if (LexicalBlockStack.empty())
6863 return llvm::DebugLoc();
6865 llvm::MDNode *
Scope = LexicalBlockStack.back();
6866 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6867 getColumnNumber(Loc),
Scope);
6873 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6874 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6875 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6876 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6877 return llvm::DINode::FlagZero;
6882 bool SupportsDWARFv4Ext =
6883 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6884 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6885 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6887 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6888 return llvm::DINode::FlagZero;
6890 return llvm::DINode::FlagAllCallsDescribed;
6901 return DBuilder.createConstantValueExpression(
6902 Val.
getFloat().bitcastToAPInt().getZExtValue());
6907 llvm::APSInt
const &ValInt = Val.
getInt();
6908 std::optional<uint64_t> ValIntOpt;
6909 if (ValInt.isUnsigned())
6910 ValIntOpt = ValInt.tryZExtValue();
6911 else if (
auto tmp = ValInt.trySExtValue())
6914 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6917 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6922CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6924 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6925 CGF.CurLexicalScope =
this;
6927 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6932 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6945#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6947 Label = "__ubsan_check_" #Name; \
6951#undef SANITIZER_CHECK
6962#define SANITIZER(NAME, ID) \
6963 case SanitizerKind::SO_##ID: \
6964 Label = "__ubsan_check_" NAME; \
6966#include "clang/Basic/Sanitizers.def"
6968 llvm_unreachable(
"unexpected sanitizer kind");
6973 for (
unsigned int i = 0; i < Label.length(); i++)
6974 if (!std::isalpha(Label[i]))
6983 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6985 if (!DI || !CheckDebugLoc)
6986 return CheckDebugLoc;
6987 const auto &AnnotateDebugInfo =
6988 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6989 if (AnnotateDebugInfo.empty())
6990 return CheckDebugLoc;
6993 if (Ordinals.size() == 1)
6998 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
7002 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
7003 "ubsan_interface.h",
7005 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
7008 return CheckDebugLoc;
7016 assert(!CGF->IsSanitizerScope);
7017 CGF->IsSanitizerScope =
true;
7021 assert(CGF->IsSanitizerScope);
7022 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 unsigned getDwarfCC(CallingConv CC, const llvm::Triple &T)
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 void completeStandardLayoutUnionType(CGDebugInfo &DebugInfo, QualType QT)
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 void completeStandardLayoutUnionMembers(CGDebugInfo &DebugInfo, const CXXRecordDecl *RD)
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 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 base class of a C++ class.
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).
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
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.
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
capture_const_iterator captures_end() const
method_range methods() const
bool defaultedDefaultConstructorIsConstexpr() const
Determine whether a defaulted default constructor for this class would be constexpr.
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.
This is an opaque type for sizes expressed in character units.
bool isPositive() const
Test whether the quantity is greater than zero.
bool isZero() const
Test whether the quantity equals zero.
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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.
std::pair< llvm::DIType *, unsigned > getOrCreatePreserveAccessInfo(QualType Ty, const FieldDecl *Field)
Return the complete record type and field index for preserve-access intrinsics.
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...
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 * getParent()
getParent - Returns the containing DeclContext.
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...
bool isInvalidDecl() const
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...
Represents a member of a struct/union/class.
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.
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
SourceLocation getFileLoc(SourceLocation Loc, unsigned MaxDepth=std::numeric_limits< unsigned >::max()) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
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.
CanQualType getCanonicalTypeUnqualified() const
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
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
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.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
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,...
Top level wrappers for InstallAPI frontend operations.
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...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
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,...
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_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, not including padding.
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 PrettyEnums
Whether to print enumerators with a matching enumerator name or via cast.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
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.