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;
630 std::optional<llvm::DIFile::ChecksumKind> CSKind =
631 computeChecksum(FID, Checksum);
633 CSInfo.emplace(*CSKind, Checksum);
639llvm::DIFile *CGDebugInfo::createFile(
641 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
642 std::optional<StringRef> Source) {
646 std::string CurDir =
remapDIPath(getCurrentDirname());
647 SmallString<128> DirBuf;
648 SmallString<128> FileBuf;
649 if (llvm::sys::path::is_absolute(RemappedFile)) {
652 auto FileIt = llvm::sys::path::begin(RemappedFile);
653 auto FileE = llvm::sys::path::end(RemappedFile);
654 auto CurDirIt = llvm::sys::path::begin(CurDir);
655 auto CurDirE = llvm::sys::path::end(CurDir);
656 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
657 llvm::sys::path::append(DirBuf, *CurDirIt);
658 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
664 for (; FileIt != FileE; ++FileIt)
665 llvm::sys::path::append(FileBuf, *FileIt);
670 if (!llvm::sys::path::is_absolute(
FileName))
674 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
675 DIFileCache[
FileName.data()].reset(F);
680 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
688 if (DebugLoc == CurLoc)
703 if (DebugLoc == CurLoc)
709StringRef CGDebugInfo::getCurrentDirname() {
717 assert(CGO.DwarfVersion <= 5);
719 llvm::dwarf::SourceLanguage LangTag;
722 LangTag = llvm::dwarf::DW_LANG_HLSL;
724 LangTag = llvm::dwarf::DW_LANG_HIP;
726 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
727 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
728 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
729 else if (LO.CPlusPlus14)
730 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
731 else if (LO.CPlusPlus11)
732 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
734 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
735 }
else if (LO.ObjC) {
736 LangTag = llvm::dwarf::DW_LANG_ObjC;
737 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
738 LangTag = llvm::dwarf::DW_LANG_OpenCL;
739 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
740 LangTag = llvm::dwarf::DW_LANG_C11;
742 LangTag = llvm::dwarf::DW_LANG_C99;
744 LangTag = llvm::dwarf::DW_LANG_C89;
750static llvm::DISourceLanguageName
759 llvm::dwarf::SourceLanguageName LangTag;
762 LangTag = llvm::dwarf::DW_LNAME_HLSL;
764 LangTag = llvm::dwarf::DW_LNAME_HIP;
765 }
else if (LO.ObjC) {
766 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
768 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
771 }
else if (LO.ObjC) {
772 LangTag = llvm::dwarf::DW_LNAME_ObjC;
773 }
else if (LO.OpenCL) {
774 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
776 LangTag = llvm::dwarf::DW_LNAME_C;
780 return llvm::DISourceLanguageName(LangTag, LangVersion);
783void CGDebugInfo::CreateCompileUnit() {
784 SmallString<64> Checksum;
785 std::optional<llvm::DIFile::ChecksumKind> CSKind;
786 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
796 SourceManager &SM = CGM.getContext().getSourceManager();
797 auto &CGO = CGM.getCodeGenOpts();
798 const LangOptions &LO = CGM.getLangOpts();
799 std::string MainFileName = CGO.MainFileName;
800 if (MainFileName.empty())
801 MainFileName =
"<stdin>";
807 std::string MainFileDir;
810 MainFileDir = std::string(MainFile->getDir().getName());
811 if (!llvm::sys::path::is_absolute(MainFileName)) {
812 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
813 llvm::sys::path::Style Style =
815 ? (CGM.getTarget().
getTriple().isOSWindows()
816 ? llvm::sys::path::Style::windows_backslash
817 : llvm::sys::path::Style::posix)
818 : llvm::sys::path::Style::native;
819 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
820 MainFileName = std::string(
821 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
828 if (MainFile->getName() == MainFileName &&
830 MainFile->getName().rsplit(
'.').second)
832 MainFileName = CGM.getModule().getName().str();
841 unsigned RuntimeVers = 0;
845 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
847 case llvm::codegenoptions::NoDebugInfo:
848 case llvm::codegenoptions::LocTrackingOnly:
849 EmissionKind = llvm::DICompileUnit::NoDebug;
851 case llvm::codegenoptions::DebugLineTablesOnly:
852 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
854 case llvm::codegenoptions::DebugDirectivesOnly:
855 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
857 case llvm::codegenoptions::DebugInfoConstructor:
858 case llvm::codegenoptions::LimitedDebugInfo:
859 case llvm::codegenoptions::FullDebugInfo:
860 case llvm::codegenoptions::UnusedTypeInfo:
861 EmissionKind = llvm::DICompileUnit::FullDebug;
866 auto &CGOpts = CGM.getCodeGenOpts();
872 CSInfo.emplace(*CSKind, Checksum);
873 llvm::DIFile *CUFile = DBuilder.createFile(
877 StringRef Sysroot, SDK;
878 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
879 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
880 if (CGM.getCodeGenOpts().DebugRecordSysroot)
881 Sysroot = FullSysroot;
882 auto B = llvm::sys::path::rbegin(FullSysroot);
883 auto E = llvm::sys::path::rend(FullSysroot);
885 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
890 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
891 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
892 CGOpts.DebugNameTable);
893 if (CGM.getTarget().getTriple().isNVPTX())
894 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
895 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
896 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
899 TheCU = DBuilder.createCompileUnit(
901 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
902 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
903 CGOpts.PrepareForThinLTO,
904 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
905 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
906 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
909llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
913#define BUILTIN_TYPE(Id, SingletonId)
914#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
915#include "clang/AST/BuiltinTypes.def"
916 case BuiltinType::Dependent:
917 llvm_unreachable(
"Unexpected builtin type");
918 case BuiltinType::NullPtr:
919 return DBuilder.createNullPtrType();
920 case BuiltinType::Void:
922 case BuiltinType::ObjCClass:
925 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
926 "objc_class", TheCU, TheCU->getFile(), 0);
928 case BuiltinType::ObjCId: {
939 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
940 "objc_class", TheCU, TheCU->getFile(), 0);
942 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
944 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
946 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
947 (uint64_t)0, 0, llvm::DINode::FlagZero,
948 nullptr, llvm::DINodeArray());
950 DBuilder.replaceArrays(
951 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
952 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
953 llvm::DINode::FlagZero, ISATy)));
956 case BuiltinType::ObjCSel: {
958 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
959 "objc_selector", TheCU,
960 TheCU->getFile(), 0);
964#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
965 case BuiltinType::Id: \
966 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
968#include "clang/Basic/OpenCLImageTypes.def"
969 case BuiltinType::OCLSampler:
970 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
971 case BuiltinType::OCLEvent:
972 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
973 case BuiltinType::OCLClkEvent:
974 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
975 case BuiltinType::OCLQueue:
976 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
977 case BuiltinType::OCLReserveID:
978 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
979#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
980 case BuiltinType::Id: \
981 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
982#include "clang/Basic/OpenCLExtensionTypes.def"
983#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
984 case BuiltinType::Id: \
985 return getOrCreateStructPtrType(#Name, SingletonId);
986#include "clang/Basic/HLSLIntangibleTypes.def"
987#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
988 case BuiltinType::Id: \
989 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
990#include "clang/Basic/HLSLPackedTypes.def"
992#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
993#include "clang/Basic/AArch64ACLETypes.def"
995 if (BT->
getKind() == BuiltinType::MFloat8) {
996 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
997 BTName = BT->
getName(CGM.getLangOpts());
1000 return DBuilder.createBasicType(BTName, Size, Encoding);
1002 ASTContext::BuiltinVectorTypeInfo Info =
1004 BT->
getKind() == BuiltinType::SveCount
1005 ? ASTContext::BuiltinVectorTypeInfo(
1006 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1008 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1015 "Unsupported number of vectors for svcount_t");
1017 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1018 llvm::Metadata *BitStride =
nullptr;
1019 if (BT->
getKind() == BuiltinType::SveBool) {
1020 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1021 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1022 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1023 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1025 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1028 llvm::Metadata *LowerBound, *UpperBound;
1029 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1030 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1031 if (Info.
EC.isScalable()) {
1032 unsigned NumElemsPerVG = NumElems / 2;
1033 SmallVector<uint64_t, 9> Expr(
1034 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1035 46, 0, llvm::dwarf::DW_OP_mul,
1036 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1037 UpperBound = DBuilder.createExpression(Expr);
1039 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1040 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1042 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1043 nullptr, LowerBound, UpperBound,
nullptr);
1044 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1045 llvm::DIType *ElemTy =
1046 getOrCreateType(Info.
ElementType, TheCU->getFile());
1048 return DBuilder.createVectorType( 0, Align, ElemTy,
1049 SubscriptArray, BitStride);
1053#define PPC_VECTOR_TYPE(Name, Id, size) \
1054 case BuiltinType::Id:
1055#include "clang/Basic/PPCTypes.def"
1058#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1059#include "clang/Basic/RISCVVTypes.def"
1061 ASTContext::BuiltinVectorTypeInfo Info =
1062 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1064 unsigned ElementCount = Info.
EC.getKnownMinValue();
1065 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1067 bool Fractional =
false;
1070 unsigned FixedSize = ElementCount * SEW;
1071 if (Info.
ElementType == CGM.getContext().BoolTy) {
1074 }
else if (FixedSize < 64) {
1077 LMUL = 64 / FixedSize;
1079 LMUL = FixedSize / 64;
1083 SmallVector<uint64_t, 12> Expr(
1087 {llvm::dwarf::DW_OP_bregx,
1090 llvm::dwarf::DW_OP_constu,
1092 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1094 Expr.push_back(llvm::dwarf::DW_OP_div);
1096 Expr.push_back(llvm::dwarf::DW_OP_mul);
1099 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1101 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1104 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1105 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1106 auto *UpperBound = DBuilder.createExpression(Expr);
1107 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1108 nullptr, LowerBound, UpperBound,
nullptr);
1109 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1110 llvm::DIType *ElemTy =
1111 getOrCreateType(Info.
ElementType, TheCU->getFile());
1114 return DBuilder.createVectorType(0, Align, ElemTy,
1118#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1119 case BuiltinType::Id: { \
1122 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1123 MangledName, TheCU, TheCU->getFile(), 0); \
1124 return SingletonId; \
1126#include "clang/Basic/WebAssemblyReferenceTypes.def"
1127#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1128 case BuiltinType::Id: { \
1131 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1132 TheCU, TheCU->getFile(), 0); \
1133 return SingletonId; \
1135#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1136 case BuiltinType::Id: { \
1139 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1140 return SingletonId; \
1142#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1143 case BuiltinType::Id: { \
1146 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1147 return SingletonId; \
1149#include "clang/Basic/AMDGPUTypes.def"
1150#define SPIRV_TYPE(Name, Id, SingletonId) \
1151 case BuiltinType::Id: \
1152 return getOrCreateStructPtrType(Name, SingletonId);
1153#include "clang/Basic/SPIRVTypes.def"
1154 case BuiltinType::UChar:
1155 case BuiltinType::Char_U:
1156 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1158 case BuiltinType::Char_S:
1159 case BuiltinType::SChar:
1160 Encoding = llvm::dwarf::DW_ATE_signed_char;
1162 case BuiltinType::Char8:
1163 case BuiltinType::Char16:
1164 case BuiltinType::Char32:
1165 Encoding = llvm::dwarf::DW_ATE_UTF;
1167 case BuiltinType::UShort:
1168 case BuiltinType::UInt:
1169 case BuiltinType::UInt128:
1170 case BuiltinType::ULong:
1171 case BuiltinType::WChar_U:
1172 case BuiltinType::ULongLong:
1173 Encoding = llvm::dwarf::DW_ATE_unsigned;
1175 case BuiltinType::Short:
1176 case BuiltinType::Int:
1177 case BuiltinType::Int128:
1178 case BuiltinType::Long:
1179 case BuiltinType::WChar_S:
1180 case BuiltinType::LongLong:
1181 Encoding = llvm::dwarf::DW_ATE_signed;
1183 case BuiltinType::Bool:
1184 Encoding = llvm::dwarf::DW_ATE_boolean;
1186 case BuiltinType::Half:
1187 case BuiltinType::Float:
1188 case BuiltinType::LongDouble:
1189 case BuiltinType::Float16:
1190 case BuiltinType::BFloat16:
1191 case BuiltinType::Float128:
1192 case BuiltinType::Double:
1193 case BuiltinType::Ibm128:
1199 Encoding = llvm::dwarf::DW_ATE_float;
1201 case BuiltinType::ShortAccum:
1202 case BuiltinType::Accum:
1203 case BuiltinType::LongAccum:
1204 case BuiltinType::ShortFract:
1205 case BuiltinType::Fract:
1206 case BuiltinType::LongFract:
1207 case BuiltinType::SatShortFract:
1208 case BuiltinType::SatFract:
1209 case BuiltinType::SatLongFract:
1210 case BuiltinType::SatShortAccum:
1211 case BuiltinType::SatAccum:
1212 case BuiltinType::SatLongAccum:
1213 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1215 case BuiltinType::UShortAccum:
1216 case BuiltinType::UAccum:
1217 case BuiltinType::ULongAccum:
1218 case BuiltinType::UShortFract:
1219 case BuiltinType::UFract:
1220 case BuiltinType::ULongFract:
1221 case BuiltinType::SatUShortAccum:
1222 case BuiltinType::SatUAccum:
1223 case BuiltinType::SatULongAccum:
1224 case BuiltinType::SatUShortFract:
1225 case BuiltinType::SatUFract:
1226 case BuiltinType::SatULongFract:
1227 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1229 case BuiltinType::MetaInfo:
1230 llvm_unreachable(
"std::meta::info is consteval-only type");
1233 BTName = BT->
getName(CGM.getLangOpts());
1236 return DBuilder.createBasicType(BTName, Size, Encoding);
1239llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1240 SmallString<32> Name;
1241 llvm::raw_svector_ostream
OS(Name);
1242 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1245 ? llvm::dwarf::DW_ATE_unsigned
1246 : llvm::dwarf::DW_ATE_signed;
1247 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1248 Encoding, llvm::DINode::FlagZero, 0,
1252llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1254 return getOrCreateType(Ty->getUnderlyingType(), U);
1257llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1259 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1261 Encoding = llvm::dwarf::DW_ATE_lo_user;
1264 return DBuilder.createBasicType(
"complex", Size, Encoding);
1278 return llvm::dwarf::DW_TAG_const_type;
1282 return llvm::dwarf::DW_TAG_volatile_type;
1286 return llvm::dwarf::DW_TAG_restrict_type;
1288 return (llvm::dwarf::Tag)0;
1291llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1292 llvm::DIFile *Unit) {
1293 QualifierCollector Qc;
1307 bool AuthenticatesNullValues =
1310 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1311 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1312 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1313 ExtraDiscr, IsaPointer,
1314 AuthenticatesNullValues);
1316 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1317 return getOrCreateType(QualType(
T, 0), Unit);
1321 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1325 return DBuilder.createQualifiedType(Tag, FromTy);
1328llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1329 llvm::DIFile *Unit) {
1338 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1343 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1349 return DBuilder.createQualifiedType(Tag, FromTy);
1352llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1353 llvm::DIFile *Unit) {
1359 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1361 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1365llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1366 llvm::DIFile *Unit) {
1367 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1373 case llvm::dwarf::DW_LANG_C_plus_plus:
1374 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1375 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1376 case llvm::dwarf::DW_LANG_HIP:
1378 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1388 case llvm::dwarf::DW_LNAME_C_plus_plus:
1389 case llvm::dwarf::DW_LNAME_HIP:
1391 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1402 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1403 SourceLang.hasVersionedName())
1405 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1409 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1435 llvm::DICompileUnit *TheCU) {
1453 llvm::DICompileUnit *TheCU) {
1459 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1461 if (RD->isDynamicClass() &&
1467 llvm::raw_svector_ostream Out(Identifier);
1474 llvm::dwarf::Tag Tag;
1476 Tag = llvm::dwarf::DW_TAG_structure_type;
1478 Tag = llvm::dwarf::DW_TAG_union_type;
1483 Tag = llvm::dwarf::DW_TAG_class_type;
1488llvm::DICompositeType *
1489CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1490 llvm::DIScope *Ctx) {
1492 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1494 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1495 const unsigned Line =
1497 StringRef RDName = getClassName(RD);
1504 Size = CGM.getContext().getTypeSize(Ty);
1506 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1511 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1512 if (!CXXRD->hasDefinition() ||
1513 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1514 Flags |= llvm::DINode::FlagNonTrivial;
1517 SmallString<256> Identifier;
1519 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1521 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1524 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1525 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1526 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1527 CollectCXXTemplateParams(TSpecial, DefUnit));
1528 ReplaceMap.emplace_back(
1529 std::piecewise_construct, std::make_tuple(Ty),
1530 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1534llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1537 llvm::DIFile *Unit) {
1542 std::optional<unsigned> DWARFAddressSpace =
1543 CGM.getTarget().getDWARFAddressSpace(
1544 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1546 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1547 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1548 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1549 Size, Align, DWARFAddressSpace);
1551 SmallVector<llvm::Metadata *, 4> Annots;
1552 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1554 llvm::DINodeArray Annotations =
nullptr;
1555 if (Annots.size() > 0)
1556 Annotations = DBuilder.getOrCreateArray(Annots);
1557 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1558 Align, DWARFAddressSpace, StringRef(),
1563llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1564 llvm::DIType *&
Cache) {
1567 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1568 TheCU, TheCU->getFile(), 0);
1569 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1570 Cache = DBuilder.createPointerType(
Cache, Size);
1574uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1575 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1576 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1586 if (CGM.getLangOpts().OpenCL) {
1587 FType = CGM.getContext().IntTy;
1588 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1589 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1591 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1592 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1593 FType = CGM.getContext().IntTy;
1594 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1595 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1597 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1598 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1599 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1600 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1601 EltTys.push_back(DBuilder.createMemberType(
1602 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1603 FieldOffset, llvm::DINode::FlagZero, DescTy));
1604 FieldOffset += FieldSize;
1610llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1611 llvm::DIFile *Unit) {
1612 SmallVector<llvm::Metadata *, 8> EltTys;
1615 llvm::DINodeArray Elements;
1618 FType = CGM.getContext().UnsignedLongTy;
1619 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1620 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1622 Elements = DBuilder.getOrCreateArray(EltTys);
1625 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1628 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1629 FieldOffset, 0, Flags,
nullptr, Elements);
1634 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1636 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1639 Elements = DBuilder.getOrCreateArray(EltTys);
1645 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1646 Flags,
nullptr, Elements);
1648 return DBuilder.createPointerType(EltTy, Size);
1651static llvm::SmallVector<TemplateArgument>
1653 assert(Ty->isTypeAlias());
1662 ArrayRef SubstArgs = Ty->template_arguments();
1665 if (Param->isParameterPack()) {
1674 if (SubstArgs.empty()) {
1683 SpecArgs.push_back(SubstArgs.front());
1684 SubstArgs = SubstArgs.drop_front();
1689llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1690 llvm::DIFile *Unit) {
1691 assert(Ty->isTypeAlias());
1692 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1694 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1702 SmallString<128> NS;
1703 llvm::raw_svector_ostream
OS(NS);
1705 auto PP = getPrintingPolicy();
1708 SourceLocation Loc =
AliasDecl->getLocation();
1710 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1711 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1720 llvm::raw_string_ostream
OS(Name);
1722 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1723 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1724 !HasReconstitutableArgs(Args.Args))
1725 printTemplateArgumentList(OS, Args.Args, PP);
1727 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1728 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1729 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1733 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1735 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1752 return llvm::DINode::FlagZero;
1756 return llvm::DINode::FlagPrivate;
1758 return llvm::DINode::FlagProtected;
1760 return llvm::DINode::FlagPublic;
1762 return llvm::DINode::FlagZero;
1764 llvm_unreachable(
"unexpected access enumerator");
1767llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1768 llvm::DIFile *Unit) {
1769 llvm::DIType *Underlying =
1785 SmallVector<llvm::Metadata *, 4> Annots;
1786 llvm::DINodeArray Annotations;
1788 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1789 if (!Annots.empty())
1790 Annotations = DBuilder.getOrCreateArray(Annots);
1792 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1797 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1798 getOrCreateFile(Loc), getLineNumber(Loc),
1799 getDeclContextDescriptor(Ty->
getDecl()), Align,
1800 Flags, Annotations);
1808 if (
T.isSPIROrSPIRV())
1809 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1814 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1816 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1818 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1820 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1822 return llvm::dwarf::DW_CC_BORLAND_pascal;
1824 return llvm::dwarf::DW_CC_LLVM_Win64;
1826 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1830 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1832 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1834 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1836 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1838 return llvm::dwarf::DW_CC_LLVM_Swift;
1840 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1842 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1844 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1846 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1848 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1850 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1852 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1853#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1867 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1873 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1875 Flags |= llvm::DINode::FlagLValueReference;
1877 Flags |= llvm::DINode::FlagRValueReference;
1881llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1882 llvm::DIFile *Unit) {
1883 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1885 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1891 SmallVector<llvm::Metadata *, 16> EltTys;
1894 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1896 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1900 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1903 for (
const QualType &ParamType : FPT->param_types())
1904 EltTys.push_back(getOrCreateType(ParamType, Unit));
1905 if (FPT->isVariadic())
1906 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1909 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1910 llvm::DIType *F = DBuilder.createSubroutineType(
1911 EltTypeArray, Flags,
1916llvm::DIDerivedType *
1917CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1918 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1919 StringRef Name = BitFieldDecl->
getName();
1920 QualType Ty = BitFieldDecl->
getType();
1921 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1924 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1925 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1928 llvm::DIFile *
File = getOrCreateFile(Loc);
1929 unsigned Line = getLineNumber(Loc);
1931 const CGBitFieldInfo &BitFieldInfo =
1932 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1934 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1941 if (CGM.getDataLayout().isBigEndian())
1943 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1945 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1946 return DBuilder.createBitFieldMemberType(
1947 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1948 Flags, DebugType, Annotations);
1951llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1952 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1953 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1955 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1980 if (PreviousFieldsDI.empty())
1984 auto *PreviousMDEntry =
1985 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1986 auto *PreviousMDField =
1987 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1988 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1989 PreviousMDField->getSizeInBits() == 0)
1993 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1995 assert(PreviousBitfield->isBitField());
1997 if (!PreviousBitfield->isZeroLengthBitField())
2000 QualType Ty = PreviousBitfield->getType();
2001 SourceLocation Loc = PreviousBitfield->getLocation();
2002 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2003 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
2004 llvm::DIScope *RecordTy = BitFieldDI->getScope();
2006 llvm::DIFile *
File = getOrCreateFile(Loc);
2007 unsigned Line = getLineNumber(Loc);
2013 llvm::DINode::DIFlags Flags =
2015 llvm::DINodeArray Annotations =
2016 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2017 return DBuilder.createBitFieldMemberType(
2018 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2019 Flags, DebugType, Annotations);
2022llvm::DIType *CGDebugInfo::createFieldType(
2024 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2025 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2026 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2029 llvm::DIFile *file = getOrCreateFile(loc);
2030 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2033 auto Align = AlignInBits;
2034 if (!
type->isIncompleteArrayType()) {
2035 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2036 SizeInBits = TI.
Width;
2042 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2043 offsetInBits, flags, debugType, Annotations);
2047CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2048 llvm::DIFile *FileScope) {
2052 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2055 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2056 SP = DBuilder.createFunction(
2057 FileScope, FuncName, StringRef(),
2058 FileScope, 0, DIFnTy,
2060 llvm::DINode::FlagArtificial,
2061 llvm::DISubprogram::SPFlagDefinition,
2062 nullptr,
nullptr,
nullptr,
2063 nullptr, StringRef(),
2064 CGM.getCodeGenOpts().DebugKeyInstructions);
2071CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2073 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2075 assert(
Capture.capturesVariable());
2077 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2078 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2080 return CaptureDecl->
getName();
2083void CGDebugInfo::CollectRecordLambdaFields(
2084 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2085 llvm::DIType *RecordTy) {
2090 unsigned fieldno = 0;
2093 I != E; ++I, ++Field, ++fieldno) {
2094 const LambdaCapture &
Capture = *I;
2096 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2098 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2108 Loc =
Field->getLocation();
2109 }
else if (
Capture.capturesVariable()) {
2112 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2113 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2120 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2122 FieldIndexCache[*
Field] = elements.size();
2123 elements.push_back(createFieldType(
2125 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2131template <
typename T>
2132static llvm::Constant *
2143 return llvm::ConstantDataArray::get(Ctx, Vals);
2156 const QualType ElemQTy = ArrayTy->getElementType();
2163 switch (ElemBitWidth) {
2179llvm::DIDerivedType *
2180CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2181 const RecordDecl *RD) {
2185 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2186 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2188 unsigned LineNumber = getLineNumber(Var->
getLocation());
2189 StringRef VName = Var->
getName();
2193 llvm::Constant *
C =
nullptr;
2198 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2199 if (
Value->isFloat())
2200 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2201 if (
Value->isArray())
2207 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2208 ? llvm::dwarf::DW_TAG_variable
2209 : llvm::dwarf::DW_TAG_member;
2211 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2212 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2217void CGDebugInfo::CollectRecordNormalField(
2218 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2219 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2220 const RecordDecl *RD) {
2225 if (
name.empty() && !
type->isRecordType())
2228 llvm::DIType *FieldType;
2230 llvm::DIDerivedType *BitFieldType;
2231 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2232 if (llvm::DIType *Separator =
2233 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2234 elements.push_back(Separator);
2237 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2240 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2243 FieldIndexCache[field] = elements.size();
2244 elements.push_back(FieldType);
2247void CGDebugInfo::CollectRecordNestedType(
2248 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2249 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2256 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2257 elements.push_back(nestedType);
2260void CGDebugInfo::CollectRecordFields(
2261 const RecordDecl *record, llvm::DIFile *tunit,
2262 SmallVectorImpl<llvm::Metadata *> &elements,
2263 llvm::DICompositeType *RecordTy) {
2264 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2266 if (CXXDecl && CXXDecl->
isLambda())
2267 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2269 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2272 unsigned fieldNo = 0;
2276 for (
const auto *I : record->
decls())
2277 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2278 if (
V->hasAttr<NoDebugAttr>())
2283 if (CGM.getCodeGenOpts().EmitCodeView &&
2291 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2292 if (MI != StaticDataMemberCache.end()) {
2293 assert(MI->second &&
2294 "Static data member declaration should still exist");
2295 elements.push_back(MI->second);
2297 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2298 elements.push_back(Field);
2300 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2301 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2302 elements, RecordTy, record);
2306 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2309 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2314 if (!nestedType->isImplicit() &&
2315 nestedType->getDeclContext() == record)
2316 CollectRecordNestedType(nestedType, elements);
2322llvm::DISubroutineType *
2323CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2324 llvm::DIFile *Unit) {
2325 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2327 return cast_or_null<llvm::DISubroutineType>(
2328 getOrCreateType(QualType(
Func, 0), Unit));
2331 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2332 ThisType =
Method->getThisType();
2334 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2337llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2338 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2339 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2341 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2344llvm::DISubroutineType *
2345CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2346 const FunctionProtoType *
Func,
2347 llvm::DIFile *Unit,
bool SkipFirst) {
2348 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2363 getOrCreateType(CGM.getContext().getFunctionType(
2364 Func->getReturnType(),
Func->getParamTypes(), EPI),
2366 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2367 assert(Args.size() &&
"Invalid number of arguments!");
2369 SmallVector<llvm::Metadata *, 16> Elts;
2372 Elts.push_back(Args[0]);
2374 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2378 if (!HasExplicitObjectParameter) {
2379 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2382 DBuilder.createObjectPointerType(ThisPtrType,
true);
2383 Elts.push_back(ThisPtrType);
2387 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2388 Elts.push_back(Args[i]);
2391 if (HasExplicitObjectParameter) {
2392 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2393 "Expected at least return type and object parameter.");
2394 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2397 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2399 return DBuilder.createSubroutineType(
2400 EltTypeArray, OriginalFunc->getFlags(),
2407 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2415CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2418 const bool IsCtorOrDtor =
2421 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2428 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2431 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2434 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2437 return CGM.getMangledName(
Method);
2440bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2443 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2446llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2447 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2450 StringRef MethodName = getFunctionName(
Method);
2451 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2453 StringRef MethodLinkageName;
2460 MethodLinkageName = GetMethodLinkageName(
Method);
2463 llvm::DIFile *MethodDefUnit =
nullptr;
2464 unsigned MethodLine = 0;
2465 if (!
Method->isImplicit()) {
2466 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2467 MethodLine = getLineNumber(
Method->getLocation());
2471 llvm::DIType *ContainingType =
nullptr;
2472 unsigned VIndex = 0;
2473 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2474 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2475 int ThisAdjustment = 0;
2478 if (
Method->isPureVirtual())
2479 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2481 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2483 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2487 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2491 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2494 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2495 CGM.getContext().getLangOpts())
2499 MethodVFTableLocation ML =
2500 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2508 if (
Method->size_overridden_methods() == 0)
2509 Flags |= llvm::DINode::FlagIntroducedVirtual;
2514 ThisAdjustment = CGM.getCXXABI()
2515 .getVirtualFunctionPrologueThisAdjustment(GD)
2518 ContainingType = RecordTy;
2521 if (
Method->getCanonicalDecl()->isDeleted())
2522 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2524 if (
Method->isNoReturn())
2525 Flags |= llvm::DINode::FlagNoReturn;
2528 Flags |= llvm::DINode::FlagStaticMember;
2529 if (
Method->isImplicit())
2530 Flags |= llvm::DINode::FlagArtificial;
2532 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2533 if (CXXC->isExplicit())
2534 Flags |= llvm::DINode::FlagExplicit;
2535 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2536 if (CXXC->isExplicit())
2537 Flags |= llvm::DINode::FlagExplicit;
2539 if (
Method->hasPrototype())
2540 Flags |= llvm::DINode::FlagPrototyped;
2542 Flags |= llvm::DINode::FlagLValueReference;
2544 Flags |= llvm::DINode::FlagRValueReference;
2545 if (!
Method->isExternallyVisible())
2546 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2547 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2548 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2553 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2554 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2555 if (
const auto *Def =
2556 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2557 Def && !Def->isDelegatingConstructor()) {
2563 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2564 llvm::DISubprogram *SP = DBuilder.createMethod(
2565 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2566 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2567 TParamsArray.get(),
nullptr,
2568 CGM.getCodeGenOpts().DebugKeyInstructions);
2570 SPCache[
Method->getCanonicalDecl()].reset(SP);
2575void CGDebugInfo::CollectCXXMemberFunctions(
2576 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2577 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2582 for (
const auto *I : RD->
decls()) {
2583 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2597 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2606 auto MI = SPCache.find(
Method->getCanonicalDecl());
2607 EltTys.push_back(MI == SPCache.end()
2608 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2609 :
static_cast<llvm::Metadata *
>(MI->second));
2613void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2614 SmallVectorImpl<llvm::Metadata *> &EltTys,
2615 llvm::DIType *RecordTy) {
2616 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2617 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2618 llvm::DINode::FlagZero);
2622 if (CGM.getCodeGenOpts().EmitCodeView) {
2623 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2624 llvm::DINode::FlagIndirectVirtualBase);
2628void CGDebugInfo::CollectCXXBasesAux(
2629 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2630 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2632 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2633 llvm::DINode::DIFlags StartingFlags) {
2634 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2635 for (
const auto &BI : Bases) {
2638 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2640 if (!SeenTypes.insert(Base).second)
2642 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2643 llvm::DINode::DIFlags BFlags = StartingFlags;
2647 if (BI.isVirtual()) {
2648 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2651 BaseOffset = 0 - CGM.getItaniumVTableContext()
2652 .getVirtualBaseOffsetOffset(RD, Base)
2658 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2659 VBPtrOffset = CGM.getContext()
2660 .getASTRecordLayout(RD)
2664 BFlags |= llvm::DINode::FlagVirtual;
2671 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2672 VBPtrOffset, BFlags);
2673 EltTys.push_back(DTy);
2678CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2679 llvm::DIFile *Unit) {
2681 return llvm::DINodeArray();
2682 TemplateArgs &Args = *OArgs;
2683 SmallVector<llvm::Metadata *, 16> TemplateParams;
2684 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2685 const TemplateArgument &TA = Args.Args[i];
2689 Name = Args.TList->getParam(i)->getName();
2693 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2694 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2695 TheCU, Name, TTy, defaultParameter));
2700 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2701 TheCU, Name, TTy, defaultParameter,
2702 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2707 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2708 llvm::Constant *
V =
nullptr;
2711 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2712 !D->
hasAttr<CUDADeviceAttr>()) {
2715 if (
const auto *VD = dyn_cast<VarDecl>(D))
2716 V = CGM.GetAddrOfGlobalVar(VD);
2719 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2720 MD && MD->isImplicitObjectMemberFunction())
2721 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2722 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2723 V = CGM.GetAddrOfFunction(FD);
2726 else if (
const auto *MPT =
2727 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2731 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2733 CGM.getContext().toCharUnitsFromBits((
int64_t)fieldOffset);
2734 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2735 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2736 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2737 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2739 V = ConstantEmitter(CGM).emitAbstract(
2740 SourceLocation(), TPO->getValue(), TPO->getType());
2742 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2744 assert(
V &&
"Failed to find template parameter pointer");
2745 V =
V->stripPointerCasts();
2747 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2748 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2752 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2753 llvm::Constant *
V =
nullptr;
2756 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2762 if (MPT->isMemberDataPointer())
2763 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2765 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2766 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2767 TheCU, Name, TTy, defaultParameter,
V));
2771 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2772 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2774 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2775 TheCU, Name, TTy, defaultParameter,
V));
2778 std::string QualName;
2779 llvm::raw_string_ostream
OS(QualName);
2781 OS, getPrintingPolicy());
2782 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2783 TheCU, Name,
nullptr, QualName, defaultParameter));
2787 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2788 TheCU, Name,
nullptr,
2795 T = CGM.getContext().getLValueReferenceType(
T);
2796 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2797 assert(
V &&
"Expression in template argument isn't constant");
2798 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2799 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2800 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2806 "These argument types shouldn't exist in concrete types");
2809 return DBuilder.getOrCreateArray(TemplateParams);
2812std::optional<CGDebugInfo::TemplateArgs>
2813CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2821 return std::nullopt;
2823std::optional<CGDebugInfo::TemplateArgs>
2824CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2828 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2830 return std::nullopt;
2831 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2832 const TemplateParameterList *TList =
T->getTemplateParameters();
2833 auto TA = TS->getTemplateArgs().asArray();
2834 return {{TList, TA}};
2836std::optional<CGDebugInfo::TemplateArgs>
2837CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2838 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2842 TemplateParameterList *TPList =
2843 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2844 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2845 return {{TPList, TAList.
asArray()}};
2847 return std::nullopt;
2851CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2852 llvm::DIFile *Unit) {
2853 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2856llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2857 llvm::DIFile *Unit) {
2858 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2861llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2862 llvm::DIFile *Unit) {
2863 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2866void CGDebugInfo::CollectBTFDeclTagAnnotations(
2867 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2869 llvm::Metadata *Ops[2] = {
2870 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2871 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2872 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2876llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2877 if (!D->
hasAttr<BTFDeclTagAttr>())
2880 SmallVector<llvm::Metadata *, 4> Annotations;
2881 CollectBTFDeclTagAnnotations(D, Annotations);
2882 return DBuilder.getOrCreateArray(Annotations);
2885void CGDebugInfo::CollectBTFTypeTagAnnotations(
2886 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2887 const BTFTagAttributedType *BTFAttrTy;
2889 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2891 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2894 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2896 llvm::Metadata *Ops[2] = {
2897 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2898 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2899 Annotations.insert(Annotations.begin(),
2900 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2902 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2906llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2908 return VTablePtrType;
2910 ASTContext &Context = CGM.getContext();
2913 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2914 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2915 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2917 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2918 std::optional<unsigned> DWARFAddressSpace =
2919 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2921 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2922 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2923 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2924 return VTablePtrType;
2927StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2939 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2941 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2951 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2952 VTable->isDeclarationForLinker())
2956 StringRef SymbolName =
"__clang_vtable";
2958 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2967 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2969 llvm::DIFile *Unit = getOrCreateFile(Loc);
2970 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2972 llvm::DINode::FlagArtificial;
2973 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2974 ? llvm::dwarf::DW_TAG_variable
2975 : llvm::dwarf::DW_TAG_member;
2976 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2977 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2981 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2985 llvm::DIGlobalVariableExpression *GVE =
2986 DBuilder.createGlobalVariableExpression(
2987 TheCU, SymbolName, VTable->getName(), Unit, 0,
2988 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2989 true,
nullptr, DT,
nullptr,
2991 VTable->addDebugInfo(GVE);
2994StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2996 llvm::Function *InitFn) {
3001 return InitFn->getName();
3011 llvm::raw_svector_ostream OS(QualifiedGV);
3013 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3015 std::swap(Quals, GVName);
3019 llvm::raw_svector_ostream OS(InitName);
3021 OS << Quals <<
"::";
3026 llvm_unreachable(
"not an initializer");
3028 OS <<
"`dynamic initializer for '";
3031 OS <<
"`dynamic atexit destructor for '";
3038 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3039 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3040 getPrintingPolicy());
3045 return internString(
OS.str());
3048void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3049 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3058 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3065 llvm::DIType *VPtrTy =
nullptr;
3066 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3067 CGM.getTarget().getCXXABI().isMicrosoft();
3068 if (NeedVTableShape) {
3070 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3071 const VTableLayout &VFTLayout =
3072 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3073 unsigned VSlotCount =
3075 unsigned VTableWidth = PtrWidth * VSlotCount;
3076 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3077 std::optional<unsigned> DWARFAddressSpace =
3078 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3081 llvm::DIType *VTableType = DBuilder.createPointerType(
3082 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3083 EltTys.push_back(VTableType);
3086 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3094 VPtrTy = getOrCreateVTablePtrType(Unit);
3096 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3097 llvm::DIType *VPtrMember =
3098 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3099 llvm::DINode::FlagArtificial, VPtrTy);
3100 EltTys.push_back(VPtrMember);
3103std::pair<llvm::DIType *, unsigned>
3108 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3115 auto I = FieldIndexCache.find(Field);
3116 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3117 return {
T, I->second};
3127 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3128 assert(!D.
isNull() &&
"null type");
3129 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3130 assert(
T &&
"could not create debug info for type");
3139 if (CGM.getCodeGenOpts().getDebugInfo() <=
3140 llvm::codegenoptions::DebugLineTablesOnly)
3144 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3146 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3148 CI->setMetadata(
"heapallocsite", node);
3152 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3154 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3156 auto I = TypeCache.find(TyPtr);
3159 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3160 assert(!Res->isForwardDecl());
3161 TypeCache[TyPtr].reset(Res);
3165 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3166 !CGM.getLangOpts().CPlusPlus)
3172 if (RD->
hasAttr<DLLImportAttr>())
3175 if (MD->hasAttr<DLLImportAttr>())
3188 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3198 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3199 Explicit = TD->isExplicitInstantiationOrSpecialization();
3203 if (CXXDecl->
fields().empty())
3213 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3214 if (CXXRD->isDynamicClass() &&
3215 CGM.getVTableLinkage(CXXRD) ==
3216 llvm::GlobalValue::AvailableExternallyLinkage &&
3227 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3229 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3231 auto I = TypeCache.find(TyPtr);
3238 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3239 assert(!Res->isForwardDecl());
3240 TypeCache[TyPtr].reset(Res);
3247 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3248 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3275 bool HasNonDeletedCtor =
false;
3277 if (Ctor->isCopyOrMoveConstructor())
3284 if (CtorDef->isDelegatingConstructor())
3288 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3291 if (!Ctor->isDeleted())
3292 HasNonDeletedCtor =
true;
3294 return HasNonDeletedCtor;
3310 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3313 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3314 RD->
hasAttr<StandaloneDebugAttr>())
3317 if (!LangOpts.CPlusPlus)
3323 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3339 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3340 Spec = SD->getSpecializationKind();
3349 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3360 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3361 llvm::DIType *
T = getTypeOrNull(Ty);
3362 if (
T &&
T->isForwardDecl())
3366llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3368 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3372 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3376 auto [Def, Pref] = CreateTypeDefinition(Ty);
3378 return Pref ? Pref : Def;
3381llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3382 llvm::DIFile *Unit) {
3386 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3390 return getOrCreateType(PNA->getTypedefType(), Unit);
3417 const auto *RT = QT->
getAs<RecordType>();
3421 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3422 if (!CRD || !CRD->hasDefinition())
3427 assert(CRD->isStandardLayout());
3433std::pair<llvm::DIType *, llvm::DIType *>
3434CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3438 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3446 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3450 return {FwdDecl,
nullptr};
3452 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3453 CollectContainingType(CXXDecl, FwdDecl);
3456 LexicalBlockStack.emplace_back(&*FwdDecl);
3457 RegionMap[RD].reset(FwdDecl);
3460 SmallVector<llvm::Metadata *, 16> EltTys;
3467 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3469 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3470 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3474 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3475 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3476 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3478 LexicalBlockStack.pop_back();
3479 RegionMap.erase(RD);
3481 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3482 DBuilder.replaceArrays(FwdDecl, Elements);
3484 if (FwdDecl->isTemporary())
3486 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3488 RegionMap[RD].reset(FwdDecl);
3490 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3505 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3506 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3507 return {FwdDecl, PrefDI};
3509 return {FwdDecl,
nullptr};
3512llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3513 llvm::DIFile *Unit) {
3515 return getOrCreateType(Ty->getBaseType(), Unit);
3518llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3519 llvm::DIFile *Unit) {
3521 SourceLocation Loc = Ty->getDecl()->getLocation();
3524 return DBuilder.createTypedef(
3525 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3526 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3527 getDeclContextDescriptor(Ty->getDecl()));
3554llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3555 llvm::DIFile *Unit) {
3560 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3561 TheCU->getSourceLanguage().getUnversionedName());
3566 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3567 !
ID->getImplementation())
3568 return DBuilder.createForwardDecl(
3569 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3570 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3573 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3574 unsigned Line = getLineNumber(
ID->getLocation());
3578 ObjCInterfaceDecl *Def =
ID->getDefinition();
3580 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3581 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3582 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3583 DefUnit,
Line, RuntimeLang);
3584 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3588 return CreateTypeDefinition(Ty, Unit);
3591llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3592 bool CreateSkeletonCU) {
3597 auto ModRef = ModuleCache.find(M);
3598 if (ModRef != ModuleCache.end())
3602 SmallString<128> ConfigMacros;
3604 llvm::raw_svector_ostream
OS(ConfigMacros);
3605 const auto &PPOpts = CGM.getPreprocessorOpts();
3608 for (
auto &M : PPOpts.Macros) {
3611 const std::string &
Macro = M.first;
3612 bool Undef = M.second;
3613 OS <<
"\"-" << (Undef ?
'U' :
'D');
3614 for (
char c :
Macro)
3629 bool IsRootModule = M ? !M->
Parent :
true;
3633 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3634 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3635 "clang module without ASTFile must be specified by -fmodule-name");
3638 auto RemapPath = [
this](StringRef Path) -> std::string {
3640 StringRef Relative(Remapped);
3641 StringRef CompDir = TheCU->getDirectory();
3642 if (CompDir.empty())
3645 if (Relative.consume_front(CompDir))
3646 Relative.consume_front(llvm::sys::path::get_separator());
3648 return Relative.str();
3651 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3658 Signature = ModSig.truncatedValue();
3662 llvm::DIBuilder DIB(CGM.getModule());
3664 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3665 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3666 PCM = getCurrentDirname();
3670 llvm::sys::path::append(PCM, Mod.
getASTFile());
3671 DIB.createCompileUnit(
3672 TheCU->getSourceLanguage(),
3675 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3676 llvm::DICompileUnit::FullDebug, Signature);
3680 llvm::DIModule *Parent =
3682 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3684 StringRef IncludePath = Mod.
getPath();
3685 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3686 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3687 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3690 llvm::DIModule *DIMod =
3691 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3692 RemapPath(IncludePath));
3693 ModuleCache[M].reset(DIMod);
3697llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3698 llvm::DIFile *Unit) {
3700 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3701 unsigned Line = getLineNumber(
ID->getLocation());
3703 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3709 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3710 if (
ID->getImplementation())
3711 Flags |= llvm::DINode::FlagObjcClassComplete;
3713 llvm::DINodeArray Annotations;
3714 const auto *RuntimeName =
ID->getAttr<ObjCRuntimeNameAttr>();
3715 if (RuntimeName && RuntimeName->getMetadataName() !=
ID->getName()) {
3716 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
3717 llvm::Metadata *Ops[2] = {
3718 llvm::MDString::get(Ctx,
"objc_runtime_name"),
3719 llvm::MDString::get(Ctx, RuntimeName->getMetadataName())};
3720 Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)});
3723 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3724 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3725 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3726 nullptr, llvm::DINodeArray(), RuntimeLang,
nullptr,
3730 QualType QTy(Ty, 0);
3731 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3734 LexicalBlockStack.emplace_back(RealDecl);
3735 RegionMap[Ty->
getDecl()].reset(RealDecl);
3738 SmallVector<llvm::Metadata *, 16> EltTys;
3740 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3742 llvm::DIType *SClassTy =
3743 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3747 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3748 llvm::DINode::FlagZero);
3749 EltTys.push_back(InhTag);
3753 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3754 SourceLocation Loc = PD->getLocation();
3755 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3756 unsigned PLine = getLineNumber(Loc);
3757 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3758 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3759 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3760 PD->getName(), PUnit, PLine,
3762 : getSelectorName(PD->getGetterName()),
3764 : getSelectorName(PD->getSetterName()),
3765 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3766 EltTys.push_back(PropertyNode);
3771 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3775 llvm::DenseSet<IsClassAndIdent> PropertySet;
3777 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3778 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3780 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3781 for (
auto *PD : ClassExt->properties()) {
3782 PropertySet.insert(GetIsClassAndIdent(PD));
3785 for (
const auto *PD :
ID->properties()) {
3788 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3794 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3795 unsigned FieldNo = 0;
3796 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3797 Field =
Field->getNextIvar(), ++FieldNo) {
3798 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3802 StringRef FieldName =
Field->getName();
3805 if (FieldName.empty())
3809 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3810 unsigned FieldLine = getLineNumber(
Field->getLocation());
3811 QualType FType =
Field->getType();
3818 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3819 : CGM.getContext().getTypeSize(FType);
3824 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3828 if (
Field->isBitField()) {
3830 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3831 FieldOffset %= CGM.getContext().getCharWidth();
3839 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3841 Flags = llvm::DINode::FlagProtected;
3843 Flags = llvm::DINode::FlagPrivate;
3845 Flags = llvm::DINode::FlagPublic;
3847 if (
Field->isBitField())
3848 Flags |= llvm::DINode::FlagBitField;
3850 llvm::MDNode *PropertyNode =
nullptr;
3851 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3852 llvm::DIFile *PUnit =
nullptr;
3854 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3855 if (ObjCPropertyImplDecl *PImpD =
3856 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3857 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3858 SynthesizedProperty = PD;
3859 SourceLocation Loc = PD->getLocation();
3860 PUnit = getOrCreateFile(Loc);
3861 PLine = getLineNumber(Loc);
3862 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3863 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3864 PropertyNode = DBuilder.createObjCProperty(
3865 PD->getName(), PUnit, PLine,
3868 : getSelectorName(PD->getGetterName()),
3871 : getSelectorName(PD->getSetterName()),
3872 PD->getPropertyAttributes(),
3873 getOrCreateType(PD->getType(), PUnit));
3877 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3878 FieldSize, FieldAlign, FieldOffset,
3879 Flags, FieldTy, PropertyNode);
3880 EltTys.push_back(IvarTy);
3882 if (SynthesizedProperty) {
3883 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3884 EltTys.push_back(DBuilder.createProperty(
3885 SynthesizedProperty->
getName(), PUnit, PLine,
3886 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3890 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3891 DBuilder.replaceArrays(RealDecl, Elements);
3893 LexicalBlockStack.pop_back();
3897llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3898 llvm::DIFile *Unit) {
3906 auto &Ctx = CGM.getContext();
3911 QualType CharVecTy =
3913 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3916 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3919 llvm::Metadata *Subscript;
3920 QualType QTy(Ty, 0);
3921 auto SizeExpr = SizeExprCache.find(QTy);
3922 if (SizeExpr != SizeExprCache.end())
3923 Subscript = DBuilder.getOrCreateSubrange(
3924 SizeExpr->getSecond() ,
nullptr ,
3925 nullptr ,
nullptr );
3928 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3929 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3930 Subscript = DBuilder.getOrCreateSubrange(
3931 CountNode ,
nullptr ,
nullptr ,
3934 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3939 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3942llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3943 llvm::DIFile *Unit) {
3947 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3952 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3953 auto *ColumnCountNode =
3954 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3955 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3956 auto *RowCountNode =
3957 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3958 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3959 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3960 ColumnCountNode ,
nullptr ,
nullptr ,
3962 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3963 RowCountNode ,
nullptr ,
nullptr ,
3965 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3966 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3969llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3974 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3989 Size = CGM.getContext().getTypeSize(Ty);
3996 SmallVector<llvm::Metadata *, 8> Subscripts;
3997 QualType EltTy(Ty, 0);
3998 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
4007 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
4008 Count = CAT->getZExtSize();
4009 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
4010 if (Expr *Size = VAT->getSizeExpr()) {
4012 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
4013 Count =
Result.Val.getInt().getExtValue();
4017 auto SizeNode = SizeExprCache.find(EltTy);
4018 if (SizeNode != SizeExprCache.end())
4019 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4020 SizeNode->getSecond() ,
nullptr ,
4021 nullptr ,
nullptr ));
4024 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4025 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4026 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4027 CountNode ,
nullptr ,
nullptr ,
4033 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4035 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4039llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4040 llvm::DIFile *Unit) {
4041 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4045llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4046 llvm::DIFile *Unit) {
4047 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4049 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4050 CGM.getCodeGenOpts().DwarfVersion < 4)
4051 Tag = llvm::dwarf::DW_TAG_reference_type;
4053 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4056llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4058 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4062 Size = CGM.getContext().getTypeSize(Ty);
4065 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4068 Flags |= llvm::DINode::FlagSingleInheritance;
4071 Flags |= llvm::DINode::FlagMultipleInheritance;
4074 Flags |= llvm::DINode::FlagVirtualInheritance;
4084 llvm::DIType *ClassType = getOrCreateType(
T, U);
4086 return DBuilder.createMemberPointerType(
4090 const FunctionProtoType *FPT =
4092 return DBuilder.createMemberPointerType(
4093 getOrCreateInstanceMethodType(
4096 ClassType, Size, 0, Flags);
4099llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4101 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4104llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4108llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4110 return getOrCreateType(Ty->getWrappedType(), U);
4113llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4120 const EnumType *Ty) {
4132llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4135 bool isImportedFromModule =
4136 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4140 if (isImportedFromModule || !ED->getDefinition()) {
4147 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4148 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4149 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4150 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4152 unsigned Line = getLineNumber(ED->getLocation());
4153 StringRef EDName = ED->getName();
4154 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4155 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4156 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4158 ReplaceMap.emplace_back(
4159 std::piecewise_construct, std::make_tuple(Ty),
4160 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4164 return CreateTypeDefinition(Ty);
4167llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4170 SmallVector<llvm::Metadata *, 16> Enumerators;
4171 ED = ED->getDefinition();
4172 assert(ED &&
"An enumeration definition is required");
4173 for (
const auto *
Enum : ED->enumerators()) {
4174 Enumerators.push_back(
4175 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4178 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4179 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4180 EnumKind = Attr->getExtensibility();
4183 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4185 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4186 unsigned Line = getLineNumber(ED->getLocation());
4187 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4188 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4189 return DBuilder.createEnumerationType(
4190 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4191 0, Identifier, ED->isScoped(), EnumKind);
4196 StringRef Name, StringRef
Value) {
4197 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4198 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4204 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4205 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4206 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4211 llvm::DISubprogram *SynthSubprogram) {
4212 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4213 SynthSubprogram, ParentLocation);
4218 StringRef SynthFuncName,
4219 llvm::DIFile *SynthFile) {
4220 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4225 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4231 FuncName += Category;
4233 FuncName += FailureMsg;
4236 TrapLocation->getFile());
4246 Quals += InnerQuals;
4248 switch (
T->getTypeClass()) {
4250 return C.getQualifiedType(
T.getTypePtr(), Quals);
4253 case Type::InjectedClassName:
4254 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4256 case Type::TemplateSpecialization: {
4258 if (Spec->isTypeAlias())
4259 return C.getQualifiedType(
T.getTypePtr(), Quals);
4260 T = Spec->desugar();
4263 case Type::TypeOfExpr:
4269 case Type::Decltype:
4272 case Type::UnaryTransform:
4275 case Type::Attributed:
4278 case Type::BTFTagAttributed:
4281 case Type::CountAttributed:
4290 case Type::MacroQualified:
4293 case Type::SubstTemplateTypeParm:
4297 case Type::DeducedTemplateSpecialization: {
4299 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4303 case Type::PackIndexing: {
4307 case Type::Adjusted:
4314 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4319llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4322 if (It != TypeCache.end()) {
4324 if (llvm::Metadata *
V = It->second)
4337 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4344 RetainedTypes.push_back(
4345 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4348llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4352 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4354 llvm::raw_string_ostream OS(Name);
4355 Ty.
print(OS, getPrintingPolicy());
4362 if (
auto *
T = getTypeOrNull(Ty))
4365 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4366 void *TyPtr = Ty.getAsOpaquePtr();
4369 TypeCache[TyPtr].reset(Res);
4374llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4382 auto Info = Reader->getSourceDescriptor(Idx);
4384 return getOrCreateModuleRef(*Info,
true);
4385 }
else if (ClangModuleMap) {
4398 auto Info = ASTSourceDescriptor(*M);
4399 return getOrCreateModuleRef(Info,
false);
4402 return getOrCreateModuleRef(PCHDescriptor,
false);
4409llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4412 return CreateQualifiedType(Ty, Unit);
4416#define TYPE(Class, Base)
4417#define ABSTRACT_TYPE(Class, Base)
4418#define NON_CANONICAL_TYPE(Class, Base)
4419#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4420#include "clang/AST/TypeNodes.inc"
4421 llvm_unreachable(
"Dependent types cannot show up in debug information");
4423 case Type::ExtVector:
4426 case Type::ConstantMatrix:
4428 case Type::ObjCObjectPointer:
4430 case Type::ObjCObject:
4432 case Type::ObjCTypeParam:
4434 case Type::ObjCInterface:
4442 case Type::BlockPointer:
4450 case Type::FunctionProto:
4451 case Type::FunctionNoProto:
4453 case Type::ConstantArray:
4454 case Type::VariableArray:
4455 case Type::IncompleteArray:
4456 case Type::ArrayParameter:
4459 case Type::LValueReference:
4461 case Type::RValueReference:
4464 case Type::MemberPointer:
4472 case Type::OverflowBehavior:
4477 case Type::TemplateSpecialization:
4479 case Type::HLSLAttributedResource:
4481 case Type::HLSLInlineSpirv:
4483 case Type::PredefinedSugar:
4485 case Type::CountAttributed:
4486 case Type::LateParsedAttr:
4488 case Type::Attributed:
4489 case Type::BTFTagAttributed:
4490 case Type::Adjusted:
4492 case Type::DeducedTemplateSpecialization:
4495 case Type::MacroQualified:
4496 case Type::SubstTemplateTypeParm:
4497 case Type::TypeOfExpr:
4499 case Type::Decltype:
4500 case Type::PackIndexing:
4501 case Type::UnaryTransform:
4505 llvm_unreachable(
"type should have been unwrapped!");
4508llvm::DICompositeType *
4509CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4510 QualType QTy(Ty, 0);
4512 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4517 if (
T && !
T->isForwardDecl())
4521 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4526 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4529 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4534llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4536 bool NameIsSimplified =
false;
4539 StringRef RDName = getClassName(RD, &NameIsSimplified);
4541 llvm::DIFile *DefUnit =
nullptr;
4544 DefUnit = getOrCreateFile(Loc);
4545 Line = getLineNumber(Loc);
4548 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4552 auto *
T = cast_or_null<llvm::DICompositeType>(
4553 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4561 return getOrCreateRecordFwdDecl(Ty, RDContext);
4574 auto Flags = llvm::DINode::FlagZero;
4575 if (NameIsSimplified)
4576 Flags |= llvm::DINode::FlagNameIsSimplified;
4577 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4579 Flags |= llvm::DINode::FlagTypePassByReference;
4581 Flags |= llvm::DINode::FlagTypePassByValue;
4584 if (!CXXRD->isTrivial())
4585 Flags |= llvm::DINode::FlagNonTrivial;
4588 if (CXXRD->isAnonymousStructOrUnion())
4589 Flags |= llvm::DINode::FlagExportSymbols;
4592 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4595 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4596 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4598 Flags, Identifier, Annotations);
4602 switch (RealDecl->getTag()) {
4604 llvm_unreachable(
"invalid composite type tag");
4606 case llvm::dwarf::DW_TAG_array_type:
4607 case llvm::dwarf::DW_TAG_enumeration_type:
4612 if (Identifier.empty())
4616 case llvm::dwarf::DW_TAG_structure_type:
4617 case llvm::dwarf::DW_TAG_union_type:
4618 case llvm::dwarf::DW_TAG_class_type:
4621 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4625 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4626 CXXRecordDecl *TemplateDecl =
4627 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4628 RegionMap[TemplateDecl].reset(RealDecl);
4630 RegionMap[RD].reset(RealDecl);
4632 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4634 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4635 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4636 CollectCXXTemplateParams(TSpecial, DefUnit));
4640void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4641 llvm::DICompositeType *RealDecl) {
4643 llvm::DIType *ContainingType =
nullptr;
4644 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4648 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4655 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4656 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4658 ContainingType = RealDecl;
4660 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4663llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4664 StringRef Name, uint64_t *Offset) {
4665 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4666 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4669 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4670 *Offset, llvm::DINode::FlagZero, FieldTy);
4671 *Offset += FieldSize;
4675void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4677 StringRef &LinkageName,
4678 llvm::DIScope *&FDContext,
4679 llvm::DINodeArray &TParamsArray,
4680 llvm::DINode::DIFlags &Flags) {
4682 bool NameIsSimplified =
false;
4683 Name = getFunctionName(FD, &NameIsSimplified);
4684 if (NameIsSimplified)
4685 Flags |= llvm::DINode::FlagNameIsSimplified;
4686 Name = getFunctionName(FD);
4689 LinkageName = CGM.getMangledName(GD);
4691 Flags |= llvm::DINode::FlagPrototyped;
4695 if (LinkageName == Name ||
4696 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4697 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4698 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4699 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4700 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4701 LinkageName = StringRef();
4705 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4706 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4707 CGM.getCodeGenOpts().EmitCodeView)) {
4708 if (
const NamespaceDecl *NSDecl =
4710 FDContext = getOrCreateNamespace(NSDecl);
4711 else if (
const RecordDecl *RDecl =
4713 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4714 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4717 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4720 Flags |= llvm::DINode::FlagNoReturn;
4722 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4726void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4727 unsigned &LineNo, QualType &
T,
4728 StringRef &Name, StringRef &LinkageName,
4729 llvm::MDTuple *&TemplateParameters,
4730 llvm::DIScope *&VDContext) {
4739 llvm::APInt ConstVal(32, 1);
4740 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4742 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4749 LinkageName = CGM.getMangledName(VD);
4750 if (LinkageName == Name)
4751 LinkageName = StringRef();
4754 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4755 TemplateParameters = parameterNodes.get();
4757 TemplateParameters =
nullptr;
4763 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4764 VDContext = LexicalBlockStack.back();
4783 DC = CGM.getContext().getTranslationUnitDecl();
4785 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4786 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4789llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4791 llvm::DINodeArray TParamsArray;
4792 StringRef Name, LinkageName;
4793 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4794 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4796 llvm::DIFile *Unit = getOrCreateFile(Loc);
4797 llvm::DIScope *DContext = Unit;
4798 unsigned Line = getLineNumber(Loc);
4799 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4804 SmallVector<QualType, 16> ArgTypes;
4805 for (
const ParmVarDecl *Parm : FD->
parameters())
4806 ArgTypes.push_back(Parm->getType());
4809 QualType FnType = CGM.getContext().getFunctionType(
4810 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4812 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4813 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4814 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4818 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4819 return DBuilder.createFunction(
4820 DContext, Name, LinkageName, Unit,
Line,
4821 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4822 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4824 CGM.getCodeGenOpts().DebugKeyInstructions);
4827 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4828 DContext, Name, LinkageName, Unit,
Line,
4829 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4830 TParamsArray.get(), getFunctionDeclaration(FD));
4832 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4833 std::make_tuple(CanonDecl),
4834 std::make_tuple(SP));
4838llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4839 return getFunctionFwdDeclOrStub(GD,
false);
4842llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4843 return getFunctionFwdDeclOrStub(GD,
true);
4846llvm::DIGlobalVariable *
4847CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4849 StringRef Name, LinkageName;
4851 llvm::DIFile *Unit = getOrCreateFile(Loc);
4852 llvm::DIScope *DContext = Unit;
4853 unsigned Line = getLineNumber(Loc);
4854 llvm::MDTuple *TemplateParameters =
nullptr;
4856 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4859 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4860 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4862 FwdDeclReplaceMap.emplace_back(
4863 std::piecewise_construct,
4865 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4869llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4874 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4875 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4876 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4880 if (I != DeclCache.end()) {
4882 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4883 return GVE->getVariable();
4891 if (IE != ImportedDeclCache.end()) {
4892 auto N = IE->second;
4893 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4895 return dyn_cast_or_null<llvm::DINode>(N);
4900 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4901 return getFunctionForwardDeclaration(FD);
4902 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4903 return getGlobalVariableForwardDeclaration(VD);
4908llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4909 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4912 const auto *FD = dyn_cast<FunctionDecl>(D);
4917 auto *S = getDeclContextDescriptor(D);
4920 if (MI == SPCache.end()) {
4922 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4926 if (MI != SPCache.end()) {
4927 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4928 if (SP && !SP->isDefinition())
4932 for (
auto *NextFD : FD->
redecls()) {
4933 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4934 if (MI != SPCache.end()) {
4935 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4936 if (SP && !SP->isDefinition())
4943llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4944 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4945 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4946 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4949 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4953 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4957 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4966 QualType QTy(
ID->getTypeForDecl(), 0);
4967 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4968 if (It == TypeCache.end())
4971 llvm::DISubprogram *FD = DBuilder.createFunction(
4972 InterfaceType, getObjCMethodName(OMD), StringRef(),
4973 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4974 DBuilder.finalizeSubprogram(FD);
4981llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4986 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4987 !CGM.getCodeGenOpts().EmitCodeView))
4990 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4992 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4995 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4998 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4999 return getOrCreateMethodType(
Method, F);
5001 const auto *FTy = FnType->
getAs<FunctionType>();
5004 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
5006 SmallVector<llvm::Metadata *, 16> Elts;
5009 QualType ResultTy = OMethod->getReturnType();
5012 if (ResultTy == CGM.getContext().getObjCInstanceType())
5013 ResultTy = CGM.getContext().getPointerType(
5014 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5016 Elts.push_back(getOrCreateType(ResultTy, F));
5018 QualType SelfDeclTy;
5019 if (
auto *SelfDecl = OMethod->getSelfDecl())
5020 SelfDeclTy = SelfDecl->getType();
5021 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5024 if (!SelfDeclTy.
isNull())
5026 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5028 Elts.push_back(DBuilder.createArtificialType(
5029 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5031 for (
const auto *PI : OMethod->parameters())
5032 Elts.push_back(getOrCreateType(PI->getType(), F));
5034 if (OMethod->isVariadic())
5035 Elts.push_back(DBuilder.createUnspecifiedParameter());
5037 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5038 return DBuilder.createSubroutineType(
5039 EltTypeArray, llvm::DINode::FlagZero,
5040 getDwarfCC(CC, CGM.getTarget().getTriple()));
5045 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5046 if (FD->isVariadic()) {
5047 SmallVector<llvm::Metadata *, 16> EltTys;
5048 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5049 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5051 EltTys.push_back(getOrCreateType(ParamType, F));
5052 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5053 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5054 return DBuilder.createSubroutineType(
5055 EltTypeArray, llvm::DINode::FlagZero,
5056 getDwarfCC(CC, CGM.getTarget().getTriple()));
5068 CC = SrcFnTy->getCallConv();
5070 for (
const VarDecl *VD : Args)
5071 ArgTypes.push_back(VD->
getType());
5072 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5078 llvm::Function *Fn,
bool CurFuncIsThunk) {
5080 StringRef LinkageName;
5082 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5085 bool HasDecl = (D !=
nullptr);
5087 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5088 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5089 llvm::DIFile *Unit = getOrCreateFile(Loc);
5090 llvm::DIScope *FDContext = Unit;
5091 llvm::DINodeArray TParamsArray;
5092 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5095 LinkageName = Fn->getName();
5096 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5098 auto FI = SPCache.find(FD->getCanonicalDecl());
5099 if (FI != SPCache.end()) {
5100 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5101 if (SP && SP->isDefinition()) {
5102 LexicalBlockStack.emplace_back(SP);
5103 RegionMap[D].reset(SP);
5107 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5108 TParamsArray, Flags);
5111 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5112 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5113 Name = getObjCMethodName(OMD);
5114 Flags |= llvm::DINode::FlagPrototyped;
5120 if (Name != Fn->getName())
5121 LinkageName = Fn->getName();
5123 Name = Fn->getName();
5128 Flags |= llvm::DINode::FlagPrototyped;
5130 Name.consume_front(
"\01");
5134 "Unexpected DynamicInitKind !");
5138 Flags |= llvm::DINode::FlagArtificial;
5144 Flags |= llvm::DINode::FlagThunk;
5146 if (Fn->hasLocalLinkage())
5147 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5148 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5149 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5152 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5153 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5155 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5156 unsigned ScopeLine = getLineNumber(ScopeLoc);
5157 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5158 llvm::DISubprogram *
Decl =
nullptr;
5159 llvm::DINodeArray Annotations =
nullptr;
5162 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5163 : getFunctionDeclaration(D);
5164 Annotations = CollectBTFDeclTagAnnotations(D);
5172 llvm::DISubprogram *SP = DBuilder.createFunction(
5173 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5174 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5175 Annotations,
"", KeyInstructions);
5176 Fn->setSubprogram(SP);
5185 LexicalBlockStack.emplace_back(SP);
5188 RegionMap[D].reset(SP);
5192 QualType FnType, llvm::Function *Fn) {
5194 StringRef LinkageName;
5200 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5201 return GetName(D,
true);
5204 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5205 llvm::DIFile *Unit = getOrCreateFile(Loc);
5206 bool IsDeclForCallSite = Fn ?
true :
false;
5207 llvm::DIScope *FDContext =
5208 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5209 llvm::DINodeArray TParamsArray;
5212 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5213 TParamsArray, Flags);
5214 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5215 Name = getObjCMethodName(OMD);
5216 Flags |= llvm::DINode::FlagPrototyped;
5218 llvm_unreachable(
"not a function or ObjC method");
5220 Name.consume_front(
"\01");
5223 Flags |= llvm::DINode::FlagArtificial;
5228 unsigned LineNo = getLineNumber(Loc);
5229 unsigned ScopeLine = 0;
5230 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5231 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5232 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5234 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5235 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5237 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5238 llvm::DISubprogram *SP = DBuilder.createFunction(
5239 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5240 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5246 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5247 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5248 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5251 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5252 DBuilder.createParameterVariable(
5253 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5254 llvm::DINode::FlagZero, ParamAnnotations);
5260 if (IsDeclForCallSite)
5261 Fn->setSubprogram(SP);
5265 llvm::CallBase *CI) {
5266 if (!shouldGenerateVirtualCallSite())
5272 assert(CI &&
"Invalid Call Instruction.");
5273 if (!CI->isIndirectCall())
5277 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5278 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5286 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5289 if (
Func->getSubprogram())
5293 if (!
Func->isDeclaration())
5315 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5316 Func->setSubprogram(SP);
5327 auto FI = SPCache.find(FD->getCanonicalDecl());
5328 llvm::DISubprogram *SP =
nullptr;
5329 if (FI != SPCache.end())
5330 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5331 if (!SP || !SP->isDefinition())
5332 SP = getFunctionStub(GD);
5333 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5334 LexicalBlockStack.emplace_back(SP);
5340 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5349 if (CurLoc.isInvalid() ||
5350 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5351 LexicalBlockStack.empty())
5354 llvm::MDNode *
Scope = LexicalBlockStack.back();
5355 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5356 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5360 llvm::MDNode *Back =
nullptr;
5361 if (!LexicalBlockStack.empty())
5362 Back = LexicalBlockStack.back().get();
5365 unsigned Line = getLineNumber(CurLoc);
5366 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5367 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5371void CGDebugInfo::AppendAddressSpaceXDeref(
5373 std::optional<unsigned> DWARFAddressSpace =
5375 if (!DWARFAddressSpace)
5378 Expr.push_back(llvm::dwarf::DW_OP_constu);
5379 Expr.push_back(*DWARFAddressSpace);
5380 Expr.push_back(llvm::dwarf::DW_OP_swap);
5381 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5390 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5391 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5392 LexicalBlockStack.back(), CurInlinedAt));
5394 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5398 CreateLexicalBlock(Loc);
5403 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5408 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5411 LexicalBlockStack.pop_back();
5415 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5416 unsigned RCount = FnBeginRegionCount.back();
5417 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5420 while (LexicalBlockStack.size() != RCount) {
5423 LexicalBlockStack.pop_back();
5425 FnBeginRegionCount.pop_back();
5427 if (Fn && Fn->getSubprogram())
5428 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5431CGDebugInfo::BlockByRefType
5432CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5433 uint64_t *XOffset) {
5436 uint64_t FieldSize, FieldOffset;
5437 uint32_t FieldAlign;
5439 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5444 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5445 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5447 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5448 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5451 if (HasCopyAndDispose) {
5454 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5456 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5458 bool HasByrefExtendedLayout;
5461 HasByrefExtendedLayout) &&
5462 HasByrefExtendedLayout) {
5465 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5474 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5477 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5480 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5485 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5486 FieldSize = CGM.getContext().getTypeSize(FType);
5487 FieldAlign = CGM.getContext().toBits(Align);
5489 *XOffset = FieldOffset;
5490 llvm::DIType *FieldTy = DBuilder.createMemberType(
5491 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5492 llvm::DINode::FlagZero, WrappedTy);
5493 EltTys.push_back(FieldTy);
5494 FieldOffset += FieldSize;
5496 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5497 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5498 llvm::DINode::FlagZero,
nullptr, Elements),
5502llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5503 llvm::Value *Storage,
5504 std::optional<unsigned> ArgNo,
5506 const bool UsePointerValue) {
5507 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5508 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5509 if (VD->
hasAttr<NoDebugAttr>())
5514 llvm::DIFile *Unit =
nullptr;
5515 if (!VarIsArtificial)
5519 if (VD->
hasAttr<BlocksAttr>())
5520 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5522 Ty = getOrCreateType(VD->
getType(), Unit);
5532 if (!VarIsArtificial) {
5536 SmallVector<uint64_t, 13> Expr;
5537 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5544 Flags |= llvm::DINode::FlagArtificial;
5548 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5549 AppendAddressSpaceXDeref(AddressSpace, Expr);
5553 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5556 Flags |= llvm::DINode::FlagObjectPointer;
5557 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5558 if (PVD->isExplicitObjectParameter())
5559 Flags |= llvm::DINode::FlagObjectPointer;
5567 StringRef Name = VD->
getName();
5568 if (!Name.empty()) {
5574 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5576 offset = CGM.getContext().toCharUnitsFromBits(
5579 Expr.push_back(llvm::dwarf::DW_OP_deref);
5580 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5582 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5585 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5597 for (
const auto *Field : RD->
fields()) {
5598 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5599 StringRef FieldName =
Field->getName();
5607 auto *D = DBuilder.createAutoVariable(
5608 Scope, FieldName, Unit,
Line, FieldTy,
5609 CGM.getCodeGenOpts().OptimizationLevel != 0,
5610 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5613 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5614 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5617 Builder.GetInsertBlock());
5625 if (UsePointerValue) {
5626 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5627 "Debug info already contains DW_OP_deref.");
5628 Expr.push_back(llvm::dwarf::DW_OP_deref);
5632 llvm::DILocalVariable *D =
nullptr;
5634 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5635 D = DBuilder.createParameterVariable(
5636 Scope, Name, *ArgNo, Unit,
Line, Ty,
5637 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5646 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5652 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5653 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5654 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5655 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5657 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5663 if (Iter != CoroutineParameterMappings.end()) {
5664 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5665 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5666 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5668 if (Iter2 != ParamDbgMappings.end())
5669 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5675 D = RemapCoroArgToLocalVar();
5678 D = DBuilder.createAutoVariable(
5679 Scope, Name, Unit,
Line, Ty,
5680 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5683 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5684 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5685 Column, Scope, CurInlinedAt),
5686 Builder.GetInsertBlock());
5691llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5692 llvm::Value *Storage,
5693 std::optional<unsigned> ArgNo,
5695 const bool UsePointerValue) {
5696 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5697 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5698 if (BD->
hasAttr<NoDebugAttr>())
5705 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5706 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5714 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5716 SmallVector<uint64_t, 3> Expr;
5717 AppendAddressSpaceXDeref(AddressSpace, Expr);
5722 if (UsePointerValue) {
5723 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5724 "Debug info already contains DW_OP_deref.");
5725 Expr.push_back(llvm::dwarf::DW_OP_deref);
5730 StringRef Name = BD->
getName();
5733 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5734 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5735 llvm::DINode::FlagZero, Align);
5737 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5738 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5739 const unsigned fieldIndex = FD->getFieldIndex();
5740 const clang::CXXRecordDecl *parent =
5741 (
const CXXRecordDecl *)FD->getParent();
5742 const ASTRecordLayout &layout =
5743 CGM.getContext().getASTRecordLayout(parent);
5745 if (FD->isBitField()) {
5746 const CGRecordLayout &RL =
5747 CGM.getTypes().getCGRecordLayout(FD->getParent());
5752 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5758 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5759 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5760 Expr.push_back(Info.
Offset);
5763 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5764 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5765 }
else if (fieldOffset != 0) {
5766 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5767 "Unexpected non-bitfield with non-byte-aligned offset");
5768 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5770 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5773 }
else if (
const ArraySubscriptExpr *ASE =
5774 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5775 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5776 const uint64_t value = IL->getValue().getZExtValue();
5777 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5780 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5781 Expr.push_back(CGM.getContext()
5782 .toCharUnitsFromBits(value * typeSize)
5789 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5790 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5791 Column, Scope, CurInlinedAt),
5792 Builder.GetInsertBlock());
5797llvm::DILocalVariable *
5800 const bool UsePointerValue) {
5801 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5803 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5805 EmitDeclare(B, Storage, std::nullopt, Builder,
5812 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5816 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5817 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5819 if (D->
hasAttr<NoDebugAttr>())
5823 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5829 StringRef Name = D->
getName();
5835 CGM.getCodeGenOpts().OptimizationLevel != 0);
5838 DBuilder.insertLabel(L,
5839 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5840 Scope, CurInlinedAt),
5841 Builder.GetInsertBlock()->end());
5844llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5846 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5849 return DBuilder.createObjectPointerType(Ty,
true);
5854 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5855 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5856 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5858 if (Builder.GetInsertBlock() ==
nullptr)
5860 if (VD->
hasAttr<NoDebugAttr>())
5863 bool isByRef = VD->
hasAttr<BlocksAttr>();
5865 uint64_t XOffset = 0;
5866 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5869 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5871 Ty = getOrCreateType(VD->
getType(), Unit);
5875 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5877 Ty = CreateSelfType(VD->
getType(), Ty);
5880 const unsigned Line =
5884 const llvm::DataLayout &target = CGM.getDataLayout();
5891 addr.push_back(llvm::dwarf::DW_OP_deref);
5892 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5895 addr.push_back(llvm::dwarf::DW_OP_deref);
5896 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5899 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5901 addr.push_back(llvm::dwarf::DW_OP_deref);
5902 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5904 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5910 auto *D = DBuilder.createAutoVariable(
5912 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5915 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5916 LexicalBlockStack.back(), CurInlinedAt);
5917 auto *
Expr = DBuilder.createExpression(addr);
5919 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5921 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5924llvm::DILocalVariable *
5927 bool UsePointerValue) {
5928 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5929 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5933struct BlockLayoutChunk {
5934 uint64_t OffsetInBits;
5937bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5938 return l.OffsetInBits < r.OffsetInBits;
5942void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5944 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5945 SmallVectorImpl<llvm::Metadata *> &Fields) {
5949 if (CGM.getLangOpts().OpenCL) {
5950 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5951 BlockLayout.getElementOffsetInBits(0),
5953 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5954 BlockLayout.getElementOffsetInBits(1),
5958 BlockLayout.getElementOffsetInBits(0),
5960 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5961 BlockLayout.getElementOffsetInBits(1),
5965 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5966 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5967 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5968 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5969 BlockLayout.getElementOffsetInBits(3),
5971 Fields.push_back(createFieldType(
5976 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5983 llvm::AllocaInst *Alloca,
5985 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5991 llvm::DIFile *tunit = getOrCreateFile(loc);
5992 unsigned line = getLineNumber(loc);
5993 unsigned column = getColumnNumber(loc);
5998 const llvm::StructLayout *blockLayout =
6002 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
6011 BlockLayoutChunk chunk;
6012 chunk.OffsetInBits =
6013 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
6014 chunk.Capture =
nullptr;
6015 chunks.push_back(chunk);
6019 for (
const auto &capture :
blockDecl->captures()) {
6020 const VarDecl *variable = capture.getVariable();
6027 BlockLayoutChunk chunk;
6028 chunk.OffsetInBits =
6029 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6030 chunk.Capture = &capture;
6031 chunks.push_back(chunk);
6035 llvm::array_pod_sort(chunks.begin(), chunks.end());
6037 for (
const BlockLayoutChunk &Chunk : chunks) {
6038 uint64_t offsetInBits = Chunk.OffsetInBits;
6045 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6047 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6048 type = CGM.getContext().getCanonicalTagType(RDecl);
6050 llvm_unreachable(
"unexpected block declcontext");
6052 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6053 offsetInBits, tunit, tunit));
6058 StringRef name = variable->
getName();
6060 llvm::DIType *fieldType;
6062 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6067 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6068 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6069 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6070 PtrInfo.
Width, Align, offsetInBits,
6071 llvm::DINode::FlagZero, fieldType);
6075 offsetInBits, Align, tunit, tunit);
6077 fields.push_back(fieldType);
6081 llvm::raw_svector_ostream(typeName)
6082 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6084 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6086 llvm::DIType *
type =
6087 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6088 CGM.getContext().toBits(block.
BlockSize), 0,
6089 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6090 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6093 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6097 auto *debugVar = DBuilder.createParameterVariable(
6098 scope, Name, ArgNo, tunit, line,
type,
6099 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6102 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6103 llvm::DILocation::get(CGM.getLLVMContext(), line,
6104 column, scope, CurInlinedAt),
6105 Builder.GetInsertBlock());
6108llvm::DIDerivedType *
6109CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6114 if (MI != StaticDataMemberCache.end()) {
6115 assert(MI->second &&
"Static data member declaration should still exist");
6126llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6127 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6128 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6129 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6131 for (
const auto *Field : RD->
fields()) {
6132 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6133 StringRef FieldName = Field->getName();
6136 if (FieldName.empty()) {
6137 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6138 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6139 LineNo, LinkageName, Var, DContext);
6143 GVE = DBuilder.createGlobalVariableExpression(
6144 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6145 Var->hasLocalLinkage());
6146 Var->addDebugInfo(GVE);
6158 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6163 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6174 struct ReferencesAnonymous
6176 bool RefAnon =
false;
6177 bool VisitRecordType(RecordType *RT) {
6185 ReferencesAnonymous RT;
6198struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6199 bool Reconstitutable =
true;
6200 bool VisitVectorType(VectorType *FT) {
6201 Reconstitutable =
false;
6204 bool VisitAtomicType(AtomicType *FT) {
6205 Reconstitutable =
false;
6208 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6211 const EnumDecl *ED = ET->getDecl();
6213 Reconstitutable =
false;
6217 Reconstitutable =
false;
6222 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6226 return Reconstitutable;
6228 bool VisitRecordType(RecordType *RT,
bool =
false) {
6230 Reconstitutable =
false;
6240 ReconstitutableType
T;
6242 return T.Reconstitutable;
6245bool CGDebugInfo::HasReconstitutableArgs(
6246 ArrayRef<TemplateArgument> Args)
const {
6247 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6287 llvm_unreachable(
"Other, unresolved, template arguments should "
6288 "not be seen here");
6293std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6294 bool *NameIsSimplified)
const {
6296 llvm::raw_string_ostream
OS(Name);
6297 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6300 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6301 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6303 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6304 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6306 std::optional<TemplateArgs> Args;
6308 bool IsOperatorOverload =
false;
6309 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6310 Args = GetTemplateArgs(RD);
6311 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6312 Args = GetTemplateArgs(FD);
6314 IsOperatorOverload |=
6317 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6318 Args = GetTemplateArgs(VD);
6342 bool Reconstitutable =
6343 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6345 PrintingPolicy PP = getPrintingPolicy();
6347 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6352 if (NameIsSimplified)
6353 *NameIsSimplified =
true;
6354 bool Mangled = TemplateNamesKind ==
6355 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6361 std::string EncodedOriginalName;
6362 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6367 printTemplateArgumentList(OS, Args->Args, PP);
6368 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6370 std::string CanonicalOriginalName;
6371 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6373 assert(EncodedOriginalName == CanonicalOriginalName);
6382 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6383 if (D->
hasAttr<NoDebugAttr>())
6386 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6387 return GetName(D,
true);
6393 if (Cached != DeclCache.end())
6394 return Var->addDebugInfo(
6398 llvm::DIFile *Unit =
nullptr;
6399 llvm::DIScope *DContext =
nullptr;
6401 StringRef DeclName, LinkageName;
6403 llvm::MDTuple *TemplateParameters =
nullptr;
6404 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6405 TemplateParameters, DContext);
6409 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6414 if (
T->isUnionType() && DeclName.empty()) {
6415 const auto *RD =
T->castAsRecordDecl();
6417 "unnamed non-anonymous struct or union?");
6418 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6423 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6424 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6425 if (D->
hasAttr<CUDASharedAttr>())
6428 else if (D->
hasAttr<CUDAConstantAttr>())
6432 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6434 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6435 GVE = DBuilder.createGlobalVariableExpression(
6436 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6437 Var->hasLocalLinkage(),
true,
6438 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6439 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6440 Align, Annotations);
6441 Var->addDebugInfo(GVE);
6447 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6448 if (VD->
hasAttr<NoDebugAttr>())
6450 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6451 return GetName(VD,
true);
6456 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6457 StringRef Name = VD->
getName();
6458 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6460 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6462 if (CGM.getCodeGenOpts().EmitCodeView) {
6473 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6474 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6475 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6485 auto *VarD = dyn_cast<VarDecl>(VD);
6486 if (VarD && VarD->isStaticDataMember()) {
6488 getDeclContextDescriptor(VarD);
6493 RetainedTypes.push_back(
6494 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6498 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6500 auto &GV = DeclCache[VD];
6504 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6505 llvm::MDTuple *TemplateParameters =
nullptr;
6509 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6510 TemplateParameters = parameterNodes.get();
6513 GV.reset(DBuilder.createGlobalVariableExpression(
6514 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6515 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6516 TemplateParameters, Align));
6521 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6522 if (D->
hasAttr<NoDebugAttr>())
6526 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6527 StringRef Name = D->
getName();
6528 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6530 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6531 llvm::DIGlobalVariableExpression *GVE =
6532 DBuilder.createGlobalVariableExpression(
6533 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6534 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6535 Var->addDebugInfo(GVE);
6542 if (CGM.getCodeGenOpts().getDebugInfo() <=
6543 llvm::codegenoptions::DebugLineTablesOnly)
6546 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6550 llvm::DIFile *Unit = DIL->getFile();
6551 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6556 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6557 llvm::Value *Var = Load->getPointerOperand();
6562 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6563 return DbgDeclare->getVariable()->getType() ==
Type;
6565 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6569 llvm::DILocalVariable *D =
6570 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6571 Type,
false, llvm::DINode::FlagArtificial);
6573 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6574 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6584 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6588 if (D->
hasAttr<NoDebugAttr>())
6591 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6606 if (!(DI = getDeclarationOrDefinition(
6607 AliaseeDecl.getCanonicalDecl().getDecl())))
6610 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6613 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6614 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6628 llvm::DIFile *
File = getOrCreateFile(Loc);
6629 llvm::DIGlobalVariableExpression *Debug =
6630 DBuilder.createGlobalVariableExpression(
6631 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6632 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6633 GV->addDebugInfo(Debug);
6636llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6637 if (!LexicalBlockStack.empty())
6638 return LexicalBlockStack.back();
6639 llvm::DIScope *Mod = getParentModuleOrNull(D);
6640 return getContextDescriptor(D, Mod ? Mod : TheCU);
6644 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6648 CGM.getCodeGenOpts().DebugExplicitImport) {
6652 DBuilder.createImportedModule(
6654 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6659 if (llvm::DINode *
Target =
6662 DBuilder.createImportedDeclaration(
6664 getOrCreateFile(Loc), getLineNumber(Loc));
6669 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6672 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6674 for (
const auto *USD : UD.
shadows()) {
6679 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6680 if (
const auto *AT = FD->getType()
6683 if (AT->getDeducedType().isNull())
6694 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6697 "We shouldn't be codegening an invalid UsingEnumDecl"
6698 " containing no decls");
6700 for (
const auto *USD : UD.
shadows())
6705 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6707 if (
Module *M = ID.getImportedModule()) {
6709 auto Loc = ID.getLocation();
6710 DBuilder.createImportedDeclaration(
6711 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6712 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6713 getLineNumber(Loc));
6717llvm::DIImportedEntity *
6719 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6721 auto &VH = NamespaceAliasCache[&NA];
6724 llvm::DIImportedEntity *R;
6726 if (
const auto *Underlying =
6729 R = DBuilder.createImportedDeclaration(
6732 getLineNumber(Loc), NA.
getName());
6734 R = DBuilder.createImportedDeclaration(
6737 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6743CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6747 auto I = NamespaceCache.find(NSDecl);
6748 if (I != NamespaceCache.end())
6751 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6753 llvm::DINamespace *NS =
6754 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6755 NamespaceCache[NSDecl].reset(NS);
6760 assert(TheCU &&
"no main compile unit");
6761 TheCU->setDWOId(Signature);
6767 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6768 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6770 ? CreateTypeDefinition(E.Type, E.Unit)
6772 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6776 for (
const auto &P : ObjCMethodCache) {
6777 if (P.second.empty())
6780 QualType QTy(P.first->getTypeForDecl(), 0);
6782 assert(It != TypeCache.end());
6784 llvm::DICompositeType *InterfaceDecl =
6787 auto CurElts = InterfaceDecl->getElements();
6791 for (
auto &SubprogramDirect : P.second)
6792 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6793 EltTys.push_back(SubprogramDirect.getPointer());
6795 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6796 DBuilder.replaceArrays(InterfaceDecl, Elements);
6799 for (
const auto &P : ReplaceMap) {
6802 assert(Ty->isForwardDecl());
6804 auto It = TypeCache.find(P.first);
6805 assert(It != TypeCache.end());
6808 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6812 for (
const auto &P : FwdDeclReplaceMap) {
6815 llvm::Metadata *Repl;
6817 auto It = DeclCache.find(P.first);
6821 if (It == DeclCache.end())
6826 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6827 Repl = GVE->getVariable();
6833 for (
auto &RT : RetainedTypes)
6834 if (
auto MD = TypeCache[RT])
6837 DBuilder.finalize();
6842 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6843 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6844 DBuilder.retainType(DieTy);
6848 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6849 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6850 DBuilder.retainType(DieTy);
6854 if (LexicalBlockStack.empty())
6855 return llvm::DebugLoc();
6857 llvm::MDNode *
Scope = LexicalBlockStack.back();
6858 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6859 getColumnNumber(Loc),
Scope);
6865 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6866 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6867 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6868 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6869 return llvm::DINode::FlagZero;
6874 bool SupportsDWARFv4Ext =
6875 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6876 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6877 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6879 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6880 return llvm::DINode::FlagZero;
6882 return llvm::DINode::FlagAllCallsDescribed;
6893 return DBuilder.createConstantValueExpression(
6894 Val.
getFloat().bitcastToAPInt().getZExtValue());
6899 llvm::APSInt
const &ValInt = Val.
getInt();
6900 std::optional<uint64_t> ValIntOpt;
6901 if (ValInt.isUnsigned())
6902 ValIntOpt = ValInt.tryZExtValue();
6903 else if (
auto tmp = ValInt.trySExtValue())
6906 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6909 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6914CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6916 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6917 CGF.CurLexicalScope =
this;
6919 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6924 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6937#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6939 Label = "__ubsan_check_" #Name; \
6943#undef SANITIZER_CHECK
6954#define SANITIZER(NAME, ID) \
6955 case SanitizerKind::SO_##ID: \
6956 Label = "__ubsan_check_" NAME; \
6958#include "clang/Basic/Sanitizers.def"
6960 llvm_unreachable(
"unexpected sanitizer kind");
6965 for (
unsigned int i = 0; i < Label.length(); i++)
6966 if (!std::isalpha(Label[i]))
6975 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6977 if (!DI || !CheckDebugLoc)
6978 return CheckDebugLoc;
6979 const auto &AnnotateDebugInfo =
6980 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6981 if (AnnotateDebugInfo.empty())
6982 return CheckDebugLoc;
6985 if (Ordinals.size() == 1)
6990 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6994 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6995 "ubsan_interface.h",
6997 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
7000 return CheckDebugLoc;
7008 assert(!CGF->IsSanitizerScope);
7009 CGF->IsSanitizerScope =
true;
7013 assert(CGF->IsSanitizerScope);
7014 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.
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.