40#include "llvm/ADT/DenseSet.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/DerivedTypes.h"
46#include "llvm/IR/Instruction.h"
47#include "llvm/IR/Instructions.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/Metadata.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/MD5.h"
52#include "llvm/Support/Path.h"
53#include "llvm/Support/SHA1.h"
54#include "llvm/Support/SHA256.h"
55#include "llvm/Support/TimeProfiler.h"
63 if (TI.isAlignRequired())
91 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
95 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
113 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
114 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
115 DBuilder(CGM.getModule()) {
120 assert(LexicalBlockStack.empty() &&
121 "Region stack mismatch, stack not empty!");
124void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
125 uint64_t Group, uint8_t Rank) {
126 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
130 Rank = std::min<uint8_t>(Rank, 7);
132 const llvm::DebugLoc &DL = I->getDebugLoc();
137 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
138 Group = DL->getAtomGroup();
139 Rank = DL->getAtomRank();
144 KeyInstructionsInfo.HighestEmittedAtom =
145 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
148 llvm::DILocation *NewDL = llvm::DILocation::get(
149 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
150 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
151 I->setDebugLoc(NewDL);
155 llvm::Value *Backup) {
157 KeyInstructionsInfo.CurrentAtom);
163 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
166 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
167 if (!SP || !SP->getKeyInstructionsEnabled())
170 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
172 llvm::Instruction *BackupI =
173 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
178 addInstSourceAtomMetadata(BackupI, Group, 2);
184 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
185 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
188 addInstSourceAtomMetadata(BackupI, Group, Rank++);
194 KeyInstructionsInfo.NextAtom = 1;
195 KeyInstructionsInfo.HighestEmittedAtom = 0;
196 KeyInstructionsInfo.CurrentAtom = 0;
202 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
203 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
211 DI->KeyInstructionsInfo.NextAtom =
212 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
213 DI->KeyInstructionsInfo.NextAtom);
215 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
221 init(TemporaryLocation);
228 init(TemporaryLocation, DefaultToEmpty);
232 bool DefaultToEmpty) {
239 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
241 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
244 if (TemporaryLocation.
isValid()) {
245 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
249 if (DefaultToEmpty) {
250 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
255 assert(!DI->LexicalBlockStack.empty());
256 CGF->Builder.SetCurrentDebugLocation(
257 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
258 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
268 if (!CGF.getDebugInfo()) {
272 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
276 if (Loc->getAtomGroup())
277 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
278 Loc->getColumn(), Loc->getScope(),
279 Loc->getInlinedAt(), Loc.isImplicitCode());
280 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
288 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
294 if (!CGF.getDebugInfo()) {
298 auto &DI = *CGF.getDebugInfo();
299 SavedLocation = DI.getLocation();
300 assert((DI.getInlinedAt() ==
301 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
302 "CGDebugInfo and IRBuilder are out of sync");
304 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
310 auto &DI = *CGF->getDebugInfo();
311 DI.EmitInlineFunctionEnd(CGF->Builder);
312 DI.EmitLocation(CGF->Builder, SavedLocation);
320 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
325 if (LexicalBlockStack.empty())
331 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
334 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
335 LexicalBlockStack.pop_back();
336 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
337 LBF->getScope(), getOrCreateFile(CurLoc)));
340 LexicalBlockStack.pop_back();
341 LexicalBlockStack.emplace_back(
342 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
346llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
347 llvm::DIScope *Mod = getParentModuleOrNull(D);
352llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
357 auto I = RegionMap.find(Context);
358 if (I != RegionMap.end()) {
359 llvm::Metadata *
V = I->second;
360 return dyn_cast_or_null<llvm::DIScope>(
V);
364 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
365 return getOrCreateNamespace(NSDecl);
367 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
368 if (!RDecl->isDependentType())
374PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
375 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
382 if (CGM.getCodeGenOpts().EmitCodeView) {
403StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
404 return internString(GetName(FD));
407StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
408 SmallString<256> MethodName;
409 llvm::raw_svector_ostream
OS(MethodName);
412 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
413 OS << OID->getName();
414 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
415 OS << OID->getName();
416 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
417 if (OC->IsClassExtension()) {
418 OS << OC->getClassInterface()->getName();
420 OS << OC->getIdentifier()->getNameStart() <<
'('
421 << OC->getIdentifier()->getNameStart() <<
')';
423 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
424 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
428 return internString(
OS.str());
431StringRef CGDebugInfo::getSelectorName(Selector S) {
435StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
438 return internString(GetName(RD));
444 return II->getName();
449 if (CGM.getCodeGenOpts().EmitCodeView) {
452 "Typedef should not be in another decl context!");
453 assert(D->getDeclName().getAsIdentifierInfo() &&
454 "Typedef was not named!");
455 return D->getDeclName().getAsIdentifierInfo()->getName();
458 if (CGM.getLangOpts().CPlusPlus) {
461 ASTContext &Context = CGM.getContext();
465 Name = DD->getName();
466 else if (
const TypedefNameDecl *TND =
470 Name = TND->getName();
473 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
474 if (CXXRD->isLambda())
476 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
479 SmallString<256> UnnamedType(
"<unnamed-type-");
482 return internString(UnnamedType);
490std::optional<llvm::DIFile::ChecksumKind>
491CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
494 if (!CGM.getCodeGenOpts().EmitCodeView &&
495 CGM.getCodeGenOpts().DwarfVersion < 5)
498 SourceManager &
SM = CGM.getContext().getSourceManager();
499 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
503 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
504 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
506 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
507 return llvm::DIFile::CSK_MD5;
509 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
510 return llvm::DIFile::CSK_SHA1;
512 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
513 return llvm::DIFile::CSK_SHA256;
517 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
520std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
522 if (!CGM.getCodeGenOpts().EmbedSource)
525 bool SourceInvalid =
false;
526 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
534llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
535 SourceManager &
SM = CGM.getContext().getSourceManager();
538 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
544 FileName = TheCU->getFile()->getFilename();
545 CSInfo = TheCU->getFile()->getChecksum();
547 PresumedLoc PLoc =
SM.getPresumedLoc(Loc);
551 FileName = TheCU->getFile()->getFilename();
559 auto It = DIFileCache.find(
FileName.data());
560 if (It != DIFileCache.end()) {
562 if (llvm::Metadata *
V = It->second)
567 SmallString<64> Checksum;
569 std::optional<llvm::DIFile::ChecksumKind> CSKind =
570 computeChecksum(FID, Checksum);
572 CSInfo.emplace(*CSKind, Checksum);
574 return createFile(
FileName, CSInfo, getSource(
SM,
SM.getFileID(Loc)));
577llvm::DIFile *CGDebugInfo::createFile(
579 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
580 std::optional<StringRef> Source) {
584 std::string CurDir =
remapDIPath(getCurrentDirname());
585 SmallString<128> DirBuf;
586 SmallString<128> FileBuf;
587 if (llvm::sys::path::is_absolute(RemappedFile)) {
590 auto FileIt = llvm::sys::path::begin(RemappedFile);
591 auto FileE = llvm::sys::path::end(RemappedFile);
592 auto CurDirIt = llvm::sys::path::begin(CurDir);
593 auto CurDirE = llvm::sys::path::end(CurDir);
594 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
595 llvm::sys::path::append(DirBuf, *CurDirIt);
596 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
602 for (; FileIt != FileE; ++FileIt)
603 llvm::sys::path::append(FileBuf, *FileIt);
608 if (!llvm::sys::path::is_absolute(
FileName))
612 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
613 DIFileCache[
FileName.data()].reset(F);
619 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
620 if (llvm::sys::path::replace_path_prefix(P, From, To))
622 return P.str().str();
629 return SM.getPresumedLoc(Loc).getLine();
632unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
645StringRef CGDebugInfo::getCurrentDirname() {
649void CGDebugInfo::CreateCompileUnit() {
650 SmallString<64> Checksum;
651 std::optional<llvm::DIFile::ChecksumKind> CSKind;
652 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
662 SourceManager &
SM = CGM.getContext().getSourceManager();
663 auto &CGO = CGM.getCodeGenOpts();
664 const LangOptions &LO = CGM.getLangOpts();
665 std::string MainFileName = CGO.MainFileName;
666 if (MainFileName.empty())
667 MainFileName =
"<stdin>";
673 std::string MainFileDir;
675 SM.getFileEntryRefForID(
SM.getMainFileID())) {
676 MainFileDir = std::string(MainFile->getDir().getName());
677 if (!llvm::sys::path::is_absolute(MainFileName)) {
678 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
679 llvm::sys::path::Style Style =
681 ? (CGM.getTarget().getTriple().isOSWindows()
682 ? llvm::sys::path::Style::windows_backslash
683 : llvm::sys::path::Style::posix)
684 : llvm::sys::path::Style::native;
685 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
686 MainFileName = std::string(
687 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
694 if (MainFile->getName() == MainFileName &&
696 MainFile->getName().rsplit(
'.').second)
698 MainFileName = CGM.getModule().getName().str();
700 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
704 llvm::dwarf::SourceLanguage LangTag;
707 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
708 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
709 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
710 else if (LO.CPlusPlus14)
711 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
712 else if (LO.CPlusPlus11)
713 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
715 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
716 }
else if (LO.ObjC) {
717 LangTag = llvm::dwarf::DW_LANG_ObjC;
718 }
else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf ||
719 CGM.getCodeGenOpts().DwarfVersion >= 5)) {
720 LangTag = llvm::dwarf::DW_LANG_OpenCL;
721 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
722 LangTag = llvm::dwarf::DW_LANG_C11;
724 LangTag = llvm::dwarf::DW_LANG_C99;
726 LangTag = llvm::dwarf::DW_LANG_C89;
732 unsigned RuntimeVers = 0;
736 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
738 case llvm::codegenoptions::NoDebugInfo:
739 case llvm::codegenoptions::LocTrackingOnly:
740 EmissionKind = llvm::DICompileUnit::NoDebug;
742 case llvm::codegenoptions::DebugLineTablesOnly:
743 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
745 case llvm::codegenoptions::DebugDirectivesOnly:
746 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
748 case llvm::codegenoptions::DebugInfoConstructor:
749 case llvm::codegenoptions::LimitedDebugInfo:
750 case llvm::codegenoptions::FullDebugInfo:
751 case llvm::codegenoptions::UnusedTypeInfo:
752 EmissionKind = llvm::DICompileUnit::FullDebug;
757 auto &CGOpts = CGM.getCodeGenOpts();
763 CSInfo.emplace(*CSKind, Checksum);
764 llvm::DIFile *CUFile = DBuilder.createFile(
766 getSource(
SM,
SM.getMainFileID()));
768 StringRef Sysroot, SDK;
769 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
770 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
771 auto B = llvm::sys::path::rbegin(Sysroot);
772 auto E = llvm::sys::path::rend(Sysroot);
774 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
779 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
780 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
781 CGOpts.DebugNameTable);
782 if (CGM.getTarget().getTriple().isNVPTX())
783 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
784 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
785 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
788 TheCU = DBuilder.createCompileUnit(
789 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
790 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
791 CGOpts.PrepareForThinLTO,
792 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
793 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
794 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
797llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
801#define BUILTIN_TYPE(Id, SingletonId)
802#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
803#include "clang/AST/BuiltinTypes.def"
804 case BuiltinType::Dependent:
805 llvm_unreachable(
"Unexpected builtin type");
806 case BuiltinType::NullPtr:
807 return DBuilder.createNullPtrType();
808 case BuiltinType::Void:
810 case BuiltinType::ObjCClass:
813 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
814 "objc_class", TheCU, TheCU->getFile(), 0);
816 case BuiltinType::ObjCId: {
827 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
828 "objc_class", TheCU, TheCU->getFile(), 0);
830 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
832 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
834 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
835 (uint64_t)0, 0, llvm::DINode::FlagZero,
836 nullptr, llvm::DINodeArray());
838 DBuilder.replaceArrays(
839 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
840 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
841 llvm::DINode::FlagZero, ISATy)));
844 case BuiltinType::ObjCSel: {
846 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
847 "objc_selector", TheCU,
848 TheCU->getFile(), 0);
852#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
853 case BuiltinType::Id: \
854 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
856#include "clang/Basic/OpenCLImageTypes.def"
857 case BuiltinType::OCLSampler:
858 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
859 case BuiltinType::OCLEvent:
860 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
861 case BuiltinType::OCLClkEvent:
862 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
863 case BuiltinType::OCLQueue:
864 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
865 case BuiltinType::OCLReserveID:
866 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
867#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
868 case BuiltinType::Id: \
869 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
870#include "clang/Basic/OpenCLExtensionTypes.def"
871#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
872 case BuiltinType::Id: \
873 return getOrCreateStructPtrType(#Name, SingletonId);
874#include "clang/Basic/HLSLIntangibleTypes.def"
876#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
877#include "clang/Basic/AArch64ACLETypes.def"
879 if (BT->
getKind() == BuiltinType::MFloat8) {
880 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
881 BTName = BT->
getName(CGM.getLangOpts());
884 return DBuilder.createBasicType(BTName, Size, Encoding);
886 ASTContext::BuiltinVectorTypeInfo Info =
888 BT->
getKind() == BuiltinType::SveCount
889 ? ASTContext::BuiltinVectorTypeInfo(
890 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
892 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
899 "Unsupported number of vectors for svcount_t");
903 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
906 Info.
ElementType = CGM.getContext().UnsignedCharTy;
909 llvm::Metadata *LowerBound, *UpperBound;
910 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
911 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
912 if (Info.
EC.isScalable()) {
913 unsigned NumElemsPerVG = NumElems / 2;
914 SmallVector<uint64_t, 9> Expr(
915 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
916 46, 0, llvm::dwarf::DW_OP_mul,
917 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
918 UpperBound = DBuilder.createExpression(Expr);
920 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
921 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
923 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
924 nullptr, LowerBound, UpperBound,
nullptr);
925 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
926 llvm::DIType *ElemTy =
927 getOrCreateType(Info.
ElementType, TheCU->getFile());
929 return DBuilder.createVectorType( 0, Align, ElemTy,
934#define PPC_VECTOR_TYPE(Name, Id, size) \
935 case BuiltinType::Id:
936#include "clang/Basic/PPCTypes.def"
939#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
940#include "clang/Basic/RISCVVTypes.def"
942 ASTContext::BuiltinVectorTypeInfo Info =
943 CGM.getContext().getBuiltinVectorTypeInfo(BT);
945 unsigned ElementCount = Info.
EC.getKnownMinValue();
946 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
948 bool Fractional =
false;
951 unsigned FixedSize = ElementCount * SEW;
955 }
else if (FixedSize < 64) {
958 LMUL = 64 / FixedSize;
960 LMUL = FixedSize / 64;
964 SmallVector<uint64_t, 12> Expr(
968 {llvm::dwarf::DW_OP_bregx,
971 llvm::dwarf::DW_OP_constu,
973 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
975 Expr.push_back(llvm::dwarf::DW_OP_div);
977 Expr.push_back(llvm::dwarf::DW_OP_mul);
980 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
982 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
985 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
986 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
987 auto *UpperBound = DBuilder.createExpression(Expr);
988 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
989 nullptr, LowerBound, UpperBound,
nullptr);
990 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
991 llvm::DIType *ElemTy =
992 getOrCreateType(Info.
ElementType, TheCU->getFile());
995 return DBuilder.createVectorType(0, Align, ElemTy,
999#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1000 case BuiltinType::Id: { \
1003 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1004 MangledName, TheCU, TheCU->getFile(), 0); \
1005 return SingletonId; \
1007#include "clang/Basic/WebAssemblyReferenceTypes.def"
1008#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1009 case BuiltinType::Id: { \
1012 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1013 TheCU, TheCU->getFile(), 0); \
1014 return SingletonId; \
1016#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1017 case BuiltinType::Id: { \
1020 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1021 return SingletonId; \
1023#include "clang/Basic/AMDGPUTypes.def"
1024 case BuiltinType::UChar:
1025 case BuiltinType::Char_U:
1026 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1028 case BuiltinType::Char_S:
1029 case BuiltinType::SChar:
1030 Encoding = llvm::dwarf::DW_ATE_signed_char;
1032 case BuiltinType::Char8:
1033 case BuiltinType::Char16:
1034 case BuiltinType::Char32:
1035 Encoding = llvm::dwarf::DW_ATE_UTF;
1037 case BuiltinType::UShort:
1038 case BuiltinType::UInt:
1039 case BuiltinType::UInt128:
1040 case BuiltinType::ULong:
1041 case BuiltinType::WChar_U:
1042 case BuiltinType::ULongLong:
1043 Encoding = llvm::dwarf::DW_ATE_unsigned;
1045 case BuiltinType::Short:
1046 case BuiltinType::Int:
1047 case BuiltinType::Int128:
1048 case BuiltinType::Long:
1049 case BuiltinType::WChar_S:
1050 case BuiltinType::LongLong:
1051 Encoding = llvm::dwarf::DW_ATE_signed;
1053 case BuiltinType::Bool:
1054 Encoding = llvm::dwarf::DW_ATE_boolean;
1056 case BuiltinType::Half:
1057 case BuiltinType::Float:
1058 case BuiltinType::LongDouble:
1059 case BuiltinType::Float16:
1060 case BuiltinType::BFloat16:
1061 case BuiltinType::Float128:
1062 case BuiltinType::Double:
1063 case BuiltinType::Ibm128:
1069 Encoding = llvm::dwarf::DW_ATE_float;
1071 case BuiltinType::ShortAccum:
1072 case BuiltinType::Accum:
1073 case BuiltinType::LongAccum:
1074 case BuiltinType::ShortFract:
1075 case BuiltinType::Fract:
1076 case BuiltinType::LongFract:
1077 case BuiltinType::SatShortFract:
1078 case BuiltinType::SatFract:
1079 case BuiltinType::SatLongFract:
1080 case BuiltinType::SatShortAccum:
1081 case BuiltinType::SatAccum:
1082 case BuiltinType::SatLongAccum:
1083 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1085 case BuiltinType::UShortAccum:
1086 case BuiltinType::UAccum:
1087 case BuiltinType::ULongAccum:
1088 case BuiltinType::UShortFract:
1089 case BuiltinType::UFract:
1090 case BuiltinType::ULongFract:
1091 case BuiltinType::SatUShortAccum:
1092 case BuiltinType::SatUAccum:
1093 case BuiltinType::SatULongAccum:
1094 case BuiltinType::SatUShortFract:
1095 case BuiltinType::SatUFract:
1096 case BuiltinType::SatULongFract:
1097 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1101 BTName = BT->
getName(CGM.getLangOpts());
1104 return DBuilder.createBasicType(BTName, Size, Encoding);
1107llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1109 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1111 ? llvm::dwarf::DW_ATE_unsigned
1112 : llvm::dwarf::DW_ATE_signed;
1114 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1118llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1120 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1122 Encoding = llvm::dwarf::DW_ATE_lo_user;
1125 return DBuilder.createBasicType(
"complex", Size, Encoding);
1139 return llvm::dwarf::DW_TAG_const_type;
1143 return llvm::dwarf::DW_TAG_volatile_type;
1147 return llvm::dwarf::DW_TAG_restrict_type;
1149 return (llvm::dwarf::Tag)0;
1152llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1153 llvm::DIFile *Unit) {
1154 QualifierCollector Qc;
1168 bool AuthenticatesNullValues =
1171 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1172 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1173 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1174 ExtraDiscr, IsaPointer,
1175 AuthenticatesNullValues);
1177 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1178 return getOrCreateType(QualType(
T, 0), Unit);
1182 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1186 return DBuilder.createQualifiedType(Tag, FromTy);
1189llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1190 llvm::DIFile *Unit) {
1199 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1204 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1210 return DBuilder.createQualifiedType(Tag, FromTy);
1213llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1214 llvm::DIFile *Unit) {
1220 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1222 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1226llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1227 llvm::DIFile *Unit) {
1228 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1234 switch (TheCU->getSourceLanguage()) {
1235 case llvm::dwarf::DW_LANG_C_plus_plus:
1236 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1237 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1239 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1268 llvm::DICompileUnit *TheCU) {
1286 llvm::DICompileUnit *TheCU) {
1292 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1294 if (RD->isDynamicClass() &&
1300 llvm::raw_svector_ostream Out(Identifier);
1307 llvm::dwarf::Tag Tag;
1309 Tag = llvm::dwarf::DW_TAG_structure_type;
1311 Tag = llvm::dwarf::DW_TAG_union_type;
1316 Tag = llvm::dwarf::DW_TAG_class_type;
1321llvm::DICompositeType *
1322CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1323 llvm::DIScope *Ctx) {
1324 const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
1325 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1327 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1328 const unsigned Line =
1330 StringRef RDName = getClassName(RD);
1337 Size = CGM.getContext().getTypeSize(Ty);
1339 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1344 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1345 if (!CXXRD->hasDefinition() ||
1346 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1347 Flags |= llvm::DINode::FlagNonTrivial;
1350 SmallString<256> Identifier;
1352 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1354 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1357 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1358 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1359 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1360 CollectCXXTemplateParams(TSpecial, DefUnit));
1361 ReplaceMap.emplace_back(
1362 std::piecewise_construct, std::make_tuple(Ty),
1363 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1367llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1370 llvm::DIFile *Unit) {
1375 std::optional<unsigned> DWARFAddressSpace =
1376 CGM.getTarget().getDWARFAddressSpace(
1377 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1379 const BTFTagAttributedType *BTFAttrTy;
1380 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1381 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1383 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1384 SmallVector<llvm::Metadata *, 4> Annots;
1386 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1388 llvm::Metadata *Ops[2] = {
1389 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1390 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1391 Annots.insert(Annots.begin(),
1392 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1394 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1397 llvm::DINodeArray Annotations =
nullptr;
1398 if (Annots.size() > 0)
1399 Annotations = DBuilder.getOrCreateArray(Annots);
1401 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1402 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1403 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1404 Size, Align, DWARFAddressSpace);
1406 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1407 Align, DWARFAddressSpace, StringRef(),
1411llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1412 llvm::DIType *&
Cache) {
1415 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1416 TheCU, TheCU->getFile(), 0);
1417 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1418 Cache = DBuilder.createPointerType(
Cache, Size);
1422uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1423 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1424 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1434 if (CGM.getLangOpts().OpenCL) {
1435 FType = CGM.getContext().IntTy;
1436 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1437 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1439 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1440 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1441 FType = CGM.getContext().IntTy;
1442 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1443 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1445 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1446 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1447 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1448 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1449 EltTys.push_back(DBuilder.createMemberType(
1450 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1451 FieldOffset, llvm::DINode::FlagZero, DescTy));
1452 FieldOffset += FieldSize;
1458llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1459 llvm::DIFile *Unit) {
1460 SmallVector<llvm::Metadata *, 8> EltTys;
1463 llvm::DINodeArray Elements;
1466 FType = CGM.getContext().UnsignedLongTy;
1467 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1468 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1470 Elements = DBuilder.getOrCreateArray(EltTys);
1473 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1476 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1477 FieldOffset, 0, Flags,
nullptr, Elements);
1482 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1484 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1487 Elements = DBuilder.getOrCreateArray(EltTys);
1493 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1494 Flags,
nullptr, Elements);
1496 return DBuilder.createPointerType(EltTy, Size);
1499static llvm::SmallVector<TemplateArgument>
1501 assert(Ty->isTypeAlias());
1510 ArrayRef SubstArgs = Ty->template_arguments();
1513 if (Param->isParameterPack()) {
1522 if (SubstArgs.empty()) {
1531 SpecArgs.push_back(SubstArgs.front());
1532 SubstArgs = SubstArgs.drop_front();
1537llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1538 llvm::DIFile *Unit) {
1539 assert(Ty->isTypeAlias());
1540 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1542 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1550 SmallString<128> NS;
1551 llvm::raw_svector_ostream
OS(NS);
1553 auto PP = getPrintingPolicy();
1556 SourceLocation Loc =
AliasDecl->getLocation();
1558 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1559 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1568 llvm::raw_string_ostream
OS(Name);
1570 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1571 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1572 !HasReconstitutableArgs(Args.Args))
1573 printTemplateArgumentList(OS, Args.Args, PP);
1575 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1576 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1577 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1581 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1583 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1600 return llvm::DINode::FlagZero;
1604 return llvm::DINode::FlagPrivate;
1606 return llvm::DINode::FlagProtected;
1608 return llvm::DINode::FlagPublic;
1610 return llvm::DINode::FlagZero;
1612 llvm_unreachable(
"unexpected access enumerator");
1615llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1616 llvm::DIFile *Unit) {
1617 llvm::DIType *Underlying =
1629 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1631 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1636 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1637 getOrCreateFile(Loc), getLineNumber(Loc),
1638 getDeclContextDescriptor(Ty->
getDecl()), Align,
1639 Flags, Annotations);
1649 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1651 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1653 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1655 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1657 return llvm::dwarf::DW_CC_BORLAND_pascal;
1659 return llvm::dwarf::DW_CC_LLVM_Win64;
1661 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1665 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1667 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1669 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1671 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1673 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1675 return llvm::dwarf::DW_CC_LLVM_Swift;
1677 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1679 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1681 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1683 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1685 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1687 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1689 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1690#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1704 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1710 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1712 Flags |= llvm::DINode::FlagLValueReference;
1714 Flags |= llvm::DINode::FlagRValueReference;
1718llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1719 llvm::DIFile *Unit) {
1720 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1722 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1728 SmallVector<llvm::Metadata *, 16> EltTys;
1731 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1733 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1737 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1740 for (
const QualType &ParamType : FPT->param_types())
1741 EltTys.push_back(getOrCreateType(ParamType, Unit));
1742 if (FPT->isVariadic())
1743 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1746 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1747 llvm::DIType *F = DBuilder.createSubroutineType(
1752llvm::DIDerivedType *
1753CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1754 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1755 StringRef Name = BitFieldDecl->
getName();
1756 QualType Ty = BitFieldDecl->
getType();
1757 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1760 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1761 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1764 llvm::DIFile *
File = getOrCreateFile(Loc);
1765 unsigned Line = getLineNumber(Loc);
1767 const CGBitFieldInfo &BitFieldInfo =
1768 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1770 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1777 if (CGM.getDataLayout().isBigEndian())
1779 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1781 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1782 return DBuilder.createBitFieldMemberType(
1783 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1784 Flags, DebugType, Annotations);
1787llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1788 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1789 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1791 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1816 if (PreviousFieldsDI.empty())
1820 auto *PreviousMDEntry =
1821 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1822 auto *PreviousMDField =
1823 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1824 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1825 PreviousMDField->getSizeInBits() == 0)
1829 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1831 assert(PreviousBitfield->isBitField());
1833 if (!PreviousBitfield->isZeroLengthBitField())
1836 QualType Ty = PreviousBitfield->getType();
1837 SourceLocation Loc = PreviousBitfield->getLocation();
1838 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1839 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1840 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1842 llvm::DIFile *
File = getOrCreateFile(Loc);
1843 unsigned Line = getLineNumber(Loc);
1849 llvm::DINode::DIFlags Flags =
1851 llvm::DINodeArray Annotations =
1852 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1853 return DBuilder.createBitFieldMemberType(
1854 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1855 Flags, DebugType, Annotations);
1858llvm::DIType *CGDebugInfo::createFieldType(
1860 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1861 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1862 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1865 llvm::DIFile *file = getOrCreateFile(loc);
1866 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1869 auto Align = AlignInBits;
1870 if (!
type->isIncompleteArrayType()) {
1871 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1872 SizeInBits = TI.
Width;
1878 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1879 offsetInBits, flags, debugType, Annotations);
1883CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1884 llvm::DIFile *FileScope) {
1888 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1891 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1892 SP = DBuilder.createFunction(
1893 FileScope, FuncName, StringRef(),
1894 FileScope, 0, DIFnTy,
1896 llvm::DINode::FlagArtificial,
1897 llvm::DISubprogram::SPFlagDefinition,
1898 nullptr,
nullptr,
nullptr,
1899 nullptr, StringRef(),
1900 CGM.getCodeGenOpts().DebugKeyInstructions);
1906void CGDebugInfo::CollectRecordLambdaFields(
1907 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
1908 llvm::DIType *RecordTy) {
1912 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
1914 unsigned fieldno = 0;
1917 I != E; ++I, ++Field, ++fieldno) {
1918 const LambdaCapture &
C = *I;
1919 if (
C.capturesVariable()) {
1920 SourceLocation Loc =
C.getLocation();
1921 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1922 ValueDecl *
V =
C.getCapturedVar();
1923 StringRef VName =
V->getName();
1924 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1926 llvm::DIType *FieldType = createFieldType(
1927 VName,
Field->getType(), Loc,
Field->getAccess(),
1928 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1929 elements.push_back(FieldType);
1930 }
else if (
C.capturesThis()) {
1935 FieldDecl *f = *
Field;
1936 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1938 StringRef ThisName =
1939 CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
1940 llvm::DIType *fieldType = createFieldType(
1944 elements.push_back(fieldType);
1949llvm::DIDerivedType *
1950CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1951 const RecordDecl *RD) {
1955 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1956 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1958 unsigned LineNumber = getLineNumber(Var->
getLocation());
1959 StringRef VName = Var->
getName();
1963 llvm::Constant *
C =
nullptr;
1968 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
1969 if (
Value->isFloat())
1970 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
1975 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
1976 ? llvm::dwarf::DW_TAG_variable
1977 : llvm::dwarf::DW_TAG_member;
1979 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1980 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1985void CGDebugInfo::CollectRecordNormalField(
1986 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1987 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
1988 const RecordDecl *RD) {
1993 if (
name.empty() && !
type->isRecordType())
1996 llvm::DIType *FieldType;
1998 llvm::DIDerivedType *BitFieldType;
1999 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2000 if (llvm::DIType *Separator =
2001 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2002 elements.push_back(Separator);
2005 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2008 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2011 elements.push_back(FieldType);
2014void CGDebugInfo::CollectRecordNestedType(
2015 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2016 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2023 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2024 elements.push_back(nestedType);
2027void CGDebugInfo::CollectRecordFields(
2028 const RecordDecl *record, llvm::DIFile *tunit,
2029 SmallVectorImpl<llvm::Metadata *> &elements,
2030 llvm::DICompositeType *RecordTy) {
2031 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2033 if (CXXDecl && CXXDecl->
isLambda())
2034 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2036 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2039 unsigned fieldNo = 0;
2043 for (
const auto *I : record->
decls())
2044 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2045 if (
V->hasAttr<NoDebugAttr>())
2050 if (CGM.getCodeGenOpts().EmitCodeView &&
2058 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2059 if (MI != StaticDataMemberCache.end()) {
2060 assert(MI->second &&
2061 "Static data member declaration should still exist");
2062 elements.push_back(MI->second);
2064 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2065 elements.push_back(Field);
2067 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2068 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2069 elements, RecordTy, record);
2073 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2076 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2081 if (!nestedType->isImplicit() &&
2082 nestedType->getDeclContext() == record)
2083 CollectRecordNestedType(nestedType, elements);
2089llvm::DISubroutineType *
2090CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2091 llvm::DIFile *Unit) {
2092 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2094 return cast_or_null<llvm::DISubroutineType>(
2095 getOrCreateType(QualType(
Func, 0), Unit));
2098 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2099 ThisType =
Method->getThisType();
2101 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2104llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2105 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2106 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2108 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2111llvm::DISubroutineType *
2112CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2113 const FunctionProtoType *
Func,
2114 llvm::DIFile *Unit,
bool SkipFirst) {
2115 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2130 getOrCreateType(CGM.getContext().getFunctionType(
2131 Func->getReturnType(),
Func->getParamTypes(), EPI),
2133 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2134 assert(Args.size() &&
"Invalid number of arguments!");
2136 SmallVector<llvm::Metadata *, 16> Elts;
2139 Elts.push_back(Args[0]);
2141 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2145 if (!HasExplicitObjectParameter) {
2146 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2149 DBuilder.createObjectPointerType(ThisPtrType,
true);
2150 Elts.push_back(ThisPtrType);
2154 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2155 Elts.push_back(Args[i]);
2158 if (HasExplicitObjectParameter) {
2159 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2160 "Expected at least return type and object parameter.");
2161 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2164 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2166 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2173 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2181CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2184 const bool IsCtorOrDtor =
2187 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2194 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2197 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2200 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2203 return CGM.getMangledName(
Method);
2206llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2207 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2210 StringRef MethodName = getFunctionName(
Method);
2211 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2213 StringRef MethodLinkageName;
2220 MethodLinkageName = GetMethodLinkageName(
Method);
2223 llvm::DIFile *MethodDefUnit =
nullptr;
2224 unsigned MethodLine = 0;
2225 if (!
Method->isImplicit()) {
2226 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2227 MethodLine = getLineNumber(
Method->getLocation());
2231 llvm::DIType *ContainingType =
nullptr;
2232 unsigned VIndex = 0;
2233 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2234 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2235 int ThisAdjustment = 0;
2238 if (
Method->isPureVirtual())
2239 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2241 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2243 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2247 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2251 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2253 MethodVFTableLocation ML =
2254 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2262 if (
Method->size_overridden_methods() == 0)
2263 Flags |= llvm::DINode::FlagIntroducedVirtual;
2268 ThisAdjustment = CGM.getCXXABI()
2269 .getVirtualFunctionPrologueThisAdjustment(GD)
2272 ContainingType = RecordTy;
2275 if (
Method->getCanonicalDecl()->isDeleted())
2276 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2278 if (
Method->isNoReturn())
2279 Flags |= llvm::DINode::FlagNoReturn;
2282 Flags |= llvm::DINode::FlagStaticMember;
2283 if (
Method->isImplicit())
2284 Flags |= llvm::DINode::FlagArtificial;
2286 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2287 if (CXXC->isExplicit())
2288 Flags |= llvm::DINode::FlagExplicit;
2289 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2290 if (CXXC->isExplicit())
2291 Flags |= llvm::DINode::FlagExplicit;
2293 if (
Method->hasPrototype())
2294 Flags |= llvm::DINode::FlagPrototyped;
2296 Flags |= llvm::DINode::FlagLValueReference;
2298 Flags |= llvm::DINode::FlagRValueReference;
2299 if (!
Method->isExternallyVisible())
2300 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2301 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2302 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2306 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2307 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2310 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2311 llvm::DISubprogram *SP = DBuilder.createMethod(
2312 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2313 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2314 TParamsArray.get(),
nullptr,
2315 CGM.getCodeGenOpts().DebugKeyInstructions);
2317 SPCache[
Method->getCanonicalDecl()].reset(SP);
2322void CGDebugInfo::CollectCXXMemberFunctions(
2323 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2324 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2329 for (
const auto *I : RD->
decls()) {
2330 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2344 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2353 auto MI = SPCache.find(
Method->getCanonicalDecl());
2354 EltTys.push_back(MI == SPCache.end()
2355 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2356 :
static_cast<llvm::Metadata *
>(MI->second));
2360void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2361 SmallVectorImpl<llvm::Metadata *> &EltTys,
2362 llvm::DIType *RecordTy) {
2363 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2364 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2365 llvm::DINode::FlagZero);
2369 if (CGM.getCodeGenOpts().EmitCodeView) {
2370 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2371 llvm::DINode::FlagIndirectVirtualBase);
2375void CGDebugInfo::CollectCXXBasesAux(
2376 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2377 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2379 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2380 llvm::DINode::DIFlags StartingFlags) {
2381 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2382 for (
const auto &BI : Bases) {
2385 BI.getType()->castAsCanonical<RecordType>()->getOriginalDecl())
2387 if (!SeenTypes.insert(Base).second)
2389 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2390 llvm::DINode::DIFlags BFlags = StartingFlags;
2394 if (BI.isVirtual()) {
2395 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2398 BaseOffset = 0 - CGM.getItaniumVTableContext()
2399 .getVirtualBaseOffsetOffset(RD, Base)
2405 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2406 VBPtrOffset = CGM.getContext()
2407 .getASTRecordLayout(RD)
2411 BFlags |= llvm::DINode::FlagVirtual;
2418 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2419 VBPtrOffset, BFlags);
2420 EltTys.push_back(DTy);
2425CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2426 llvm::DIFile *Unit) {
2428 return llvm::DINodeArray();
2429 TemplateArgs &Args = *OArgs;
2430 SmallVector<llvm::Metadata *, 16> TemplateParams;
2431 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2432 const TemplateArgument &TA = Args.Args[i];
2436 Name = Args.TList->getParam(i)->getName();
2440 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2441 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2442 TheCU, Name, TTy, defaultParameter));
2447 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2448 TheCU, Name, TTy, defaultParameter,
2449 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2454 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2455 llvm::Constant *
V =
nullptr;
2458 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2459 !D->
hasAttr<CUDADeviceAttr>()) {
2462 if (
const auto *VD = dyn_cast<VarDecl>(D))
2463 V = CGM.GetAddrOfGlobalVar(VD);
2466 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2467 MD && MD->isImplicitObjectMemberFunction())
2468 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2469 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2470 V = CGM.GetAddrOfFunction(FD);
2473 else if (
const auto *MPT =
2474 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2478 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2480 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2481 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2482 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2483 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2484 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2486 V = ConstantEmitter(CGM).emitAbstract(
2487 SourceLocation(), TPO->getValue(), TPO->getType());
2489 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2491 assert(
V &&
"Failed to find template parameter pointer");
2492 V =
V->stripPointerCasts();
2494 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2495 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2499 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2500 llvm::Constant *
V =
nullptr;
2503 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2509 if (MPT->isMemberDataPointer())
2510 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2512 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2513 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2514 TheCU, Name, TTy, defaultParameter,
V));
2518 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2519 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2521 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2522 TheCU, Name, TTy, defaultParameter,
V));
2525 std::string QualName;
2526 llvm::raw_string_ostream
OS(QualName);
2528 OS, getPrintingPolicy());
2529 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2530 TheCU, Name,
nullptr, QualName, defaultParameter));
2534 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2535 TheCU, Name,
nullptr,
2542 T = CGM.getContext().getLValueReferenceType(
T);
2543 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2544 assert(
V &&
"Expression in template argument isn't constant");
2545 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2546 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2547 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2553 "These argument types shouldn't exist in concrete types");
2556 return DBuilder.getOrCreateArray(TemplateParams);
2559std::optional<CGDebugInfo::TemplateArgs>
2560CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2568 return std::nullopt;
2570std::optional<CGDebugInfo::TemplateArgs>
2571CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2575 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2577 return std::nullopt;
2578 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2579 const TemplateParameterList *TList =
T->getTemplateParameters();
2580 auto TA = TS->getTemplateArgs().asArray();
2581 return {{TList, TA}};
2583std::optional<CGDebugInfo::TemplateArgs>
2584CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2585 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2589 TemplateParameterList *TPList =
2590 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2591 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2592 return {{TPList, TAList.
asArray()}};
2594 return std::nullopt;
2598CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2599 llvm::DIFile *Unit) {
2600 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2603llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2604 llvm::DIFile *Unit) {
2605 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2608llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2609 llvm::DIFile *Unit) {
2610 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2613llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2614 if (!D->
hasAttr<BTFDeclTagAttr>())
2617 SmallVector<llvm::Metadata *, 4> Annotations;
2619 llvm::Metadata *Ops[2] = {
2620 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2621 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2622 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2624 return DBuilder.getOrCreateArray(Annotations);
2627llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2629 return VTablePtrType;
2631 ASTContext &Context = CGM.getContext();
2634 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2635 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2636 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2638 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2639 std::optional<unsigned> DWARFAddressSpace =
2640 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2642 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2643 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2644 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2645 return VTablePtrType;
2648StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2660 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2662 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2672 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2673 VTable->isDeclarationForLinker())
2677 StringRef SymbolName =
"_vtable$";
2679 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2688 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2690 llvm::DIFile *Unit = getOrCreateFile(Loc);
2691 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2693 llvm::DINode::FlagArtificial;
2694 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2695 ? llvm::dwarf::DW_TAG_variable
2696 : llvm::dwarf::DW_TAG_member;
2697 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2698 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2702 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2706 llvm::DIGlobalVariableExpression *GVE =
2707 DBuilder.createGlobalVariableExpression(
2708 TheCU, SymbolName, VTable->getName(), Unit, 0,
2709 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2710 true,
nullptr, DT,
nullptr,
2712 VTable->addDebugInfo(GVE);
2715StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2717 llvm::Function *InitFn) {
2722 return InitFn->getName();
2732 llvm::raw_svector_ostream OS(QualifiedGV);
2734 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2736 std::swap(Quals, GVName);
2740 llvm::raw_svector_ostream OS(InitName);
2742 OS << Quals <<
"::";
2747 llvm_unreachable(
"not an initializer");
2749 OS <<
"`dynamic initializer for '";
2752 OS <<
"`dynamic atexit destructor for '";
2759 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2760 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2761 getPrintingPolicy());
2766 return internString(
OS.str());
2769void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2770 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2779 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2786 llvm::DIType *VPtrTy =
nullptr;
2787 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2788 CGM.getTarget().getCXXABI().isMicrosoft();
2789 if (NeedVTableShape) {
2791 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2792 const VTableLayout &VFTLayout =
2793 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2794 unsigned VSlotCount =
2796 unsigned VTableWidth = PtrWidth * VSlotCount;
2797 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2798 std::optional<unsigned> DWARFAddressSpace =
2799 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2802 llvm::DIType *VTableType = DBuilder.createPointerType(
2803 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2804 EltTys.push_back(VTableType);
2807 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2815 VPtrTy = getOrCreateVTablePtrType(Unit);
2817 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2818 llvm::DIType *VPtrMember =
2819 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2820 llvm::DINode::FlagArtificial, VPtrTy);
2821 EltTys.push_back(VPtrMember);
2826 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2827 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2838 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2839 assert(!D.
isNull() &&
"null type");
2840 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2841 assert(
T &&
"could not create debug info for type");
2850 if (CGM.getCodeGenOpts().getDebugInfo() <=
2851 llvm::codegenoptions::DebugLineTablesOnly)
2855 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2857 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2859 CI->setMetadata(
"heapallocsite", node);
2863 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2865 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2867 auto I = TypeCache.find(TyPtr);
2870 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2871 assert(!Res->isForwardDecl());
2872 TypeCache[TyPtr].reset(Res);
2876 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2877 !CGM.getLangOpts().CPlusPlus)
2883 if (RD->
hasAttr<DLLImportAttr>())
2886 if (MD->hasAttr<DLLImportAttr>())
2899 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2909 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2910 Explicit = TD->isExplicitInstantiationOrSpecialization();
2914 if (CXXDecl->
fields().empty())
2924 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2925 if (CXXRD->isDynamicClass() &&
2926 CGM.getVTableLinkage(CXXRD) ==
2927 llvm::GlobalValue::AvailableExternallyLinkage &&
2938 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2940 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
2942 auto I = TypeCache.find(TyPtr);
2949 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
2950 assert(!Res->isForwardDecl());
2951 TypeCache[TyPtr].reset(Res);
2958 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2959 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2982 if (Ctor->isCopyOrMoveConstructor())
2984 if (!Ctor->isDeleted())
3003 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3006 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3007 RD->
hasAttr<StandaloneDebugAttr>())
3010 if (!LangOpts.CPlusPlus)
3016 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3032 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3033 Spec = SD->getSpecializationKind();
3042 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3053 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3054 llvm::DIType *
T = getTypeOrNull(Ty);
3055 if (
T &&
T->isForwardDecl())
3059llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3060 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3061 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3065 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3069 auto [Def, Pref] = CreateTypeDefinition(Ty);
3071 return Pref ? Pref : Def;
3074llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3075 llvm::DIFile *Unit) {
3079 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3083 return getOrCreateType(PNA->getTypedefType(), Unit);
3086std::pair<llvm::DIType *, llvm::DIType *>
3087CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3088 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3091 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3099 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3103 return {FwdDecl,
nullptr};
3105 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3106 CollectContainingType(CXXDecl, FwdDecl);
3109 LexicalBlockStack.emplace_back(&*FwdDecl);
3110 RegionMap[RD].reset(FwdDecl);
3113 SmallVector<llvm::Metadata *, 16> EltTys;
3120 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3122 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3123 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3127 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3128 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3129 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3131 LexicalBlockStack.pop_back();
3132 RegionMap.erase(RD);
3134 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3135 DBuilder.replaceArrays(FwdDecl, Elements);
3137 if (FwdDecl->isTemporary())
3139 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3141 RegionMap[RD].reset(FwdDecl);
3143 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3144 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3145 return {FwdDecl, PrefDI};
3147 return {FwdDecl,
nullptr};
3150llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3151 llvm::DIFile *Unit) {
3153 return getOrCreateType(Ty->getBaseType(), Unit);
3156llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3157 llvm::DIFile *Unit) {
3159 SourceLocation Loc = Ty->getDecl()->getLocation();
3162 return DBuilder.createTypedef(
3163 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3164 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3165 getDeclContextDescriptor(Ty->getDecl()));
3192llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3193 llvm::DIFile *Unit) {
3199 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
3204 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3205 !
ID->getImplementation())
3206 return DBuilder.createForwardDecl(
3207 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3208 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3211 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3212 unsigned Line = getLineNumber(
ID->getLocation());
3216 ObjCInterfaceDecl *Def =
ID->getDefinition();
3218 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3219 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3220 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3221 DefUnit,
Line, RuntimeLang);
3222 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3226 return CreateTypeDefinition(Ty, Unit);
3229llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3230 bool CreateSkeletonCU) {
3235 auto ModRef = ModuleCache.find(M);
3236 if (ModRef != ModuleCache.end())
3240 SmallString<128> ConfigMacros;
3242 llvm::raw_svector_ostream
OS(ConfigMacros);
3243 const auto &PPOpts = CGM.getPreprocessorOpts();
3246 for (
auto &M : PPOpts.Macros) {
3249 const std::string &
Macro = M.first;
3250 bool Undef = M.second;
3251 OS <<
"\"-" << (Undef ?
'U' :
'D');
3267 bool IsRootModule = M ? !M->
Parent :
true;
3271 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3272 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3273 "clang module without ASTFile must be specified by -fmodule-name");
3276 auto RemapPath = [
this](StringRef Path) -> std::string {
3278 StringRef Relative(Remapped);
3279 StringRef CompDir = TheCU->getDirectory();
3280 if (CompDir.empty())
3283 if (Relative.consume_front(CompDir))
3284 Relative.consume_front(llvm::sys::path::get_separator());
3286 return Relative.str();
3289 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3296 Signature = ModSig.truncatedValue();
3300 llvm::DIBuilder DIB(CGM.getModule());
3302 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3303 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3304 PCM = getCurrentDirname();
3308 llvm::sys::path::append(PCM, Mod.
getASTFile());
3309 DIB.createCompileUnit(
3310 TheCU->getSourceLanguage(),
3313 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3314 llvm::DICompileUnit::FullDebug, Signature);
3318 llvm::DIModule *Parent =
3320 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3322 std::string IncludePath = Mod.
getPath().str();
3323 llvm::DIModule *DIMod =
3324 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3325 RemapPath(IncludePath));
3326 ModuleCache[M].reset(DIMod);
3330llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3331 llvm::DIFile *Unit) {
3333 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3334 unsigned Line = getLineNumber(
ID->getLocation());
3335 unsigned RuntimeLang = TheCU->getSourceLanguage();
3341 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3342 if (
ID->getImplementation())
3343 Flags |= llvm::DINode::FlagObjcClassComplete;
3345 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3346 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3347 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3348 nullptr, llvm::DINodeArray(), RuntimeLang);
3350 QualType QTy(Ty, 0);
3351 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3354 LexicalBlockStack.emplace_back(RealDecl);
3355 RegionMap[Ty->
getDecl()].reset(RealDecl);
3358 SmallVector<llvm::Metadata *, 16> EltTys;
3360 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3362 llvm::DIType *SClassTy =
3363 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3367 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3368 llvm::DINode::FlagZero);
3369 EltTys.push_back(InhTag);
3373 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3374 SourceLocation Loc = PD->getLocation();
3375 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3376 unsigned PLine = getLineNumber(Loc);
3377 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3378 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3379 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3380 PD->getName(), PUnit, PLine,
3382 : getSelectorName(PD->getGetterName()),
3384 : getSelectorName(PD->getSetterName()),
3385 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3386 EltTys.push_back(PropertyNode);
3391 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3395 llvm::DenseSet<IsClassAndIdent> PropertySet;
3397 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3398 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3400 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3401 for (
auto *PD : ClassExt->properties()) {
3402 PropertySet.insert(GetIsClassAndIdent(PD));
3405 for (
const auto *PD :
ID->properties()) {
3408 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3414 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3415 unsigned FieldNo = 0;
3416 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3417 Field =
Field->getNextIvar(), ++FieldNo) {
3418 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3422 StringRef FieldName =
Field->getName();
3425 if (FieldName.empty())
3429 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3430 unsigned FieldLine = getLineNumber(
Field->getLocation());
3431 QualType FType =
Field->getType();
3438 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3439 : CGM.getContext().getTypeSize(FType);
3444 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3448 if (
Field->isBitField()) {
3450 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3451 FieldOffset %= CGM.getContext().getCharWidth();
3459 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3461 Flags = llvm::DINode::FlagProtected;
3463 Flags = llvm::DINode::FlagPrivate;
3465 Flags = llvm::DINode::FlagPublic;
3467 if (
Field->isBitField())
3468 Flags |= llvm::DINode::FlagBitField;
3470 llvm::MDNode *PropertyNode =
nullptr;
3471 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3472 if (ObjCPropertyImplDecl *PImpD =
3473 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3474 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3475 SourceLocation Loc = PD->getLocation();
3476 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3477 unsigned PLine = getLineNumber(Loc);
3478 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3479 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3480 PropertyNode = DBuilder.createObjCProperty(
3481 PD->getName(), PUnit, PLine,
3484 : getSelectorName(PD->getGetterName()),
3487 : getSelectorName(PD->getSetterName()),
3488 PD->getPropertyAttributes(),
3489 getOrCreateType(PD->getType(), PUnit));
3493 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3494 FieldSize, FieldAlign, FieldOffset, Flags,
3495 FieldTy, PropertyNode);
3496 EltTys.push_back(FieldTy);
3499 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3500 DBuilder.replaceArrays(RealDecl, Elements);
3502 LexicalBlockStack.pop_back();
3506llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3507 llvm::DIFile *Unit) {
3515 auto &Ctx = CGM.getContext();
3520 QualType CharVecTy =
3522 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3525 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3528 llvm::Metadata *Subscript;
3529 QualType QTy(Ty, 0);
3530 auto SizeExpr = SizeExprCache.find(QTy);
3531 if (SizeExpr != SizeExprCache.end())
3532 Subscript = DBuilder.getOrCreateSubrange(
3533 SizeExpr->getSecond() ,
nullptr ,
3534 nullptr ,
nullptr );
3537 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3538 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3539 Subscript = DBuilder.getOrCreateSubrange(
3540 CountNode ,
nullptr ,
nullptr ,
3543 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3548 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3551llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3552 llvm::DIFile *Unit) {
3556 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3561 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3562 auto *ColumnCountNode =
3563 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3564 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3565 auto *RowCountNode =
3566 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3567 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3568 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3569 ColumnCountNode ,
nullptr ,
nullptr ,
3571 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3572 RowCountNode ,
nullptr ,
nullptr ,
3574 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3575 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3578llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3583 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3598 Size = CGM.getContext().getTypeSize(Ty);
3605 SmallVector<llvm::Metadata *, 8> Subscripts;
3606 QualType EltTy(Ty, 0);
3607 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3616 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3617 Count = CAT->getZExtSize();
3618 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3619 if (Expr *Size = VAT->getSizeExpr()) {
3621 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3622 Count =
Result.Val.getInt().getExtValue();
3626 auto SizeNode = SizeExprCache.find(EltTy);
3627 if (SizeNode != SizeExprCache.end())
3628 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3629 SizeNode->getSecond() ,
nullptr ,
3630 nullptr ,
nullptr ));
3633 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3634 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3635 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3636 CountNode ,
nullptr ,
nullptr ,
3642 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3644 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3648llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3649 llvm::DIFile *Unit) {
3650 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3654llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3655 llvm::DIFile *Unit) {
3656 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3658 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3659 CGM.getCodeGenOpts().DwarfVersion < 4)
3660 Tag = llvm::dwarf::DW_TAG_reference_type;
3662 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3665llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3667 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3671 Size = CGM.getContext().getTypeSize(Ty);
3674 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3677 Flags |= llvm::DINode::FlagSingleInheritance;
3680 Flags |= llvm::DINode::FlagMultipleInheritance;
3683 Flags |= llvm::DINode::FlagVirtualInheritance;
3693 llvm::DIType *ClassType = getOrCreateType(
T, U);
3695 return DBuilder.createMemberPointerType(
3699 const FunctionProtoType *FPT =
3701 return DBuilder.createMemberPointerType(
3702 getOrCreateInstanceMethodType(
3705 ClassType, Size, 0, Flags);
3708llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3710 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3713llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3717llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3719 return getOrCreateType(Ty->getWrappedType(), U);
3722llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3729 const EnumType *Ty) {
3741llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3744 bool isImportedFromModule =
3745 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3749 if (isImportedFromModule || !ED->getDefinition()) {
3756 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3757 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3758 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3759 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3761 unsigned Line = getLineNumber(ED->getLocation());
3762 StringRef EDName = ED->getName();
3763 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3764 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3765 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3767 ReplaceMap.emplace_back(
3768 std::piecewise_construct, std::make_tuple(Ty),
3769 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3773 return CreateTypeDefinition(Ty);
3776llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3779 SmallVector<llvm::Metadata *, 16> Enumerators;
3780 ED = ED->getDefinition();
3781 assert(ED &&
"An enumeration definition is required");
3782 for (
const auto *
Enum : ED->enumerators()) {
3783 Enumerators.push_back(
3784 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3787 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3788 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3789 EnumKind = Attr->getExtensibility();
3792 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3794 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3795 unsigned Line = getLineNumber(ED->getLocation());
3796 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3797 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3798 return DBuilder.createEnumerationType(
3799 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3800 0, Identifier, ED->isScoped(), EnumKind);
3805 StringRef Name, StringRef
Value) {
3806 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3807 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3813 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3814 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3815 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3819 StringRef FuncName) {
3820 llvm::DISubprogram *SP =
3821 createInlinedSubprogram(FuncName, Location->getFile());
3822 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3827 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3833 FuncName += Category;
3835 FuncName += FailureMsg;
3847 Quals += InnerQuals;
3849 switch (
T->getTypeClass()) {
3851 return C.getQualifiedType(
T.getTypePtr(), Quals);
3854 case Type::InjectedClassName:
3855 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3857 case Type::TemplateSpecialization: {
3859 if (Spec->isTypeAlias())
3860 return C.getQualifiedType(
T.getTypePtr(), Quals);
3861 T = Spec->desugar();
3864 case Type::TypeOfExpr:
3870 case Type::Decltype:
3873 case Type::UnaryTransform:
3876 case Type::Attributed:
3879 case Type::BTFTagAttributed:
3882 case Type::CountAttributed:
3891 case Type::MacroQualified:
3894 case Type::SubstTemplateTypeParm:
3898 case Type::DeducedTemplateSpecialization: {
3900 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3904 case Type::PackIndexing: {
3908 case Type::Adjusted:
3915 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3920llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
3923 if (It != TypeCache.end()) {
3925 if (llvm::Metadata *
V = It->second)
3938 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3945 RetainedTypes.push_back(
3946 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
3949llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3953 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3955 llvm::raw_string_ostream OS(Name);
3956 Ty.
print(OS, getPrintingPolicy());
3963 if (
auto *
T = getTypeOrNull(Ty))
3966 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3967 void *TyPtr = Ty.getAsOpaquePtr();
3970 TypeCache[TyPtr].reset(Res);
3975llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3983 auto Info = Reader->getSourceDescriptor(Idx);
3985 return getOrCreateModuleRef(*Info,
true);
3986 }
else if (ClangModuleMap) {
3999 auto Info = ASTSourceDescriptor(*M);
4000 return getOrCreateModuleRef(Info,
false);
4003 return getOrCreateModuleRef(PCHDescriptor,
false);
4010llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4013 return CreateQualifiedType(Ty, Unit);
4017#define TYPE(Class, Base)
4018#define ABSTRACT_TYPE(Class, Base)
4019#define NON_CANONICAL_TYPE(Class, Base)
4020#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4021#include "clang/AST/TypeNodes.inc"
4022 llvm_unreachable(
"Dependent types cannot show up in debug information");
4024 case Type::ExtVector:
4027 case Type::ConstantMatrix:
4029 case Type::ObjCObjectPointer:
4031 case Type::ObjCObject:
4033 case Type::ObjCTypeParam:
4035 case Type::ObjCInterface:
4043 case Type::BlockPointer:
4051 case Type::FunctionProto:
4052 case Type::FunctionNoProto:
4054 case Type::ConstantArray:
4055 case Type::VariableArray:
4056 case Type::IncompleteArray:
4057 case Type::ArrayParameter:
4060 case Type::LValueReference:
4062 case Type::RValueReference:
4065 case Type::MemberPointer:
4076 case Type::TemplateSpecialization:
4078 case Type::HLSLAttributedResource:
4080 case Type::HLSLInlineSpirv:
4082 case Type::PredefinedSugar:
4084 case Type::CountAttributed:
4086 case Type::Attributed:
4087 case Type::BTFTagAttributed:
4088 case Type::Adjusted:
4090 case Type::DeducedTemplateSpecialization:
4093 case Type::MacroQualified:
4094 case Type::SubstTemplateTypeParm:
4095 case Type::TypeOfExpr:
4097 case Type::Decltype:
4098 case Type::PackIndexing:
4099 case Type::UnaryTransform:
4103 llvm_unreachable(
"type should have been unwrapped!");
4106llvm::DICompositeType *
4107CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4108 QualType QTy(Ty, 0);
4110 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4115 if (
T && !
T->isForwardDecl())
4119 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4124 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4127 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4132llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4133 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
4136 StringRef RDName = getClassName(RD);
4138 llvm::DIFile *DefUnit =
nullptr;
4141 DefUnit = getOrCreateFile(Loc);
4142 Line = getLineNumber(Loc);
4145 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4149 auto *
T = cast_or_null<llvm::DICompositeType>(
4150 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4158 return getOrCreateRecordFwdDecl(Ty, RDContext);
4171 auto Flags = llvm::DINode::FlagZero;
4172 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4174 Flags |= llvm::DINode::FlagTypePassByReference;
4176 Flags |= llvm::DINode::FlagTypePassByValue;
4179 if (!CXXRD->isTrivial())
4180 Flags |= llvm::DINode::FlagNonTrivial;
4183 if (CXXRD->isAnonymousStructOrUnion())
4184 Flags |= llvm::DINode::FlagExportSymbols;
4187 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4190 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4191 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4193 Flags, Identifier, Annotations);
4197 switch (RealDecl->getTag()) {
4199 llvm_unreachable(
"invalid composite type tag");
4201 case llvm::dwarf::DW_TAG_array_type:
4202 case llvm::dwarf::DW_TAG_enumeration_type:
4207 if (Identifier.empty())
4211 case llvm::dwarf::DW_TAG_structure_type:
4212 case llvm::dwarf::DW_TAG_union_type:
4213 case llvm::dwarf::DW_TAG_class_type:
4216 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4221 dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
4222 CXXRecordDecl *TemplateDecl =
4223 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4224 RegionMap[TemplateDecl].reset(RealDecl);
4226 RegionMap[RD].reset(RealDecl);
4228 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4230 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4231 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4232 CollectCXXTemplateParams(TSpecial, DefUnit));
4236void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4237 llvm::DICompositeType *RealDecl) {
4239 llvm::DIType *ContainingType =
nullptr;
4240 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4244 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4251 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4252 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4254 ContainingType = RealDecl;
4256 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4259llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4260 StringRef Name, uint64_t *Offset) {
4261 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4262 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4265 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4266 *Offset, llvm::DINode::FlagZero, FieldTy);
4267 *Offset += FieldSize;
4271void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4273 StringRef &LinkageName,
4274 llvm::DIScope *&FDContext,
4275 llvm::DINodeArray &TParamsArray,
4276 llvm::DINode::DIFlags &Flags) {
4278 Name = getFunctionName(FD);
4281 LinkageName = CGM.getMangledName(GD);
4283 Flags |= llvm::DINode::FlagPrototyped;
4287 if (LinkageName == Name ||
4288 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4289 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4290 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4291 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4292 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4293 LinkageName = StringRef();
4297 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4298 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4299 CGM.getCodeGenOpts().EmitCodeView)) {
4300 if (
const NamespaceDecl *NSDecl =
4302 FDContext = getOrCreateNamespace(NSDecl);
4303 else if (
const RecordDecl *RDecl =
4305 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4306 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4309 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4312 Flags |= llvm::DINode::FlagNoReturn;
4314 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4318void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4319 unsigned &LineNo, QualType &
T,
4320 StringRef &Name, StringRef &LinkageName,
4321 llvm::MDTuple *&TemplateParameters,
4322 llvm::DIScope *&VDContext) {
4331 llvm::APInt ConstVal(32, 1);
4332 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4334 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4341 LinkageName = CGM.getMangledName(VD);
4342 if (LinkageName == Name)
4343 LinkageName = StringRef();
4346 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4347 TemplateParameters = parameterNodes.get();
4349 TemplateParameters =
nullptr;
4367 DC = CGM.getContext().getTranslationUnitDecl();
4369 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4370 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4373llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4375 llvm::DINodeArray TParamsArray;
4376 StringRef Name, LinkageName;
4377 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4378 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4380 llvm::DIFile *Unit = getOrCreateFile(Loc);
4381 llvm::DIScope *DContext = Unit;
4382 unsigned Line = getLineNumber(Loc);
4383 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4388 SmallVector<QualType, 16> ArgTypes;
4389 for (
const ParmVarDecl *Parm : FD->
parameters())
4390 ArgTypes.push_back(Parm->getType());
4393 QualType FnType = CGM.getContext().getFunctionType(
4394 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4396 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4397 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4398 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4401 Flags |= getCallSiteRelatedAttrs();
4402 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4403 return DBuilder.createFunction(
4404 DContext, Name, LinkageName, Unit,
Line,
4405 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4406 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4408 CGM.getCodeGenOpts().DebugKeyInstructions);
4411 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4412 DContext, Name, LinkageName, Unit,
Line,
4413 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4414 TParamsArray.get(), getFunctionDeclaration(FD));
4416 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4417 std::make_tuple(CanonDecl),
4418 std::make_tuple(SP));
4422llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4423 return getFunctionFwdDeclOrStub(GD,
false);
4426llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4427 return getFunctionFwdDeclOrStub(GD,
true);
4430llvm::DIGlobalVariable *
4431CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4433 StringRef Name, LinkageName;
4435 llvm::DIFile *Unit = getOrCreateFile(Loc);
4436 llvm::DIScope *DContext = Unit;
4437 unsigned Line = getLineNumber(Loc);
4438 llvm::MDTuple *TemplateParameters =
nullptr;
4440 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4443 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4444 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4446 FwdDeclReplaceMap.emplace_back(
4447 std::piecewise_construct,
4449 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4453llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4458 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4459 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4460 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4464 if (I != DeclCache.end()) {
4466 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4467 return GVE->getVariable();
4475 if (IE != ImportedDeclCache.end()) {
4476 auto N = IE->second;
4477 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4479 return dyn_cast_or_null<llvm::DINode>(N);
4484 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4485 return getFunctionForwardDeclaration(FD);
4486 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4487 return getGlobalVariableForwardDeclaration(VD);
4492llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4493 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4496 const auto *FD = dyn_cast<FunctionDecl>(D);
4501 auto *S = getDeclContextDescriptor(D);
4504 if (MI == SPCache.end()) {
4506 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4510 if (MI != SPCache.end()) {
4511 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4512 if (SP && !SP->isDefinition())
4516 for (
auto *NextFD : FD->
redecls()) {
4517 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4518 if (MI != SPCache.end()) {
4519 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4520 if (SP && !SP->isDefinition())
4527llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4528 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4529 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4530 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4533 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4537 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4541 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4550 QualType QTy(
ID->getTypeForDecl(), 0);
4551 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4552 if (It == TypeCache.end())
4555 llvm::DISubprogram *FD = DBuilder.createFunction(
4556 InterfaceType, getObjCMethodName(OMD), StringRef(),
4557 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4558 DBuilder.finalizeSubprogram(FD);
4565llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4570 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4571 !CGM.getCodeGenOpts().EmitCodeView))
4574 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4576 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4579 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4582 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4583 return getOrCreateMethodType(
Method, F);
4585 const auto *FTy = FnType->
getAs<FunctionType>();
4588 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4590 SmallVector<llvm::Metadata *, 16> Elts;
4593 QualType ResultTy = OMethod->getReturnType();
4596 if (ResultTy == CGM.getContext().getObjCInstanceType())
4597 ResultTy = CGM.getContext().getPointerType(
4598 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4600 Elts.push_back(getOrCreateType(ResultTy, F));
4602 QualType SelfDeclTy;
4603 if (
auto *SelfDecl = OMethod->getSelfDecl())
4604 SelfDeclTy = SelfDecl->getType();
4605 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4608 if (!SelfDeclTy.
isNull())
4610 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4612 Elts.push_back(DBuilder.createArtificialType(
4613 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4615 for (
const auto *PI : OMethod->parameters())
4616 Elts.push_back(getOrCreateType(PI->getType(), F));
4618 if (OMethod->isVariadic())
4619 Elts.push_back(DBuilder.createUnspecifiedParameter());
4621 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4622 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4628 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4629 if (FD->isVariadic()) {
4630 SmallVector<llvm::Metadata *, 16> EltTys;
4631 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4632 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4634 EltTys.push_back(getOrCreateType(ParamType, F));
4635 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4636 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4637 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4650 CC = SrcFnTy->getCallConv();
4652 for (
const VarDecl *VD : Args)
4653 ArgTypes.push_back(VD->
getType());
4654 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4660 llvm::Function *Fn,
bool CurFuncIsThunk) {
4662 StringRef LinkageName;
4664 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4667 bool HasDecl = (D !=
nullptr);
4669 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4670 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4671 llvm::DIFile *Unit = getOrCreateFile(Loc);
4672 llvm::DIScope *FDContext = Unit;
4673 llvm::DINodeArray TParamsArray;
4674 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4677 LinkageName = Fn->getName();
4678 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4680 auto FI = SPCache.find(FD->getCanonicalDecl());
4681 if (FI != SPCache.end()) {
4682 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4683 if (SP && SP->isDefinition()) {
4684 LexicalBlockStack.emplace_back(SP);
4685 RegionMap[D].reset(SP);
4689 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4690 TParamsArray, Flags);
4693 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4694 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4695 Name = getObjCMethodName(OMD);
4696 Flags |= llvm::DINode::FlagPrototyped;
4703 Name = Fn->getName();
4708 Flags |= llvm::DINode::FlagPrototyped;
4710 Name.consume_front(
"\01");
4714 "Unexpected DynamicInitKind !");
4718 Flags |= llvm::DINode::FlagArtificial;
4724 Flags |= llvm::DINode::FlagThunk;
4726 if (Fn->hasLocalLinkage())
4727 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4728 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4729 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4731 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4732 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4733 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4735 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4736 unsigned ScopeLine = getLineNumber(ScopeLoc);
4737 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4738 llvm::DISubprogram *
Decl =
nullptr;
4739 llvm::DINodeArray Annotations =
nullptr;
4742 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4743 : getFunctionDeclaration(D);
4744 Annotations = CollectBTFDeclTagAnnotations(D);
4752 llvm::DISubprogram *SP = DBuilder.createFunction(
4753 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4754 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4755 Annotations,
"", KeyInstructions);
4756 Fn->setSubprogram(SP);
4765 LexicalBlockStack.emplace_back(SP);
4768 RegionMap[D].reset(SP);
4772 QualType FnType, llvm::Function *Fn) {
4774 StringRef LinkageName;
4780 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4781 return GetName(D,
true);
4784 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4785 llvm::DIFile *Unit = getOrCreateFile(Loc);
4786 bool IsDeclForCallSite = Fn ?
true :
false;
4787 llvm::DIScope *FDContext =
4788 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4789 llvm::DINodeArray TParamsArray;
4792 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4793 TParamsArray, Flags);
4794 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4795 Name = getObjCMethodName(OMD);
4796 Flags |= llvm::DINode::FlagPrototyped;
4798 llvm_unreachable(
"not a function or ObjC method");
4800 Name.consume_front(
"\01");
4803 Flags |= llvm::DINode::FlagArtificial;
4808 unsigned LineNo = getLineNumber(Loc);
4809 unsigned ScopeLine = 0;
4810 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4811 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4812 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4814 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4815 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4817 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4818 llvm::DISubprogram *SP = DBuilder.createFunction(
4819 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4820 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4826 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4827 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4828 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4831 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4832 DBuilder.createParameterVariable(
4833 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4834 llvm::DINode::FlagZero, ParamAnnotations);
4840 if (IsDeclForCallSite)
4841 Fn->setSubprogram(SP);
4849 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4852 if (
Func->getSubprogram())
4857 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4858 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4871 auto FI = SPCache.find(FD->getCanonicalDecl());
4872 llvm::DISubprogram *SP =
nullptr;
4873 if (FI != SPCache.end())
4874 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4875 if (!SP || !SP->isDefinition())
4876 SP = getFunctionStub(GD);
4877 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4878 LexicalBlockStack.emplace_back(SP);
4884 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4893 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4896 llvm::MDNode *
Scope = LexicalBlockStack.back();
4897 Builder.SetCurrentDebugLocation(
4898 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
4899 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4903 llvm::MDNode *Back =
nullptr;
4904 if (!LexicalBlockStack.empty())
4905 Back = LexicalBlockStack.back().get();
4906 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4908 getColumnNumber(CurLoc)));
4911void CGDebugInfo::AppendAddressSpaceXDeref(
4913 std::optional<unsigned> DWARFAddressSpace =
4915 if (!DWARFAddressSpace)
4918 Expr.push_back(llvm::dwarf::DW_OP_constu);
4919 Expr.push_back(*DWARFAddressSpace);
4920 Expr.push_back(llvm::dwarf::DW_OP_swap);
4921 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4930 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4931 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
4932 LexicalBlockStack.back(), CurInlinedAt));
4934 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4938 CreateLexicalBlock(Loc);
4943 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4948 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4951 LexicalBlockStack.pop_back();
4955 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4956 unsigned RCount = FnBeginRegionCount.back();
4957 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4960 while (LexicalBlockStack.size() != RCount) {
4963 LexicalBlockStack.pop_back();
4965 FnBeginRegionCount.pop_back();
4967 if (Fn && Fn->getSubprogram())
4968 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4971CGDebugInfo::BlockByRefType
4972CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4973 uint64_t *XOffset) {
4976 uint64_t FieldSize, FieldOffset;
4977 uint32_t FieldAlign;
4979 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4984 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4985 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4987 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4988 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4991 if (HasCopyAndDispose) {
4994 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4996 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4998 bool HasByrefExtendedLayout;
5001 HasByrefExtendedLayout) &&
5002 HasByrefExtendedLayout) {
5005 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5014 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5017 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5020 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5025 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5026 FieldSize = CGM.getContext().getTypeSize(FType);
5027 FieldAlign = CGM.getContext().toBits(Align);
5029 *XOffset = FieldOffset;
5030 llvm::DIType *FieldTy = DBuilder.createMemberType(
5031 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5032 llvm::DINode::FlagZero, WrappedTy);
5033 EltTys.push_back(FieldTy);
5034 FieldOffset += FieldSize;
5036 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5037 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5038 llvm::DINode::FlagZero,
nullptr, Elements),
5042llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5043 llvm::Value *Storage,
5044 std::optional<unsigned> ArgNo,
5046 const bool UsePointerValue) {
5047 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5048 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5049 if (VD->
hasAttr<NoDebugAttr>())
5054 llvm::DIFile *Unit =
nullptr;
5055 if (!VarIsArtificial)
5059 if (VD->
hasAttr<BlocksAttr>())
5060 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5062 Ty = getOrCreateType(VD->
getType(), Unit);
5072 if (!VarIsArtificial) {
5076 SmallVector<uint64_t, 13> Expr;
5077 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5078 if (VarIsArtificial)
5079 Flags |= llvm::DINode::FlagArtificial;
5083 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5084 AppendAddressSpaceXDeref(AddressSpace, Expr);
5088 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5091 Flags |= llvm::DINode::FlagObjectPointer;
5092 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5093 if (PVD->isExplicitObjectParameter())
5094 Flags |= llvm::DINode::FlagObjectPointer;
5102 StringRef Name = VD->
getName();
5103 if (!Name.empty()) {
5109 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5111 offset = CGM.getContext().toCharUnitsFromBits(
5114 Expr.push_back(llvm::dwarf::DW_OP_deref);
5115 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5117 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5120 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5132 for (
const auto *Field : RD->
fields()) {
5133 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5134 StringRef FieldName =
Field->getName();
5142 auto *D = DBuilder.createAutoVariable(
5143 Scope, FieldName, Unit,
Line, FieldTy,
5144 CGM.getCodeGenOpts().OptimizationLevel != 0,
5145 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5148 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5149 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5152 Builder.GetInsertBlock());
5160 if (UsePointerValue) {
5161 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5162 "Debug info already contains DW_OP_deref.");
5163 Expr.push_back(llvm::dwarf::DW_OP_deref);
5167 llvm::DILocalVariable *D =
nullptr;
5169 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5170 D = DBuilder.createParameterVariable(
5171 Scope, Name, *ArgNo, Unit,
Line, Ty,
5172 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5181 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5187 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5188 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5189 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5190 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5192 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5198 if (Iter != CoroutineParameterMappings.end()) {
5199 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5200 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5201 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5203 if (Iter2 != ParamDbgMappings.end())
5204 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5210 D = RemapCoroArgToLocalVar();
5213 D = DBuilder.createAutoVariable(
5214 Scope, Name, Unit,
Line, Ty,
5215 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5218 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5219 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5220 Column, Scope, CurInlinedAt),
5221 Builder.GetInsertBlock());
5226llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5227 llvm::Value *Storage,
5228 std::optional<unsigned> ArgNo,
5230 const bool UsePointerValue) {
5231 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5232 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5233 if (BD->
hasAttr<NoDebugAttr>())
5240 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5241 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5249 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5251 SmallVector<uint64_t, 3> Expr;
5252 AppendAddressSpaceXDeref(AddressSpace, Expr);
5257 if (UsePointerValue) {
5258 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5259 "Debug info already contains DW_OP_deref.");
5260 Expr.push_back(llvm::dwarf::DW_OP_deref);
5265 StringRef Name = BD->
getName();
5268 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5269 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5270 llvm::DINode::FlagZero, Align);
5272 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5273 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5274 const unsigned fieldIndex = FD->getFieldIndex();
5275 const clang::CXXRecordDecl *parent =
5276 (
const CXXRecordDecl *)FD->getParent();
5277 const ASTRecordLayout &layout =
5278 CGM.getContext().getASTRecordLayout(parent);
5280 if (FD->isBitField()) {
5281 const CGRecordLayout &RL =
5282 CGM.getTypes().getCGRecordLayout(FD->getParent());
5287 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5293 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5294 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5295 Expr.push_back(Info.
Offset);
5298 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5299 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5300 }
else if (fieldOffset != 0) {
5301 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5302 "Unexpected non-bitfield with non-byte-aligned offset");
5303 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5305 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5308 }
else if (
const ArraySubscriptExpr *ASE =
5309 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5310 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5311 const uint64_t value = IL->getValue().getZExtValue();
5312 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5315 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5316 Expr.push_back(CGM.getContext()
5317 .toCharUnitsFromBits(value * typeSize)
5324 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5325 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5326 Column, Scope, CurInlinedAt),
5327 Builder.GetInsertBlock());
5332llvm::DILocalVariable *
5335 const bool UsePointerValue) {
5336 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5338 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5340 EmitDeclare(B, Storage, std::nullopt, Builder,
5347 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5351 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5352 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5354 if (D->
hasAttr<NoDebugAttr>())
5358 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5364 StringRef Name = D->
getName();
5370 CGM.getCodeGenOpts().OptimizationLevel != 0);
5373 DBuilder.insertLabel(L,
5374 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5375 Scope, CurInlinedAt),
5376 Builder.GetInsertBlock()->end());
5379llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5381 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5384 return DBuilder.createObjectPointerType(Ty,
true);
5389 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5390 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5391 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5393 if (Builder.GetInsertBlock() ==
nullptr)
5395 if (VD->
hasAttr<NoDebugAttr>())
5398 bool isByRef = VD->
hasAttr<BlocksAttr>();
5400 uint64_t XOffset = 0;
5401 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5404 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5406 Ty = getOrCreateType(VD->
getType(), Unit);
5410 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5412 Ty = CreateSelfType(VD->
getType(), Ty);
5415 const unsigned Line =
5419 const llvm::DataLayout &target = CGM.getDataLayout();
5426 addr.push_back(llvm::dwarf::DW_OP_deref);
5427 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5430 addr.push_back(llvm::dwarf::DW_OP_deref);
5431 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5434 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5436 addr.push_back(llvm::dwarf::DW_OP_deref);
5437 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5439 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5445 auto *D = DBuilder.createAutoVariable(
5447 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5450 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5451 LexicalBlockStack.back(), CurInlinedAt);
5452 auto *
Expr = DBuilder.createExpression(addr);
5454 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5456 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5459llvm::DILocalVariable *
5462 bool UsePointerValue) {
5463 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5464 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5468struct BlockLayoutChunk {
5469 uint64_t OffsetInBits;
5472bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5473 return l.OffsetInBits < r.OffsetInBits;
5477void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5479 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5480 SmallVectorImpl<llvm::Metadata *> &Fields) {
5484 if (CGM.getLangOpts().OpenCL) {
5485 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5486 BlockLayout.getElementOffsetInBits(0),
5488 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5489 BlockLayout.getElementOffsetInBits(1),
5493 BlockLayout.getElementOffsetInBits(0),
5495 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5496 BlockLayout.getElementOffsetInBits(1),
5500 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5501 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5502 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5503 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5504 BlockLayout.getElementOffsetInBits(3),
5506 Fields.push_back(createFieldType(
5511 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5518 llvm::AllocaInst *Alloca,
5520 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5526 llvm::DIFile *tunit = getOrCreateFile(loc);
5527 unsigned line = getLineNumber(loc);
5528 unsigned column = getColumnNumber(loc);
5533 const llvm::StructLayout *blockLayout =
5537 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5546 BlockLayoutChunk chunk;
5547 chunk.OffsetInBits =
5548 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5549 chunk.Capture =
nullptr;
5550 chunks.push_back(chunk);
5554 for (
const auto &capture :
blockDecl->captures()) {
5555 const VarDecl *variable = capture.getVariable();
5562 BlockLayoutChunk chunk;
5563 chunk.OffsetInBits =
5564 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5565 chunk.Capture = &capture;
5566 chunks.push_back(chunk);
5570 llvm::array_pod_sort(chunks.begin(), chunks.end());
5572 for (
const BlockLayoutChunk &Chunk : chunks) {
5573 uint64_t offsetInBits = Chunk.OffsetInBits;
5580 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5582 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5583 type = CGM.getContext().getCanonicalTagType(RDecl);
5585 llvm_unreachable(
"unexpected block declcontext");
5587 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5588 offsetInBits, tunit, tunit));
5593 StringRef name = variable->
getName();
5595 llvm::DIType *fieldType;
5597 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5602 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5603 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5604 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5605 PtrInfo.
Width, Align, offsetInBits,
5606 llvm::DINode::FlagZero, fieldType);
5610 offsetInBits, Align, tunit, tunit);
5612 fields.push_back(fieldType);
5616 llvm::raw_svector_ostream(typeName)
5617 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5619 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5621 llvm::DIType *
type =
5622 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5623 CGM.getContext().toBits(block.
BlockSize), 0,
5624 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5625 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5628 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5632 auto *debugVar = DBuilder.createParameterVariable(
5633 scope, Name, ArgNo, tunit, line,
type,
5634 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5637 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5638 llvm::DILocation::get(CGM.getLLVMContext(), line,
5639 column, scope, CurInlinedAt),
5640 Builder.GetInsertBlock());
5643llvm::DIDerivedType *
5644CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5649 if (MI != StaticDataMemberCache.end()) {
5650 assert(MI->second &&
"Static data member declaration should still exist");
5661llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5662 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5663 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5664 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5666 for (
const auto *Field : RD->
fields()) {
5667 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5668 StringRef FieldName = Field->getName();
5671 if (FieldName.empty()) {
5672 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5674 CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
5675 Unit, LineNo, LinkageName, Var, DContext);
5679 GVE = DBuilder.createGlobalVariableExpression(
5680 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5681 Var->hasLocalLinkage());
5682 Var->addDebugInfo(GVE);
5694 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
5699 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5710 struct ReferencesAnonymous
5712 bool RefAnon =
false;
5713 bool VisitRecordType(RecordType *RT) {
5721 ReferencesAnonymous RT;
5734struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5735 bool Reconstitutable =
true;
5736 bool VisitVectorType(VectorType *FT) {
5737 Reconstitutable =
false;
5740 bool VisitAtomicType(AtomicType *FT) {
5741 Reconstitutable =
false;
5744 bool VisitType(
Type *
T) {
5748 Reconstitutable =
false;
5753 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5756 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
5757 if (!ED->getIdentifier()) {
5758 Reconstitutable =
false;
5761 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5762 Reconstitutable =
false;
5768 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5772 return Reconstitutable;
5774 bool VisitRecordType(RecordType *RT,
bool =
false) {
5776 Reconstitutable =
false;
5786 ReconstitutableType
T;
5788 return T.Reconstitutable;
5791bool CGDebugInfo::HasReconstitutableArgs(
5792 ArrayRef<TemplateArgument> Args)
const {
5793 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5833 llvm_unreachable(
"Other, unresolved, template arguments should "
5834 "not be seen here");
5839std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5841 llvm::raw_string_ostream
OS(Name);
5842 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5845 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5846 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5848 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5849 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5851 std::optional<TemplateArgs> Args;
5853 bool IsOperatorOverload =
false;
5854 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5855 Args = GetTemplateArgs(RD);
5856 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5857 Args = GetTemplateArgs(FD);
5859 IsOperatorOverload |=
5862 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5863 Args = GetTemplateArgs(VD);
5887 bool Reconstitutable =
5888 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5890 PrintingPolicy PP = getPrintingPolicy();
5892 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5896 bool Mangled = TemplateNamesKind ==
5897 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5903 std::string EncodedOriginalName;
5904 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5909 printTemplateArgumentList(OS, Args->Args, PP);
5910 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
5912 std::string CanonicalOriginalName;
5913 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5915 assert(EncodedOriginalName == CanonicalOriginalName);
5924 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5925 if (D->
hasAttr<NoDebugAttr>())
5928 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5929 return GetName(D,
true);
5935 if (Cached != DeclCache.end())
5936 return Var->addDebugInfo(
5940 llvm::DIFile *Unit =
nullptr;
5941 llvm::DIScope *DContext =
nullptr;
5943 StringRef DeclName, LinkageName;
5945 llvm::MDTuple *TemplateParameters =
nullptr;
5946 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5947 TemplateParameters, DContext);
5951 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5956 if (
T->isUnionType() && DeclName.empty()) {
5957 const auto *RD =
T->castAsRecordDecl();
5959 "unnamed non-anonymous struct or union?");
5960 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5965 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
5966 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
5967 if (D->
hasAttr<CUDASharedAttr>())
5970 else if (D->
hasAttr<CUDAConstantAttr>())
5974 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5976 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5977 GVE = DBuilder.createGlobalVariableExpression(
5978 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5979 Var->hasLocalLinkage(),
true,
5980 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5981 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5982 Align, Annotations);
5983 Var->addDebugInfo(GVE);
5989 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5990 if (VD->
hasAttr<NoDebugAttr>())
5992 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5993 return GetName(VD,
true);
5998 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5999 StringRef Name = VD->
getName();
6000 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6002 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6004 if (CGM.getCodeGenOpts().EmitCodeView) {
6015 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6016 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6017 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6027 auto *VarD = dyn_cast<VarDecl>(VD);
6028 if (VarD && VarD->isStaticDataMember()) {
6030 getDeclContextDescriptor(VarD);
6035 RetainedTypes.push_back(
6036 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6040 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6042 auto &GV = DeclCache[VD];
6046 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6047 llvm::MDTuple *TemplateParameters =
nullptr;
6051 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6052 TemplateParameters = parameterNodes.get();
6055 GV.reset(DBuilder.createGlobalVariableExpression(
6056 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6057 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6058 TemplateParameters, Align));
6063 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6064 if (D->
hasAttr<NoDebugAttr>())
6068 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6069 StringRef Name = D->
getName();
6070 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6072 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6073 llvm::DIGlobalVariableExpression *GVE =
6074 DBuilder.createGlobalVariableExpression(
6075 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6076 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6077 Var->addDebugInfo(GVE);
6084 if (CGM.getCodeGenOpts().getDebugInfo() <=
6085 llvm::codegenoptions::DebugLineTablesOnly)
6088 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6092 llvm::DIFile *Unit = DIL->getFile();
6093 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6098 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6099 llvm::Value *Var = Load->getPointerOperand();
6104 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6105 return DbgDeclare->getVariable()->getType() ==
Type;
6107 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6111 llvm::DILocalVariable *D =
6112 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6113 Type,
false, llvm::DINode::FlagArtificial);
6115 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6116 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6126 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6130 if (D->
hasAttr<NoDebugAttr>())
6133 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6148 if (!(DI = getDeclarationOrDefinition(
6149 AliaseeDecl.getCanonicalDecl().getDecl())))
6152 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6155 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6156 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6165 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
6169 llvm::DIFile *
File = getOrCreateFile(Loc);
6170 llvm::DIGlobalVariableExpression *Debug =
6171 DBuilder.createGlobalVariableExpression(
6172 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6173 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6174 GV->addDebugInfo(Debug);
6177llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6178 if (!LexicalBlockStack.empty())
6179 return LexicalBlockStack.back();
6180 llvm::DIScope *Mod = getParentModuleOrNull(D);
6181 return getContextDescriptor(D, Mod ? Mod : TheCU);
6185 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6189 CGM.getCodeGenOpts().DebugExplicitImport) {
6193 DBuilder.createImportedModule(
6195 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6200 if (llvm::DINode *
Target =
6203 DBuilder.createImportedDeclaration(
6205 getOrCreateFile(Loc), getLineNumber(Loc));
6210 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6213 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6215 for (
const auto *USD : UD.
shadows()) {
6220 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6221 if (
const auto *AT = FD->getType()
6224 if (AT->getDeducedType().isNull())
6235 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6238 "We shouldn't be codegening an invalid UsingEnumDecl"
6239 " containing no decls");
6241 for (
const auto *USD : UD.
shadows())
6246 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6248 if (
Module *M = ID.getImportedModule()) {
6250 auto Loc = ID.getLocation();
6251 DBuilder.createImportedDeclaration(
6252 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6253 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6254 getLineNumber(Loc));
6258llvm::DIImportedEntity *
6260 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6262 auto &VH = NamespaceAliasCache[&NA];
6265 llvm::DIImportedEntity *R;
6267 if (
const auto *Underlying =
6270 R = DBuilder.createImportedDeclaration(
6273 getLineNumber(Loc), NA.
getName());
6275 R = DBuilder.createImportedDeclaration(
6278 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6284CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6288 auto I = NamespaceCache.find(NSDecl);
6289 if (I != NamespaceCache.end())
6292 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6294 llvm::DINamespace *NS =
6295 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6296 NamespaceCache[NSDecl].reset(NS);
6301 assert(TheCU &&
"no main compile unit");
6302 TheCU->setDWOId(Signature);
6308 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6309 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6311 ? CreateTypeDefinition(E.Type, E.Unit)
6313 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6317 for (
const auto &P : ObjCMethodCache) {
6318 if (P.second.empty())
6321 QualType QTy(P.first->getTypeForDecl(), 0);
6323 assert(It != TypeCache.end());
6325 llvm::DICompositeType *InterfaceDecl =
6328 auto CurElts = InterfaceDecl->getElements();
6332 for (
auto &SubprogramDirect : P.second)
6333 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6334 EltTys.push_back(SubprogramDirect.getPointer());
6336 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6337 DBuilder.replaceArrays(InterfaceDecl, Elements);
6340 for (
const auto &P : ReplaceMap) {
6343 assert(Ty->isForwardDecl());
6345 auto It = TypeCache.find(P.first);
6346 assert(It != TypeCache.end());
6349 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6353 for (
const auto &P : FwdDeclReplaceMap) {
6356 llvm::Metadata *Repl;
6358 auto It = DeclCache.find(P.first);
6362 if (It == DeclCache.end())
6367 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6368 Repl = GVE->getVariable();
6374 for (
auto &RT : RetainedTypes)
6375 if (
auto MD = TypeCache[RT])
6378 DBuilder.finalize();
6383 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6384 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6385 DBuilder.retainType(DieTy);
6389 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6390 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6391 DBuilder.retainType(DieTy);
6395 if (LexicalBlockStack.empty())
6396 return llvm::DebugLoc();
6398 llvm::MDNode *
Scope = LexicalBlockStack.back();
6399 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6400 getColumnNumber(Loc),
Scope);
6403llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6407 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6408 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6409 return llvm::DINode::FlagZero;
6414 bool SupportsDWARFv4Ext =
6416 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6417 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6419 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6420 return llvm::DINode::FlagZero;
6422 return llvm::DINode::FlagAllCallsDescribed;
6433 return DBuilder.createConstantValueExpression(
6434 Val.
getFloat().bitcastToAPInt().getZExtValue());
6439 llvm::APSInt
const &ValInt = Val.
getInt();
6440 std::optional<uint64_t> ValIntOpt;
6441 if (ValInt.isUnsigned())
6442 ValIntOpt = ValInt.tryZExtValue();
6443 else if (
auto tmp = ValInt.trySExtValue())
6446 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6449 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6454CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6456 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6457 CGF.CurLexicalScope =
this;
6459 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6464 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6477#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6479 Label = "__ubsan_check_" #Name; \
6483#undef SANITIZER_CHECK
6494#define SANITIZER(NAME, ID) \
6495 case SanitizerKind::SO_##ID: \
6496 Label = "__ubsan_check_" NAME; \
6498#include "clang/Basic/Sanitizers.def"
6500 llvm_unreachable(
"unexpected sanitizer kind");
6505 for (
unsigned int i = 0; i < Label.length(); i++)
6506 if (!std::isalpha(Label[i]))
6515 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6517 if (!DI || !CheckDebugLoc)
6518 return CheckDebugLoc;
6519 const auto &AnnotateDebugInfo =
6520 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6521 if (AnnotateDebugInfo.empty())
6522 return CheckDebugLoc;
6525 if (Ordinals.size() == 1)
6530 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6531 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6533 return CheckDebugLoc;
6541 assert(!CGF->IsSanitizerScope);
6542 CGF->IsSanitizerScope =
true;
6546 assert(CGF->IsSanitizerScope);
6547 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 std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static 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 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 bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
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)
constexpr llvm::StringRef ClangTrapPrefix
#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.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
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()
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.
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
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...
llvm::MDNode * getInlinedAt() const
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 setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
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 EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, const FunctionDecl *CalleeDecl)
Emit debug info for an extern function being called.
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.
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
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.
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::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
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.
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
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.
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.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isBitIntType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
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,...
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.