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"
64 if (TI.isAlignRequired())
92 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
96 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
120 if (!llvm::isa<ParmVarDecl>(VD))
130 if (!Method->isImplicit() || !Method->isPropertyAccessor())
141 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
142 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
143 DBuilder(CGM.getModule()) {
148 assert(LexicalBlockStack.empty() &&
149 "Region stack mismatch, stack not empty!");
152void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
153 uint64_t Group, uint8_t Rank) {
154 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
158 Rank = std::min<uint8_t>(Rank, 7);
160 const llvm::DebugLoc &DL = I->getDebugLoc();
165 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
166 Group = DL->getAtomGroup();
167 Rank = DL->getAtomRank();
172 KeyInstructionsInfo.HighestEmittedAtom =
173 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
176 llvm::DILocation *NewDL = llvm::DILocation::get(
177 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
178 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
179 I->setDebugLoc(NewDL);
183 llvm::Value *Backup) {
185 KeyInstructionsInfo.CurrentAtom);
191 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
194 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
195 if (!SP || !SP->getKeyInstructionsEnabled())
198 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
200 llvm::Instruction *BackupI =
201 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
206 addInstSourceAtomMetadata(BackupI, Group, 2);
212 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
213 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
216 addInstSourceAtomMetadata(BackupI, Group, Rank++);
222 KeyInstructionsInfo.NextAtom = 1;
223 KeyInstructionsInfo.HighestEmittedAtom = 0;
224 KeyInstructionsInfo.CurrentAtom = 0;
230 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
231 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
239 DI->KeyInstructionsInfo.NextAtom =
240 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
241 DI->KeyInstructionsInfo.NextAtom);
243 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
249 init(TemporaryLocation);
256 init(TemporaryLocation, DefaultToEmpty);
260 bool DefaultToEmpty) {
267 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
269 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
272 if (TemporaryLocation.
isValid()) {
273 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
277 if (DefaultToEmpty) {
278 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
283 assert(!DI->LexicalBlockStack.empty());
284 CGF->Builder.SetCurrentDebugLocation(
285 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
286 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
296 if (!CGF.getDebugInfo()) {
300 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
304 if (Loc->getAtomGroup())
305 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
306 Loc->getColumn(), Loc->getScope(),
307 Loc->getInlinedAt(), Loc.isImplicitCode());
308 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
316 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
322 if (!CGF.getDebugInfo()) {
326 auto &DI = *CGF.getDebugInfo();
327 SavedLocation = DI.getLocation();
328 assert((DI.getInlinedAt() ==
329 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
330 "CGDebugInfo and IRBuilder are out of sync");
332 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
338 auto &DI = *CGF->getDebugInfo();
339 DI.EmitInlineFunctionEnd(CGF->Builder);
340 DI.EmitLocation(CGF->Builder, SavedLocation);
350 if (CurLoc != NewLoc) {
352 CurLocFile =
nullptr;
361 if (CGM.getCodeGenOpts().DebugColumnInfo)
363 CurLocFile = getOrCreateFile(CurLoc);
369 if (LexicalBlockStack.empty())
373 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
376 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
377 LexicalBlockStack.pop_back();
378 LexicalBlockStack.emplace_back(
379 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
382 LexicalBlockStack.pop_back();
383 LexicalBlockStack.emplace_back(
384 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
388llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
389 llvm::DIScope *Mod = getParentModuleOrNull(D);
394llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
399 auto I = RegionMap.find(Context);
400 if (I != RegionMap.end()) {
401 llvm::Metadata *
V = I->second;
402 return dyn_cast_or_null<llvm::DIScope>(
V);
406 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
407 return getOrCreateNamespace(NSDecl);
409 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
410 if (!RDecl->isDependentType())
416PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
417 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
424 if (CGM.getCodeGenOpts().EmitCodeView) {
425 PP.MSVCFormatting =
true;
435 PP.PrintAsCanonical =
true;
436 PP.UsePreferredNames =
false;
437 PP.AlwaysIncludeTypeForTemplateArgument =
true;
446StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
447 bool *NameIsSimplified) {
448 return internString(GetName(FD,
false, NameIsSimplified));
451StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
452 SmallString<256> MethodName;
453 llvm::raw_svector_ostream
OS(MethodName);
456 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
457 OS << OID->getName();
458 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
459 OS << OID->getName();
460 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
461 if (OC->IsClassExtension()) {
462 OS << OC->getClassInterface()->getName();
464 OS << OC->getIdentifier()->getNameStart() <<
'('
465 << OC->getIdentifier()->getNameStart() <<
')';
467 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
468 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
472 return internString(
OS.str());
475StringRef CGDebugInfo::getSelectorName(Selector S) {
479StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
480 bool *NameIsSimplified) {
483 return internString(GetName(RD,
false, NameIsSimplified));
489 return II->getName();
494 if (CGM.getCodeGenOpts().EmitCodeView) {
497 "Typedef should not be in another decl context!");
498 assert(D->getDeclName().getAsIdentifierInfo() &&
499 "Typedef was not named!");
500 return D->getDeclName().getAsIdentifierInfo()->getName();
503 if (CGM.getLangOpts().CPlusPlus) {
506 ASTContext &Context = CGM.getContext();
510 Name = DD->getName();
511 else if (
const TypedefNameDecl *TND =
515 Name = TND->getName();
518 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
519 if (CXXRD->isLambda())
521 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
524 SmallString<256> UnnamedType(
"<unnamed-type-");
527 return internString(UnnamedType);
535std::optional<llvm::DIFile::ChecksumKind>
536CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
539 if (!CGM.getCodeGenOpts().EmitCodeView &&
540 CGM.getCodeGenOpts().DwarfVersion < 5)
543 SourceManager &SM = CGM.getContext().getSourceManager();
544 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
548 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
549 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
551 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
552 return llvm::DIFile::CSK_MD5;
554 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
555 return llvm::DIFile::CSK_SHA1;
557 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
558 return llvm::DIFile::CSK_SHA256;
562 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
565std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
567 if (!CGM.getCodeGenOpts().EmbedSource)
570 bool SourceInvalid =
false;
579llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
580 SourceManager &SM = CGM.getContext().getSourceManager();
583 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
589 FileName = TheCU->getFile()->getFilename();
590 CSInfo = TheCU->getFile()->getChecksum();
592 if (Loc == CurLoc && CurLocFile)
599 FileName = TheCU->getFile()->getFilename();
607 auto It = DIFileCache.find(
FileName.data());
608 if (It != DIFileCache.end()) {
610 if (llvm::Metadata *
V = It->second)
615 SmallString<64> Checksum;
618 CSInfo = TheCU->getFile()->getChecksum();
620 std::optional<llvm::DIFile::ChecksumKind> CSKind =
621 computeChecksum(FID, Checksum);
623 CSInfo.emplace(*CSKind, Checksum);
628llvm::DIFile *CGDebugInfo::createFile(
630 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
631 std::optional<StringRef> Source) {
635 std::string CurDir =
remapDIPath(getCurrentDirname());
636 SmallString<128> DirBuf;
637 SmallString<128> FileBuf;
638 if (llvm::sys::path::is_absolute(RemappedFile)) {
641 auto FileIt = llvm::sys::path::begin(RemappedFile);
642 auto FileE = llvm::sys::path::end(RemappedFile);
643 auto CurDirIt = llvm::sys::path::begin(CurDir);
644 auto CurDirE = llvm::sys::path::end(CurDir);
645 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
646 llvm::sys::path::append(DirBuf, *CurDirIt);
647 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
653 for (; FileIt != FileE; ++FileIt)
654 llvm::sys::path::append(FileBuf, *FileIt);
659 if (!llvm::sys::path::is_absolute(
FileName))
663 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
664 DIFileCache[
FileName.data()].reset(F);
669 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
691 if (DebugLoc == CurLoc)
697StringRef CGDebugInfo::getCurrentDirname() {
705 assert(CGO.DwarfVersion <= 5);
707 llvm::dwarf::SourceLanguage LangTag;
710 LangTag = llvm::dwarf::DW_LANG_HLSL;
712 LangTag = llvm::dwarf::DW_LANG_HIP;
714 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
715 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
716 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
717 else if (LO.CPlusPlus14)
718 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
719 else if (LO.CPlusPlus11)
720 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
722 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
723 }
else if (LO.ObjC) {
724 LangTag = llvm::dwarf::DW_LANG_ObjC;
725 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
726 LangTag = llvm::dwarf::DW_LANG_OpenCL;
727 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
728 LangTag = llvm::dwarf::DW_LANG_C11;
730 LangTag = llvm::dwarf::DW_LANG_C99;
732 LangTag = llvm::dwarf::DW_LANG_C89;
738static llvm::DISourceLanguageName
747 llvm::dwarf::SourceLanguageName LangTag;
750 LangTag = llvm::dwarf::DW_LNAME_HLSL;
752 LangTag = llvm::dwarf::DW_LNAME_HIP;
753 }
else if (LO.ObjC) {
754 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
756 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
759 }
else if (LO.ObjC) {
760 LangTag = llvm::dwarf::DW_LNAME_ObjC;
761 }
else if (LO.OpenCL) {
762 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
764 LangTag = llvm::dwarf::DW_LNAME_C;
768 return llvm::DISourceLanguageName(LangTag, LangVersion);
771void CGDebugInfo::CreateCompileUnit() {
772 SmallString<64> Checksum;
773 std::optional<llvm::DIFile::ChecksumKind> CSKind;
774 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
784 SourceManager &SM = CGM.getContext().getSourceManager();
785 auto &CGO = CGM.getCodeGenOpts();
786 const LangOptions &LO = CGM.getLangOpts();
787 std::string MainFileName = CGO.MainFileName;
788 if (MainFileName.empty())
789 MainFileName =
"<stdin>";
795 std::string MainFileDir;
798 MainFileDir = std::string(MainFile->getDir().getName());
799 if (!llvm::sys::path::is_absolute(MainFileName)) {
800 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
801 llvm::sys::path::Style Style =
803 ? (CGM.getTarget().
getTriple().isOSWindows()
804 ? llvm::sys::path::Style::windows_backslash
805 : llvm::sys::path::Style::posix)
806 : llvm::sys::path::Style::native;
807 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
808 MainFileName = std::string(
809 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
816 if (MainFile->getName() == MainFileName &&
818 MainFile->getName().rsplit(
'.').second)
820 MainFileName = CGM.getModule().getName().str();
829 unsigned RuntimeVers = 0;
833 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
835 case llvm::codegenoptions::NoDebugInfo:
836 case llvm::codegenoptions::LocTrackingOnly:
837 EmissionKind = llvm::DICompileUnit::NoDebug;
839 case llvm::codegenoptions::DebugLineTablesOnly:
840 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
842 case llvm::codegenoptions::DebugDirectivesOnly:
843 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
845 case llvm::codegenoptions::DebugInfoConstructor:
846 case llvm::codegenoptions::LimitedDebugInfo:
847 case llvm::codegenoptions::FullDebugInfo:
848 case llvm::codegenoptions::UnusedTypeInfo:
849 EmissionKind = llvm::DICompileUnit::FullDebug;
854 auto &CGOpts = CGM.getCodeGenOpts();
860 CSInfo.emplace(*CSKind, Checksum);
861 const llvm::StringRef cwd =
862 !CGOpts.EmitCodeView ||
863 (CGOpts.EmitCodeView && CGOpts.CodeViewEmitCurrentWorkdir)
864 ? getCurrentDirname()
865 : llvm::StringRef(
"");
866 llvm::DIFile *CUFile =
870 StringRef Sysroot, SDK;
871 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
872 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
873 if (CGM.getCodeGenOpts().DebugRecordSysroot)
874 Sysroot = FullSysroot;
875 auto B = llvm::sys::path::rbegin(FullSysroot);
876 auto E = llvm::sys::path::rend(FullSysroot);
878 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
883 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
884 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
885 CGOpts.DebugNameTable);
886 if (CGM.getTarget().getTriple().isNVPTX())
887 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
888 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
889 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
892 TheCU = DBuilder.createCompileUnit(
894 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
895 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
896 CGOpts.PrepareForThinLTO,
897 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
898 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
899 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
902llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
906#define BUILTIN_TYPE(Id, SingletonId)
907#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
908#include "clang/AST/BuiltinTypes.def"
909 case BuiltinType::Dependent:
910 llvm_unreachable(
"Unexpected builtin type");
911 case BuiltinType::NullPtr:
912 return DBuilder.createNullPtrType();
913 case BuiltinType::Void:
915 case BuiltinType::ObjCClass:
918 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
919 "objc_class", TheCU, TheCU->getFile(), 0);
921 case BuiltinType::ObjCId: {
932 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
933 "objc_class", TheCU, TheCU->getFile(), 0);
935 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
937 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
939 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
940 (uint64_t)0, 0, llvm::DINode::FlagZero,
941 nullptr, llvm::DINodeArray());
943 DBuilder.replaceArrays(
944 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
945 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
946 llvm::DINode::FlagZero, ISATy)));
949 case BuiltinType::ObjCSel: {
951 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
952 "objc_selector", TheCU,
953 TheCU->getFile(), 0);
957#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
958 case BuiltinType::Id: \
959 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
961#include "clang/Basic/OpenCLImageTypes.def"
962 case BuiltinType::OCLSampler:
963 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
964 case BuiltinType::OCLEvent:
965 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
966 case BuiltinType::OCLClkEvent:
967 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
968 case BuiltinType::OCLQueue:
969 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
970 case BuiltinType::OCLReserveID:
971 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
972#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
973 case BuiltinType::Id: \
974 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
975#include "clang/Basic/OpenCLExtensionTypes.def"
976#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
977 case BuiltinType::Id: \
978 return getOrCreateStructPtrType(#Name, SingletonId);
979#include "clang/Basic/HLSLIntangibleTypes.def"
980#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
981 case BuiltinType::Id: \
982 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
983#include "clang/Basic/HLSLPackedTypes.def"
985#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
986#include "clang/Basic/AArch64ACLETypes.def"
988 if (BT->
getKind() == BuiltinType::MFloat8) {
989 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
990 BTName = BT->
getName(CGM.getLangOpts());
993 return DBuilder.createBasicType(BTName, Size, Encoding);
995 ASTContext::BuiltinVectorTypeInfo Info =
997 BT->
getKind() == BuiltinType::SveCount
998 ? ASTContext::BuiltinVectorTypeInfo(
999 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1001 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1008 "Unsupported number of vectors for svcount_t");
1010 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1011 llvm::Metadata *BitStride =
nullptr;
1012 if (BT->
getKind() == BuiltinType::SveBool) {
1013 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1014 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1015 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1016 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1018 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1021 llvm::Metadata *LowerBound, *UpperBound;
1022 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1023 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1024 if (Info.
EC.isScalable()) {
1025 unsigned NumElemsPerVG = NumElems / 2;
1026 SmallVector<uint64_t, 9> Expr(
1027 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1028 46, 0, llvm::dwarf::DW_OP_mul,
1029 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1030 UpperBound = DBuilder.createExpression(Expr);
1032 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1033 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1035 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1036 nullptr, LowerBound, UpperBound,
nullptr);
1037 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1038 llvm::DIType *ElemTy =
1039 getOrCreateType(Info.
ElementType, TheCU->getFile());
1041 return DBuilder.createVectorType( 0, Align, ElemTy,
1042 SubscriptArray, BitStride);
1046#define PPC_VECTOR_TYPE(Name, Id, size) \
1047 case BuiltinType::Id:
1048#include "clang/Basic/PPCTypes.def"
1051#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1052#include "clang/Basic/RISCVVTypes.def"
1054 ASTContext::BuiltinVectorTypeInfo Info =
1055 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1057 unsigned ElementCount = Info.
EC.getKnownMinValue();
1058 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1060 bool Fractional =
false;
1063 unsigned FixedSize = ElementCount * SEW;
1064 if (Info.
ElementType == CGM.getContext().BoolTy) {
1067 }
else if (FixedSize < 64) {
1070 LMUL = 64 / FixedSize;
1072 LMUL = FixedSize / 64;
1076 SmallVector<uint64_t, 12> Expr(
1080 {llvm::dwarf::DW_OP_bregx,
1083 llvm::dwarf::DW_OP_constu,
1085 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1087 Expr.push_back(llvm::dwarf::DW_OP_div);
1089 Expr.push_back(llvm::dwarf::DW_OP_mul);
1092 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1094 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1097 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1098 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1099 auto *UpperBound = DBuilder.createExpression(Expr);
1100 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1101 nullptr, LowerBound, UpperBound,
nullptr);
1102 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1103 llvm::DIType *ElemTy =
1104 getOrCreateType(Info.
ElementType, TheCU->getFile());
1107 return DBuilder.createVectorType(0, Align, ElemTy,
1111#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1112 case BuiltinType::Id: { \
1115 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1116 MangledName, TheCU, TheCU->getFile(), 0); \
1117 return SingletonId; \
1119#include "clang/Basic/WebAssemblyReferenceTypes.def"
1120#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1121 case BuiltinType::Id: { \
1124 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1125 TheCU, TheCU->getFile(), 0); \
1126 return SingletonId; \
1128#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1129 case BuiltinType::Id: { \
1132 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1133 return SingletonId; \
1135#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1136 case BuiltinType::Id: { \
1139 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1140 return SingletonId; \
1142#include "clang/Basic/AMDGPUTypes.def"
1143#define SPIRV_TYPE(Name, Id, SingletonId) \
1144 case BuiltinType::Id: \
1145 return getOrCreateStructPtrType(Name, SingletonId);
1146#include "clang/Basic/SPIRVTypes.def"
1147 case BuiltinType::UChar:
1148 case BuiltinType::Char_U:
1149 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1151 case BuiltinType::Char_S:
1152 case BuiltinType::SChar:
1153 Encoding = llvm::dwarf::DW_ATE_signed_char;
1155 case BuiltinType::Char8:
1156 case BuiltinType::Char16:
1157 case BuiltinType::Char32:
1158 Encoding = llvm::dwarf::DW_ATE_UTF;
1160 case BuiltinType::UShort:
1161 case BuiltinType::UInt:
1162 case BuiltinType::UInt128:
1163 case BuiltinType::ULong:
1164 case BuiltinType::WChar_U:
1165 case BuiltinType::ULongLong:
1166 Encoding = llvm::dwarf::DW_ATE_unsigned;
1168 case BuiltinType::Short:
1169 case BuiltinType::Int:
1170 case BuiltinType::Int128:
1171 case BuiltinType::Long:
1172 case BuiltinType::WChar_S:
1173 case BuiltinType::LongLong:
1174 Encoding = llvm::dwarf::DW_ATE_signed;
1176 case BuiltinType::Bool:
1177 Encoding = llvm::dwarf::DW_ATE_boolean;
1179 case BuiltinType::Half:
1180 case BuiltinType::Float:
1181 case BuiltinType::LongDouble:
1182 case BuiltinType::Float16:
1183 case BuiltinType::BFloat16:
1184 case BuiltinType::Float128:
1185 case BuiltinType::Double:
1186 case BuiltinType::Ibm128:
1192 Encoding = llvm::dwarf::DW_ATE_float;
1194 case BuiltinType::ShortAccum:
1195 case BuiltinType::Accum:
1196 case BuiltinType::LongAccum:
1197 case BuiltinType::ShortFract:
1198 case BuiltinType::Fract:
1199 case BuiltinType::LongFract:
1200 case BuiltinType::SatShortFract:
1201 case BuiltinType::SatFract:
1202 case BuiltinType::SatLongFract:
1203 case BuiltinType::SatShortAccum:
1204 case BuiltinType::SatAccum:
1205 case BuiltinType::SatLongAccum:
1206 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1208 case BuiltinType::UShortAccum:
1209 case BuiltinType::UAccum:
1210 case BuiltinType::ULongAccum:
1211 case BuiltinType::UShortFract:
1212 case BuiltinType::UFract:
1213 case BuiltinType::ULongFract:
1214 case BuiltinType::SatUShortAccum:
1215 case BuiltinType::SatUAccum:
1216 case BuiltinType::SatULongAccum:
1217 case BuiltinType::SatUShortFract:
1218 case BuiltinType::SatUFract:
1219 case BuiltinType::SatULongFract:
1220 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1222 case BuiltinType::MetaInfo:
1223 llvm_unreachable(
"std::meta::info is consteval-only type");
1226 BTName = BT->
getName(CGM.getLangOpts());
1229 return DBuilder.createBasicType(BTName, Size, Encoding);
1232llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1233 SmallString<32> Name;
1234 llvm::raw_svector_ostream
OS(Name);
1235 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1238 ? llvm::dwarf::DW_ATE_unsigned
1239 : llvm::dwarf::DW_ATE_signed;
1240 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1241 Encoding, llvm::DINode::FlagZero, 0,
1245llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1247 return getOrCreateType(Ty->getUnderlyingType(), U);
1250llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1252 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1254 Encoding = llvm::dwarf::DW_ATE_lo_user;
1257 return DBuilder.createBasicType(
"complex", Size, Encoding);
1271 return llvm::dwarf::DW_TAG_const_type;
1275 return llvm::dwarf::DW_TAG_volatile_type;
1279 return llvm::dwarf::DW_TAG_restrict_type;
1281 return (llvm::dwarf::Tag)0;
1284llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1285 llvm::DIFile *Unit) {
1286 QualifierCollector Qc;
1300 bool AuthenticatesNullValues =
1303 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1304 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1305 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1306 ExtraDiscr, IsaPointer,
1307 AuthenticatesNullValues);
1309 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1310 return getOrCreateType(QualType(
T, 0), Unit);
1314 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1318 return DBuilder.createQualifiedType(Tag, FromTy);
1321llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1322 llvm::DIFile *Unit) {
1331 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1336 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1342 return DBuilder.createQualifiedType(Tag, FromTy);
1345llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1346 llvm::DIFile *Unit) {
1352 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1354 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1358llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1359 llvm::DIFile *Unit) {
1360 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1366 case llvm::dwarf::DW_LANG_C_plus_plus:
1367 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1368 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1369 case llvm::dwarf::DW_LANG_HIP:
1371 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1381 case llvm::dwarf::DW_LNAME_C_plus_plus:
1382 case llvm::dwarf::DW_LNAME_HIP:
1384 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1395 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1396 SourceLang.hasVersionedName())
1398 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1402 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1428 llvm::DICompileUnit *TheCU) {
1446 llvm::DICompileUnit *TheCU) {
1452 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1454 if (RD->isDynamicClass() &&
1460 llvm::raw_svector_ostream Out(Identifier);
1467 llvm::dwarf::Tag Tag;
1469 Tag = llvm::dwarf::DW_TAG_structure_type;
1471 Tag = llvm::dwarf::DW_TAG_union_type;
1476 Tag = llvm::dwarf::DW_TAG_class_type;
1481llvm::DICompositeType *
1482CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1483 llvm::DIScope *Ctx) {
1485 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1487 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1488 const unsigned Line =
1490 StringRef RDName = getClassName(RD);
1497 Size = CGM.getContext().getTypeSize(Ty);
1499 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1504 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1505 if (!CXXRD->hasDefinition() ||
1506 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1507 Flags |= llvm::DINode::FlagNonTrivial;
1510 SmallString<256> Identifier;
1512 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1514 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1517 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1518 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1519 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1520 CollectCXXTemplateParams(TSpecial, DefUnit));
1521 ReplaceMap.emplace_back(
1522 std::piecewise_construct, std::make_tuple(Ty),
1523 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1527llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1530 llvm::DIFile *Unit) {
1535 std::optional<unsigned> DWARFAddressSpace =
1536 CGM.getTarget().getDWARFAddressSpace(
1537 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1539 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1540 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1541 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1542 Size, Align, DWARFAddressSpace);
1544 SmallVector<llvm::Metadata *, 4> Annots;
1545 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1547 llvm::DINodeArray Annotations =
nullptr;
1548 if (Annots.size() > 0)
1549 Annotations = DBuilder.getOrCreateArray(Annots);
1550 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1551 Align, DWARFAddressSpace, StringRef(),
1556llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1557 llvm::DIType *&
Cache) {
1560 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1561 TheCU, TheCU->getFile(), 0);
1562 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1563 Cache = DBuilder.createPointerType(
Cache, Size);
1567uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1568 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1569 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1579 if (CGM.getLangOpts().OpenCL) {
1580 FType = CGM.getContext().IntTy;
1581 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1582 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1584 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1585 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1586 FType = CGM.getContext().IntTy;
1587 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1588 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1590 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1591 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1592 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1593 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1594 EltTys.push_back(DBuilder.createMemberType(
1595 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1596 FieldOffset, llvm::DINode::FlagZero, DescTy));
1597 FieldOffset += FieldSize;
1603llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1604 llvm::DIFile *Unit) {
1605 SmallVector<llvm::Metadata *, 8> EltTys;
1608 llvm::DINodeArray Elements;
1611 FType = CGM.getContext().UnsignedLongTy;
1612 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1613 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1615 Elements = DBuilder.getOrCreateArray(EltTys);
1618 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1621 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1622 FieldOffset, 0, Flags,
nullptr, Elements);
1627 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1629 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1632 Elements = DBuilder.getOrCreateArray(EltTys);
1638 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1639 Flags,
nullptr, Elements);
1641 return DBuilder.createPointerType(EltTy, Size);
1644static llvm::SmallVector<TemplateArgument>
1646 assert(Ty->isTypeAlias());
1655 ArrayRef SubstArgs = Ty->template_arguments();
1658 if (Param->isParameterPack()) {
1667 if (SubstArgs.empty()) {
1676 SpecArgs.push_back(SubstArgs.front());
1677 SubstArgs = SubstArgs.drop_front();
1682llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1683 llvm::DIFile *Unit) {
1684 assert(Ty->isTypeAlias());
1685 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1687 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1695 SmallString<128> NS;
1696 llvm::raw_svector_ostream
OS(NS);
1698 auto PP = getPrintingPolicy();
1701 SourceLocation Loc =
AliasDecl->getLocation();
1703 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1704 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1713 llvm::raw_string_ostream
OS(Name);
1715 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1716 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1717 !HasReconstitutableArgs(Args.Args))
1718 printTemplateArgumentList(OS, Args.Args, PP);
1720 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1721 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1722 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1726 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1728 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1745 return llvm::DINode::FlagZero;
1749 return llvm::DINode::FlagPrivate;
1751 return llvm::DINode::FlagProtected;
1753 return llvm::DINode::FlagPublic;
1755 return llvm::DINode::FlagZero;
1757 llvm_unreachable(
"unexpected access enumerator");
1760llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1761 llvm::DIFile *Unit) {
1762 llvm::DIType *Underlying =
1778 SmallVector<llvm::Metadata *, 4> Annots;
1779 llvm::DINodeArray Annotations;
1781 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1782 if (!Annots.empty())
1783 Annotations = DBuilder.getOrCreateArray(Annots);
1785 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1790 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1791 getOrCreateFile(Loc), getLineNumber(Loc),
1792 getDeclContextDescriptor(Ty->
getDecl()), Align,
1793 Flags, Annotations);
1801 if (
T.isSPIROrSPIRV())
1802 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1807 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1809 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1811 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1813 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1815 return llvm::dwarf::DW_CC_BORLAND_pascal;
1817 return llvm::dwarf::DW_CC_LLVM_Win64;
1819 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1823 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1825 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1827 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1829 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1831 return llvm::dwarf::DW_CC_LLVM_Swift;
1833 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1835 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1837 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1839 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1841 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1843 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1845 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1846#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1860 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1866 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1868 Flags |= llvm::DINode::FlagLValueReference;
1870 Flags |= llvm::DINode::FlagRValueReference;
1874llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1875 llvm::DIFile *Unit) {
1876 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1878 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1884 SmallVector<llvm::Metadata *, 16> EltTys;
1887 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1889 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1893 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1896 for (
const QualType &ParamType : FPT->param_types())
1897 EltTys.push_back(getOrCreateType(ParamType, Unit));
1898 if (FPT->isVariadic())
1899 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1902 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1903 llvm::DIType *F = DBuilder.createSubroutineType(
1904 EltTypeArray, Flags,
1909llvm::DIDerivedType *
1910CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1911 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1912 StringRef Name = BitFieldDecl->
getName();
1913 QualType Ty = BitFieldDecl->
getType();
1914 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1917 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1918 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1921 llvm::DIFile *
File = getOrCreateFile(Loc);
1922 unsigned Line = getLineNumber(Loc);
1924 const CGBitFieldInfo &BitFieldInfo =
1925 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1927 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1934 if (CGM.getDataLayout().isBigEndian())
1936 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1938 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1939 return DBuilder.createBitFieldMemberType(
1940 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1941 Flags, DebugType, Annotations);
1944llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1945 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1946 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1948 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1973 if (PreviousFieldsDI.empty())
1977 auto *PreviousMDEntry =
1978 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1979 auto *PreviousMDField =
1980 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1981 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1982 PreviousMDField->getSizeInBits() == 0)
1986 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1988 assert(PreviousBitfield->isBitField());
1990 if (!PreviousBitfield->isZeroLengthBitField())
1993 QualType Ty = PreviousBitfield->getType();
1994 SourceLocation Loc = PreviousBitfield->getLocation();
1995 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1996 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1997 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1999 llvm::DIFile *
File = getOrCreateFile(Loc);
2000 unsigned Line = getLineNumber(Loc);
2006 llvm::DINode::DIFlags Flags =
2008 llvm::DINodeArray Annotations =
2009 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2010 return DBuilder.createBitFieldMemberType(
2011 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2012 Flags, DebugType, Annotations);
2015llvm::DIType *CGDebugInfo::createFieldType(
2017 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2018 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2019 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2022 llvm::DIFile *file = getOrCreateFile(loc);
2023 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2026 auto Align = AlignInBits;
2027 if (!
type->isIncompleteArrayType()) {
2028 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2029 SizeInBits = TI.
Width;
2035 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2036 offsetInBits, flags, debugType, Annotations);
2040CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2041 llvm::DIFile *FileScope) {
2045 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2048 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2049 SP = DBuilder.createFunction(
2050 FileScope, FuncName, StringRef(),
2051 FileScope, 0, DIFnTy,
2053 llvm::DINode::FlagArtificial,
2054 llvm::DISubprogram::SPFlagDefinition,
2055 nullptr,
nullptr,
nullptr,
2056 nullptr, StringRef(),
2057 CGM.getCodeGenOpts().DebugKeyInstructions);
2064CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2066 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2068 assert(
Capture.capturesVariable());
2070 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2071 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2073 return CaptureDecl->
getName();
2076void CGDebugInfo::CollectRecordLambdaFields(
2077 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2078 llvm::DIType *RecordTy) {
2083 unsigned fieldno = 0;
2086 I != E; ++I, ++Field, ++fieldno) {
2087 const LambdaCapture &
Capture = *I;
2089 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2091 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2101 Loc =
Field->getLocation();
2102 }
else if (
Capture.capturesVariable()) {
2105 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2106 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2113 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2115 FieldIndexCache[*
Field] = elements.size();
2116 elements.push_back(createFieldType(
2118 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2124template <
typename T>
2125static llvm::Constant *
2136 return llvm::ConstantDataArray::get(Ctx, Vals);
2149 const QualType ElemQTy = ArrayTy->getElementType();
2156 switch (ElemBitWidth) {
2172llvm::DIDerivedType *
2173CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2174 const RecordDecl *RD) {
2178 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2179 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2181 unsigned LineNumber = getLineNumber(Var->
getLocation());
2182 StringRef VName = Var->
getName();
2186 llvm::Constant *
C =
nullptr;
2191 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2192 if (
Value->isFloat())
2193 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2194 if (
Value->isArray())
2200 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2201 ? llvm::dwarf::DW_TAG_variable
2202 : llvm::dwarf::DW_TAG_member;
2204 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2205 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2210void CGDebugInfo::CollectRecordNormalField(
2211 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2212 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2213 const RecordDecl *RD) {
2218 if (
name.empty() && !
type->isRecordType())
2221 llvm::DIType *FieldType;
2223 llvm::DIDerivedType *BitFieldType;
2224 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2225 if (llvm::DIType *Separator =
2226 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2227 elements.push_back(Separator);
2230 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2233 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2236 FieldIndexCache[field] = elements.size();
2237 elements.push_back(FieldType);
2240void CGDebugInfo::CollectRecordNestedType(
2241 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2242 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2249 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2250 elements.push_back(nestedType);
2253void CGDebugInfo::CollectRecordFields(
2254 const RecordDecl *record, llvm::DIFile *tunit,
2255 SmallVectorImpl<llvm::Metadata *> &elements,
2256 llvm::DICompositeType *RecordTy) {
2257 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2259 if (CXXDecl && CXXDecl->
isLambda())
2260 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2262 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2265 unsigned fieldNo = 0;
2269 for (
const auto *I : record->
decls())
2270 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2271 if (
V->hasAttr<NoDebugAttr>())
2276 if (CGM.getCodeGenOpts().EmitCodeView &&
2284 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2285 if (MI != StaticDataMemberCache.end()) {
2286 assert(MI->second &&
2287 "Static data member declaration should still exist");
2288 elements.push_back(MI->second);
2290 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2291 elements.push_back(Field);
2293 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2294 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2295 elements, RecordTy, record);
2299 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2302 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2307 if (!nestedType->isImplicit() &&
2308 nestedType->getDeclContext() == record)
2309 CollectRecordNestedType(nestedType, elements);
2315llvm::DISubroutineType *
2316CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2317 llvm::DIFile *Unit) {
2318 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2320 return cast_or_null<llvm::DISubroutineType>(
2321 getOrCreateType(QualType(
Func, 0), Unit));
2324 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2325 ThisType =
Method->getThisType();
2327 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2330llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2331 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2332 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2334 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2337llvm::DISubroutineType *
2338CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2339 const FunctionProtoType *
Func,
2340 llvm::DIFile *Unit,
bool SkipFirst) {
2341 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2356 getOrCreateType(CGM.getContext().getFunctionType(
2357 Func->getReturnType(),
Func->getParamTypes(), EPI),
2359 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2360 assert(Args.size() &&
"Invalid number of arguments!");
2362 SmallVector<llvm::Metadata *, 16> Elts;
2365 Elts.push_back(Args[0]);
2367 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2371 if (!HasExplicitObjectParameter) {
2372 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2375 DBuilder.createObjectPointerType(ThisPtrType,
true);
2376 Elts.push_back(ThisPtrType);
2380 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2381 Elts.push_back(Args[i]);
2384 if (HasExplicitObjectParameter) {
2385 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2386 "Expected at least return type and object parameter.");
2387 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2390 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2392 return DBuilder.createSubroutineType(
2393 EltTypeArray, OriginalFunc->getFlags(),
2400 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2408CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2411 const bool IsCtorOrDtor =
2414 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2421 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2424 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2427 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2430 return CGM.getMangledName(
Method);
2433bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2436 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2439llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2440 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2443 StringRef MethodName = getFunctionName(
Method);
2444 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2446 StringRef MethodLinkageName;
2453 MethodLinkageName = GetMethodLinkageName(
Method);
2456 llvm::DIFile *MethodDefUnit =
nullptr;
2457 unsigned MethodLine = 0;
2458 if (!
Method->isImplicit()) {
2459 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2460 MethodLine = getLineNumber(
Method->getLocation());
2464 llvm::DIType *ContainingType =
nullptr;
2465 unsigned VIndex = 0;
2466 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2467 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2468 int ThisAdjustment = 0;
2471 if (
Method->isPureVirtual())
2472 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2474 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2476 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2480 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2484 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2487 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2488 CGM.getContext().getLangOpts())
2492 MethodVFTableLocation ML =
2493 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2501 if (
Method->size_overridden_methods() == 0)
2502 Flags |= llvm::DINode::FlagIntroducedVirtual;
2507 ThisAdjustment = CGM.getCXXABI()
2508 .getVirtualFunctionPrologueThisAdjustment(GD)
2511 ContainingType = RecordTy;
2514 if (
Method->getCanonicalDecl()->isDeleted())
2515 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2517 if (
Method->isNoReturn())
2518 Flags |= llvm::DINode::FlagNoReturn;
2521 Flags |= llvm::DINode::FlagStaticMember;
2522 if (
Method->isImplicit())
2523 Flags |= llvm::DINode::FlagArtificial;
2525 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2526 if (CXXC->isExplicit())
2527 Flags |= llvm::DINode::FlagExplicit;
2528 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2529 if (CXXC->isExplicit())
2530 Flags |= llvm::DINode::FlagExplicit;
2532 if (
Method->hasPrototype())
2533 Flags |= llvm::DINode::FlagPrototyped;
2535 Flags |= llvm::DINode::FlagLValueReference;
2537 Flags |= llvm::DINode::FlagRValueReference;
2538 if (!
Method->isExternallyVisible())
2539 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2540 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2541 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2546 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2547 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2548 if (
const auto *Def =
2549 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2550 Def && !Def->isDelegatingConstructor()) {
2556 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2557 llvm::DISubprogram *SP = DBuilder.createMethod(
2558 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2559 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2560 TParamsArray.get(),
nullptr,
2561 CGM.getCodeGenOpts().DebugKeyInstructions);
2563 SPCache[
Method->getCanonicalDecl()].reset(SP);
2568void CGDebugInfo::CollectCXXMemberFunctions(
2569 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2570 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2575 for (
const auto *I : RD->
decls()) {
2576 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2590 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2599 auto MI = SPCache.find(
Method->getCanonicalDecl());
2600 EltTys.push_back(MI == SPCache.end()
2601 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2602 :
static_cast<llvm::Metadata *
>(MI->second));
2606void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2607 SmallVectorImpl<llvm::Metadata *> &EltTys,
2608 llvm::DIType *RecordTy) {
2609 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2610 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2611 llvm::DINode::FlagZero);
2615 if (CGM.getCodeGenOpts().EmitCodeView) {
2616 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2617 llvm::DINode::FlagIndirectVirtualBase);
2621void CGDebugInfo::CollectCXXBasesAux(
2622 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2623 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2625 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2626 llvm::DINode::DIFlags StartingFlags) {
2627 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2628 for (
const auto &BI : Bases) {
2631 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2633 if (!SeenTypes.insert(Base).second)
2635 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2636 llvm::DINode::DIFlags BFlags = StartingFlags;
2640 if (BI.isVirtual()) {
2641 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2644 BaseOffset = 0 - CGM.getItaniumVTableContext()
2645 .getVirtualBaseOffsetOffset(RD, Base)
2651 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2652 VBPtrOffset = CGM.getContext()
2653 .getASTRecordLayout(RD)
2657 BFlags |= llvm::DINode::FlagVirtual;
2664 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2665 VBPtrOffset, BFlags);
2666 EltTys.push_back(DTy);
2671CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2672 llvm::DIFile *Unit) {
2674 return llvm::DINodeArray();
2675 TemplateArgs &Args = *OArgs;
2676 SmallVector<llvm::Metadata *, 16> TemplateParams;
2677 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2678 const TemplateArgument &TA = Args.Args[i];
2682 Name = Args.TList->getParam(i)->getName();
2686 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2687 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2688 TheCU, Name, TTy, defaultParameter));
2693 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2694 TheCU, Name, TTy, defaultParameter,
2695 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2700 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2701 llvm::Constant *
V =
nullptr;
2704 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2705 !D->
hasAttr<CUDADeviceAttr>()) {
2708 if (
const auto *VD = dyn_cast<VarDecl>(D))
2709 V = CGM.GetAddrOfGlobalVar(VD);
2712 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2713 MD && MD->isImplicitObjectMemberFunction())
2714 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2715 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2716 V = CGM.GetAddrOfFunction(FD);
2719 else if (
const auto *MPT =
2720 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2724 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2726 CGM.getContext().toCharUnitsFromBits((
int64_t)fieldOffset);
2727 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2728 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2729 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2730 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2732 V = ConstantEmitter(CGM).emitAbstract(
2733 SourceLocation(), TPO->getValue(), TPO->getType());
2735 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2737 assert(
V &&
"Failed to find template parameter pointer");
2738 V =
V->stripPointerCasts();
2740 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2741 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2745 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2746 llvm::Constant *
V =
nullptr;
2749 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2755 if (MPT->isMemberDataPointer())
2756 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2758 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2759 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2760 TheCU, Name, TTy, defaultParameter,
V));
2764 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2765 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2767 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2768 TheCU, Name, TTy, defaultParameter,
V));
2771 std::string QualName;
2772 llvm::raw_string_ostream
OS(QualName);
2774 OS, getPrintingPolicy());
2775 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2776 TheCU, Name,
nullptr, QualName, defaultParameter));
2780 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2781 TheCU, Name,
nullptr,
2788 T = CGM.getContext().getLValueReferenceType(
T);
2789 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2790 assert(
V &&
"Expression in template argument isn't constant");
2791 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2792 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2793 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2799 "These argument types shouldn't exist in concrete types");
2802 return DBuilder.getOrCreateArray(TemplateParams);
2805std::optional<CGDebugInfo::TemplateArgs>
2806CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2814 return std::nullopt;
2816std::optional<CGDebugInfo::TemplateArgs>
2817CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2821 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2823 return std::nullopt;
2824 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2825 const TemplateParameterList *TList =
T->getTemplateParameters();
2826 auto TA = TS->getTemplateArgs().asArray();
2827 return {{TList, TA}};
2829std::optional<CGDebugInfo::TemplateArgs>
2830CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2831 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2835 TemplateParameterList *TPList =
2836 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2837 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2838 return {{TPList, TAList.
asArray()}};
2840 return std::nullopt;
2844CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2845 llvm::DIFile *Unit) {
2846 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2849llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2850 llvm::DIFile *Unit) {
2851 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2854llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2855 llvm::DIFile *Unit) {
2856 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2859void CGDebugInfo::CollectBTFDeclTagAnnotations(
2860 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2862 llvm::Metadata *Ops[2] = {
2863 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2864 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2865 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2869llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2870 if (!D->
hasAttr<BTFDeclTagAttr>())
2873 SmallVector<llvm::Metadata *, 4> Annotations;
2874 CollectBTFDeclTagAnnotations(D, Annotations);
2875 return DBuilder.getOrCreateArray(Annotations);
2878void CGDebugInfo::CollectBTFTypeTagAnnotations(
2879 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2880 const BTFTagAttributedType *BTFAttrTy;
2882 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2884 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2887 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2889 llvm::Metadata *Ops[2] = {
2890 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2891 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2892 Annotations.insert(Annotations.begin(),
2893 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2895 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2899llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2901 return VTablePtrType;
2903 ASTContext &Context = CGM.getContext();
2906 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2907 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2908 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2910 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2911 std::optional<unsigned> DWARFAddressSpace =
2912 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2914 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2915 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2916 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2917 return VTablePtrType;
2920StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2932 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2934 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2944 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2945 VTable->isDeclarationForLinker())
2949 StringRef SymbolName =
"__clang_vtable";
2951 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2960 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2962 llvm::DIFile *Unit = getOrCreateFile(Loc);
2963 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2965 llvm::DINode::FlagArtificial;
2966 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2967 ? llvm::dwarf::DW_TAG_variable
2968 : llvm::dwarf::DW_TAG_member;
2969 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2970 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2974 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2978 llvm::DIGlobalVariableExpression *GVE =
2979 DBuilder.createGlobalVariableExpression(
2980 TheCU, SymbolName, VTable->getName(), Unit, 0,
2981 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2982 true,
nullptr, DT,
nullptr,
2984 VTable->addDebugInfo(GVE);
2987StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2989 llvm::Function *InitFn) {
2994 return InitFn->getName();
3004 llvm::raw_svector_ostream OS(QualifiedGV);
3006 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3008 std::swap(Quals, GVName);
3012 llvm::raw_svector_ostream OS(InitName);
3014 OS << Quals <<
"::";
3019 llvm_unreachable(
"not an initializer");
3021 OS <<
"`dynamic initializer for '";
3024 OS <<
"`dynamic atexit destructor for '";
3031 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3032 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3033 getPrintingPolicy());
3038 return internString(
OS.str());
3041void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3042 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3051 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3058 llvm::DIType *VPtrTy =
nullptr;
3059 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3060 CGM.getTarget().getCXXABI().isMicrosoft();
3061 if (NeedVTableShape) {
3063 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3064 const VTableLayout &VFTLayout =
3065 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3066 unsigned VSlotCount =
3068 unsigned VTableWidth = PtrWidth * VSlotCount;
3069 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3070 std::optional<unsigned> DWARFAddressSpace =
3071 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3074 llvm::DIType *VTableType = DBuilder.createPointerType(
3075 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3076 EltTys.push_back(VTableType);
3079 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3087 VPtrTy = getOrCreateVTablePtrType(Unit);
3089 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3090 llvm::DIType *VPtrMember =
3091 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3092 llvm::DINode::FlagArtificial, VPtrTy);
3093 EltTys.push_back(VPtrMember);
3096std::pair<llvm::DIType *, unsigned>
3101 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3108 auto I = FieldIndexCache.find(Field);
3109 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3110 return {
T, I->second};
3120 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3121 assert(!D.
isNull() &&
"null type");
3122 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3123 assert(
T &&
"could not create debug info for type");
3132 if (CGM.getCodeGenOpts().getDebugInfo() <=
3133 llvm::codegenoptions::DebugLineTablesOnly)
3137 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3139 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3141 CI->setMetadata(
"heapallocsite", node);
3145 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3147 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3149 auto I = TypeCache.find(TyPtr);
3152 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3153 assert(!Res->isForwardDecl());
3154 TypeCache[TyPtr].reset(Res);
3158 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3159 !CGM.getLangOpts().CPlusPlus)
3165 if (RD->
hasAttr<DLLImportAttr>())
3168 if (MD->hasAttr<DLLImportAttr>())
3181 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3191 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3192 Explicit = TD->isExplicitInstantiationOrSpecialization();
3196 if (CXXDecl->
fields().empty())
3206 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3207 if (CXXRD->isDynamicClass() &&
3208 CGM.getVTableLinkage(CXXRD) ==
3209 llvm::GlobalValue::AvailableExternallyLinkage &&
3220 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3222 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3224 auto I = TypeCache.find(TyPtr);
3231 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3232 assert(!Res->isForwardDecl());
3233 TypeCache[TyPtr].reset(Res);
3240 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3241 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3268 bool HasNonDeletedCtor =
false;
3270 if (Ctor->isCopyOrMoveConstructor())
3277 if (CtorDef->isDelegatingConstructor())
3281 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3284 if (!Ctor->isDeleted())
3285 HasNonDeletedCtor =
true;
3287 return HasNonDeletedCtor;
3303 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3306 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3307 RD->
hasAttr<StandaloneDebugAttr>())
3310 if (!LangOpts.CPlusPlus)
3316 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3332 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3333 Spec = SD->getSpecializationKind();
3342 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3353 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3354 llvm::DIType *
T = getTypeOrNull(Ty);
3355 if (
T &&
T->isForwardDecl())
3359llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3361 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3365 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3369 auto [Def, Pref] = CreateTypeDefinition(Ty);
3371 return Pref ? Pref : Def;
3374llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3375 llvm::DIFile *Unit) {
3379 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3383 return getOrCreateType(PNA->getTypedefType(), Unit);
3410 const auto *RT = QT->
getAs<RecordType>();
3414 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3415 if (!CRD || !CRD->hasDefinition())
3420 assert(CRD->isStandardLayout());
3426std::pair<llvm::DIType *, llvm::DIType *>
3427CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3431 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3439 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3443 return {FwdDecl,
nullptr};
3445 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3446 CollectContainingType(CXXDecl, FwdDecl);
3449 LexicalBlockStack.emplace_back(&*FwdDecl);
3450 RegionMap[RD].reset(FwdDecl);
3453 SmallVector<llvm::Metadata *, 16> EltTys;
3460 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3462 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3463 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3467 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3468 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3469 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3471 LexicalBlockStack.pop_back();
3472 RegionMap.erase(RD);
3474 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3475 DBuilder.replaceArrays(FwdDecl, Elements);
3477 if (FwdDecl->isTemporary())
3479 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3481 RegionMap[RD].reset(FwdDecl);
3483 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3498 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3499 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3500 return {FwdDecl, PrefDI};
3502 return {FwdDecl,
nullptr};
3505llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3506 llvm::DIFile *Unit) {
3508 return getOrCreateType(Ty->getBaseType(), Unit);
3511llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3512 llvm::DIFile *Unit) {
3514 SourceLocation Loc = Ty->getDecl()->getLocation();
3517 return DBuilder.createTypedef(
3518 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3519 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3520 getDeclContextDescriptor(Ty->getDecl()));
3547llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3548 llvm::DIFile *Unit) {
3553 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3554 TheCU->getSourceLanguage().getUnversionedName());
3559 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3560 !
ID->getImplementation())
3561 return DBuilder.createForwardDecl(
3562 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3563 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3566 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3567 unsigned Line = getLineNumber(
ID->getLocation());
3571 ObjCInterfaceDecl *Def =
ID->getDefinition();
3573 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3574 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3575 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3576 DefUnit,
Line, RuntimeLang);
3577 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3581 return CreateTypeDefinition(Ty, Unit);
3584llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3585 bool CreateSkeletonCU) {
3590 auto ModRef = ModuleCache.find(M);
3591 if (ModRef != ModuleCache.end())
3595 SmallString<128> ConfigMacros;
3597 llvm::raw_svector_ostream
OS(ConfigMacros);
3598 const auto &PPOpts = CGM.getPreprocessorOpts();
3601 for (
auto &M : PPOpts.Macros) {
3604 const std::string &
Macro = M.first;
3605 bool Undef = M.second;
3606 OS <<
"\"-" << (Undef ?
'U' :
'D');
3607 for (
char c :
Macro)
3622 bool IsRootModule = M ? !M->
Parent :
true;
3626 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3627 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3628 "clang module without ASTFile must be specified by -fmodule-name");
3631 auto RemapPath = [
this](StringRef Path) -> std::string {
3633 StringRef Relative(Remapped);
3634 StringRef CompDir = TheCU->getDirectory();
3635 if (CompDir.empty())
3638 if (Relative.consume_front(CompDir))
3639 Relative.consume_front(llvm::sys::path::get_separator());
3641 return Relative.str();
3644 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3651 Signature = ModSig.truncatedValue();
3655 llvm::DIBuilder DIB(CGM.getModule());
3657 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3658 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3659 PCM = getCurrentDirname();
3663 llvm::sys::path::append(PCM, Mod.
getASTFile());
3664 DIB.createCompileUnit(
3665 TheCU->getSourceLanguage(),
3668 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3669 llvm::DICompileUnit::FullDebug, Signature);
3673 llvm::DIModule *Parent =
3675 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3677 StringRef IncludePath = Mod.
getPath();
3678 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3679 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3680 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3683 llvm::DIModule *DIMod =
3684 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3685 RemapPath(IncludePath));
3686 ModuleCache[M].reset(DIMod);
3690llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3691 llvm::DIFile *Unit) {
3693 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3694 unsigned Line = getLineNumber(
ID->getLocation());
3696 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3702 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3703 if (
ID->getImplementation())
3704 Flags |= llvm::DINode::FlagObjcClassComplete;
3706 llvm::DINodeArray Annotations;
3707 const auto *RuntimeName =
ID->getAttr<ObjCRuntimeNameAttr>();
3708 if (RuntimeName && RuntimeName->getMetadataName() !=
ID->getName()) {
3709 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
3710 llvm::Metadata *Ops[2] = {
3711 llvm::MDString::get(Ctx,
"objc_runtime_name"),
3712 llvm::MDString::get(Ctx, RuntimeName->getMetadataName())};
3713 Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)});
3716 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3717 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3718 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3719 nullptr, llvm::DINodeArray(), RuntimeLang,
nullptr,
3723 QualType QTy(Ty, 0);
3724 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3727 LexicalBlockStack.emplace_back(RealDecl);
3728 RegionMap[Ty->
getDecl()].reset(RealDecl);
3731 SmallVector<llvm::Metadata *, 16> EltTys;
3733 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3735 llvm::DIType *SClassTy =
3736 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3740 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3741 llvm::DINode::FlagZero);
3742 EltTys.push_back(InhTag);
3746 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3747 SourceLocation Loc = PD->getLocation();
3748 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3749 unsigned PLine = getLineNumber(Loc);
3750 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3751 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3752 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3753 PD->getName(), PUnit, PLine,
3755 : getSelectorName(PD->getGetterName()),
3757 : getSelectorName(PD->getSetterName()),
3758 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3759 EltTys.push_back(PropertyNode);
3764 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3768 llvm::DenseSet<IsClassAndIdent> PropertySet;
3770 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3771 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3773 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3774 for (
auto *PD : ClassExt->properties()) {
3775 PropertySet.insert(GetIsClassAndIdent(PD));
3778 for (
const auto *PD :
ID->properties()) {
3781 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3787 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3788 unsigned FieldNo = 0;
3789 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3790 Field =
Field->getNextIvar(), ++FieldNo) {
3791 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3795 StringRef FieldName =
Field->getName();
3798 if (FieldName.empty())
3802 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3803 unsigned FieldLine = getLineNumber(
Field->getLocation());
3804 QualType FType =
Field->getType();
3811 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3812 : CGM.getContext().getTypeSize(FType);
3817 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3821 if (
Field->isBitField()) {
3823 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3824 FieldOffset %= CGM.getContext().getCharWidth();
3832 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3834 Flags = llvm::DINode::FlagProtected;
3836 Flags = llvm::DINode::FlagPrivate;
3838 Flags = llvm::DINode::FlagPublic;
3840 if (
Field->isBitField())
3841 Flags |= llvm::DINode::FlagBitField;
3843 llvm::MDNode *PropertyNode =
nullptr;
3844 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3845 llvm::DIFile *PUnit =
nullptr;
3847 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3848 if (ObjCPropertyImplDecl *PImpD =
3849 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3850 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3851 SynthesizedProperty = PD;
3852 SourceLocation Loc = PD->getLocation();
3853 PUnit = getOrCreateFile(Loc);
3854 PLine = getLineNumber(Loc);
3855 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3856 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3857 PropertyNode = DBuilder.createObjCProperty(
3858 PD->getName(), PUnit, PLine,
3861 : getSelectorName(PD->getGetterName()),
3864 : getSelectorName(PD->getSetterName()),
3865 PD->getPropertyAttributes(),
3866 getOrCreateType(PD->getType(), PUnit));
3870 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3871 FieldSize, FieldAlign, FieldOffset,
3872 Flags, FieldTy, PropertyNode);
3873 EltTys.push_back(IvarTy);
3875 if (SynthesizedProperty) {
3876 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3877 EltTys.push_back(DBuilder.createProperty(
3878 SynthesizedProperty->
getName(), PUnit, PLine,
3879 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3883 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3884 DBuilder.replaceArrays(RealDecl, Elements);
3886 LexicalBlockStack.pop_back();
3890llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3891 llvm::DIFile *Unit) {
3899 auto &Ctx = CGM.getContext();
3904 QualType CharVecTy =
3906 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3909 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3912 llvm::Metadata *Subscript;
3913 QualType QTy(Ty, 0);
3914 auto SizeExpr = SizeExprCache.find(QTy);
3915 if (SizeExpr != SizeExprCache.end())
3916 Subscript = DBuilder.getOrCreateSubrange(
3917 SizeExpr->getSecond() ,
nullptr ,
3918 nullptr ,
nullptr );
3921 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3922 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3923 Subscript = DBuilder.getOrCreateSubrange(
3924 CountNode ,
nullptr ,
nullptr ,
3927 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3932 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3935llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3936 llvm::DIFile *Unit) {
3940 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3945 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3946 auto *ColumnCountNode =
3947 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3948 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3949 auto *RowCountNode =
3950 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3951 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3952 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3953 ColumnCountNode ,
nullptr ,
nullptr ,
3955 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3956 RowCountNode ,
nullptr ,
nullptr ,
3958 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3959 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3962llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3967 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3982 Size = CGM.getContext().getTypeSize(Ty);
3989 SmallVector<llvm::Metadata *, 8> Subscripts;
3990 QualType EltTy(Ty, 0);
3991 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
4000 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
4001 Count = CAT->getZExtSize();
4002 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
4003 if (Expr *Size = VAT->getSizeExpr()) {
4005 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
4006 Count =
Result.Val.getInt().getExtValue();
4010 auto SizeNode = SizeExprCache.find(EltTy);
4011 if (SizeNode != SizeExprCache.end())
4012 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4013 SizeNode->getSecond() ,
nullptr ,
4014 nullptr ,
nullptr ));
4017 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4018 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4019 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4020 CountNode ,
nullptr ,
nullptr ,
4026 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4028 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4032llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4033 llvm::DIFile *Unit) {
4034 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4038llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4039 llvm::DIFile *Unit) {
4040 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4042 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4043 CGM.getCodeGenOpts().DwarfVersion < 4)
4044 Tag = llvm::dwarf::DW_TAG_reference_type;
4046 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4049llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4051 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4055 Size = CGM.getContext().getTypeSize(Ty);
4058 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4061 Flags |= llvm::DINode::FlagSingleInheritance;
4064 Flags |= llvm::DINode::FlagMultipleInheritance;
4067 Flags |= llvm::DINode::FlagVirtualInheritance;
4077 llvm::DIType *ClassType = getOrCreateType(
T, U);
4079 return DBuilder.createMemberPointerType(
4083 const FunctionProtoType *FPT =
4085 return DBuilder.createMemberPointerType(
4086 getOrCreateInstanceMethodType(
4089 ClassType, Size, 0, Flags);
4092llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4094 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4097llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4101llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4103 return getOrCreateType(Ty->getWrappedType(), U);
4106llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4113 const EnumType *Ty) {
4125llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4128 bool isImportedFromModule =
4129 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4133 if (isImportedFromModule || !ED->getDefinition()) {
4140 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4141 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4142 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4143 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4145 unsigned Line = getLineNumber(ED->getLocation());
4146 StringRef EDName = ED->getName();
4147 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4148 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4149 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4151 ReplaceMap.emplace_back(
4152 std::piecewise_construct, std::make_tuple(Ty),
4153 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4157 return CreateTypeDefinition(Ty);
4160llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4163 SmallVector<llvm::Metadata *, 16> Enumerators;
4164 ED = ED->getDefinition();
4165 assert(ED &&
"An enumeration definition is required");
4166 for (
const auto *
Enum : ED->enumerators()) {
4167 Enumerators.push_back(
4168 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4171 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4172 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4173 EnumKind = Attr->getExtensibility();
4176 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4178 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4179 unsigned Line = getLineNumber(ED->getLocation());
4180 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4181 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4182 return DBuilder.createEnumerationType(
4183 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4184 0, Identifier, ED->isScoped(), EnumKind);
4189 StringRef Name, StringRef
Value) {
4190 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4191 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4197 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4198 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4199 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4204 llvm::DISubprogram *SynthSubprogram) {
4205 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4206 SynthSubprogram, ParentLocation);
4211 StringRef SynthFuncName,
4212 llvm::DIFile *SynthFile) {
4213 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4218 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4224 FuncName += Category;
4226 FuncName += FailureMsg;
4229 TrapLocation->getFile());
4239 Quals += InnerQuals;
4241 switch (
T->getTypeClass()) {
4243 return C.getQualifiedType(
T.getTypePtr(), Quals);
4246 case Type::InjectedClassName:
4247 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4249 case Type::TemplateSpecialization: {
4251 if (Spec->isTypeAlias())
4252 return C.getQualifiedType(
T.getTypePtr(), Quals);
4253 T = Spec->desugar();
4256 case Type::TypeOfExpr:
4262 case Type::Decltype:
4265 case Type::UnaryTransform:
4268 case Type::Attributed:
4271 case Type::BTFTagAttributed:
4274 case Type::CountAttributed:
4283 case Type::MacroQualified:
4286 case Type::SubstTemplateTypeParm:
4290 case Type::DeducedTemplateSpecialization: {
4292 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4296 case Type::PackIndexing: {
4300 case Type::Adjusted:
4307 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4312llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4315 if (It != TypeCache.end()) {
4317 if (llvm::Metadata *
V = It->second)
4330 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4337 RetainedTypes.push_back(
4338 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4341llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4345 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4347 llvm::raw_string_ostream OS(Name);
4348 Ty.
print(OS, getPrintingPolicy());
4355 if (
auto *
T = getTypeOrNull(Ty))
4358 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4359 void *TyPtr = Ty.getAsOpaquePtr();
4362 TypeCache[TyPtr].reset(Res);
4367llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4375 auto Info = Reader->getSourceDescriptor(Idx);
4377 return getOrCreateModuleRef(*Info,
true);
4378 }
else if (ClangModuleMap) {
4391 auto Info = ASTSourceDescriptor(*M);
4392 return getOrCreateModuleRef(Info,
false);
4395 return getOrCreateModuleRef(PCHDescriptor,
false);
4402llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4405 return CreateQualifiedType(Ty, Unit);
4409#define TYPE(Class, Base)
4410#define ABSTRACT_TYPE(Class, Base)
4411#define NON_CANONICAL_TYPE(Class, Base)
4412#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4413#include "clang/AST/TypeNodes.inc"
4414 llvm_unreachable(
"Dependent types cannot show up in debug information");
4416 case Type::ExtVector:
4419 case Type::ConstantMatrix:
4421 case Type::ObjCObjectPointer:
4423 case Type::ObjCObject:
4425 case Type::ObjCTypeParam:
4427 case Type::ObjCInterface:
4435 case Type::BlockPointer:
4443 case Type::FunctionProto:
4444 case Type::FunctionNoProto:
4446 case Type::ConstantArray:
4447 case Type::VariableArray:
4448 case Type::IncompleteArray:
4449 case Type::ArrayParameter:
4452 case Type::LValueReference:
4454 case Type::RValueReference:
4457 case Type::MemberPointer:
4465 case Type::OverflowBehavior:
4470 case Type::TemplateSpecialization:
4472 case Type::HLSLAttributedResource:
4474 case Type::HLSLInlineSpirv:
4476 case Type::PredefinedSugar:
4478 case Type::CountAttributed:
4479 case Type::LateParsedAttr:
4481 case Type::Attributed:
4482 case Type::BTFTagAttributed:
4483 case Type::Adjusted:
4485 case Type::DeducedTemplateSpecialization:
4488 case Type::MacroQualified:
4489 case Type::SubstTemplateTypeParm:
4490 case Type::TypeOfExpr:
4492 case Type::Decltype:
4493 case Type::PackIndexing:
4494 case Type::UnaryTransform:
4498 llvm_unreachable(
"type should have been unwrapped!");
4501llvm::DICompositeType *
4502CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4503 QualType QTy(Ty, 0);
4505 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4510 if (
T && !
T->isForwardDecl())
4514 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4519 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4522 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4527llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4529 bool NameIsSimplified =
false;
4532 StringRef RDName = getClassName(RD, &NameIsSimplified);
4534 llvm::DIFile *DefUnit =
nullptr;
4537 DefUnit = getOrCreateFile(Loc);
4538 Line = getLineNumber(Loc);
4541 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4545 auto *
T = cast_or_null<llvm::DICompositeType>(
4546 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4554 return getOrCreateRecordFwdDecl(Ty, RDContext);
4567 auto Flags = llvm::DINode::FlagZero;
4568 if (NameIsSimplified)
4569 Flags |= llvm::DINode::FlagNameIsSimplified;
4570 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4572 Flags |= llvm::DINode::FlagTypePassByReference;
4574 Flags |= llvm::DINode::FlagTypePassByValue;
4577 if (!CXXRD->isTrivial())
4578 Flags |= llvm::DINode::FlagNonTrivial;
4581 if (CXXRD->isAnonymousStructOrUnion())
4582 Flags |= llvm::DINode::FlagExportSymbols;
4585 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4588 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4589 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4591 Flags, Identifier, Annotations);
4595 switch (RealDecl->getTag()) {
4597 llvm_unreachable(
"invalid composite type tag");
4599 case llvm::dwarf::DW_TAG_array_type:
4600 case llvm::dwarf::DW_TAG_enumeration_type:
4605 if (Identifier.empty())
4609 case llvm::dwarf::DW_TAG_structure_type:
4610 case llvm::dwarf::DW_TAG_union_type:
4611 case llvm::dwarf::DW_TAG_class_type:
4614 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4618 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4619 CXXRecordDecl *TemplateDecl =
4620 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4621 RegionMap[TemplateDecl].reset(RealDecl);
4623 RegionMap[RD].reset(RealDecl);
4625 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4627 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4628 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4629 CollectCXXTemplateParams(TSpecial, DefUnit));
4633void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4634 llvm::DICompositeType *RealDecl) {
4636 llvm::DIType *ContainingType =
nullptr;
4637 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4641 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4648 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4649 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4651 ContainingType = RealDecl;
4653 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4656llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4657 StringRef Name, uint64_t *Offset) {
4658 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4659 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4662 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4663 *Offset, llvm::DINode::FlagZero, FieldTy);
4664 *Offset += FieldSize;
4668void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4670 StringRef &LinkageName,
4671 llvm::DIScope *&FDContext,
4672 llvm::DINodeArray &TParamsArray,
4673 llvm::DINode::DIFlags &Flags) {
4675 bool NameIsSimplified =
false;
4676 Name = getFunctionName(FD, &NameIsSimplified);
4677 if (NameIsSimplified)
4678 Flags |= llvm::DINode::FlagNameIsSimplified;
4679 Name = getFunctionName(FD);
4682 LinkageName = CGM.getMangledName(GD);
4684 Flags |= llvm::DINode::FlagPrototyped;
4688 if (LinkageName == Name ||
4689 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4690 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4691 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4692 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4693 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4694 LinkageName = StringRef();
4698 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4699 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4700 CGM.getCodeGenOpts().EmitCodeView)) {
4701 if (
const NamespaceDecl *NSDecl =
4703 FDContext = getOrCreateNamespace(NSDecl);
4704 else if (
const RecordDecl *RDecl =
4706 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4707 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4710 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4713 Flags |= llvm::DINode::FlagNoReturn;
4715 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4719void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4720 unsigned &LineNo, QualType &
T,
4721 StringRef &Name, StringRef &LinkageName,
4722 llvm::MDTuple *&TemplateParameters,
4723 llvm::DIScope *&VDContext) {
4732 llvm::APInt ConstVal(32, 1);
4733 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4735 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4742 LinkageName = CGM.getMangledName(VD);
4743 if (LinkageName == Name)
4744 LinkageName = StringRef();
4747 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4748 TemplateParameters = parameterNodes.get();
4750 TemplateParameters =
nullptr;
4756 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4757 VDContext = LexicalBlockStack.back();
4776 DC = CGM.getContext().getTranslationUnitDecl();
4778 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4779 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4782llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4784 llvm::DINodeArray TParamsArray;
4785 StringRef Name, LinkageName;
4786 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4787 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4789 llvm::DIFile *Unit = getOrCreateFile(Loc);
4790 llvm::DIScope *DContext = Unit;
4791 unsigned Line = getLineNumber(Loc);
4792 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4797 SmallVector<QualType, 16> ArgTypes;
4798 for (
const ParmVarDecl *Parm : FD->
parameters())
4799 ArgTypes.push_back(Parm->getType());
4802 QualType FnType = CGM.getContext().getFunctionType(
4803 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4805 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4806 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4807 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4811 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4812 return DBuilder.createFunction(
4813 DContext, Name, LinkageName, Unit,
Line,
4814 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4815 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4817 CGM.getCodeGenOpts().DebugKeyInstructions);
4820 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4821 DContext, Name, LinkageName, Unit,
Line,
4822 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4823 TParamsArray.get(), getFunctionDeclaration(FD));
4825 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4826 std::make_tuple(CanonDecl),
4827 std::make_tuple(SP));
4831llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4832 return getFunctionFwdDeclOrStub(GD,
false);
4835llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4836 return getFunctionFwdDeclOrStub(GD,
true);
4839llvm::DIGlobalVariable *
4840CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4842 StringRef Name, LinkageName;
4844 llvm::DIFile *Unit = getOrCreateFile(Loc);
4845 llvm::DIScope *DContext = Unit;
4846 unsigned Line = getLineNumber(Loc);
4847 llvm::MDTuple *TemplateParameters =
nullptr;
4849 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4852 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4853 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4855 FwdDeclReplaceMap.emplace_back(
4856 std::piecewise_construct,
4858 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4862llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4867 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4868 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4869 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4873 if (I != DeclCache.end()) {
4875 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4876 return GVE->getVariable();
4884 if (IE != ImportedDeclCache.end()) {
4885 auto N = IE->second;
4886 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4888 return dyn_cast_or_null<llvm::DINode>(N);
4893 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4894 return getFunctionForwardDeclaration(FD);
4895 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4896 return getGlobalVariableForwardDeclaration(VD);
4901llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4902 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4905 const auto *FD = dyn_cast<FunctionDecl>(D);
4910 auto *S = getDeclContextDescriptor(D);
4913 if (MI == SPCache.end()) {
4915 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4919 if (MI != SPCache.end()) {
4920 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4921 if (SP && !SP->isDefinition())
4925 for (
auto *NextFD : FD->
redecls()) {
4926 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4927 if (MI != SPCache.end()) {
4928 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4929 if (SP && !SP->isDefinition())
4936llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4937 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4938 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4939 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4942 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4946 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4950 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4959 QualType QTy(
ID->getTypeForDecl(), 0);
4960 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4961 if (It == TypeCache.end())
4964 llvm::DISubprogram *FD = DBuilder.createFunction(
4965 InterfaceType, getObjCMethodName(OMD), StringRef(),
4966 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4967 DBuilder.finalizeSubprogram(FD);
4974llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4979 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4980 !CGM.getCodeGenOpts().EmitCodeView))
4983 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4985 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4988 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4991 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4992 return getOrCreateMethodType(
Method, F);
4994 const auto *FTy = FnType->
getAs<FunctionType>();
4997 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4999 SmallVector<llvm::Metadata *, 16> Elts;
5002 QualType ResultTy = OMethod->getReturnType();
5005 if (ResultTy == CGM.getContext().getObjCInstanceType())
5006 ResultTy = CGM.getContext().getPointerType(
5007 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5009 Elts.push_back(getOrCreateType(ResultTy, F));
5011 QualType SelfDeclTy;
5012 if (
auto *SelfDecl = OMethod->getSelfDecl())
5013 SelfDeclTy = SelfDecl->getType();
5014 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5017 if (!SelfDeclTy.
isNull())
5019 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5021 Elts.push_back(DBuilder.createArtificialType(
5022 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5024 for (
const auto *PI : OMethod->parameters())
5025 Elts.push_back(getOrCreateType(PI->getType(), F));
5027 if (OMethod->isVariadic())
5028 Elts.push_back(DBuilder.createUnspecifiedParameter());
5030 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5031 return DBuilder.createSubroutineType(
5032 EltTypeArray, llvm::DINode::FlagZero,
5033 getDwarfCC(CC, CGM.getTarget().getTriple()));
5038 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5039 if (FD->isVariadic()) {
5040 SmallVector<llvm::Metadata *, 16> EltTys;
5041 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5042 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5044 EltTys.push_back(getOrCreateType(ParamType, F));
5045 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5046 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5047 return DBuilder.createSubroutineType(
5048 EltTypeArray, llvm::DINode::FlagZero,
5049 getDwarfCC(CC, CGM.getTarget().getTriple()));
5061 CC = SrcFnTy->getCallConv();
5063 for (
const VarDecl *VD : Args)
5064 ArgTypes.push_back(VD->
getType());
5065 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5071 llvm::Function *Fn,
bool CurFuncIsThunk) {
5073 StringRef LinkageName;
5075 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5078 bool HasDecl = (D !=
nullptr);
5080 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5081 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5082 llvm::DIFile *Unit = getOrCreateFile(Loc);
5083 llvm::DIScope *FDContext = Unit;
5084 llvm::DINodeArray TParamsArray;
5085 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5088 LinkageName = Fn->getName();
5089 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5091 auto FI = SPCache.find(FD->getCanonicalDecl());
5092 if (FI != SPCache.end()) {
5093 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5094 if (SP && SP->isDefinition()) {
5095 LexicalBlockStack.emplace_back(SP);
5096 RegionMap[D].reset(SP);
5100 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5101 TParamsArray, Flags);
5104 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5105 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5106 Name = getObjCMethodName(OMD);
5107 Flags |= llvm::DINode::FlagPrototyped;
5113 if (Name != Fn->getName())
5114 LinkageName = Fn->getName();
5116 Name = Fn->getName();
5121 Flags |= llvm::DINode::FlagPrototyped;
5123 Name.consume_front(
"\01");
5127 "Unexpected DynamicInitKind !");
5131 Flags |= llvm::DINode::FlagArtificial;
5137 Flags |= llvm::DINode::FlagThunk;
5139 if (Fn->hasLocalLinkage())
5140 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5141 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5142 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5145 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5146 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5148 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5149 unsigned ScopeLine = getLineNumber(ScopeLoc);
5150 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5151 llvm::DISubprogram *
Decl =
nullptr;
5152 llvm::DINodeArray Annotations =
nullptr;
5155 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5156 : getFunctionDeclaration(D);
5157 Annotations = CollectBTFDeclTagAnnotations(D);
5165 llvm::DISubprogram *SP = DBuilder.createFunction(
5166 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5167 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5168 Annotations,
"", KeyInstructions);
5169 Fn->setSubprogram(SP);
5178 LexicalBlockStack.emplace_back(SP);
5181 RegionMap[D].reset(SP);
5185 QualType FnType, llvm::Function *Fn) {
5187 StringRef LinkageName;
5193 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5194 return GetName(D,
true);
5197 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5198 llvm::DIFile *Unit = getOrCreateFile(Loc);
5199 bool IsDeclForCallSite = Fn ?
true :
false;
5200 llvm::DIScope *FDContext =
5201 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5202 llvm::DINodeArray TParamsArray;
5205 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5206 TParamsArray, Flags);
5207 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5208 Name = getObjCMethodName(OMD);
5209 Flags |= llvm::DINode::FlagPrototyped;
5211 llvm_unreachable(
"not a function or ObjC method");
5213 Name.consume_front(
"\01");
5216 Flags |= llvm::DINode::FlagArtificial;
5221 unsigned LineNo = getLineNumber(Loc);
5222 unsigned ScopeLine = 0;
5223 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5224 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5225 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5227 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5228 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5230 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5231 llvm::DISubprogram *SP = DBuilder.createFunction(
5232 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5233 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5239 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5240 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5241 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5244 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5245 DBuilder.createParameterVariable(
5246 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5247 llvm::DINode::FlagZero, ParamAnnotations);
5253 if (IsDeclForCallSite)
5254 Fn->setSubprogram(SP);
5258 llvm::CallBase *CI) {
5259 if (!shouldGenerateVirtualCallSite())
5265 assert(CI &&
"Invalid Call Instruction.");
5266 if (!CI->isIndirectCall())
5270 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5271 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5279 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5282 if (
Func->getSubprogram())
5286 if (!
Func->isDeclaration())
5308 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5309 Func->setSubprogram(SP);
5320 auto FI = SPCache.find(FD->getCanonicalDecl());
5321 llvm::DISubprogram *SP =
nullptr;
5322 if (FI != SPCache.end())
5323 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5324 if (!SP || !SP->isDefinition())
5325 SP = getFunctionStub(GD);
5326 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5327 LexicalBlockStack.emplace_back(SP);
5333 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5342 if (CurLoc.isInvalid() || LexicalBlockStack.empty())
5345 llvm::MDNode *
Scope = LexicalBlockStack.back();
5346 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5347 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5351 llvm::MDNode *Back =
nullptr;
5352 if (!LexicalBlockStack.empty())
5353 Back = LexicalBlockStack.back().get();
5356 unsigned Line = getLineNumber(CurLoc);
5357 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5358 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5362void CGDebugInfo::AppendAddressSpaceXDeref(
5364 std::optional<unsigned> DWARFAddressSpace =
5366 if (!DWARFAddressSpace)
5369 Expr.push_back(llvm::dwarf::DW_OP_constu);
5370 Expr.push_back(*DWARFAddressSpace);
5371 Expr.push_back(llvm::dwarf::DW_OP_swap);
5372 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5381 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5382 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5383 LexicalBlockStack.back(), CurInlinedAt));
5385 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5389 CreateLexicalBlock(Loc);
5394 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5399 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5402 LexicalBlockStack.pop_back();
5406 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5407 unsigned RCount = FnBeginRegionCount.back();
5408 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5411 while (LexicalBlockStack.size() != RCount) {
5414 LexicalBlockStack.pop_back();
5416 FnBeginRegionCount.pop_back();
5418 if (Fn && Fn->getSubprogram())
5419 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5422CGDebugInfo::BlockByRefType
5423CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5424 uint64_t *XOffset) {
5427 uint64_t FieldSize, FieldOffset;
5428 uint32_t FieldAlign;
5430 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5435 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5436 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5438 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5439 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5442 if (HasCopyAndDispose) {
5445 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5447 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5449 bool HasByrefExtendedLayout;
5452 HasByrefExtendedLayout) &&
5453 HasByrefExtendedLayout) {
5456 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5465 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5468 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5471 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5476 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5477 FieldSize = CGM.getContext().getTypeSize(FType);
5478 FieldAlign = CGM.getContext().toBits(Align);
5480 *XOffset = FieldOffset;
5481 llvm::DIType *FieldTy = DBuilder.createMemberType(
5482 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5483 llvm::DINode::FlagZero, WrappedTy);
5484 EltTys.push_back(FieldTy);
5485 FieldOffset += FieldSize;
5487 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5488 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5489 llvm::DINode::FlagZero,
nullptr, Elements),
5493llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5494 llvm::Value *Storage,
5495 std::optional<unsigned> ArgNo,
5497 const bool UsePointerValue) {
5498 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5499 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5500 if (VD->
hasAttr<NoDebugAttr>())
5505 llvm::DIFile *Unit =
nullptr;
5506 if (!VarIsArtificial)
5510 if (VD->
hasAttr<BlocksAttr>())
5511 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5513 Ty = getOrCreateType(VD->
getType(), Unit);
5523 if (!VarIsArtificial) {
5527 SmallVector<uint64_t, 13> Expr;
5528 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5535 Flags |= llvm::DINode::FlagArtificial;
5539 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5540 AppendAddressSpaceXDeref(AddressSpace, Expr);
5544 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5547 Flags |= llvm::DINode::FlagObjectPointer;
5548 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5549 if (PVD->isExplicitObjectParameter())
5550 Flags |= llvm::DINode::FlagObjectPointer;
5558 StringRef Name = VD->
getName();
5559 if (!Name.empty()) {
5565 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5567 offset = CGM.getContext().toCharUnitsFromBits(
5570 Expr.push_back(llvm::dwarf::DW_OP_deref);
5571 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5573 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5576 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5588 for (
const auto *Field : RD->
fields()) {
5589 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5590 StringRef FieldName =
Field->getName();
5598 auto *D = DBuilder.createAutoVariable(
5599 Scope, FieldName, Unit,
Line, FieldTy,
5600 CGM.getCodeGenOpts().OptimizationLevel != 0,
5601 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5604 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5605 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5608 Builder.GetInsertBlock());
5616 if (UsePointerValue) {
5617 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5618 "Debug info already contains DW_OP_deref.");
5619 Expr.push_back(llvm::dwarf::DW_OP_deref);
5623 llvm::DILocalVariable *D =
nullptr;
5625 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5626 D = DBuilder.createParameterVariable(
5627 Scope, Name, *ArgNo, Unit,
Line, Ty,
5628 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5637 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5643 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5644 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5645 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5646 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5648 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5654 if (Iter != CoroutineParameterMappings.end()) {
5655 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5656 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5657 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5659 if (Iter2 != ParamDbgMappings.end())
5660 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5666 D = RemapCoroArgToLocalVar();
5669 D = DBuilder.createAutoVariable(
5670 Scope, Name, Unit,
Line, Ty,
5671 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5674 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5675 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5676 Column, Scope, CurInlinedAt),
5677 Builder.GetInsertBlock());
5682llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5683 llvm::Value *Storage,
5684 std::optional<unsigned> ArgNo,
5686 const bool UsePointerValue) {
5687 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5688 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5689 if (BD->
hasAttr<NoDebugAttr>())
5696 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5697 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5705 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5707 SmallVector<uint64_t, 3> Expr;
5708 AppendAddressSpaceXDeref(AddressSpace, Expr);
5713 if (UsePointerValue) {
5714 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5715 "Debug info already contains DW_OP_deref.");
5716 Expr.push_back(llvm::dwarf::DW_OP_deref);
5721 StringRef Name = BD->
getName();
5724 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5725 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5726 llvm::DINode::FlagZero, Align);
5728 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5729 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5730 const unsigned fieldIndex = FD->getFieldIndex();
5731 const clang::CXXRecordDecl *parent =
5732 (
const CXXRecordDecl *)FD->getParent();
5733 const ASTRecordLayout &layout =
5734 CGM.getContext().getASTRecordLayout(parent);
5736 if (FD->isBitField()) {
5737 const CGRecordLayout &RL =
5738 CGM.getTypes().getCGRecordLayout(FD->getParent());
5743 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5749 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5750 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5751 Expr.push_back(Info.
Offset);
5754 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5755 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5756 }
else if (fieldOffset != 0) {
5757 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5758 "Unexpected non-bitfield with non-byte-aligned offset");
5759 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5761 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5764 }
else if (
const ArraySubscriptExpr *ASE =
5765 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5766 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5767 const uint64_t value = IL->getValue().getZExtValue();
5768 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5771 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5772 Expr.push_back(CGM.getContext()
5773 .toCharUnitsFromBits(value * typeSize)
5780 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5781 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5782 Column, Scope, CurInlinedAt),
5783 Builder.GetInsertBlock());
5788llvm::DILocalVariable *
5791 const bool UsePointerValue) {
5792 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5794 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5796 EmitDeclare(B, Storage, std::nullopt, Builder,
5803 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5807 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5808 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5810 if (D->
hasAttr<NoDebugAttr>())
5814 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5820 StringRef Name = D->
getName();
5826 CGM.getCodeGenOpts().OptimizationLevel != 0);
5829 DBuilder.insertLabel(L,
5830 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5831 Scope, CurInlinedAt),
5832 Builder.GetInsertBlock()->end());
5835llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5837 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5840 return DBuilder.createObjectPointerType(Ty,
true);
5845 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5846 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5847 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5849 if (Builder.GetInsertBlock() ==
nullptr)
5851 if (VD->
hasAttr<NoDebugAttr>())
5854 bool isByRef = VD->
hasAttr<BlocksAttr>();
5856 uint64_t XOffset = 0;
5857 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5860 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5862 Ty = getOrCreateType(VD->
getType(), Unit);
5866 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5868 Ty = CreateSelfType(VD->
getType(), Ty);
5871 const unsigned Line =
5875 const llvm::DataLayout &target = CGM.getDataLayout();
5882 addr.push_back(llvm::dwarf::DW_OP_deref);
5883 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5886 addr.push_back(llvm::dwarf::DW_OP_deref);
5887 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5890 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5892 addr.push_back(llvm::dwarf::DW_OP_deref);
5893 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5895 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5901 auto *D = DBuilder.createAutoVariable(
5903 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5906 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5907 LexicalBlockStack.back(), CurInlinedAt);
5908 auto *
Expr = DBuilder.createExpression(addr);
5910 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5912 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5915llvm::DILocalVariable *
5918 bool UsePointerValue) {
5919 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5920 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5924struct BlockLayoutChunk {
5925 uint64_t OffsetInBits;
5928bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5929 return l.OffsetInBits < r.OffsetInBits;
5933void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5935 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5936 SmallVectorImpl<llvm::Metadata *> &Fields) {
5940 if (CGM.getLangOpts().OpenCL) {
5941 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5942 BlockLayout.getElementOffsetInBits(0),
5944 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5945 BlockLayout.getElementOffsetInBits(1),
5949 BlockLayout.getElementOffsetInBits(0),
5951 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5952 BlockLayout.getElementOffsetInBits(1),
5956 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5957 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5958 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5959 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5960 BlockLayout.getElementOffsetInBits(3),
5962 Fields.push_back(createFieldType(
5967 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5974 llvm::AllocaInst *Alloca,
5976 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5982 llvm::DIFile *tunit = getOrCreateFile(loc);
5983 unsigned line = getLineNumber(loc);
5984 unsigned column = getColumnNumber(loc);
5989 const llvm::StructLayout *blockLayout =
5993 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
6002 BlockLayoutChunk chunk;
6003 chunk.OffsetInBits =
6004 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
6005 chunk.Capture =
nullptr;
6006 chunks.push_back(chunk);
6010 for (
const auto &capture :
blockDecl->captures()) {
6011 const VarDecl *variable = capture.getVariable();
6018 BlockLayoutChunk chunk;
6019 chunk.OffsetInBits =
6020 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6021 chunk.Capture = &capture;
6022 chunks.push_back(chunk);
6026 llvm::array_pod_sort(chunks.begin(), chunks.end());
6028 for (
const BlockLayoutChunk &Chunk : chunks) {
6029 uint64_t offsetInBits = Chunk.OffsetInBits;
6036 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6038 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6039 type = CGM.getContext().getCanonicalTagType(RDecl);
6041 llvm_unreachable(
"unexpected block declcontext");
6043 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6044 offsetInBits, tunit, tunit));
6049 StringRef name = variable->
getName();
6051 llvm::DIType *fieldType;
6053 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6058 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6059 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6060 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6061 PtrInfo.
Width, Align, offsetInBits,
6062 llvm::DINode::FlagZero, fieldType);
6066 offsetInBits, Align, tunit, tunit);
6068 fields.push_back(fieldType);
6072 llvm::raw_svector_ostream(typeName)
6073 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6075 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6077 llvm::DIType *
type =
6078 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6079 CGM.getContext().toBits(block.
BlockSize), 0,
6080 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6081 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6084 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6088 auto *debugVar = DBuilder.createParameterVariable(
6089 scope, Name, ArgNo, tunit, line,
type,
6090 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6093 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6094 llvm::DILocation::get(CGM.getLLVMContext(), line,
6095 column, scope, CurInlinedAt),
6096 Builder.GetInsertBlock());
6099llvm::DIDerivedType *
6100CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6105 if (MI != StaticDataMemberCache.end()) {
6106 assert(MI->second &&
"Static data member declaration should still exist");
6117llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6118 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6119 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6120 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6122 for (
const auto *Field : RD->
fields()) {
6123 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6124 StringRef FieldName = Field->getName();
6127 if (FieldName.empty()) {
6128 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6129 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6130 LineNo, LinkageName, Var, DContext);
6134 GVE = DBuilder.createGlobalVariableExpression(
6135 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6136 Var->hasLocalLinkage());
6137 Var->addDebugInfo(GVE);
6149 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6154 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6165 struct ReferencesAnonymous
6167 bool RefAnon =
false;
6168 bool VisitRecordType(RecordType *RT) {
6176 ReferencesAnonymous RT;
6189struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6190 bool Reconstitutable =
true;
6191 bool VisitVectorType(VectorType *FT) {
6192 Reconstitutable =
false;
6195 bool VisitAtomicType(AtomicType *FT) {
6196 Reconstitutable =
false;
6199 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6202 const EnumDecl *ED = ET->getDecl();
6204 Reconstitutable =
false;
6208 Reconstitutable =
false;
6213 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6217 return Reconstitutable;
6219 bool VisitRecordType(RecordType *RT,
bool =
false) {
6221 Reconstitutable =
false;
6231 ReconstitutableType
T;
6233 return T.Reconstitutable;
6236bool CGDebugInfo::HasReconstitutableArgs(
6237 ArrayRef<TemplateArgument> Args)
const {
6238 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6278 llvm_unreachable(
"Other, unresolved, template arguments should "
6279 "not be seen here");
6284std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6285 bool *NameIsSimplified)
const {
6287 llvm::raw_string_ostream
OS(Name);
6288 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6291 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6292 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6294 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6295 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6297 std::optional<TemplateArgs> Args;
6299 bool IsOperatorOverload =
false;
6300 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6301 Args = GetTemplateArgs(RD);
6302 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6303 Args = GetTemplateArgs(FD);
6305 IsOperatorOverload |=
6308 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6309 Args = GetTemplateArgs(VD);
6333 bool Reconstitutable =
6334 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6336 PrintingPolicy PP = getPrintingPolicy();
6338 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6343 if (NameIsSimplified)
6344 *NameIsSimplified =
true;
6345 bool Mangled = TemplateNamesKind ==
6346 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6352 std::string EncodedOriginalName;
6353 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6358 printTemplateArgumentList(OS, Args->Args, PP);
6359 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6361 std::string CanonicalOriginalName;
6362 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6364 assert(EncodedOriginalName == CanonicalOriginalName);
6373 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6374 if (D->
hasAttr<NoDebugAttr>())
6377 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6378 return GetName(D,
true);
6384 if (Cached != DeclCache.end())
6385 return Var->addDebugInfo(
6389 llvm::DIFile *Unit =
nullptr;
6390 llvm::DIScope *DContext =
nullptr;
6392 StringRef DeclName, LinkageName;
6394 llvm::MDTuple *TemplateParameters =
nullptr;
6395 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6396 TemplateParameters, DContext);
6400 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6405 if (
T->isUnionType() && DeclName.empty()) {
6406 const auto *RD =
T->castAsRecordDecl();
6408 "unnamed non-anonymous struct or union?");
6409 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6414 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6415 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6416 if (D->
hasAttr<CUDASharedAttr>())
6419 else if (D->
hasAttr<CUDAConstantAttr>())
6423 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6425 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6426 GVE = DBuilder.createGlobalVariableExpression(
6427 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6428 Var->hasLocalLinkage(),
true,
6429 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6430 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6431 Align, Annotations);
6432 Var->addDebugInfo(GVE);
6438 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6439 if (VD->
hasAttr<NoDebugAttr>())
6441 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6442 return GetName(VD,
true);
6447 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6448 StringRef Name = VD->
getName();
6449 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6451 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6453 if (CGM.getCodeGenOpts().EmitCodeView) {
6464 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6465 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6466 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6476 auto *VarD = dyn_cast<VarDecl>(VD);
6477 if (VarD && VarD->isStaticDataMember()) {
6479 getDeclContextDescriptor(VarD);
6484 RetainedTypes.push_back(
6485 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6489 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6491 auto &GV = DeclCache[VD];
6495 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6496 llvm::MDTuple *TemplateParameters =
nullptr;
6500 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6501 TemplateParameters = parameterNodes.get();
6504 GV.reset(DBuilder.createGlobalVariableExpression(
6505 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6506 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6507 TemplateParameters, Align));
6512 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6513 if (D->
hasAttr<NoDebugAttr>())
6517 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6518 StringRef Name = D->
getName();
6519 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6521 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6522 llvm::DIGlobalVariableExpression *GVE =
6523 DBuilder.createGlobalVariableExpression(
6524 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6525 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6526 Var->addDebugInfo(GVE);
6533 if (CGM.getCodeGenOpts().getDebugInfo() <=
6534 llvm::codegenoptions::DebugLineTablesOnly)
6537 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6541 llvm::DIFile *Unit = DIL->getFile();
6542 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6547 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6548 llvm::Value *Var = Load->getPointerOperand();
6553 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6554 return DbgDeclare->getVariable()->getType() ==
Type;
6556 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6560 llvm::DILocalVariable *D =
6561 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6562 Type,
false, llvm::DINode::FlagArtificial);
6564 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6565 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6575 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6579 if (D->
hasAttr<NoDebugAttr>())
6582 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6597 if (!(DI = getDeclarationOrDefinition(
6598 AliaseeDecl.getCanonicalDecl().getDecl())))
6601 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6604 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6605 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6619 llvm::DIFile *
File = getOrCreateFile(Loc);
6620 llvm::DIGlobalVariableExpression *Debug =
6621 DBuilder.createGlobalVariableExpression(
6622 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6623 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6624 GV->addDebugInfo(Debug);
6627llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6628 if (!LexicalBlockStack.empty())
6629 return LexicalBlockStack.back();
6630 llvm::DIScope *Mod = getParentModuleOrNull(D);
6631 return getContextDescriptor(D, Mod ? Mod : TheCU);
6635 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6639 CGM.getCodeGenOpts().DebugExplicitImport) {
6643 DBuilder.createImportedModule(
6645 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6650 if (llvm::DINode *
Target =
6653 DBuilder.createImportedDeclaration(
6655 getOrCreateFile(Loc), getLineNumber(Loc));
6660 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6663 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6665 for (
const auto *USD : UD.
shadows()) {
6670 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6671 if (
const auto *AT = FD->getType()
6674 if (AT->getDeducedType().isNull())
6685 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6688 "We shouldn't be codegening an invalid UsingEnumDecl"
6689 " containing no decls");
6691 for (
const auto *USD : UD.
shadows())
6696 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6698 if (
Module *M = ID.getImportedModule()) {
6700 auto Loc = ID.getLocation();
6701 DBuilder.createImportedDeclaration(
6702 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6703 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6704 getLineNumber(Loc));
6708llvm::DIImportedEntity *
6710 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6712 auto &VH = NamespaceAliasCache[&NA];
6715 llvm::DIImportedEntity *R;
6717 if (
const auto *Underlying =
6720 R = DBuilder.createImportedDeclaration(
6723 getLineNumber(Loc), NA.
getName());
6725 R = DBuilder.createImportedDeclaration(
6728 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6734CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6738 auto I = NamespaceCache.find(NSDecl);
6739 if (I != NamespaceCache.end())
6742 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6744 llvm::DINamespace *NS =
6745 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6746 NamespaceCache[NSDecl].reset(NS);
6751 assert(TheCU &&
"no main compile unit");
6752 TheCU->setDWOId(Signature);
6758 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6759 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6761 ? CreateTypeDefinition(E.Type, E.Unit)
6763 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6767 for (
const auto &P : ObjCMethodCache) {
6768 if (P.second.empty())
6771 QualType QTy(P.first->getTypeForDecl(), 0);
6773 assert(It != TypeCache.end());
6775 llvm::DICompositeType *InterfaceDecl =
6778 auto CurElts = InterfaceDecl->getElements();
6782 for (
auto &SubprogramDirect : P.second)
6783 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6784 EltTys.push_back(SubprogramDirect.getPointer());
6786 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6787 DBuilder.replaceArrays(InterfaceDecl, Elements);
6790 for (
const auto &P : ReplaceMap) {
6793 assert(Ty->isForwardDecl());
6795 auto It = TypeCache.find(P.first);
6796 assert(It != TypeCache.end());
6799 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6803 for (
const auto &P : FwdDeclReplaceMap) {
6806 llvm::Metadata *Repl;
6808 auto It = DeclCache.find(P.first);
6812 if (It == DeclCache.end())
6817 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6818 Repl = GVE->getVariable();
6824 for (
auto &RT : RetainedTypes)
6825 if (
auto MD = TypeCache[RT])
6828 DBuilder.finalize();
6833 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6834 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6835 DBuilder.retainType(DieTy);
6839 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6840 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6841 DBuilder.retainType(DieTy);
6845 if (LexicalBlockStack.empty())
6846 return llvm::DebugLoc();
6848 llvm::MDNode *
Scope = LexicalBlockStack.back();
6849 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6850 getColumnNumber(Loc),
Scope);
6856 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6857 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6858 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6859 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6860 return llvm::DINode::FlagZero;
6865 bool SupportsDWARFv4Ext =
6866 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6867 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6868 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6870 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6871 return llvm::DINode::FlagZero;
6873 return llvm::DINode::FlagAllCallsDescribed;
6884 return DBuilder.createConstantValueExpression(
6885 Val.
getFloat().bitcastToAPInt().getZExtValue());
6890 llvm::APSInt
const &ValInt = Val.
getInt();
6891 std::optional<uint64_t> ValIntOpt;
6892 if (ValInt.isUnsigned())
6893 ValIntOpt = ValInt.tryZExtValue();
6894 else if (
auto tmp = ValInt.trySExtValue())
6897 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6900 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6905CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6907 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6908 CGF.CurLexicalScope =
this;
6910 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6915 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6928#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6930 Label = "__ubsan_check_" #Name; \
6934#undef SANITIZER_CHECK
6945#define SANITIZER(NAME, ID) \
6946 case SanitizerKind::SO_##ID: \
6947 Label = "__ubsan_check_" NAME; \
6949#include "clang/Basic/Sanitizers.def"
6951 llvm_unreachable(
"unexpected sanitizer kind");
6956 for (
unsigned int i = 0; i < Label.length(); i++)
6957 if (!std::isalpha(Label[i]))
6966 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6968 if (!DI || !CheckDebugLoc)
6969 return CheckDebugLoc;
6970 const auto &AnnotateDebugInfo =
6971 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6972 if (AnnotateDebugInfo.empty())
6973 return CheckDebugLoc;
6976 if (Ordinals.size() == 1)
6981 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6985 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6986 "ubsan_interface.h",
6988 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6991 return CheckDebugLoc;
6999 assert(!CGF->IsSanitizerScope);
7000 CGF->IsSanitizerScope =
true;
7004 assert(CGF->IsSanitizerScope);
7005 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 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.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits, not including padding.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned PrettyEnums
Whether to print enumerators with a matching enumerator name or via cast.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.