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 llvm::DIFile *CUFile = DBuilder.createFile(
865 StringRef Sysroot, SDK;
866 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
867 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
868 if (CGM.getCodeGenOpts().DebugRecordSysroot)
869 Sysroot = FullSysroot;
870 auto B = llvm::sys::path::rbegin(FullSysroot);
871 auto E = llvm::sys::path::rend(FullSysroot);
873 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
878 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
879 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
880 CGOpts.DebugNameTable);
881 if (CGM.getTarget().getTriple().isNVPTX())
882 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
883 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
884 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
887 TheCU = DBuilder.createCompileUnit(
889 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
890 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
891 CGOpts.PrepareForThinLTO,
892 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
893 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
894 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
897llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
901#define BUILTIN_TYPE(Id, SingletonId)
902#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
903#include "clang/AST/BuiltinTypes.def"
904 case BuiltinType::Dependent:
905 llvm_unreachable(
"Unexpected builtin type");
906 case BuiltinType::NullPtr:
907 return DBuilder.createNullPtrType();
908 case BuiltinType::Void:
910 case BuiltinType::ObjCClass:
913 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
914 "objc_class", TheCU, TheCU->getFile(), 0);
916 case BuiltinType::ObjCId: {
927 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
928 "objc_class", TheCU, TheCU->getFile(), 0);
930 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
932 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
934 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
935 (uint64_t)0, 0, llvm::DINode::FlagZero,
936 nullptr, llvm::DINodeArray());
938 DBuilder.replaceArrays(
939 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
940 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
941 llvm::DINode::FlagZero, ISATy)));
944 case BuiltinType::ObjCSel: {
946 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
947 "objc_selector", TheCU,
948 TheCU->getFile(), 0);
952#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
953 case BuiltinType::Id: \
954 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
956#include "clang/Basic/OpenCLImageTypes.def"
957 case BuiltinType::OCLSampler:
958 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
959 case BuiltinType::OCLEvent:
960 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
961 case BuiltinType::OCLClkEvent:
962 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
963 case BuiltinType::OCLQueue:
964 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
965 case BuiltinType::OCLReserveID:
966 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
967#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
968 case BuiltinType::Id: \
969 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
970#include "clang/Basic/OpenCLExtensionTypes.def"
971#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
972 case BuiltinType::Id: \
973 return getOrCreateStructPtrType(#Name, SingletonId);
974#include "clang/Basic/HLSLIntangibleTypes.def"
975#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
976 case BuiltinType::Id: \
977 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
978#include "clang/Basic/HLSLPackedTypes.def"
980#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
981#include "clang/Basic/AArch64ACLETypes.def"
983 if (BT->
getKind() == BuiltinType::MFloat8) {
984 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
985 BTName = BT->
getName(CGM.getLangOpts());
988 return DBuilder.createBasicType(BTName, Size, Encoding);
990 ASTContext::BuiltinVectorTypeInfo Info =
992 BT->
getKind() == BuiltinType::SveCount
993 ? ASTContext::BuiltinVectorTypeInfo(
994 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
996 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1003 "Unsupported number of vectors for svcount_t");
1005 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1006 llvm::Metadata *BitStride =
nullptr;
1007 if (BT->
getKind() == BuiltinType::SveBool) {
1008 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1009 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1010 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1011 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1013 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1016 llvm::Metadata *LowerBound, *UpperBound;
1017 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1018 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1019 if (Info.
EC.isScalable()) {
1020 unsigned NumElemsPerVG = NumElems / 2;
1021 SmallVector<uint64_t, 9> Expr(
1022 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1023 46, 0, llvm::dwarf::DW_OP_mul,
1024 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1025 UpperBound = DBuilder.createExpression(Expr);
1027 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1028 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1030 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1031 nullptr, LowerBound, UpperBound,
nullptr);
1032 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1033 llvm::DIType *ElemTy =
1034 getOrCreateType(Info.
ElementType, TheCU->getFile());
1036 return DBuilder.createVectorType( 0, Align, ElemTy,
1037 SubscriptArray, BitStride);
1041#define PPC_VECTOR_TYPE(Name, Id, size) \
1042 case BuiltinType::Id:
1043#include "clang/Basic/PPCTypes.def"
1046#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1047#include "clang/Basic/RISCVVTypes.def"
1049 ASTContext::BuiltinVectorTypeInfo Info =
1050 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1052 unsigned ElementCount = Info.
EC.getKnownMinValue();
1053 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1055 bool Fractional =
false;
1058 unsigned FixedSize = ElementCount * SEW;
1059 if (Info.
ElementType == CGM.getContext().BoolTy) {
1062 }
else if (FixedSize < 64) {
1065 LMUL = 64 / FixedSize;
1067 LMUL = FixedSize / 64;
1071 SmallVector<uint64_t, 12> Expr(
1075 {llvm::dwarf::DW_OP_bregx,
1078 llvm::dwarf::DW_OP_constu,
1080 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1082 Expr.push_back(llvm::dwarf::DW_OP_div);
1084 Expr.push_back(llvm::dwarf::DW_OP_mul);
1087 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1089 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1092 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1093 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1094 auto *UpperBound = DBuilder.createExpression(Expr);
1095 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1096 nullptr, LowerBound, UpperBound,
nullptr);
1097 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1098 llvm::DIType *ElemTy =
1099 getOrCreateType(Info.
ElementType, TheCU->getFile());
1102 return DBuilder.createVectorType(0, Align, ElemTy,
1106#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1107 case BuiltinType::Id: { \
1110 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1111 MangledName, TheCU, TheCU->getFile(), 0); \
1112 return SingletonId; \
1114#include "clang/Basic/WebAssemblyReferenceTypes.def"
1115#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1116 case BuiltinType::Id: { \
1119 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1120 TheCU, TheCU->getFile(), 0); \
1121 return SingletonId; \
1123#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1124 case BuiltinType::Id: { \
1127 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1128 return SingletonId; \
1130#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1131 case BuiltinType::Id: { \
1134 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1135 return SingletonId; \
1137#include "clang/Basic/AMDGPUTypes.def"
1138#define SPIRV_TYPE(Name, Id, SingletonId) \
1139 case BuiltinType::Id: \
1140 return getOrCreateStructPtrType(Name, SingletonId);
1141#include "clang/Basic/SPIRVTypes.def"
1142 case BuiltinType::UChar:
1143 case BuiltinType::Char_U:
1144 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1146 case BuiltinType::Char_S:
1147 case BuiltinType::SChar:
1148 Encoding = llvm::dwarf::DW_ATE_signed_char;
1150 case BuiltinType::Char8:
1151 case BuiltinType::Char16:
1152 case BuiltinType::Char32:
1153 Encoding = llvm::dwarf::DW_ATE_UTF;
1155 case BuiltinType::UShort:
1156 case BuiltinType::UInt:
1157 case BuiltinType::UInt128:
1158 case BuiltinType::ULong:
1159 case BuiltinType::WChar_U:
1160 case BuiltinType::ULongLong:
1161 Encoding = llvm::dwarf::DW_ATE_unsigned;
1163 case BuiltinType::Short:
1164 case BuiltinType::Int:
1165 case BuiltinType::Int128:
1166 case BuiltinType::Long:
1167 case BuiltinType::WChar_S:
1168 case BuiltinType::LongLong:
1169 Encoding = llvm::dwarf::DW_ATE_signed;
1171 case BuiltinType::Bool:
1172 Encoding = llvm::dwarf::DW_ATE_boolean;
1174 case BuiltinType::Half:
1175 case BuiltinType::Float:
1176 case BuiltinType::LongDouble:
1177 case BuiltinType::Float16:
1178 case BuiltinType::BFloat16:
1179 case BuiltinType::Float128:
1180 case BuiltinType::Double:
1181 case BuiltinType::Ibm128:
1187 Encoding = llvm::dwarf::DW_ATE_float;
1189 case BuiltinType::ShortAccum:
1190 case BuiltinType::Accum:
1191 case BuiltinType::LongAccum:
1192 case BuiltinType::ShortFract:
1193 case BuiltinType::Fract:
1194 case BuiltinType::LongFract:
1195 case BuiltinType::SatShortFract:
1196 case BuiltinType::SatFract:
1197 case BuiltinType::SatLongFract:
1198 case BuiltinType::SatShortAccum:
1199 case BuiltinType::SatAccum:
1200 case BuiltinType::SatLongAccum:
1201 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1203 case BuiltinType::UShortAccum:
1204 case BuiltinType::UAccum:
1205 case BuiltinType::ULongAccum:
1206 case BuiltinType::UShortFract:
1207 case BuiltinType::UFract:
1208 case BuiltinType::ULongFract:
1209 case BuiltinType::SatUShortAccum:
1210 case BuiltinType::SatUAccum:
1211 case BuiltinType::SatULongAccum:
1212 case BuiltinType::SatUShortFract:
1213 case BuiltinType::SatUFract:
1214 case BuiltinType::SatULongFract:
1215 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1217 case BuiltinType::MetaInfo:
1218 llvm_unreachable(
"std::meta::info is consteval-only type");
1221 BTName = BT->
getName(CGM.getLangOpts());
1224 return DBuilder.createBasicType(BTName, Size, Encoding);
1227llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1228 SmallString<32> Name;
1229 llvm::raw_svector_ostream
OS(Name);
1230 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1233 ? llvm::dwarf::DW_ATE_unsigned
1234 : llvm::dwarf::DW_ATE_signed;
1235 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1236 Encoding, llvm::DINode::FlagZero, 0,
1240llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1242 return getOrCreateType(Ty->getUnderlyingType(), U);
1245llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1247 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1249 Encoding = llvm::dwarf::DW_ATE_lo_user;
1252 return DBuilder.createBasicType(
"complex", Size, Encoding);
1266 return llvm::dwarf::DW_TAG_const_type;
1270 return llvm::dwarf::DW_TAG_volatile_type;
1274 return llvm::dwarf::DW_TAG_restrict_type;
1276 return (llvm::dwarf::Tag)0;
1279llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1280 llvm::DIFile *Unit) {
1281 QualifierCollector Qc;
1295 bool AuthenticatesNullValues =
1298 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1299 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1300 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1301 ExtraDiscr, IsaPointer,
1302 AuthenticatesNullValues);
1304 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1305 return getOrCreateType(QualType(
T, 0), Unit);
1309 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1313 return DBuilder.createQualifiedType(Tag, FromTy);
1316llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1317 llvm::DIFile *Unit) {
1326 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1331 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1337 return DBuilder.createQualifiedType(Tag, FromTy);
1340llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1341 llvm::DIFile *Unit) {
1347 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1349 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1353llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1354 llvm::DIFile *Unit) {
1355 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1361 case llvm::dwarf::DW_LANG_C_plus_plus:
1362 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1363 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1364 case llvm::dwarf::DW_LANG_HIP:
1366 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1376 case llvm::dwarf::DW_LNAME_C_plus_plus:
1377 case llvm::dwarf::DW_LNAME_HIP:
1379 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1390 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1391 SourceLang.hasVersionedName())
1393 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1397 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1423 llvm::DICompileUnit *TheCU) {
1441 llvm::DICompileUnit *TheCU) {
1447 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1449 if (RD->isDynamicClass() &&
1455 llvm::raw_svector_ostream Out(Identifier);
1462 llvm::dwarf::Tag Tag;
1464 Tag = llvm::dwarf::DW_TAG_structure_type;
1466 Tag = llvm::dwarf::DW_TAG_union_type;
1471 Tag = llvm::dwarf::DW_TAG_class_type;
1476llvm::DICompositeType *
1477CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1478 llvm::DIScope *Ctx) {
1480 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1482 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1483 const unsigned Line =
1485 StringRef RDName = getClassName(RD);
1492 Size = CGM.getContext().getTypeSize(Ty);
1494 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1499 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1500 if (!CXXRD->hasDefinition() ||
1501 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1502 Flags |= llvm::DINode::FlagNonTrivial;
1505 SmallString<256> Identifier;
1507 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1509 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1512 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1513 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1514 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1515 CollectCXXTemplateParams(TSpecial, DefUnit));
1516 ReplaceMap.emplace_back(
1517 std::piecewise_construct, std::make_tuple(Ty),
1518 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1522llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1525 llvm::DIFile *Unit) {
1530 std::optional<unsigned> DWARFAddressSpace =
1531 CGM.getTarget().getDWARFAddressSpace(
1532 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1534 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1535 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1536 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1537 Size, Align, DWARFAddressSpace);
1539 SmallVector<llvm::Metadata *, 4> Annots;
1540 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1542 llvm::DINodeArray Annotations =
nullptr;
1543 if (Annots.size() > 0)
1544 Annotations = DBuilder.getOrCreateArray(Annots);
1545 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1546 Align, DWARFAddressSpace, StringRef(),
1551llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1552 llvm::DIType *&
Cache) {
1555 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1556 TheCU, TheCU->getFile(), 0);
1557 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1558 Cache = DBuilder.createPointerType(
Cache, Size);
1562uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1563 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1564 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1574 if (CGM.getLangOpts().OpenCL) {
1575 FType = CGM.getContext().IntTy;
1576 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1579 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1580 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1581 FType = CGM.getContext().IntTy;
1582 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1583 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1585 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1586 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1587 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1588 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1589 EltTys.push_back(DBuilder.createMemberType(
1590 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1591 FieldOffset, llvm::DINode::FlagZero, DescTy));
1592 FieldOffset += FieldSize;
1598llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1599 llvm::DIFile *Unit) {
1600 SmallVector<llvm::Metadata *, 8> EltTys;
1603 llvm::DINodeArray Elements;
1606 FType = CGM.getContext().UnsignedLongTy;
1607 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1608 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1610 Elements = DBuilder.getOrCreateArray(EltTys);
1613 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1616 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1617 FieldOffset, 0, Flags,
nullptr, Elements);
1622 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1624 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1627 Elements = DBuilder.getOrCreateArray(EltTys);
1633 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1634 Flags,
nullptr, Elements);
1636 return DBuilder.createPointerType(EltTy, Size);
1639static llvm::SmallVector<TemplateArgument>
1641 assert(Ty->isTypeAlias());
1650 ArrayRef SubstArgs = Ty->template_arguments();
1653 if (Param->isParameterPack()) {
1662 if (SubstArgs.empty()) {
1671 SpecArgs.push_back(SubstArgs.front());
1672 SubstArgs = SubstArgs.drop_front();
1677llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1678 llvm::DIFile *Unit) {
1679 assert(Ty->isTypeAlias());
1680 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1682 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1690 SmallString<128> NS;
1691 llvm::raw_svector_ostream
OS(NS);
1693 auto PP = getPrintingPolicy();
1696 SourceLocation Loc =
AliasDecl->getLocation();
1698 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1699 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1708 llvm::raw_string_ostream
OS(Name);
1710 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1711 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1712 !HasReconstitutableArgs(Args.Args))
1713 printTemplateArgumentList(OS, Args.Args, PP);
1715 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1716 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1717 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1721 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1723 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1740 return llvm::DINode::FlagZero;
1744 return llvm::DINode::FlagPrivate;
1746 return llvm::DINode::FlagProtected;
1748 return llvm::DINode::FlagPublic;
1750 return llvm::DINode::FlagZero;
1752 llvm_unreachable(
"unexpected access enumerator");
1755llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1756 llvm::DIFile *Unit) {
1757 llvm::DIType *Underlying =
1773 SmallVector<llvm::Metadata *, 4> Annots;
1774 llvm::DINodeArray Annotations;
1776 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1777 if (!Annots.empty())
1778 Annotations = DBuilder.getOrCreateArray(Annots);
1780 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1785 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1786 getOrCreateFile(Loc), getLineNumber(Loc),
1787 getDeclContextDescriptor(Ty->
getDecl()), Align,
1788 Flags, Annotations);
1796 if (
T.isSPIROrSPIRV())
1797 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1802 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1804 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1806 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1808 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1810 return llvm::dwarf::DW_CC_BORLAND_pascal;
1812 return llvm::dwarf::DW_CC_LLVM_Win64;
1814 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1818 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1820 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1822 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1824 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1826 return llvm::dwarf::DW_CC_LLVM_Swift;
1828 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1830 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1832 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1834 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1836 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1838 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1840 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1841#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1855 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1861 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1863 Flags |= llvm::DINode::FlagLValueReference;
1865 Flags |= llvm::DINode::FlagRValueReference;
1869llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1870 llvm::DIFile *Unit) {
1871 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1873 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1879 SmallVector<llvm::Metadata *, 16> EltTys;
1882 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1884 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1888 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1891 for (
const QualType &ParamType : FPT->param_types())
1892 EltTys.push_back(getOrCreateType(ParamType, Unit));
1893 if (FPT->isVariadic())
1894 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1897 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1898 llvm::DIType *F = DBuilder.createSubroutineType(
1899 EltTypeArray, Flags,
1904llvm::DIDerivedType *
1905CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1906 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1907 StringRef Name = BitFieldDecl->
getName();
1908 QualType Ty = BitFieldDecl->
getType();
1909 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1912 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1913 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1916 llvm::DIFile *
File = getOrCreateFile(Loc);
1917 unsigned Line = getLineNumber(Loc);
1919 const CGBitFieldInfo &BitFieldInfo =
1920 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1922 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1929 if (CGM.getDataLayout().isBigEndian())
1931 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1933 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1934 return DBuilder.createBitFieldMemberType(
1935 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1936 Flags, DebugType, Annotations);
1939llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1940 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1941 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1943 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1968 if (PreviousFieldsDI.empty())
1972 auto *PreviousMDEntry =
1973 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1974 auto *PreviousMDField =
1975 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1976 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1977 PreviousMDField->getSizeInBits() == 0)
1981 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1983 assert(PreviousBitfield->isBitField());
1985 if (!PreviousBitfield->isZeroLengthBitField())
1988 QualType Ty = PreviousBitfield->getType();
1989 SourceLocation Loc = PreviousBitfield->getLocation();
1990 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1991 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1992 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1994 llvm::DIFile *
File = getOrCreateFile(Loc);
1995 unsigned Line = getLineNumber(Loc);
2001 llvm::DINode::DIFlags Flags =
2003 llvm::DINodeArray Annotations =
2004 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2005 return DBuilder.createBitFieldMemberType(
2006 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2007 Flags, DebugType, Annotations);
2010llvm::DIType *CGDebugInfo::createFieldType(
2012 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2013 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2014 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2017 llvm::DIFile *file = getOrCreateFile(loc);
2018 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2021 auto Align = AlignInBits;
2022 if (!
type->isIncompleteArrayType()) {
2023 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2024 SizeInBits = TI.
Width;
2030 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2031 offsetInBits, flags, debugType, Annotations);
2035CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2036 llvm::DIFile *FileScope) {
2040 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2043 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2044 SP = DBuilder.createFunction(
2045 FileScope, FuncName, StringRef(),
2046 FileScope, 0, DIFnTy,
2048 llvm::DINode::FlagArtificial,
2049 llvm::DISubprogram::SPFlagDefinition,
2050 nullptr,
nullptr,
nullptr,
2051 nullptr, StringRef(),
2052 CGM.getCodeGenOpts().DebugKeyInstructions);
2059CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2061 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2063 assert(
Capture.capturesVariable());
2065 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2066 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2068 return CaptureDecl->
getName();
2071void CGDebugInfo::CollectRecordLambdaFields(
2072 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2073 llvm::DIType *RecordTy) {
2078 unsigned fieldno = 0;
2081 I != E; ++I, ++Field, ++fieldno) {
2082 const LambdaCapture &
Capture = *I;
2084 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2086 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2096 Loc =
Field->getLocation();
2097 }
else if (
Capture.capturesVariable()) {
2100 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2101 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2108 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2110 FieldIndexCache[*
Field] = elements.size();
2111 elements.push_back(createFieldType(
2113 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2119template <
typename T>
2120static llvm::Constant *
2131 return llvm::ConstantDataArray::get(Ctx, Vals);
2144 const QualType ElemQTy = ArrayTy->getElementType();
2151 switch (ElemBitWidth) {
2167llvm::DIDerivedType *
2168CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2169 const RecordDecl *RD) {
2173 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2174 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2176 unsigned LineNumber = getLineNumber(Var->
getLocation());
2177 StringRef VName = Var->
getName();
2181 llvm::Constant *
C =
nullptr;
2186 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2187 if (
Value->isFloat())
2188 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2189 if (
Value->isArray())
2195 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2196 ? llvm::dwarf::DW_TAG_variable
2197 : llvm::dwarf::DW_TAG_member;
2199 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2200 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2205void CGDebugInfo::CollectRecordNormalField(
2206 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2207 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2208 const RecordDecl *RD) {
2213 if (
name.empty() && !
type->isRecordType())
2216 llvm::DIType *FieldType;
2218 llvm::DIDerivedType *BitFieldType;
2219 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2220 if (llvm::DIType *Separator =
2221 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2222 elements.push_back(Separator);
2225 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2228 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2231 FieldIndexCache[field] = elements.size();
2232 elements.push_back(FieldType);
2235void CGDebugInfo::CollectRecordNestedType(
2236 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2237 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2244 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2245 elements.push_back(nestedType);
2248void CGDebugInfo::CollectRecordFields(
2249 const RecordDecl *record, llvm::DIFile *tunit,
2250 SmallVectorImpl<llvm::Metadata *> &elements,
2251 llvm::DICompositeType *RecordTy) {
2252 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2254 if (CXXDecl && CXXDecl->
isLambda())
2255 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2257 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2260 unsigned fieldNo = 0;
2264 for (
const auto *I : record->
decls())
2265 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2266 if (
V->hasAttr<NoDebugAttr>())
2271 if (CGM.getCodeGenOpts().EmitCodeView &&
2279 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2280 if (MI != StaticDataMemberCache.end()) {
2281 assert(MI->second &&
2282 "Static data member declaration should still exist");
2283 elements.push_back(MI->second);
2285 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2286 elements.push_back(Field);
2288 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2289 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2290 elements, RecordTy, record);
2294 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2297 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2302 if (!nestedType->isImplicit() &&
2303 nestedType->getDeclContext() == record)
2304 CollectRecordNestedType(nestedType, elements);
2310llvm::DISubroutineType *
2311CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2312 llvm::DIFile *Unit) {
2313 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2315 return cast_or_null<llvm::DISubroutineType>(
2316 getOrCreateType(QualType(
Func, 0), Unit));
2319 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2320 ThisType =
Method->getThisType();
2322 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2325llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2326 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2327 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2329 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2332llvm::DISubroutineType *
2333CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2334 const FunctionProtoType *
Func,
2335 llvm::DIFile *Unit,
bool SkipFirst) {
2336 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2351 getOrCreateType(CGM.getContext().getFunctionType(
2352 Func->getReturnType(),
Func->getParamTypes(), EPI),
2354 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2355 assert(Args.size() &&
"Invalid number of arguments!");
2357 SmallVector<llvm::Metadata *, 16> Elts;
2360 Elts.push_back(Args[0]);
2362 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2366 if (!HasExplicitObjectParameter) {
2367 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2370 DBuilder.createObjectPointerType(ThisPtrType,
true);
2371 Elts.push_back(ThisPtrType);
2375 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2376 Elts.push_back(Args[i]);
2379 if (HasExplicitObjectParameter) {
2380 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2381 "Expected at least return type and object parameter.");
2382 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2385 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2387 return DBuilder.createSubroutineType(
2388 EltTypeArray, OriginalFunc->getFlags(),
2395 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2403CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2406 const bool IsCtorOrDtor =
2409 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2416 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2419 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2422 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2425 return CGM.getMangledName(
Method);
2428bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2431 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2434llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2435 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2438 StringRef MethodName = getFunctionName(
Method);
2439 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2441 StringRef MethodLinkageName;
2448 MethodLinkageName = GetMethodLinkageName(
Method);
2451 llvm::DIFile *MethodDefUnit =
nullptr;
2452 unsigned MethodLine = 0;
2453 if (!
Method->isImplicit()) {
2454 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2455 MethodLine = getLineNumber(
Method->getLocation());
2459 llvm::DIType *ContainingType =
nullptr;
2460 unsigned VIndex = 0;
2461 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2462 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2463 int ThisAdjustment = 0;
2466 if (
Method->isPureVirtual())
2467 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2469 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2471 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2475 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2479 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2482 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2483 CGM.getContext().getLangOpts())
2487 MethodVFTableLocation ML =
2488 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2496 if (
Method->size_overridden_methods() == 0)
2497 Flags |= llvm::DINode::FlagIntroducedVirtual;
2502 ThisAdjustment = CGM.getCXXABI()
2503 .getVirtualFunctionPrologueThisAdjustment(GD)
2506 ContainingType = RecordTy;
2509 if (
Method->getCanonicalDecl()->isDeleted())
2510 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2512 if (
Method->isNoReturn())
2513 Flags |= llvm::DINode::FlagNoReturn;
2516 Flags |= llvm::DINode::FlagStaticMember;
2517 if (
Method->isImplicit())
2518 Flags |= llvm::DINode::FlagArtificial;
2520 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2521 if (CXXC->isExplicit())
2522 Flags |= llvm::DINode::FlagExplicit;
2523 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2524 if (CXXC->isExplicit())
2525 Flags |= llvm::DINode::FlagExplicit;
2527 if (
Method->hasPrototype())
2528 Flags |= llvm::DINode::FlagPrototyped;
2530 Flags |= llvm::DINode::FlagLValueReference;
2532 Flags |= llvm::DINode::FlagRValueReference;
2533 if (!
Method->isExternallyVisible())
2534 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2535 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2536 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2541 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2542 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2543 if (
const auto *Def =
2544 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2545 Def && !Def->isDelegatingConstructor()) {
2551 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2552 llvm::DISubprogram *SP = DBuilder.createMethod(
2553 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2554 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2555 TParamsArray.get(),
nullptr,
2556 CGM.getCodeGenOpts().DebugKeyInstructions);
2558 SPCache[
Method->getCanonicalDecl()].reset(SP);
2563void CGDebugInfo::CollectCXXMemberFunctions(
2564 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2565 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2570 for (
const auto *I : RD->
decls()) {
2571 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2585 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2594 auto MI = SPCache.find(
Method->getCanonicalDecl());
2595 EltTys.push_back(MI == SPCache.end()
2596 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2597 :
static_cast<llvm::Metadata *
>(MI->second));
2601void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2602 SmallVectorImpl<llvm::Metadata *> &EltTys,
2603 llvm::DIType *RecordTy) {
2604 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2605 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2606 llvm::DINode::FlagZero);
2610 if (CGM.getCodeGenOpts().EmitCodeView) {
2611 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2612 llvm::DINode::FlagIndirectVirtualBase);
2616void CGDebugInfo::CollectCXXBasesAux(
2617 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2618 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2620 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2621 llvm::DINode::DIFlags StartingFlags) {
2622 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2623 for (
const auto &BI : Bases) {
2626 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2628 if (!SeenTypes.insert(Base).second)
2630 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2631 llvm::DINode::DIFlags BFlags = StartingFlags;
2635 if (BI.isVirtual()) {
2636 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2639 BaseOffset = 0 - CGM.getItaniumVTableContext()
2640 .getVirtualBaseOffsetOffset(RD, Base)
2646 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2647 VBPtrOffset = CGM.getContext()
2648 .getASTRecordLayout(RD)
2652 BFlags |= llvm::DINode::FlagVirtual;
2659 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2660 VBPtrOffset, BFlags);
2661 EltTys.push_back(DTy);
2666CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2667 llvm::DIFile *Unit) {
2669 return llvm::DINodeArray();
2670 TemplateArgs &Args = *OArgs;
2671 SmallVector<llvm::Metadata *, 16> TemplateParams;
2672 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2673 const TemplateArgument &TA = Args.Args[i];
2677 Name = Args.TList->getParam(i)->getName();
2681 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2682 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2683 TheCU, Name, TTy, defaultParameter));
2688 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2689 TheCU, Name, TTy, defaultParameter,
2690 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2695 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2696 llvm::Constant *
V =
nullptr;
2699 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2700 !D->
hasAttr<CUDADeviceAttr>()) {
2703 if (
const auto *VD = dyn_cast<VarDecl>(D))
2704 V = CGM.GetAddrOfGlobalVar(VD);
2707 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2708 MD && MD->isImplicitObjectMemberFunction())
2709 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2710 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2711 V = CGM.GetAddrOfFunction(FD);
2714 else if (
const auto *MPT =
2715 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2719 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2721 CGM.getContext().toCharUnitsFromBits((
int64_t)fieldOffset);
2722 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2723 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2724 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2725 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2727 V = ConstantEmitter(CGM).emitAbstract(
2728 SourceLocation(), TPO->getValue(), TPO->getType());
2730 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2732 assert(
V &&
"Failed to find template parameter pointer");
2733 V =
V->stripPointerCasts();
2735 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2736 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2740 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2741 llvm::Constant *
V =
nullptr;
2744 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2750 if (MPT->isMemberDataPointer())
2751 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2753 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2754 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2755 TheCU, Name, TTy, defaultParameter,
V));
2759 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2760 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2762 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2763 TheCU, Name, TTy, defaultParameter,
V));
2766 std::string QualName;
2767 llvm::raw_string_ostream
OS(QualName);
2769 OS, getPrintingPolicy());
2770 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2771 TheCU, Name,
nullptr, QualName, defaultParameter));
2775 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2776 TheCU, Name,
nullptr,
2783 T = CGM.getContext().getLValueReferenceType(
T);
2784 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2785 assert(
V &&
"Expression in template argument isn't constant");
2786 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2787 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2788 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2794 "These argument types shouldn't exist in concrete types");
2797 return DBuilder.getOrCreateArray(TemplateParams);
2800std::optional<CGDebugInfo::TemplateArgs>
2801CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2809 return std::nullopt;
2811std::optional<CGDebugInfo::TemplateArgs>
2812CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2816 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2818 return std::nullopt;
2819 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2820 const TemplateParameterList *TList =
T->getTemplateParameters();
2821 auto TA = TS->getTemplateArgs().asArray();
2822 return {{TList, TA}};
2824std::optional<CGDebugInfo::TemplateArgs>
2825CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2826 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2830 TemplateParameterList *TPList =
2831 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2832 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2833 return {{TPList, TAList.
asArray()}};
2835 return std::nullopt;
2839CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2840 llvm::DIFile *Unit) {
2841 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2844llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2845 llvm::DIFile *Unit) {
2846 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2849llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2850 llvm::DIFile *Unit) {
2851 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2854void CGDebugInfo::CollectBTFDeclTagAnnotations(
2855 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2857 llvm::Metadata *Ops[2] = {
2858 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2859 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2860 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2864llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2865 if (!D->
hasAttr<BTFDeclTagAttr>())
2868 SmallVector<llvm::Metadata *, 4> Annotations;
2869 CollectBTFDeclTagAnnotations(D, Annotations);
2870 return DBuilder.getOrCreateArray(Annotations);
2873void CGDebugInfo::CollectBTFTypeTagAnnotations(
2874 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2875 const BTFTagAttributedType *BTFAttrTy;
2877 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2879 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2882 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2884 llvm::Metadata *Ops[2] = {
2885 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2886 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2887 Annotations.insert(Annotations.begin(),
2888 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2890 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2894llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2896 return VTablePtrType;
2898 ASTContext &Context = CGM.getContext();
2901 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2902 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2903 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2905 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2906 std::optional<unsigned> DWARFAddressSpace =
2907 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2909 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2910 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2911 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2912 return VTablePtrType;
2915StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2927 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2929 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2939 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2940 VTable->isDeclarationForLinker())
2944 StringRef SymbolName =
"__clang_vtable";
2946 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2955 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2957 llvm::DIFile *Unit = getOrCreateFile(Loc);
2958 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2960 llvm::DINode::FlagArtificial;
2961 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2962 ? llvm::dwarf::DW_TAG_variable
2963 : llvm::dwarf::DW_TAG_member;
2964 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2965 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2969 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2973 llvm::DIGlobalVariableExpression *GVE =
2974 DBuilder.createGlobalVariableExpression(
2975 TheCU, SymbolName, VTable->getName(), Unit, 0,
2976 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2977 true,
nullptr, DT,
nullptr,
2979 VTable->addDebugInfo(GVE);
2982StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2984 llvm::Function *InitFn) {
2989 return InitFn->getName();
2999 llvm::raw_svector_ostream OS(QualifiedGV);
3001 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3003 std::swap(Quals, GVName);
3007 llvm::raw_svector_ostream OS(InitName);
3009 OS << Quals <<
"::";
3014 llvm_unreachable(
"not an initializer");
3016 OS <<
"`dynamic initializer for '";
3019 OS <<
"`dynamic atexit destructor for '";
3026 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3027 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3028 getPrintingPolicy());
3033 return internString(
OS.str());
3036void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3037 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3046 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3053 llvm::DIType *VPtrTy =
nullptr;
3054 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3055 CGM.getTarget().getCXXABI().isMicrosoft();
3056 if (NeedVTableShape) {
3058 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3059 const VTableLayout &VFTLayout =
3060 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3061 unsigned VSlotCount =
3063 unsigned VTableWidth = PtrWidth * VSlotCount;
3064 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3065 std::optional<unsigned> DWARFAddressSpace =
3066 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3069 llvm::DIType *VTableType = DBuilder.createPointerType(
3070 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3071 EltTys.push_back(VTableType);
3074 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3082 VPtrTy = getOrCreateVTablePtrType(Unit);
3084 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3085 llvm::DIType *VPtrMember =
3086 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3087 llvm::DINode::FlagArtificial, VPtrTy);
3088 EltTys.push_back(VPtrMember);
3091std::pair<llvm::DIType *, unsigned>
3096 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3103 auto I = FieldIndexCache.find(Field);
3104 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3105 return {
T, I->second};
3115 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3116 assert(!D.
isNull() &&
"null type");
3117 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3118 assert(
T &&
"could not create debug info for type");
3127 if (CGM.getCodeGenOpts().getDebugInfo() <=
3128 llvm::codegenoptions::DebugLineTablesOnly)
3132 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3134 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3136 CI->setMetadata(
"heapallocsite", node);
3140 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3142 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3144 auto I = TypeCache.find(TyPtr);
3147 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3148 assert(!Res->isForwardDecl());
3149 TypeCache[TyPtr].reset(Res);
3153 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3154 !CGM.getLangOpts().CPlusPlus)
3160 if (RD->
hasAttr<DLLImportAttr>())
3163 if (MD->hasAttr<DLLImportAttr>())
3176 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3186 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3187 Explicit = TD->isExplicitInstantiationOrSpecialization();
3191 if (CXXDecl->
fields().empty())
3201 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3202 if (CXXRD->isDynamicClass() &&
3203 CGM.getVTableLinkage(CXXRD) ==
3204 llvm::GlobalValue::AvailableExternallyLinkage &&
3215 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3217 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3219 auto I = TypeCache.find(TyPtr);
3226 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3227 assert(!Res->isForwardDecl());
3228 TypeCache[TyPtr].reset(Res);
3235 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3236 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3263 bool HasNonDeletedCtor =
false;
3265 if (Ctor->isCopyOrMoveConstructor())
3272 if (CtorDef->isDelegatingConstructor())
3276 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3279 if (!Ctor->isDeleted())
3280 HasNonDeletedCtor =
true;
3282 return HasNonDeletedCtor;
3298 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3301 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3302 RD->
hasAttr<StandaloneDebugAttr>())
3305 if (!LangOpts.CPlusPlus)
3311 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3327 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3328 Spec = SD->getSpecializationKind();
3337 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3348 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3349 llvm::DIType *
T = getTypeOrNull(Ty);
3350 if (
T &&
T->isForwardDecl())
3354llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3356 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3360 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3364 auto [Def, Pref] = CreateTypeDefinition(Ty);
3366 return Pref ? Pref : Def;
3369llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3370 llvm::DIFile *Unit) {
3374 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3378 return getOrCreateType(PNA->getTypedefType(), Unit);
3405 const auto *RT = QT->
getAs<RecordType>();
3409 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3410 if (!CRD || !CRD->hasDefinition())
3415 assert(CRD->isStandardLayout());
3421std::pair<llvm::DIType *, llvm::DIType *>
3422CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3426 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3434 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3438 return {FwdDecl,
nullptr};
3440 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3441 CollectContainingType(CXXDecl, FwdDecl);
3444 LexicalBlockStack.emplace_back(&*FwdDecl);
3445 RegionMap[RD].reset(FwdDecl);
3448 SmallVector<llvm::Metadata *, 16> EltTys;
3455 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3457 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3458 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3462 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3463 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3464 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3466 LexicalBlockStack.pop_back();
3467 RegionMap.erase(RD);
3469 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3470 DBuilder.replaceArrays(FwdDecl, Elements);
3472 if (FwdDecl->isTemporary())
3474 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3476 RegionMap[RD].reset(FwdDecl);
3478 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3493 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3494 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3495 return {FwdDecl, PrefDI};
3497 return {FwdDecl,
nullptr};
3500llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3501 llvm::DIFile *Unit) {
3503 return getOrCreateType(Ty->getBaseType(), Unit);
3506llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3507 llvm::DIFile *Unit) {
3509 SourceLocation Loc = Ty->getDecl()->getLocation();
3512 return DBuilder.createTypedef(
3513 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3514 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3515 getDeclContextDescriptor(Ty->getDecl()));
3542llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3543 llvm::DIFile *Unit) {
3548 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3549 TheCU->getSourceLanguage().getUnversionedName());
3554 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3555 !
ID->getImplementation())
3556 return DBuilder.createForwardDecl(
3557 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3558 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3561 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3562 unsigned Line = getLineNumber(
ID->getLocation());
3566 ObjCInterfaceDecl *Def =
ID->getDefinition();
3568 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3569 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3570 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3571 DefUnit,
Line, RuntimeLang);
3572 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3576 return CreateTypeDefinition(Ty, Unit);
3579llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3580 bool CreateSkeletonCU) {
3585 auto ModRef = ModuleCache.find(M);
3586 if (ModRef != ModuleCache.end())
3590 SmallString<128> ConfigMacros;
3592 llvm::raw_svector_ostream
OS(ConfigMacros);
3593 const auto &PPOpts = CGM.getPreprocessorOpts();
3596 for (
auto &M : PPOpts.Macros) {
3599 const std::string &
Macro = M.first;
3600 bool Undef = M.second;
3601 OS <<
"\"-" << (Undef ?
'U' :
'D');
3602 for (
char c :
Macro)
3617 bool IsRootModule = M ? !M->
Parent :
true;
3621 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3622 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3623 "clang module without ASTFile must be specified by -fmodule-name");
3626 auto RemapPath = [
this](StringRef Path) -> std::string {
3628 StringRef Relative(Remapped);
3629 StringRef CompDir = TheCU->getDirectory();
3630 if (CompDir.empty())
3633 if (Relative.consume_front(CompDir))
3634 Relative.consume_front(llvm::sys::path::get_separator());
3636 return Relative.str();
3639 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3646 Signature = ModSig.truncatedValue();
3650 llvm::DIBuilder DIB(CGM.getModule());
3652 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3653 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3654 PCM = getCurrentDirname();
3658 llvm::sys::path::append(PCM, Mod.
getASTFile());
3659 DIB.createCompileUnit(
3660 TheCU->getSourceLanguage(),
3663 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3664 llvm::DICompileUnit::FullDebug, Signature);
3668 llvm::DIModule *Parent =
3670 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3672 StringRef IncludePath = Mod.
getPath();
3673 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3674 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3675 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3678 llvm::DIModule *DIMod =
3679 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3680 RemapPath(IncludePath));
3681 ModuleCache[M].reset(DIMod);
3685llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3686 llvm::DIFile *Unit) {
3688 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3689 unsigned Line = getLineNumber(
ID->getLocation());
3691 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3697 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3698 if (
ID->getImplementation())
3699 Flags |= llvm::DINode::FlagObjcClassComplete;
3701 llvm::DINodeArray Annotations;
3702 const auto *RuntimeName =
ID->getAttr<ObjCRuntimeNameAttr>();
3703 if (RuntimeName && RuntimeName->getMetadataName() !=
ID->getName()) {
3704 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
3705 llvm::Metadata *Ops[2] = {
3706 llvm::MDString::get(Ctx,
"objc_runtime_name"),
3707 llvm::MDString::get(Ctx, RuntimeName->getMetadataName())};
3708 Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)});
3711 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3712 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3713 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3714 nullptr, llvm::DINodeArray(), RuntimeLang,
nullptr,
3718 QualType QTy(Ty, 0);
3719 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3722 LexicalBlockStack.emplace_back(RealDecl);
3723 RegionMap[Ty->
getDecl()].reset(RealDecl);
3726 SmallVector<llvm::Metadata *, 16> EltTys;
3728 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3730 llvm::DIType *SClassTy =
3731 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3735 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3736 llvm::DINode::FlagZero);
3737 EltTys.push_back(InhTag);
3741 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3742 SourceLocation Loc = PD->getLocation();
3743 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3744 unsigned PLine = getLineNumber(Loc);
3745 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3746 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3747 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3748 PD->getName(), PUnit, PLine,
3750 : getSelectorName(PD->getGetterName()),
3752 : getSelectorName(PD->getSetterName()),
3753 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3754 EltTys.push_back(PropertyNode);
3759 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3763 llvm::DenseSet<IsClassAndIdent> PropertySet;
3765 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3766 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3768 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3769 for (
auto *PD : ClassExt->properties()) {
3770 PropertySet.insert(GetIsClassAndIdent(PD));
3773 for (
const auto *PD :
ID->properties()) {
3776 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3782 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3783 unsigned FieldNo = 0;
3784 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3785 Field =
Field->getNextIvar(), ++FieldNo) {
3786 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3790 StringRef FieldName =
Field->getName();
3793 if (FieldName.empty())
3797 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3798 unsigned FieldLine = getLineNumber(
Field->getLocation());
3799 QualType FType =
Field->getType();
3806 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3807 : CGM.getContext().getTypeSize(FType);
3812 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3816 if (
Field->isBitField()) {
3818 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3819 FieldOffset %= CGM.getContext().getCharWidth();
3827 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3829 Flags = llvm::DINode::FlagProtected;
3831 Flags = llvm::DINode::FlagPrivate;
3833 Flags = llvm::DINode::FlagPublic;
3835 if (
Field->isBitField())
3836 Flags |= llvm::DINode::FlagBitField;
3838 llvm::MDNode *PropertyNode =
nullptr;
3839 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3840 llvm::DIFile *PUnit =
nullptr;
3842 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3843 if (ObjCPropertyImplDecl *PImpD =
3844 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3845 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3846 SynthesizedProperty = PD;
3847 SourceLocation Loc = PD->getLocation();
3848 PUnit = getOrCreateFile(Loc);
3849 PLine = getLineNumber(Loc);
3850 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3851 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3852 PropertyNode = DBuilder.createObjCProperty(
3853 PD->getName(), PUnit, PLine,
3856 : getSelectorName(PD->getGetterName()),
3859 : getSelectorName(PD->getSetterName()),
3860 PD->getPropertyAttributes(),
3861 getOrCreateType(PD->getType(), PUnit));
3865 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3866 FieldSize, FieldAlign, FieldOffset,
3867 Flags, FieldTy, PropertyNode);
3868 EltTys.push_back(IvarTy);
3870 if (SynthesizedProperty) {
3871 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3872 EltTys.push_back(DBuilder.createProperty(
3873 SynthesizedProperty->
getName(), PUnit, PLine,
3874 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3878 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3879 DBuilder.replaceArrays(RealDecl, Elements);
3881 LexicalBlockStack.pop_back();
3885llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3886 llvm::DIFile *Unit) {
3894 auto &Ctx = CGM.getContext();
3899 QualType CharVecTy =
3901 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3904 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3907 llvm::Metadata *Subscript;
3908 QualType QTy(Ty, 0);
3909 auto SizeExpr = SizeExprCache.find(QTy);
3910 if (SizeExpr != SizeExprCache.end())
3911 Subscript = DBuilder.getOrCreateSubrange(
3912 SizeExpr->getSecond() ,
nullptr ,
3913 nullptr ,
nullptr );
3916 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3917 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3918 Subscript = DBuilder.getOrCreateSubrange(
3919 CountNode ,
nullptr ,
nullptr ,
3922 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3927 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3930llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3931 llvm::DIFile *Unit) {
3935 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3940 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3941 auto *ColumnCountNode =
3942 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3943 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3944 auto *RowCountNode =
3945 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3946 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3947 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3948 ColumnCountNode ,
nullptr ,
nullptr ,
3950 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3951 RowCountNode ,
nullptr ,
nullptr ,
3953 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3954 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3957llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3962 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3977 Size = CGM.getContext().getTypeSize(Ty);
3984 SmallVector<llvm::Metadata *, 8> Subscripts;
3985 QualType EltTy(Ty, 0);
3986 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3995 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3996 Count = CAT->getZExtSize();
3997 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3998 if (Expr *Size = VAT->getSizeExpr()) {
4000 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
4001 Count =
Result.Val.getInt().getExtValue();
4005 auto SizeNode = SizeExprCache.find(EltTy);
4006 if (SizeNode != SizeExprCache.end())
4007 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4008 SizeNode->getSecond() ,
nullptr ,
4009 nullptr ,
nullptr ));
4012 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4013 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4014 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4015 CountNode ,
nullptr ,
nullptr ,
4021 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4023 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4027llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4028 llvm::DIFile *Unit) {
4029 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4033llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4034 llvm::DIFile *Unit) {
4035 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4037 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4038 CGM.getCodeGenOpts().DwarfVersion < 4)
4039 Tag = llvm::dwarf::DW_TAG_reference_type;
4041 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4044llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4046 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4050 Size = CGM.getContext().getTypeSize(Ty);
4053 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4056 Flags |= llvm::DINode::FlagSingleInheritance;
4059 Flags |= llvm::DINode::FlagMultipleInheritance;
4062 Flags |= llvm::DINode::FlagVirtualInheritance;
4072 llvm::DIType *ClassType = getOrCreateType(
T, U);
4074 return DBuilder.createMemberPointerType(
4078 const FunctionProtoType *FPT =
4080 return DBuilder.createMemberPointerType(
4081 getOrCreateInstanceMethodType(
4084 ClassType, Size, 0, Flags);
4087llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4089 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4092llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4096llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4098 return getOrCreateType(Ty->getWrappedType(), U);
4101llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4108 const EnumType *Ty) {
4120llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4123 bool isImportedFromModule =
4124 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4128 if (isImportedFromModule || !ED->getDefinition()) {
4135 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4136 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4137 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4138 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4140 unsigned Line = getLineNumber(ED->getLocation());
4141 StringRef EDName = ED->getName();
4142 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4143 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4144 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4146 ReplaceMap.emplace_back(
4147 std::piecewise_construct, std::make_tuple(Ty),
4148 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4152 return CreateTypeDefinition(Ty);
4155llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4158 SmallVector<llvm::Metadata *, 16> Enumerators;
4159 ED = ED->getDefinition();
4160 assert(ED &&
"An enumeration definition is required");
4161 for (
const auto *
Enum : ED->enumerators()) {
4162 Enumerators.push_back(
4163 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4166 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4167 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4168 EnumKind = Attr->getExtensibility();
4171 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4173 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4174 unsigned Line = getLineNumber(ED->getLocation());
4175 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4176 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4177 return DBuilder.createEnumerationType(
4178 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4179 0, Identifier, ED->isScoped(), EnumKind);
4184 StringRef Name, StringRef
Value) {
4185 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4186 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4192 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4193 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4194 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4199 llvm::DISubprogram *SynthSubprogram) {
4200 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4201 SynthSubprogram, ParentLocation);
4206 StringRef SynthFuncName,
4207 llvm::DIFile *SynthFile) {
4208 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4213 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4219 FuncName += Category;
4221 FuncName += FailureMsg;
4224 TrapLocation->getFile());
4234 Quals += InnerQuals;
4236 switch (
T->getTypeClass()) {
4238 return C.getQualifiedType(
T.getTypePtr(), Quals);
4241 case Type::InjectedClassName:
4242 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4244 case Type::TemplateSpecialization: {
4246 if (Spec->isTypeAlias())
4247 return C.getQualifiedType(
T.getTypePtr(), Quals);
4248 T = Spec->desugar();
4251 case Type::TypeOfExpr:
4257 case Type::Decltype:
4260 case Type::UnaryTransform:
4263 case Type::Attributed:
4266 case Type::BTFTagAttributed:
4269 case Type::CountAttributed:
4278 case Type::MacroQualified:
4281 case Type::SubstTemplateTypeParm:
4285 case Type::DeducedTemplateSpecialization: {
4287 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4291 case Type::PackIndexing: {
4295 case Type::Adjusted:
4302 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4307llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4310 if (It != TypeCache.end()) {
4312 if (llvm::Metadata *
V = It->second)
4325 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4332 RetainedTypes.push_back(
4333 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4336llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4340 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4342 llvm::raw_string_ostream OS(Name);
4343 Ty.
print(OS, getPrintingPolicy());
4350 if (
auto *
T = getTypeOrNull(Ty))
4353 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4354 void *TyPtr = Ty.getAsOpaquePtr();
4357 TypeCache[TyPtr].reset(Res);
4362llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4370 auto Info = Reader->getSourceDescriptor(Idx);
4372 return getOrCreateModuleRef(*Info,
true);
4373 }
else if (ClangModuleMap) {
4386 auto Info = ASTSourceDescriptor(*M);
4387 return getOrCreateModuleRef(Info,
false);
4390 return getOrCreateModuleRef(PCHDescriptor,
false);
4397llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4400 return CreateQualifiedType(Ty, Unit);
4404#define TYPE(Class, Base)
4405#define ABSTRACT_TYPE(Class, Base)
4406#define NON_CANONICAL_TYPE(Class, Base)
4407#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4408#include "clang/AST/TypeNodes.inc"
4409 llvm_unreachable(
"Dependent types cannot show up in debug information");
4411 case Type::ExtVector:
4414 case Type::ConstantMatrix:
4416 case Type::ObjCObjectPointer:
4418 case Type::ObjCObject:
4420 case Type::ObjCTypeParam:
4422 case Type::ObjCInterface:
4430 case Type::BlockPointer:
4438 case Type::FunctionProto:
4439 case Type::FunctionNoProto:
4441 case Type::ConstantArray:
4442 case Type::VariableArray:
4443 case Type::IncompleteArray:
4444 case Type::ArrayParameter:
4447 case Type::LValueReference:
4449 case Type::RValueReference:
4452 case Type::MemberPointer:
4460 case Type::OverflowBehavior:
4465 case Type::TemplateSpecialization:
4467 case Type::HLSLAttributedResource:
4469 case Type::HLSLInlineSpirv:
4471 case Type::PredefinedSugar:
4473 case Type::CountAttributed:
4474 case Type::LateParsedAttr:
4476 case Type::Attributed:
4477 case Type::BTFTagAttributed:
4478 case Type::Adjusted:
4480 case Type::DeducedTemplateSpecialization:
4483 case Type::MacroQualified:
4484 case Type::SubstTemplateTypeParm:
4485 case Type::TypeOfExpr:
4487 case Type::Decltype:
4488 case Type::PackIndexing:
4489 case Type::UnaryTransform:
4493 llvm_unreachable(
"type should have been unwrapped!");
4496llvm::DICompositeType *
4497CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4498 QualType QTy(Ty, 0);
4500 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4505 if (
T && !
T->isForwardDecl())
4509 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4514 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4517 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4522llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4524 bool NameIsSimplified =
false;
4527 StringRef RDName = getClassName(RD, &NameIsSimplified);
4529 llvm::DIFile *DefUnit =
nullptr;
4532 DefUnit = getOrCreateFile(Loc);
4533 Line = getLineNumber(Loc);
4536 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4540 auto *
T = cast_or_null<llvm::DICompositeType>(
4541 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4549 return getOrCreateRecordFwdDecl(Ty, RDContext);
4562 auto Flags = llvm::DINode::FlagZero;
4563 if (NameIsSimplified)
4564 Flags |= llvm::DINode::FlagNameIsSimplified;
4565 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4567 Flags |= llvm::DINode::FlagTypePassByReference;
4569 Flags |= llvm::DINode::FlagTypePassByValue;
4572 if (!CXXRD->isTrivial())
4573 Flags |= llvm::DINode::FlagNonTrivial;
4576 if (CXXRD->isAnonymousStructOrUnion())
4577 Flags |= llvm::DINode::FlagExportSymbols;
4580 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4583 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4584 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4586 Flags, Identifier, Annotations);
4590 switch (RealDecl->getTag()) {
4592 llvm_unreachable(
"invalid composite type tag");
4594 case llvm::dwarf::DW_TAG_array_type:
4595 case llvm::dwarf::DW_TAG_enumeration_type:
4600 if (Identifier.empty())
4604 case llvm::dwarf::DW_TAG_structure_type:
4605 case llvm::dwarf::DW_TAG_union_type:
4606 case llvm::dwarf::DW_TAG_class_type:
4609 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4613 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4614 CXXRecordDecl *TemplateDecl =
4615 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4616 RegionMap[TemplateDecl].reset(RealDecl);
4618 RegionMap[RD].reset(RealDecl);
4620 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4622 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4623 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4624 CollectCXXTemplateParams(TSpecial, DefUnit));
4628void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4629 llvm::DICompositeType *RealDecl) {
4631 llvm::DIType *ContainingType =
nullptr;
4632 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4636 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4643 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4644 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4646 ContainingType = RealDecl;
4648 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4651llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4652 StringRef Name, uint64_t *Offset) {
4653 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4654 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4657 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4658 *Offset, llvm::DINode::FlagZero, FieldTy);
4659 *Offset += FieldSize;
4663void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4665 StringRef &LinkageName,
4666 llvm::DIScope *&FDContext,
4667 llvm::DINodeArray &TParamsArray,
4668 llvm::DINode::DIFlags &Flags) {
4670 bool NameIsSimplified =
false;
4671 Name = getFunctionName(FD, &NameIsSimplified);
4672 if (NameIsSimplified)
4673 Flags |= llvm::DINode::FlagNameIsSimplified;
4674 Name = getFunctionName(FD);
4677 LinkageName = CGM.getMangledName(GD);
4679 Flags |= llvm::DINode::FlagPrototyped;
4683 if (LinkageName == Name ||
4684 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4685 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4686 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4687 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4688 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4689 LinkageName = StringRef();
4693 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4694 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4695 CGM.getCodeGenOpts().EmitCodeView)) {
4696 if (
const NamespaceDecl *NSDecl =
4698 FDContext = getOrCreateNamespace(NSDecl);
4699 else if (
const RecordDecl *RDecl =
4701 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4702 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4705 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4708 Flags |= llvm::DINode::FlagNoReturn;
4710 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4714void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4715 unsigned &LineNo, QualType &
T,
4716 StringRef &Name, StringRef &LinkageName,
4717 llvm::MDTuple *&TemplateParameters,
4718 llvm::DIScope *&VDContext) {
4727 llvm::APInt ConstVal(32, 1);
4728 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4730 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4737 LinkageName = CGM.getMangledName(VD);
4738 if (LinkageName == Name)
4739 LinkageName = StringRef();
4742 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4743 TemplateParameters = parameterNodes.get();
4745 TemplateParameters =
nullptr;
4751 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4752 VDContext = LexicalBlockStack.back();
4771 DC = CGM.getContext().getTranslationUnitDecl();
4773 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4774 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4777llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4779 llvm::DINodeArray TParamsArray;
4780 StringRef Name, LinkageName;
4781 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4782 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4784 llvm::DIFile *Unit = getOrCreateFile(Loc);
4785 llvm::DIScope *DContext = Unit;
4786 unsigned Line = getLineNumber(Loc);
4787 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4792 SmallVector<QualType, 16> ArgTypes;
4793 for (
const ParmVarDecl *Parm : FD->
parameters())
4794 ArgTypes.push_back(Parm->getType());
4797 QualType FnType = CGM.getContext().getFunctionType(
4798 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4800 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4801 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4802 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4806 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4807 return DBuilder.createFunction(
4808 DContext, Name, LinkageName, Unit,
Line,
4809 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4810 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4812 CGM.getCodeGenOpts().DebugKeyInstructions);
4815 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4816 DContext, Name, LinkageName, Unit,
Line,
4817 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4818 TParamsArray.get(), getFunctionDeclaration(FD));
4820 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4821 std::make_tuple(CanonDecl),
4822 std::make_tuple(SP));
4826llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4827 return getFunctionFwdDeclOrStub(GD,
false);
4830llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4831 return getFunctionFwdDeclOrStub(GD,
true);
4834llvm::DIGlobalVariable *
4835CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4837 StringRef Name, LinkageName;
4839 llvm::DIFile *Unit = getOrCreateFile(Loc);
4840 llvm::DIScope *DContext = Unit;
4841 unsigned Line = getLineNumber(Loc);
4842 llvm::MDTuple *TemplateParameters =
nullptr;
4844 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4847 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4848 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4850 FwdDeclReplaceMap.emplace_back(
4851 std::piecewise_construct,
4853 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4857llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4862 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4863 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4864 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4868 if (I != DeclCache.end()) {
4870 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4871 return GVE->getVariable();
4879 if (IE != ImportedDeclCache.end()) {
4880 auto N = IE->second;
4881 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4883 return dyn_cast_or_null<llvm::DINode>(N);
4888 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4889 return getFunctionForwardDeclaration(FD);
4890 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4891 return getGlobalVariableForwardDeclaration(VD);
4896llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4897 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4900 const auto *FD = dyn_cast<FunctionDecl>(D);
4905 auto *S = getDeclContextDescriptor(D);
4908 if (MI == SPCache.end()) {
4910 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4914 if (MI != SPCache.end()) {
4915 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4916 if (SP && !SP->isDefinition())
4920 for (
auto *NextFD : FD->
redecls()) {
4921 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4922 if (MI != SPCache.end()) {
4923 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4924 if (SP && !SP->isDefinition())
4931llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4932 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4933 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4934 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4937 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4941 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4945 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4954 QualType QTy(
ID->getTypeForDecl(), 0);
4955 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4956 if (It == TypeCache.end())
4959 llvm::DISubprogram *FD = DBuilder.createFunction(
4960 InterfaceType, getObjCMethodName(OMD), StringRef(),
4961 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4962 DBuilder.finalizeSubprogram(FD);
4969llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4974 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4975 !CGM.getCodeGenOpts().EmitCodeView))
4978 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4980 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4983 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4986 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4987 return getOrCreateMethodType(
Method, F);
4989 const auto *FTy = FnType->
getAs<FunctionType>();
4992 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4994 SmallVector<llvm::Metadata *, 16> Elts;
4997 QualType ResultTy = OMethod->getReturnType();
5000 if (ResultTy == CGM.getContext().getObjCInstanceType())
5001 ResultTy = CGM.getContext().getPointerType(
5002 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5004 Elts.push_back(getOrCreateType(ResultTy, F));
5006 QualType SelfDeclTy;
5007 if (
auto *SelfDecl = OMethod->getSelfDecl())
5008 SelfDeclTy = SelfDecl->getType();
5009 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5012 if (!SelfDeclTy.
isNull())
5014 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5016 Elts.push_back(DBuilder.createArtificialType(
5017 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5019 for (
const auto *PI : OMethod->parameters())
5020 Elts.push_back(getOrCreateType(PI->getType(), F));
5022 if (OMethod->isVariadic())
5023 Elts.push_back(DBuilder.createUnspecifiedParameter());
5025 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5026 return DBuilder.createSubroutineType(
5027 EltTypeArray, llvm::DINode::FlagZero,
5028 getDwarfCC(CC, CGM.getTarget().getTriple()));
5033 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5034 if (FD->isVariadic()) {
5035 SmallVector<llvm::Metadata *, 16> EltTys;
5036 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5037 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5039 EltTys.push_back(getOrCreateType(ParamType, F));
5040 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5041 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5042 return DBuilder.createSubroutineType(
5043 EltTypeArray, llvm::DINode::FlagZero,
5044 getDwarfCC(CC, CGM.getTarget().getTriple()));
5056 CC = SrcFnTy->getCallConv();
5058 for (
const VarDecl *VD : Args)
5059 ArgTypes.push_back(VD->
getType());
5060 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5066 llvm::Function *Fn,
bool CurFuncIsThunk) {
5068 StringRef LinkageName;
5070 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5073 bool HasDecl = (D !=
nullptr);
5075 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5076 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5077 llvm::DIFile *Unit = getOrCreateFile(Loc);
5078 llvm::DIScope *FDContext = Unit;
5079 llvm::DINodeArray TParamsArray;
5080 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5083 LinkageName = Fn->getName();
5084 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5086 auto FI = SPCache.find(FD->getCanonicalDecl());
5087 if (FI != SPCache.end()) {
5088 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5089 if (SP && SP->isDefinition()) {
5090 LexicalBlockStack.emplace_back(SP);
5091 RegionMap[D].reset(SP);
5095 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5096 TParamsArray, Flags);
5099 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5100 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5101 Name = getObjCMethodName(OMD);
5102 Flags |= llvm::DINode::FlagPrototyped;
5108 if (Name != Fn->getName())
5109 LinkageName = Fn->getName();
5111 Name = Fn->getName();
5116 Flags |= llvm::DINode::FlagPrototyped;
5118 Name.consume_front(
"\01");
5122 "Unexpected DynamicInitKind !");
5126 Flags |= llvm::DINode::FlagArtificial;
5132 Flags |= llvm::DINode::FlagThunk;
5134 if (Fn->hasLocalLinkage())
5135 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5136 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5137 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5140 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5141 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5143 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5144 unsigned ScopeLine = getLineNumber(ScopeLoc);
5145 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5146 llvm::DISubprogram *
Decl =
nullptr;
5147 llvm::DINodeArray Annotations =
nullptr;
5150 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5151 : getFunctionDeclaration(D);
5152 Annotations = CollectBTFDeclTagAnnotations(D);
5160 llvm::DISubprogram *SP = DBuilder.createFunction(
5161 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5162 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5163 Annotations,
"", KeyInstructions);
5164 Fn->setSubprogram(SP);
5173 LexicalBlockStack.emplace_back(SP);
5176 RegionMap[D].reset(SP);
5180 QualType FnType, llvm::Function *Fn) {
5182 StringRef LinkageName;
5188 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5189 return GetName(D,
true);
5192 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5193 llvm::DIFile *Unit = getOrCreateFile(Loc);
5194 bool IsDeclForCallSite = Fn ?
true :
false;
5195 llvm::DIScope *FDContext =
5196 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5197 llvm::DINodeArray TParamsArray;
5200 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5201 TParamsArray, Flags);
5202 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5203 Name = getObjCMethodName(OMD);
5204 Flags |= llvm::DINode::FlagPrototyped;
5206 llvm_unreachable(
"not a function or ObjC method");
5208 Name.consume_front(
"\01");
5211 Flags |= llvm::DINode::FlagArtificial;
5216 unsigned LineNo = getLineNumber(Loc);
5217 unsigned ScopeLine = 0;
5218 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5219 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5220 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5222 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5223 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5225 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5226 llvm::DISubprogram *SP = DBuilder.createFunction(
5227 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5228 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5234 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5235 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5236 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5239 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5240 DBuilder.createParameterVariable(
5241 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5242 llvm::DINode::FlagZero, ParamAnnotations);
5248 if (IsDeclForCallSite)
5249 Fn->setSubprogram(SP);
5253 llvm::CallBase *CI) {
5254 if (!shouldGenerateVirtualCallSite())
5260 assert(CI &&
"Invalid Call Instruction.");
5261 if (!CI->isIndirectCall())
5265 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5266 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5274 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5277 if (
Func->getSubprogram())
5281 if (!
Func->isDeclaration())
5303 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5304 Func->setSubprogram(SP);
5315 auto FI = SPCache.find(FD->getCanonicalDecl());
5316 llvm::DISubprogram *SP =
nullptr;
5317 if (FI != SPCache.end())
5318 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5319 if (!SP || !SP->isDefinition())
5320 SP = getFunctionStub(GD);
5321 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5322 LexicalBlockStack.emplace_back(SP);
5328 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5337 if (CurLoc.isInvalid() || LexicalBlockStack.empty())
5340 llvm::MDNode *
Scope = LexicalBlockStack.back();
5341 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5342 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5346 llvm::MDNode *Back =
nullptr;
5347 if (!LexicalBlockStack.empty())
5348 Back = LexicalBlockStack.back().get();
5351 unsigned Line = getLineNumber(CurLoc);
5352 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5353 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5357void CGDebugInfo::AppendAddressSpaceXDeref(
5359 std::optional<unsigned> DWARFAddressSpace =
5361 if (!DWARFAddressSpace)
5364 Expr.push_back(llvm::dwarf::DW_OP_constu);
5365 Expr.push_back(*DWARFAddressSpace);
5366 Expr.push_back(llvm::dwarf::DW_OP_swap);
5367 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5376 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5377 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5378 LexicalBlockStack.back(), CurInlinedAt));
5380 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5384 CreateLexicalBlock(Loc);
5389 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5394 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5397 LexicalBlockStack.pop_back();
5401 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5402 unsigned RCount = FnBeginRegionCount.back();
5403 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5406 while (LexicalBlockStack.size() != RCount) {
5409 LexicalBlockStack.pop_back();
5411 FnBeginRegionCount.pop_back();
5413 if (Fn && Fn->getSubprogram())
5414 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5417CGDebugInfo::BlockByRefType
5418CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5419 uint64_t *XOffset) {
5422 uint64_t FieldSize, FieldOffset;
5423 uint32_t FieldAlign;
5425 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5430 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5431 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5433 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5434 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5437 if (HasCopyAndDispose) {
5440 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5442 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5444 bool HasByrefExtendedLayout;
5447 HasByrefExtendedLayout) &&
5448 HasByrefExtendedLayout) {
5451 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5460 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5463 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5466 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5471 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5472 FieldSize = CGM.getContext().getTypeSize(FType);
5473 FieldAlign = CGM.getContext().toBits(Align);
5475 *XOffset = FieldOffset;
5476 llvm::DIType *FieldTy = DBuilder.createMemberType(
5477 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5478 llvm::DINode::FlagZero, WrappedTy);
5479 EltTys.push_back(FieldTy);
5480 FieldOffset += FieldSize;
5482 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5483 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5484 llvm::DINode::FlagZero,
nullptr, Elements),
5488llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5489 llvm::Value *Storage,
5490 std::optional<unsigned> ArgNo,
5492 const bool UsePointerValue) {
5493 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5494 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5495 if (VD->
hasAttr<NoDebugAttr>())
5500 llvm::DIFile *Unit =
nullptr;
5501 if (!VarIsArtificial)
5505 if (VD->
hasAttr<BlocksAttr>())
5506 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5508 Ty = getOrCreateType(VD->
getType(), Unit);
5518 if (!VarIsArtificial) {
5522 SmallVector<uint64_t, 13> Expr;
5523 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5530 Flags |= llvm::DINode::FlagArtificial;
5534 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5535 AppendAddressSpaceXDeref(AddressSpace, Expr);
5539 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5542 Flags |= llvm::DINode::FlagObjectPointer;
5543 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5544 if (PVD->isExplicitObjectParameter())
5545 Flags |= llvm::DINode::FlagObjectPointer;
5553 StringRef Name = VD->
getName();
5554 if (!Name.empty()) {
5560 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5562 offset = CGM.getContext().toCharUnitsFromBits(
5565 Expr.push_back(llvm::dwarf::DW_OP_deref);
5566 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5568 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5571 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5583 for (
const auto *Field : RD->
fields()) {
5584 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5585 StringRef FieldName =
Field->getName();
5593 auto *D = DBuilder.createAutoVariable(
5594 Scope, FieldName, Unit,
Line, FieldTy,
5595 CGM.getCodeGenOpts().OptimizationLevel != 0,
5596 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5599 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5600 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5603 Builder.GetInsertBlock());
5611 if (UsePointerValue) {
5612 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5613 "Debug info already contains DW_OP_deref.");
5614 Expr.push_back(llvm::dwarf::DW_OP_deref);
5618 llvm::DILocalVariable *D =
nullptr;
5620 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5621 D = DBuilder.createParameterVariable(
5622 Scope, Name, *ArgNo, Unit,
Line, Ty,
5623 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5632 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5638 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5639 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5640 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5641 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5643 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5649 if (Iter != CoroutineParameterMappings.end()) {
5650 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5651 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5652 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5654 if (Iter2 != ParamDbgMappings.end())
5655 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5661 D = RemapCoroArgToLocalVar();
5664 D = DBuilder.createAutoVariable(
5665 Scope, Name, Unit,
Line, Ty,
5666 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5669 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5670 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5671 Column, Scope, CurInlinedAt),
5672 Builder.GetInsertBlock());
5677llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5678 llvm::Value *Storage,
5679 std::optional<unsigned> ArgNo,
5681 const bool UsePointerValue) {
5682 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5683 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5684 if (BD->
hasAttr<NoDebugAttr>())
5691 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5692 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5700 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5702 SmallVector<uint64_t, 3> Expr;
5703 AppendAddressSpaceXDeref(AddressSpace, Expr);
5708 if (UsePointerValue) {
5709 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5710 "Debug info already contains DW_OP_deref.");
5711 Expr.push_back(llvm::dwarf::DW_OP_deref);
5716 StringRef Name = BD->
getName();
5719 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5720 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5721 llvm::DINode::FlagZero, Align);
5723 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5724 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5725 const unsigned fieldIndex = FD->getFieldIndex();
5726 const clang::CXXRecordDecl *parent =
5727 (
const CXXRecordDecl *)FD->getParent();
5728 const ASTRecordLayout &layout =
5729 CGM.getContext().getASTRecordLayout(parent);
5731 if (FD->isBitField()) {
5732 const CGRecordLayout &RL =
5733 CGM.getTypes().getCGRecordLayout(FD->getParent());
5738 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5744 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5745 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5746 Expr.push_back(Info.
Offset);
5749 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5750 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5751 }
else if (fieldOffset != 0) {
5752 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5753 "Unexpected non-bitfield with non-byte-aligned offset");
5754 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5756 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5759 }
else if (
const ArraySubscriptExpr *ASE =
5760 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5761 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5762 const uint64_t value = IL->getValue().getZExtValue();
5763 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5766 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5767 Expr.push_back(CGM.getContext()
5768 .toCharUnitsFromBits(value * typeSize)
5775 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5776 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5777 Column, Scope, CurInlinedAt),
5778 Builder.GetInsertBlock());
5783llvm::DILocalVariable *
5786 const bool UsePointerValue) {
5787 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5789 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5791 EmitDeclare(B, Storage, std::nullopt, Builder,
5798 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5802 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5803 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5805 if (D->
hasAttr<NoDebugAttr>())
5809 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5815 StringRef Name = D->
getName();
5821 CGM.getCodeGenOpts().OptimizationLevel != 0);
5824 DBuilder.insertLabel(L,
5825 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5826 Scope, CurInlinedAt),
5827 Builder.GetInsertBlock()->end());
5830llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5832 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5835 return DBuilder.createObjectPointerType(Ty,
true);
5840 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5841 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5842 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5844 if (Builder.GetInsertBlock() ==
nullptr)
5846 if (VD->
hasAttr<NoDebugAttr>())
5849 bool isByRef = VD->
hasAttr<BlocksAttr>();
5851 uint64_t XOffset = 0;
5852 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5855 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5857 Ty = getOrCreateType(VD->
getType(), Unit);
5861 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5863 Ty = CreateSelfType(VD->
getType(), Ty);
5866 const unsigned Line =
5870 const llvm::DataLayout &target = CGM.getDataLayout();
5877 addr.push_back(llvm::dwarf::DW_OP_deref);
5878 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5881 addr.push_back(llvm::dwarf::DW_OP_deref);
5882 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5885 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5887 addr.push_back(llvm::dwarf::DW_OP_deref);
5888 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5890 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5896 auto *D = DBuilder.createAutoVariable(
5898 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5901 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5902 LexicalBlockStack.back(), CurInlinedAt);
5903 auto *
Expr = DBuilder.createExpression(addr);
5905 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5907 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5910llvm::DILocalVariable *
5913 bool UsePointerValue) {
5914 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5915 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5919struct BlockLayoutChunk {
5920 uint64_t OffsetInBits;
5923bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5924 return l.OffsetInBits < r.OffsetInBits;
5928void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5930 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5931 SmallVectorImpl<llvm::Metadata *> &Fields) {
5935 if (CGM.getLangOpts().OpenCL) {
5936 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5937 BlockLayout.getElementOffsetInBits(0),
5939 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5940 BlockLayout.getElementOffsetInBits(1),
5944 BlockLayout.getElementOffsetInBits(0),
5946 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5947 BlockLayout.getElementOffsetInBits(1),
5951 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5952 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5953 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5954 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5955 BlockLayout.getElementOffsetInBits(3),
5957 Fields.push_back(createFieldType(
5962 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5969 llvm::AllocaInst *Alloca,
5971 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5977 llvm::DIFile *tunit = getOrCreateFile(loc);
5978 unsigned line = getLineNumber(loc);
5979 unsigned column = getColumnNumber(loc);
5984 const llvm::StructLayout *blockLayout =
5988 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5997 BlockLayoutChunk chunk;
5998 chunk.OffsetInBits =
5999 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
6000 chunk.Capture =
nullptr;
6001 chunks.push_back(chunk);
6005 for (
const auto &capture :
blockDecl->captures()) {
6006 const VarDecl *variable = capture.getVariable();
6013 BlockLayoutChunk chunk;
6014 chunk.OffsetInBits =
6015 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6016 chunk.Capture = &capture;
6017 chunks.push_back(chunk);
6021 llvm::array_pod_sort(chunks.begin(), chunks.end());
6023 for (
const BlockLayoutChunk &Chunk : chunks) {
6024 uint64_t offsetInBits = Chunk.OffsetInBits;
6031 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6033 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6034 type = CGM.getContext().getCanonicalTagType(RDecl);
6036 llvm_unreachable(
"unexpected block declcontext");
6038 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6039 offsetInBits, tunit, tunit));
6044 StringRef name = variable->
getName();
6046 llvm::DIType *fieldType;
6048 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6053 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6054 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6055 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6056 PtrInfo.
Width, Align, offsetInBits,
6057 llvm::DINode::FlagZero, fieldType);
6061 offsetInBits, Align, tunit, tunit);
6063 fields.push_back(fieldType);
6067 llvm::raw_svector_ostream(typeName)
6068 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6070 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6072 llvm::DIType *
type =
6073 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6074 CGM.getContext().toBits(block.
BlockSize), 0,
6075 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6076 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6079 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6083 auto *debugVar = DBuilder.createParameterVariable(
6084 scope, Name, ArgNo, tunit, line,
type,
6085 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6088 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6089 llvm::DILocation::get(CGM.getLLVMContext(), line,
6090 column, scope, CurInlinedAt),
6091 Builder.GetInsertBlock());
6094llvm::DIDerivedType *
6095CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6100 if (MI != StaticDataMemberCache.end()) {
6101 assert(MI->second &&
"Static data member declaration should still exist");
6112llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6113 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6114 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6115 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6117 for (
const auto *Field : RD->
fields()) {
6118 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6119 StringRef FieldName = Field->getName();
6122 if (FieldName.empty()) {
6123 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6124 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6125 LineNo, LinkageName, Var, DContext);
6129 GVE = DBuilder.createGlobalVariableExpression(
6130 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6131 Var->hasLocalLinkage());
6132 Var->addDebugInfo(GVE);
6144 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6149 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6160 struct ReferencesAnonymous
6162 bool RefAnon =
false;
6163 bool VisitRecordType(RecordType *RT) {
6171 ReferencesAnonymous RT;
6184struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6185 bool Reconstitutable =
true;
6186 bool VisitVectorType(VectorType *FT) {
6187 Reconstitutable =
false;
6190 bool VisitAtomicType(AtomicType *FT) {
6191 Reconstitutable =
false;
6194 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6197 const EnumDecl *ED = ET->getDecl();
6199 Reconstitutable =
false;
6203 Reconstitutable =
false;
6208 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6212 return Reconstitutable;
6214 bool VisitRecordType(RecordType *RT,
bool =
false) {
6216 Reconstitutable =
false;
6226 ReconstitutableType
T;
6228 return T.Reconstitutable;
6231bool CGDebugInfo::HasReconstitutableArgs(
6232 ArrayRef<TemplateArgument> Args)
const {
6233 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6273 llvm_unreachable(
"Other, unresolved, template arguments should "
6274 "not be seen here");
6279std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6280 bool *NameIsSimplified)
const {
6282 llvm::raw_string_ostream
OS(Name);
6283 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6286 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6287 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6289 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6290 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6292 std::optional<TemplateArgs> Args;
6294 bool IsOperatorOverload =
false;
6295 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6296 Args = GetTemplateArgs(RD);
6297 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6298 Args = GetTemplateArgs(FD);
6300 IsOperatorOverload |=
6303 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6304 Args = GetTemplateArgs(VD);
6328 bool Reconstitutable =
6329 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6331 PrintingPolicy PP = getPrintingPolicy();
6333 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6338 if (NameIsSimplified)
6339 *NameIsSimplified =
true;
6340 bool Mangled = TemplateNamesKind ==
6341 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6347 std::string EncodedOriginalName;
6348 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6353 printTemplateArgumentList(OS, Args->Args, PP);
6354 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6356 std::string CanonicalOriginalName;
6357 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6359 assert(EncodedOriginalName == CanonicalOriginalName);
6368 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6369 if (D->
hasAttr<NoDebugAttr>())
6372 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6373 return GetName(D,
true);
6379 if (Cached != DeclCache.end())
6380 return Var->addDebugInfo(
6384 llvm::DIFile *Unit =
nullptr;
6385 llvm::DIScope *DContext =
nullptr;
6387 StringRef DeclName, LinkageName;
6389 llvm::MDTuple *TemplateParameters =
nullptr;
6390 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6391 TemplateParameters, DContext);
6395 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6400 if (
T->isUnionType() && DeclName.empty()) {
6401 const auto *RD =
T->castAsRecordDecl();
6403 "unnamed non-anonymous struct or union?");
6404 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6409 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6410 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6411 if (D->
hasAttr<CUDASharedAttr>())
6414 else if (D->
hasAttr<CUDAConstantAttr>())
6418 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6420 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6421 GVE = DBuilder.createGlobalVariableExpression(
6422 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6423 Var->hasLocalLinkage(),
true,
6424 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6425 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6426 Align, Annotations);
6427 Var->addDebugInfo(GVE);
6433 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6434 if (VD->
hasAttr<NoDebugAttr>())
6436 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6437 return GetName(VD,
true);
6442 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6443 StringRef Name = VD->
getName();
6444 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6446 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6448 if (CGM.getCodeGenOpts().EmitCodeView) {
6459 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6460 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6461 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6471 auto *VarD = dyn_cast<VarDecl>(VD);
6472 if (VarD && VarD->isStaticDataMember()) {
6474 getDeclContextDescriptor(VarD);
6479 RetainedTypes.push_back(
6480 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6484 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6486 auto &GV = DeclCache[VD];
6490 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6491 llvm::MDTuple *TemplateParameters =
nullptr;
6495 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6496 TemplateParameters = parameterNodes.get();
6499 GV.reset(DBuilder.createGlobalVariableExpression(
6500 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6501 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6502 TemplateParameters, Align));
6507 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6508 if (D->
hasAttr<NoDebugAttr>())
6512 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6513 StringRef Name = D->
getName();
6514 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6516 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6517 llvm::DIGlobalVariableExpression *GVE =
6518 DBuilder.createGlobalVariableExpression(
6519 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6520 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6521 Var->addDebugInfo(GVE);
6528 if (CGM.getCodeGenOpts().getDebugInfo() <=
6529 llvm::codegenoptions::DebugLineTablesOnly)
6532 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6536 llvm::DIFile *Unit = DIL->getFile();
6537 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6542 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6543 llvm::Value *Var = Load->getPointerOperand();
6548 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6549 return DbgDeclare->getVariable()->getType() ==
Type;
6551 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6555 llvm::DILocalVariable *D =
6556 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6557 Type,
false, llvm::DINode::FlagArtificial);
6559 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6560 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6570 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6574 if (D->
hasAttr<NoDebugAttr>())
6577 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6592 if (!(DI = getDeclarationOrDefinition(
6593 AliaseeDecl.getCanonicalDecl().getDecl())))
6596 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6599 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6600 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6614 llvm::DIFile *
File = getOrCreateFile(Loc);
6615 llvm::DIGlobalVariableExpression *Debug =
6616 DBuilder.createGlobalVariableExpression(
6617 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6618 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6619 GV->addDebugInfo(Debug);
6622llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6623 if (!LexicalBlockStack.empty())
6624 return LexicalBlockStack.back();
6625 llvm::DIScope *Mod = getParentModuleOrNull(D);
6626 return getContextDescriptor(D, Mod ? Mod : TheCU);
6630 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6634 CGM.getCodeGenOpts().DebugExplicitImport) {
6638 DBuilder.createImportedModule(
6640 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6645 if (llvm::DINode *
Target =
6648 DBuilder.createImportedDeclaration(
6650 getOrCreateFile(Loc), getLineNumber(Loc));
6655 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6658 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6660 for (
const auto *USD : UD.
shadows()) {
6665 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6666 if (
const auto *AT = FD->getType()
6669 if (AT->getDeducedType().isNull())
6680 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6683 "We shouldn't be codegening an invalid UsingEnumDecl"
6684 " containing no decls");
6686 for (
const auto *USD : UD.
shadows())
6691 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6693 if (
Module *M = ID.getImportedModule()) {
6695 auto Loc = ID.getLocation();
6696 DBuilder.createImportedDeclaration(
6697 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6698 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6699 getLineNumber(Loc));
6703llvm::DIImportedEntity *
6705 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6707 auto &VH = NamespaceAliasCache[&NA];
6710 llvm::DIImportedEntity *R;
6712 if (
const auto *Underlying =
6715 R = DBuilder.createImportedDeclaration(
6718 getLineNumber(Loc), NA.
getName());
6720 R = DBuilder.createImportedDeclaration(
6723 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6729CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6733 auto I = NamespaceCache.find(NSDecl);
6734 if (I != NamespaceCache.end())
6737 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6739 llvm::DINamespace *NS =
6740 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6741 NamespaceCache[NSDecl].reset(NS);
6746 assert(TheCU &&
"no main compile unit");
6747 TheCU->setDWOId(Signature);
6753 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6754 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6756 ? CreateTypeDefinition(E.Type, E.Unit)
6758 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6762 for (
const auto &P : ObjCMethodCache) {
6763 if (P.second.empty())
6766 QualType QTy(P.first->getTypeForDecl(), 0);
6768 assert(It != TypeCache.end());
6770 llvm::DICompositeType *InterfaceDecl =
6773 auto CurElts = InterfaceDecl->getElements();
6777 for (
auto &SubprogramDirect : P.second)
6778 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6779 EltTys.push_back(SubprogramDirect.getPointer());
6781 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6782 DBuilder.replaceArrays(InterfaceDecl, Elements);
6785 for (
const auto &P : ReplaceMap) {
6788 assert(Ty->isForwardDecl());
6790 auto It = TypeCache.find(P.first);
6791 assert(It != TypeCache.end());
6794 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6798 for (
const auto &P : FwdDeclReplaceMap) {
6801 llvm::Metadata *Repl;
6803 auto It = DeclCache.find(P.first);
6807 if (It == DeclCache.end())
6812 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6813 Repl = GVE->getVariable();
6819 for (
auto &RT : RetainedTypes)
6820 if (
auto MD = TypeCache[RT])
6823 DBuilder.finalize();
6828 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6829 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6830 DBuilder.retainType(DieTy);
6834 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6835 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6836 DBuilder.retainType(DieTy);
6840 if (LexicalBlockStack.empty())
6841 return llvm::DebugLoc();
6843 llvm::MDNode *
Scope = LexicalBlockStack.back();
6844 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6845 getColumnNumber(Loc),
Scope);
6851 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6852 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6853 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6854 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6855 return llvm::DINode::FlagZero;
6860 bool SupportsDWARFv4Ext =
6861 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6862 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6863 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6865 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6866 return llvm::DINode::FlagZero;
6868 return llvm::DINode::FlagAllCallsDescribed;
6879 return DBuilder.createConstantValueExpression(
6880 Val.
getFloat().bitcastToAPInt().getZExtValue());
6885 llvm::APSInt
const &ValInt = Val.
getInt();
6886 std::optional<uint64_t> ValIntOpt;
6887 if (ValInt.isUnsigned())
6888 ValIntOpt = ValInt.tryZExtValue();
6889 else if (
auto tmp = ValInt.trySExtValue())
6892 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6895 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6900CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6902 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6903 CGF.CurLexicalScope =
this;
6905 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6910 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6923#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6925 Label = "__ubsan_check_" #Name; \
6929#undef SANITIZER_CHECK
6940#define SANITIZER(NAME, ID) \
6941 case SanitizerKind::SO_##ID: \
6942 Label = "__ubsan_check_" NAME; \
6944#include "clang/Basic/Sanitizers.def"
6946 llvm_unreachable(
"unexpected sanitizer kind");
6951 for (
unsigned int i = 0; i < Label.length(); i++)
6952 if (!std::isalpha(Label[i]))
6961 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6963 if (!DI || !CheckDebugLoc)
6964 return CheckDebugLoc;
6965 const auto &AnnotateDebugInfo =
6966 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6967 if (AnnotateDebugInfo.empty())
6968 return CheckDebugLoc;
6971 if (Ordinals.size() == 1)
6976 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6980 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6981 "ubsan_interface.h",
6983 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6986 return CheckDebugLoc;
6994 assert(!CGF->IsSanitizerScope);
6995 CGF->IsSanitizerScope =
true;
6999 assert(CGF->IsSanitizerScope);
7000 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.
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.