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() ||
2661 CGM.getTarget().getTriple().isOSBinFormatCOFF())
2663 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2667 StringRef SymbolName =
"_vtable$";
2669 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2678 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2680 llvm::DIFile *Unit = getOrCreateFile(Loc);
2681 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2683 llvm::DINode::FlagArtificial;
2684 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2685 ? llvm::dwarf::DW_TAG_variable
2686 : llvm::dwarf::DW_TAG_member;
2687 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2688 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2692 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2696 llvm::DIGlobalVariableExpression *GVE =
2697 DBuilder.createGlobalVariableExpression(
2698 TheCU, SymbolName, VTable->getName(), Unit, 0,
2699 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2700 true,
nullptr, DT,
nullptr,
2702 VTable->addDebugInfo(GVE);
2705StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2707 llvm::Function *InitFn) {
2712 return InitFn->getName();
2722 llvm::raw_svector_ostream OS(QualifiedGV);
2724 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2726 std::swap(Quals, GVName);
2730 llvm::raw_svector_ostream OS(InitName);
2732 OS << Quals <<
"::";
2737 llvm_unreachable(
"not an initializer");
2739 OS <<
"`dynamic initializer for '";
2742 OS <<
"`dynamic atexit destructor for '";
2749 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2750 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2751 getPrintingPolicy());
2756 return internString(
OS.str());
2759void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2760 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2769 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2776 llvm::DIType *VPtrTy =
nullptr;
2777 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2778 CGM.getTarget().getCXXABI().isMicrosoft();
2779 if (NeedVTableShape) {
2781 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2782 const VTableLayout &VFTLayout =
2783 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2784 unsigned VSlotCount =
2786 unsigned VTableWidth = PtrWidth * VSlotCount;
2787 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2788 std::optional<unsigned> DWARFAddressSpace =
2789 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2792 llvm::DIType *VTableType = DBuilder.createPointerType(
2793 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2794 EltTys.push_back(VTableType);
2797 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2805 VPtrTy = getOrCreateVTablePtrType(Unit);
2807 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2808 llvm::DIType *VPtrMember =
2809 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2810 llvm::DINode::FlagArtificial, VPtrTy);
2811 EltTys.push_back(VPtrMember);
2816 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2817 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2828 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2829 assert(!D.
isNull() &&
"null type");
2830 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2831 assert(
T &&
"could not create debug info for type");
2840 if (CGM.getCodeGenOpts().getDebugInfo() <=
2841 llvm::codegenoptions::DebugLineTablesOnly)
2845 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2847 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2849 CI->setMetadata(
"heapallocsite", node);
2853 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2855 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2857 auto I = TypeCache.find(TyPtr);
2860 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2861 assert(!Res->isForwardDecl());
2862 TypeCache[TyPtr].reset(Res);
2866 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2867 !CGM.getLangOpts().CPlusPlus)
2873 if (RD->
hasAttr<DLLImportAttr>())
2876 if (MD->hasAttr<DLLImportAttr>())
2889 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2899 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2900 Explicit = TD->isExplicitInstantiationOrSpecialization();
2904 if (CXXDecl->
fields().empty())
2914 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2915 if (CXXRD->isDynamicClass() &&
2916 CGM.getVTableLinkage(CXXRD) ==
2917 llvm::GlobalValue::AvailableExternallyLinkage &&
2928 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2930 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
2932 auto I = TypeCache.find(TyPtr);
2939 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
2940 assert(!Res->isForwardDecl());
2941 TypeCache[TyPtr].reset(Res);
2948 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2949 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2972 if (Ctor->isCopyOrMoveConstructor())
2974 if (!Ctor->isDeleted())
2993 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2996 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2997 RD->
hasAttr<StandaloneDebugAttr>())
3000 if (!LangOpts.CPlusPlus)
3006 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3022 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3023 Spec = SD->getSpecializationKind();
3032 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3043 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3044 llvm::DIType *
T = getTypeOrNull(Ty);
3045 if (
T &&
T->isForwardDecl())
3049llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3050 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3051 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3055 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3059 auto [Def, Pref] = CreateTypeDefinition(Ty);
3061 return Pref ? Pref : Def;
3064llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3065 llvm::DIFile *Unit) {
3069 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3073 return getOrCreateType(PNA->getTypedefType(), Unit);
3076std::pair<llvm::DIType *, llvm::DIType *>
3077CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3078 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
3081 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3089 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3093 return {FwdDecl,
nullptr};
3095 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3096 CollectContainingType(CXXDecl, FwdDecl);
3099 LexicalBlockStack.emplace_back(&*FwdDecl);
3100 RegionMap[RD].reset(FwdDecl);
3103 SmallVector<llvm::Metadata *, 16> EltTys;
3110 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3112 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3113 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3117 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3118 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3119 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3121 LexicalBlockStack.pop_back();
3122 RegionMap.erase(RD);
3124 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3125 DBuilder.replaceArrays(FwdDecl, Elements);
3127 if (FwdDecl->isTemporary())
3129 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3131 RegionMap[RD].reset(FwdDecl);
3133 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3134 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3135 return {FwdDecl, PrefDI};
3137 return {FwdDecl,
nullptr};
3140llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3141 llvm::DIFile *Unit) {
3143 return getOrCreateType(Ty->getBaseType(), Unit);
3146llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3147 llvm::DIFile *Unit) {
3149 SourceLocation Loc = Ty->getDecl()->getLocation();
3152 return DBuilder.createTypedef(
3153 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3154 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3155 getDeclContextDescriptor(Ty->getDecl()));
3182llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3183 llvm::DIFile *Unit) {
3189 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
3194 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3195 !
ID->getImplementation())
3196 return DBuilder.createForwardDecl(
3197 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3198 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3201 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3202 unsigned Line = getLineNumber(
ID->getLocation());
3206 ObjCInterfaceDecl *Def =
ID->getDefinition();
3208 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3209 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3210 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3211 DefUnit,
Line, RuntimeLang);
3212 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3216 return CreateTypeDefinition(Ty, Unit);
3219llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3220 bool CreateSkeletonCU) {
3225 auto ModRef = ModuleCache.find(M);
3226 if (ModRef != ModuleCache.end())
3230 SmallString<128> ConfigMacros;
3232 llvm::raw_svector_ostream
OS(ConfigMacros);
3233 const auto &PPOpts = CGM.getPreprocessorOpts();
3236 for (
auto &M : PPOpts.Macros) {
3239 const std::string &
Macro = M.first;
3240 bool Undef = M.second;
3241 OS <<
"\"-" << (Undef ?
'U' :
'D');
3257 bool IsRootModule = M ? !M->
Parent :
true;
3261 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3262 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3263 "clang module without ASTFile must be specified by -fmodule-name");
3266 auto RemapPath = [
this](StringRef Path) -> std::string {
3268 StringRef Relative(Remapped);
3269 StringRef CompDir = TheCU->getDirectory();
3270 if (CompDir.empty())
3273 if (Relative.consume_front(CompDir))
3274 Relative.consume_front(llvm::sys::path::get_separator());
3276 return Relative.str();
3279 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3286 Signature = ModSig.truncatedValue();
3290 llvm::DIBuilder DIB(CGM.getModule());
3292 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3293 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3294 PCM = getCurrentDirname();
3298 llvm::sys::path::append(PCM, Mod.
getASTFile());
3299 DIB.createCompileUnit(
3300 TheCU->getSourceLanguage(),
3303 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3304 llvm::DICompileUnit::FullDebug, Signature);
3308 llvm::DIModule *Parent =
3310 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3312 std::string IncludePath = Mod.
getPath().str();
3313 llvm::DIModule *DIMod =
3314 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3315 RemapPath(IncludePath));
3316 ModuleCache[M].reset(DIMod);
3320llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3321 llvm::DIFile *Unit) {
3323 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3324 unsigned Line = getLineNumber(
ID->getLocation());
3325 unsigned RuntimeLang = TheCU->getSourceLanguage();
3331 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3332 if (
ID->getImplementation())
3333 Flags |= llvm::DINode::FlagObjcClassComplete;
3335 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3336 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3337 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3338 nullptr, llvm::DINodeArray(), RuntimeLang);
3340 QualType QTy(Ty, 0);
3341 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3344 LexicalBlockStack.emplace_back(RealDecl);
3345 RegionMap[Ty->
getDecl()].reset(RealDecl);
3348 SmallVector<llvm::Metadata *, 16> EltTys;
3350 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3352 llvm::DIType *SClassTy =
3353 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3357 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3358 llvm::DINode::FlagZero);
3359 EltTys.push_back(InhTag);
3363 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3364 SourceLocation Loc = PD->getLocation();
3365 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3366 unsigned PLine = getLineNumber(Loc);
3367 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3368 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3369 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3370 PD->getName(), PUnit, PLine,
3372 : getSelectorName(PD->getGetterName()),
3374 : getSelectorName(PD->getSetterName()),
3375 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3376 EltTys.push_back(PropertyNode);
3381 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3385 llvm::DenseSet<IsClassAndIdent> PropertySet;
3387 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3388 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3390 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3391 for (
auto *PD : ClassExt->properties()) {
3392 PropertySet.insert(GetIsClassAndIdent(PD));
3395 for (
const auto *PD :
ID->properties()) {
3398 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3404 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3405 unsigned FieldNo = 0;
3406 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3407 Field =
Field->getNextIvar(), ++FieldNo) {
3408 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3412 StringRef FieldName =
Field->getName();
3415 if (FieldName.empty())
3419 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3420 unsigned FieldLine = getLineNumber(
Field->getLocation());
3421 QualType FType =
Field->getType();
3428 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3429 : CGM.getContext().getTypeSize(FType);
3434 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3438 if (
Field->isBitField()) {
3440 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3441 FieldOffset %= CGM.getContext().getCharWidth();
3449 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3451 Flags = llvm::DINode::FlagProtected;
3453 Flags = llvm::DINode::FlagPrivate;
3455 Flags = llvm::DINode::FlagPublic;
3457 if (
Field->isBitField())
3458 Flags |= llvm::DINode::FlagBitField;
3460 llvm::MDNode *PropertyNode =
nullptr;
3461 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3462 if (ObjCPropertyImplDecl *PImpD =
3463 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3464 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3465 SourceLocation Loc = PD->getLocation();
3466 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3467 unsigned PLine = getLineNumber(Loc);
3468 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3469 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3470 PropertyNode = DBuilder.createObjCProperty(
3471 PD->getName(), PUnit, PLine,
3474 : getSelectorName(PD->getGetterName()),
3477 : getSelectorName(PD->getSetterName()),
3478 PD->getPropertyAttributes(),
3479 getOrCreateType(PD->getType(), PUnit));
3483 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3484 FieldSize, FieldAlign, FieldOffset, Flags,
3485 FieldTy, PropertyNode);
3486 EltTys.push_back(FieldTy);
3489 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3490 DBuilder.replaceArrays(RealDecl, Elements);
3492 LexicalBlockStack.pop_back();
3496llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3497 llvm::DIFile *Unit) {
3505 auto &Ctx = CGM.getContext();
3510 QualType CharVecTy =
3512 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3515 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3518 llvm::Metadata *Subscript;
3519 QualType QTy(Ty, 0);
3520 auto SizeExpr = SizeExprCache.find(QTy);
3521 if (SizeExpr != SizeExprCache.end())
3522 Subscript = DBuilder.getOrCreateSubrange(
3523 SizeExpr->getSecond() ,
nullptr ,
3524 nullptr ,
nullptr );
3527 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3528 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3529 Subscript = DBuilder.getOrCreateSubrange(
3530 CountNode ,
nullptr ,
nullptr ,
3533 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3538 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3541llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3542 llvm::DIFile *Unit) {
3546 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3551 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3552 auto *ColumnCountNode =
3553 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3554 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3555 auto *RowCountNode =
3556 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3557 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3558 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3559 ColumnCountNode ,
nullptr ,
nullptr ,
3561 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3562 RowCountNode ,
nullptr ,
nullptr ,
3564 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3565 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3568llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3573 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3588 Size = CGM.getContext().getTypeSize(Ty);
3595 SmallVector<llvm::Metadata *, 8> Subscripts;
3596 QualType EltTy(Ty, 0);
3597 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3606 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3607 Count = CAT->getZExtSize();
3608 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3609 if (Expr *Size = VAT->getSizeExpr()) {
3611 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3612 Count =
Result.Val.getInt().getExtValue();
3616 auto SizeNode = SizeExprCache.find(EltTy);
3617 if (SizeNode != SizeExprCache.end())
3618 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3619 SizeNode->getSecond() ,
nullptr ,
3620 nullptr ,
nullptr ));
3623 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3624 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3625 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3626 CountNode ,
nullptr ,
nullptr ,
3632 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3634 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3638llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3639 llvm::DIFile *Unit) {
3640 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3644llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3645 llvm::DIFile *Unit) {
3646 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3648 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3649 CGM.getCodeGenOpts().DwarfVersion < 4)
3650 Tag = llvm::dwarf::DW_TAG_reference_type;
3652 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3655llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3657 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3661 Size = CGM.getContext().getTypeSize(Ty);
3664 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3667 Flags |= llvm::DINode::FlagSingleInheritance;
3670 Flags |= llvm::DINode::FlagMultipleInheritance;
3673 Flags |= llvm::DINode::FlagVirtualInheritance;
3683 llvm::DIType *ClassType = getOrCreateType(
T, U);
3685 return DBuilder.createMemberPointerType(
3689 const FunctionProtoType *FPT =
3691 return DBuilder.createMemberPointerType(
3692 getOrCreateInstanceMethodType(
3695 ClassType, Size, 0, Flags);
3698llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3700 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3703llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3707llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3709 return getOrCreateType(Ty->getWrappedType(), U);
3712llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3719 const EnumType *Ty) {
3731llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3734 bool isImportedFromModule =
3735 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3739 if (isImportedFromModule || !ED->getDefinition()) {
3746 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3747 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3748 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3749 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3751 unsigned Line = getLineNumber(ED->getLocation());
3752 StringRef EDName = ED->getName();
3753 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3754 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3755 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3757 ReplaceMap.emplace_back(
3758 std::piecewise_construct, std::make_tuple(Ty),
3759 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3763 return CreateTypeDefinition(Ty);
3766llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3769 SmallVector<llvm::Metadata *, 16> Enumerators;
3770 ED = ED->getDefinition();
3771 assert(ED &&
"An enumeration definition is required");
3772 for (
const auto *
Enum : ED->enumerators()) {
3773 Enumerators.push_back(
3774 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3777 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3778 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3779 EnumKind = Attr->getExtensibility();
3782 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3784 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3785 unsigned Line = getLineNumber(ED->getLocation());
3786 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3787 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3788 return DBuilder.createEnumerationType(
3789 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3790 0, Identifier, ED->isScoped(), EnumKind);
3795 StringRef Name, StringRef
Value) {
3796 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3797 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3803 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3804 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3805 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3809 StringRef FuncName) {
3810 llvm::DISubprogram *SP =
3811 createInlinedSubprogram(FuncName, Location->getFile());
3812 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3817 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3823 FuncName += Category;
3825 FuncName += FailureMsg;
3837 Quals += InnerQuals;
3839 switch (
T->getTypeClass()) {
3841 return C.getQualifiedType(
T.getTypePtr(), Quals);
3844 case Type::InjectedClassName:
3845 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3847 case Type::TemplateSpecialization: {
3849 if (Spec->isTypeAlias())
3850 return C.getQualifiedType(
T.getTypePtr(), Quals);
3851 T = Spec->desugar();
3854 case Type::TypeOfExpr:
3860 case Type::Decltype:
3863 case Type::UnaryTransform:
3866 case Type::Attributed:
3869 case Type::BTFTagAttributed:
3872 case Type::CountAttributed:
3881 case Type::MacroQualified:
3884 case Type::SubstTemplateTypeParm:
3888 case Type::DeducedTemplateSpecialization: {
3890 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3894 case Type::PackIndexing: {
3898 case Type::Adjusted:
3905 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3910llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
3913 if (It != TypeCache.end()) {
3915 if (llvm::Metadata *
V = It->second)
3928 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3935 RetainedTypes.push_back(
3936 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
3939llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3943 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3945 llvm::raw_string_ostream OS(Name);
3946 Ty.
print(OS, getPrintingPolicy());
3953 if (
auto *
T = getTypeOrNull(Ty))
3956 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3957 void *TyPtr = Ty.getAsOpaquePtr();
3960 TypeCache[TyPtr].reset(Res);
3965llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3973 auto Info = Reader->getSourceDescriptor(Idx);
3975 return getOrCreateModuleRef(*Info,
true);
3976 }
else if (ClangModuleMap) {
3989 auto Info = ASTSourceDescriptor(*M);
3990 return getOrCreateModuleRef(Info,
false);
3993 return getOrCreateModuleRef(PCHDescriptor,
false);
4000llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4003 return CreateQualifiedType(Ty, Unit);
4007#define TYPE(Class, Base)
4008#define ABSTRACT_TYPE(Class, Base)
4009#define NON_CANONICAL_TYPE(Class, Base)
4010#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4011#include "clang/AST/TypeNodes.inc"
4012 llvm_unreachable(
"Dependent types cannot show up in debug information");
4014 case Type::ExtVector:
4017 case Type::ConstantMatrix:
4019 case Type::ObjCObjectPointer:
4021 case Type::ObjCObject:
4023 case Type::ObjCTypeParam:
4025 case Type::ObjCInterface:
4033 case Type::BlockPointer:
4041 case Type::FunctionProto:
4042 case Type::FunctionNoProto:
4044 case Type::ConstantArray:
4045 case Type::VariableArray:
4046 case Type::IncompleteArray:
4047 case Type::ArrayParameter:
4050 case Type::LValueReference:
4052 case Type::RValueReference:
4055 case Type::MemberPointer:
4066 case Type::TemplateSpecialization:
4068 case Type::HLSLAttributedResource:
4070 case Type::HLSLInlineSpirv:
4072 case Type::PredefinedSugar:
4074 case Type::CountAttributed:
4076 case Type::Attributed:
4077 case Type::BTFTagAttributed:
4078 case Type::Adjusted:
4080 case Type::DeducedTemplateSpecialization:
4083 case Type::MacroQualified:
4084 case Type::SubstTemplateTypeParm:
4085 case Type::TypeOfExpr:
4087 case Type::Decltype:
4088 case Type::PackIndexing:
4089 case Type::UnaryTransform:
4093 llvm_unreachable(
"type should have been unwrapped!");
4096llvm::DICompositeType *
4097CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4098 QualType QTy(Ty, 0);
4100 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4105 if (
T && !
T->isForwardDecl())
4109 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4114 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4117 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4122llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4123 RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
4126 StringRef RDName = getClassName(RD);
4128 llvm::DIFile *DefUnit =
nullptr;
4131 DefUnit = getOrCreateFile(Loc);
4132 Line = getLineNumber(Loc);
4135 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4139 auto *
T = cast_or_null<llvm::DICompositeType>(
4140 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4148 return getOrCreateRecordFwdDecl(Ty, RDContext);
4161 auto Flags = llvm::DINode::FlagZero;
4162 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4164 Flags |= llvm::DINode::FlagTypePassByReference;
4166 Flags |= llvm::DINode::FlagTypePassByValue;
4169 if (!CXXRD->isTrivial())
4170 Flags |= llvm::DINode::FlagNonTrivial;
4173 if (CXXRD->isAnonymousStructOrUnion())
4174 Flags |= llvm::DINode::FlagExportSymbols;
4177 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4180 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4181 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4183 Flags, Identifier, Annotations);
4187 switch (RealDecl->getTag()) {
4189 llvm_unreachable(
"invalid composite type tag");
4191 case llvm::dwarf::DW_TAG_array_type:
4192 case llvm::dwarf::DW_TAG_enumeration_type:
4197 if (Identifier.empty())
4201 case llvm::dwarf::DW_TAG_structure_type:
4202 case llvm::dwarf::DW_TAG_union_type:
4203 case llvm::dwarf::DW_TAG_class_type:
4206 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4211 dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
4212 CXXRecordDecl *TemplateDecl =
4213 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4214 RegionMap[TemplateDecl].reset(RealDecl);
4216 RegionMap[RD].reset(RealDecl);
4218 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4220 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4221 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4222 CollectCXXTemplateParams(TSpecial, DefUnit));
4226void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4227 llvm::DICompositeType *RealDecl) {
4229 llvm::DIType *ContainingType =
nullptr;
4230 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4234 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4241 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4242 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4244 ContainingType = RealDecl;
4246 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4249llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4250 StringRef Name, uint64_t *Offset) {
4251 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4252 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4255 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4256 *Offset, llvm::DINode::FlagZero, FieldTy);
4257 *Offset += FieldSize;
4261void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4263 StringRef &LinkageName,
4264 llvm::DIScope *&FDContext,
4265 llvm::DINodeArray &TParamsArray,
4266 llvm::DINode::DIFlags &Flags) {
4268 Name = getFunctionName(FD);
4271 LinkageName = CGM.getMangledName(GD);
4273 Flags |= llvm::DINode::FlagPrototyped;
4277 if (LinkageName == Name ||
4278 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4279 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4280 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4281 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4282 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4283 LinkageName = StringRef();
4287 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4288 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4289 CGM.getCodeGenOpts().EmitCodeView)) {
4290 if (
const NamespaceDecl *NSDecl =
4292 FDContext = getOrCreateNamespace(NSDecl);
4293 else if (
const RecordDecl *RDecl =
4295 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4296 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4299 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4302 Flags |= llvm::DINode::FlagNoReturn;
4304 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4308void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4309 unsigned &LineNo, QualType &
T,
4310 StringRef &Name, StringRef &LinkageName,
4311 llvm::MDTuple *&TemplateParameters,
4312 llvm::DIScope *&VDContext) {
4321 llvm::APInt ConstVal(32, 1);
4322 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4324 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4331 LinkageName = CGM.getMangledName(VD);
4332 if (LinkageName == Name)
4333 LinkageName = StringRef();
4336 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4337 TemplateParameters = parameterNodes.get();
4339 TemplateParameters =
nullptr;
4357 DC = CGM.getContext().getTranslationUnitDecl();
4359 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4360 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4363llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4365 llvm::DINodeArray TParamsArray;
4366 StringRef Name, LinkageName;
4367 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4368 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4370 llvm::DIFile *Unit = getOrCreateFile(Loc);
4371 llvm::DIScope *DContext = Unit;
4372 unsigned Line = getLineNumber(Loc);
4373 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4378 SmallVector<QualType, 16> ArgTypes;
4379 for (
const ParmVarDecl *Parm : FD->
parameters())
4380 ArgTypes.push_back(Parm->getType());
4383 QualType FnType = CGM.getContext().getFunctionType(
4384 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4386 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4387 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4388 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4391 Flags |= getCallSiteRelatedAttrs();
4392 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4393 return DBuilder.createFunction(
4394 DContext, Name, LinkageName, Unit,
Line,
4395 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4396 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4398 CGM.getCodeGenOpts().DebugKeyInstructions);
4401 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4402 DContext, Name, LinkageName, Unit,
Line,
4403 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4404 TParamsArray.get(), getFunctionDeclaration(FD));
4406 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4407 std::make_tuple(CanonDecl),
4408 std::make_tuple(SP));
4412llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4413 return getFunctionFwdDeclOrStub(GD,
false);
4416llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4417 return getFunctionFwdDeclOrStub(GD,
true);
4420llvm::DIGlobalVariable *
4421CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4423 StringRef Name, LinkageName;
4425 llvm::DIFile *Unit = getOrCreateFile(Loc);
4426 llvm::DIScope *DContext = Unit;
4427 unsigned Line = getLineNumber(Loc);
4428 llvm::MDTuple *TemplateParameters =
nullptr;
4430 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4433 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4434 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4436 FwdDeclReplaceMap.emplace_back(
4437 std::piecewise_construct,
4439 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4443llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4448 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4449 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4450 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4454 if (I != DeclCache.end()) {
4456 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4457 return GVE->getVariable();
4465 if (IE != ImportedDeclCache.end()) {
4466 auto N = IE->second;
4467 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4469 return dyn_cast_or_null<llvm::DINode>(N);
4474 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4475 return getFunctionForwardDeclaration(FD);
4476 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4477 return getGlobalVariableForwardDeclaration(VD);
4482llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4483 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4486 const auto *FD = dyn_cast<FunctionDecl>(D);
4491 auto *S = getDeclContextDescriptor(D);
4494 if (MI == SPCache.end()) {
4496 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4500 if (MI != SPCache.end()) {
4501 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4502 if (SP && !SP->isDefinition())
4506 for (
auto *NextFD : FD->
redecls()) {
4507 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4508 if (MI != SPCache.end()) {
4509 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4510 if (SP && !SP->isDefinition())
4517llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4518 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4519 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4520 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4523 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4527 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4531 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4540 QualType QTy(
ID->getTypeForDecl(), 0);
4541 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4542 if (It == TypeCache.end())
4545 llvm::DISubprogram *FD = DBuilder.createFunction(
4546 InterfaceType, getObjCMethodName(OMD), StringRef(),
4547 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4548 DBuilder.finalizeSubprogram(FD);
4555llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4560 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4561 !CGM.getCodeGenOpts().EmitCodeView))
4564 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4566 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4569 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4572 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4573 return getOrCreateMethodType(
Method, F);
4575 const auto *FTy = FnType->
getAs<FunctionType>();
4578 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4580 SmallVector<llvm::Metadata *, 16> Elts;
4583 QualType ResultTy = OMethod->getReturnType();
4586 if (ResultTy == CGM.getContext().getObjCInstanceType())
4587 ResultTy = CGM.getContext().getPointerType(
4588 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4590 Elts.push_back(getOrCreateType(ResultTy, F));
4592 QualType SelfDeclTy;
4593 if (
auto *SelfDecl = OMethod->getSelfDecl())
4594 SelfDeclTy = SelfDecl->getType();
4595 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4598 if (!SelfDeclTy.
isNull())
4600 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4602 Elts.push_back(DBuilder.createArtificialType(
4603 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4605 for (
const auto *PI : OMethod->parameters())
4606 Elts.push_back(getOrCreateType(PI->getType(), F));
4608 if (OMethod->isVariadic())
4609 Elts.push_back(DBuilder.createUnspecifiedParameter());
4611 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4612 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4618 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4619 if (FD->isVariadic()) {
4620 SmallVector<llvm::Metadata *, 16> EltTys;
4621 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4622 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4624 EltTys.push_back(getOrCreateType(ParamType, F));
4625 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4626 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4627 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4640 CC = SrcFnTy->getCallConv();
4642 for (
const VarDecl *VD : Args)
4643 ArgTypes.push_back(VD->
getType());
4644 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4650 llvm::Function *Fn,
bool CurFuncIsThunk) {
4652 StringRef LinkageName;
4654 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4657 bool HasDecl = (D !=
nullptr);
4659 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4660 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4661 llvm::DIFile *Unit = getOrCreateFile(Loc);
4662 llvm::DIScope *FDContext = Unit;
4663 llvm::DINodeArray TParamsArray;
4664 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4667 LinkageName = Fn->getName();
4668 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4670 auto FI = SPCache.find(FD->getCanonicalDecl());
4671 if (FI != SPCache.end()) {
4672 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4673 if (SP && SP->isDefinition()) {
4674 LexicalBlockStack.emplace_back(SP);
4675 RegionMap[D].reset(SP);
4679 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4680 TParamsArray, Flags);
4683 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4684 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4685 Name = getObjCMethodName(OMD);
4686 Flags |= llvm::DINode::FlagPrototyped;
4693 Name = Fn->getName();
4698 Flags |= llvm::DINode::FlagPrototyped;
4700 Name.consume_front(
"\01");
4704 "Unexpected DynamicInitKind !");
4708 Flags |= llvm::DINode::FlagArtificial;
4714 Flags |= llvm::DINode::FlagThunk;
4716 if (Fn->hasLocalLinkage())
4717 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4718 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4719 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4721 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4722 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4723 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4725 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4726 unsigned ScopeLine = getLineNumber(ScopeLoc);
4727 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4728 llvm::DISubprogram *
Decl =
nullptr;
4729 llvm::DINodeArray Annotations =
nullptr;
4732 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4733 : getFunctionDeclaration(D);
4734 Annotations = CollectBTFDeclTagAnnotations(D);
4742 llvm::DISubprogram *SP = DBuilder.createFunction(
4743 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4744 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4745 Annotations,
"", KeyInstructions);
4746 Fn->setSubprogram(SP);
4755 LexicalBlockStack.emplace_back(SP);
4758 RegionMap[D].reset(SP);
4762 QualType FnType, llvm::Function *Fn) {
4764 StringRef LinkageName;
4770 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4771 return GetName(D,
true);
4774 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4775 llvm::DIFile *Unit = getOrCreateFile(Loc);
4776 bool IsDeclForCallSite = Fn ?
true :
false;
4777 llvm::DIScope *FDContext =
4778 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4779 llvm::DINodeArray TParamsArray;
4782 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4783 TParamsArray, Flags);
4784 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4785 Name = getObjCMethodName(OMD);
4786 Flags |= llvm::DINode::FlagPrototyped;
4788 llvm_unreachable(
"not a function or ObjC method");
4790 Name.consume_front(
"\01");
4793 Flags |= llvm::DINode::FlagArtificial;
4798 unsigned LineNo = getLineNumber(Loc);
4799 unsigned ScopeLine = 0;
4800 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4801 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4802 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4804 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4805 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4807 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4808 llvm::DISubprogram *SP = DBuilder.createFunction(
4809 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4810 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4816 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4817 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4818 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4821 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4822 DBuilder.createParameterVariable(
4823 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4824 llvm::DINode::FlagZero, ParamAnnotations);
4830 if (IsDeclForCallSite)
4831 Fn->setSubprogram(SP);
4839 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4842 if (
Func->getSubprogram())
4847 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4848 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4861 auto FI = SPCache.find(FD->getCanonicalDecl());
4862 llvm::DISubprogram *SP =
nullptr;
4863 if (FI != SPCache.end())
4864 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4865 if (!SP || !SP->isDefinition())
4866 SP = getFunctionStub(GD);
4867 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4868 LexicalBlockStack.emplace_back(SP);
4874 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4883 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4886 llvm::MDNode *
Scope = LexicalBlockStack.back();
4887 Builder.SetCurrentDebugLocation(
4888 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
4889 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4893 llvm::MDNode *Back =
nullptr;
4894 if (!LexicalBlockStack.empty())
4895 Back = LexicalBlockStack.back().get();
4896 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4898 getColumnNumber(CurLoc)));
4901void CGDebugInfo::AppendAddressSpaceXDeref(
4903 std::optional<unsigned> DWARFAddressSpace =
4905 if (!DWARFAddressSpace)
4908 Expr.push_back(llvm::dwarf::DW_OP_constu);
4909 Expr.push_back(*DWARFAddressSpace);
4910 Expr.push_back(llvm::dwarf::DW_OP_swap);
4911 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4920 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4921 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
4922 LexicalBlockStack.back(), CurInlinedAt));
4924 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4928 CreateLexicalBlock(Loc);
4933 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4938 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4941 LexicalBlockStack.pop_back();
4945 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4946 unsigned RCount = FnBeginRegionCount.back();
4947 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4950 while (LexicalBlockStack.size() != RCount) {
4953 LexicalBlockStack.pop_back();
4955 FnBeginRegionCount.pop_back();
4957 if (Fn && Fn->getSubprogram())
4958 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4961CGDebugInfo::BlockByRefType
4962CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4963 uint64_t *XOffset) {
4966 uint64_t FieldSize, FieldOffset;
4967 uint32_t FieldAlign;
4969 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4974 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4975 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4977 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4978 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4981 if (HasCopyAndDispose) {
4984 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4986 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4988 bool HasByrefExtendedLayout;
4991 HasByrefExtendedLayout) &&
4992 HasByrefExtendedLayout) {
4995 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5004 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5007 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5010 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5015 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5016 FieldSize = CGM.getContext().getTypeSize(FType);
5017 FieldAlign = CGM.getContext().toBits(Align);
5019 *XOffset = FieldOffset;
5020 llvm::DIType *FieldTy = DBuilder.createMemberType(
5021 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5022 llvm::DINode::FlagZero, WrappedTy);
5023 EltTys.push_back(FieldTy);
5024 FieldOffset += FieldSize;
5026 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5027 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5028 llvm::DINode::FlagZero,
nullptr, Elements),
5032llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5033 llvm::Value *Storage,
5034 std::optional<unsigned> ArgNo,
5036 const bool UsePointerValue) {
5037 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5038 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5039 if (VD->
hasAttr<NoDebugAttr>())
5044 llvm::DIFile *Unit =
nullptr;
5045 if (!VarIsArtificial)
5049 if (VD->
hasAttr<BlocksAttr>())
5050 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5052 Ty = getOrCreateType(VD->
getType(), Unit);
5062 if (!VarIsArtificial) {
5066 SmallVector<uint64_t, 13> Expr;
5067 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5068 if (VarIsArtificial)
5069 Flags |= llvm::DINode::FlagArtificial;
5073 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5074 AppendAddressSpaceXDeref(AddressSpace, Expr);
5078 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5081 Flags |= llvm::DINode::FlagObjectPointer;
5082 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5083 if (PVD->isExplicitObjectParameter())
5084 Flags |= llvm::DINode::FlagObjectPointer;
5092 StringRef Name = VD->
getName();
5093 if (!Name.empty()) {
5099 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5101 offset = CGM.getContext().toCharUnitsFromBits(
5104 Expr.push_back(llvm::dwarf::DW_OP_deref);
5105 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5107 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5110 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5122 for (
const auto *Field : RD->
fields()) {
5123 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5124 StringRef FieldName =
Field->getName();
5132 auto *D = DBuilder.createAutoVariable(
5133 Scope, FieldName, Unit,
Line, FieldTy,
5134 CGM.getCodeGenOpts().OptimizationLevel != 0,
5135 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5138 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5139 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5142 Builder.GetInsertBlock());
5150 if (UsePointerValue) {
5151 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5152 "Debug info already contains DW_OP_deref.");
5153 Expr.push_back(llvm::dwarf::DW_OP_deref);
5157 llvm::DILocalVariable *D =
nullptr;
5159 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5160 D = DBuilder.createParameterVariable(
5161 Scope, Name, *ArgNo, Unit,
Line, Ty,
5162 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5171 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5177 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5178 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5179 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5180 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5182 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5188 if (Iter != CoroutineParameterMappings.end()) {
5189 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5190 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5191 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5193 if (Iter2 != ParamDbgMappings.end())
5194 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5200 D = RemapCoroArgToLocalVar();
5203 D = DBuilder.createAutoVariable(
5204 Scope, Name, Unit,
Line, Ty,
5205 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5208 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5209 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5210 Column, Scope, CurInlinedAt),
5211 Builder.GetInsertBlock());
5216llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5217 llvm::Value *Storage,
5218 std::optional<unsigned> ArgNo,
5220 const bool UsePointerValue) {
5221 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5222 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5223 if (BD->
hasAttr<NoDebugAttr>())
5230 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5231 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5239 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5241 SmallVector<uint64_t, 3> Expr;
5242 AppendAddressSpaceXDeref(AddressSpace, Expr);
5247 if (UsePointerValue) {
5248 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5249 "Debug info already contains DW_OP_deref.");
5250 Expr.push_back(llvm::dwarf::DW_OP_deref);
5255 StringRef Name = BD->
getName();
5258 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5259 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5260 llvm::DINode::FlagZero, Align);
5262 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5263 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5264 const unsigned fieldIndex = FD->getFieldIndex();
5265 const clang::CXXRecordDecl *parent =
5266 (
const CXXRecordDecl *)FD->getParent();
5267 const ASTRecordLayout &layout =
5268 CGM.getContext().getASTRecordLayout(parent);
5270 if (FD->isBitField()) {
5271 const CGRecordLayout &RL =
5272 CGM.getTypes().getCGRecordLayout(FD->getParent());
5277 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5283 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5284 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5285 Expr.push_back(Info.
Offset);
5288 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5289 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5290 }
else if (fieldOffset != 0) {
5291 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5292 "Unexpected non-bitfield with non-byte-aligned offset");
5293 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5295 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5298 }
else if (
const ArraySubscriptExpr *ASE =
5299 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5300 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5301 const uint64_t value = IL->getValue().getZExtValue();
5302 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5305 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5306 Expr.push_back(CGM.getContext()
5307 .toCharUnitsFromBits(value * typeSize)
5314 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5315 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5316 Column, Scope, CurInlinedAt),
5317 Builder.GetInsertBlock());
5322llvm::DILocalVariable *
5325 const bool UsePointerValue) {
5326 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5328 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5330 EmitDeclare(B, Storage, std::nullopt, Builder,
5337 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5341 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5342 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5344 if (D->
hasAttr<NoDebugAttr>())
5348 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5354 StringRef Name = D->
getName();
5360 CGM.getCodeGenOpts().OptimizationLevel != 0);
5363 DBuilder.insertLabel(L,
5364 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5365 Scope, CurInlinedAt),
5366 Builder.GetInsertBlock()->end());
5369llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5371 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5374 return DBuilder.createObjectPointerType(Ty,
true);
5379 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5380 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5381 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5383 if (Builder.GetInsertBlock() ==
nullptr)
5385 if (VD->
hasAttr<NoDebugAttr>())
5388 bool isByRef = VD->
hasAttr<BlocksAttr>();
5390 uint64_t XOffset = 0;
5391 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5394 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5396 Ty = getOrCreateType(VD->
getType(), Unit);
5400 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5402 Ty = CreateSelfType(VD->
getType(), Ty);
5405 const unsigned Line =
5409 const llvm::DataLayout &target = CGM.getDataLayout();
5416 addr.push_back(llvm::dwarf::DW_OP_deref);
5417 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5420 addr.push_back(llvm::dwarf::DW_OP_deref);
5421 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5424 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5426 addr.push_back(llvm::dwarf::DW_OP_deref);
5427 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5429 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5435 auto *D = DBuilder.createAutoVariable(
5437 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5440 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5441 LexicalBlockStack.back(), CurInlinedAt);
5442 auto *
Expr = DBuilder.createExpression(addr);
5444 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5446 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5449llvm::DILocalVariable *
5452 bool UsePointerValue) {
5453 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5454 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5458struct BlockLayoutChunk {
5459 uint64_t OffsetInBits;
5462bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5463 return l.OffsetInBits < r.OffsetInBits;
5467void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5469 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5470 SmallVectorImpl<llvm::Metadata *> &Fields) {
5474 if (CGM.getLangOpts().OpenCL) {
5475 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5476 BlockLayout.getElementOffsetInBits(0),
5478 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5479 BlockLayout.getElementOffsetInBits(1),
5483 BlockLayout.getElementOffsetInBits(0),
5485 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5486 BlockLayout.getElementOffsetInBits(1),
5490 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5491 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5492 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5493 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5494 BlockLayout.getElementOffsetInBits(3),
5496 Fields.push_back(createFieldType(
5501 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5508 llvm::AllocaInst *Alloca,
5510 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5516 llvm::DIFile *tunit = getOrCreateFile(loc);
5517 unsigned line = getLineNumber(loc);
5518 unsigned column = getColumnNumber(loc);
5523 const llvm::StructLayout *blockLayout =
5527 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5536 BlockLayoutChunk chunk;
5537 chunk.OffsetInBits =
5538 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5539 chunk.Capture =
nullptr;
5540 chunks.push_back(chunk);
5544 for (
const auto &capture :
blockDecl->captures()) {
5545 const VarDecl *variable = capture.getVariable();
5552 BlockLayoutChunk chunk;
5553 chunk.OffsetInBits =
5554 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5555 chunk.Capture = &capture;
5556 chunks.push_back(chunk);
5560 llvm::array_pod_sort(chunks.begin(), chunks.end());
5562 for (
const BlockLayoutChunk &Chunk : chunks) {
5563 uint64_t offsetInBits = Chunk.OffsetInBits;
5570 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5572 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5573 type = CGM.getContext().getCanonicalTagType(RDecl);
5575 llvm_unreachable(
"unexpected block declcontext");
5577 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5578 offsetInBits, tunit, tunit));
5583 StringRef name = variable->
getName();
5585 llvm::DIType *fieldType;
5587 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5592 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5593 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5594 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5595 PtrInfo.
Width, Align, offsetInBits,
5596 llvm::DINode::FlagZero, fieldType);
5600 offsetInBits, Align, tunit, tunit);
5602 fields.push_back(fieldType);
5606 llvm::raw_svector_ostream(typeName)
5607 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5609 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5611 llvm::DIType *
type =
5612 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5613 CGM.getContext().toBits(block.
BlockSize), 0,
5614 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5615 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5618 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5622 auto *debugVar = DBuilder.createParameterVariable(
5623 scope, Name, ArgNo, tunit, line,
type,
5624 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5627 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5628 llvm::DILocation::get(CGM.getLLVMContext(), line,
5629 column, scope, CurInlinedAt),
5630 Builder.GetInsertBlock());
5633llvm::DIDerivedType *
5634CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5639 if (MI != StaticDataMemberCache.end()) {
5640 assert(MI->second &&
"Static data member declaration should still exist");
5651llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5652 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5653 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5654 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5656 for (
const auto *Field : RD->
fields()) {
5657 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5658 StringRef FieldName = Field->getName();
5661 if (FieldName.empty()) {
5662 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5664 CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
5665 Unit, LineNo, LinkageName, Var, DContext);
5669 GVE = DBuilder.createGlobalVariableExpression(
5670 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5671 Var->hasLocalLinkage());
5672 Var->addDebugInfo(GVE);
5684 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
5689 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5700 struct ReferencesAnonymous
5702 bool RefAnon =
false;
5703 bool VisitRecordType(RecordType *RT) {
5711 ReferencesAnonymous RT;
5724struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5725 bool Reconstitutable =
true;
5726 bool VisitVectorType(VectorType *FT) {
5727 Reconstitutable =
false;
5730 bool VisitAtomicType(AtomicType *FT) {
5731 Reconstitutable =
false;
5734 bool VisitType(
Type *
T) {
5738 Reconstitutable =
false;
5743 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5746 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
5747 if (!ED->getIdentifier()) {
5748 Reconstitutable =
false;
5751 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5752 Reconstitutable =
false;
5758 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5762 return Reconstitutable;
5764 bool VisitRecordType(RecordType *RT,
bool =
false) {
5766 Reconstitutable =
false;
5776 ReconstitutableType
T;
5778 return T.Reconstitutable;
5781bool CGDebugInfo::HasReconstitutableArgs(
5782 ArrayRef<TemplateArgument> Args)
const {
5783 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5823 llvm_unreachable(
"Other, unresolved, template arguments should "
5824 "not be seen here");
5829std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5831 llvm::raw_string_ostream
OS(Name);
5832 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5835 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5836 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5838 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5839 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5841 std::optional<TemplateArgs> Args;
5843 bool IsOperatorOverload =
false;
5844 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5845 Args = GetTemplateArgs(RD);
5846 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5847 Args = GetTemplateArgs(FD);
5849 IsOperatorOverload |=
5852 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5853 Args = GetTemplateArgs(VD);
5877 bool Reconstitutable =
5878 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5880 PrintingPolicy PP = getPrintingPolicy();
5882 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5886 bool Mangled = TemplateNamesKind ==
5887 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5893 std::string EncodedOriginalName;
5894 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5899 printTemplateArgumentList(OS, Args->Args, PP);
5900 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
5902 std::string CanonicalOriginalName;
5903 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5905 assert(EncodedOriginalName == CanonicalOriginalName);
5914 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5915 if (D->
hasAttr<NoDebugAttr>())
5918 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5919 return GetName(D,
true);
5925 if (Cached != DeclCache.end())
5926 return Var->addDebugInfo(
5930 llvm::DIFile *Unit =
nullptr;
5931 llvm::DIScope *DContext =
nullptr;
5933 StringRef DeclName, LinkageName;
5935 llvm::MDTuple *TemplateParameters =
nullptr;
5936 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5937 TemplateParameters, DContext);
5941 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5946 if (
T->isUnionType() && DeclName.empty()) {
5947 const auto *RD =
T->castAsRecordDecl();
5949 "unnamed non-anonymous struct or union?");
5950 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5955 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
5956 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
5957 if (D->
hasAttr<CUDASharedAttr>())
5960 else if (D->
hasAttr<CUDAConstantAttr>())
5964 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5966 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5967 GVE = DBuilder.createGlobalVariableExpression(
5968 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5969 Var->hasLocalLinkage(),
true,
5970 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5971 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5972 Align, Annotations);
5973 Var->addDebugInfo(GVE);
5979 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5980 if (VD->
hasAttr<NoDebugAttr>())
5982 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5983 return GetName(VD,
true);
5988 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5989 StringRef Name = VD->
getName();
5990 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5992 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5994 if (CGM.getCodeGenOpts().EmitCodeView) {
6005 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6006 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6007 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6017 auto *VarD = dyn_cast<VarDecl>(VD);
6018 if (VarD && VarD->isStaticDataMember()) {
6020 getDeclContextDescriptor(VarD);
6025 RetainedTypes.push_back(
6026 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6030 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6032 auto &GV = DeclCache[VD];
6036 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6037 llvm::MDTuple *TemplateParameters =
nullptr;
6041 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6042 TemplateParameters = parameterNodes.get();
6045 GV.reset(DBuilder.createGlobalVariableExpression(
6046 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6047 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6048 TemplateParameters, Align));
6053 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6054 if (D->
hasAttr<NoDebugAttr>())
6058 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6059 StringRef Name = D->
getName();
6060 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6062 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6063 llvm::DIGlobalVariableExpression *GVE =
6064 DBuilder.createGlobalVariableExpression(
6065 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6066 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6067 Var->addDebugInfo(GVE);
6074 if (CGM.getCodeGenOpts().getDebugInfo() <=
6075 llvm::codegenoptions::DebugLineTablesOnly)
6078 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6082 llvm::DIFile *Unit = DIL->getFile();
6083 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6088 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6089 llvm::Value *Var = Load->getPointerOperand();
6094 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6095 return DbgDeclare->getVariable()->getType() ==
Type;
6097 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6101 llvm::DILocalVariable *D =
6102 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6103 Type,
false, llvm::DINode::FlagArtificial);
6105 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6106 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6116 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6120 if (D->
hasAttr<NoDebugAttr>())
6123 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6138 if (!(DI = getDeclarationOrDefinition(
6139 AliaseeDecl.getCanonicalDecl().getDecl())))
6142 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6145 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6146 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6155 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
6159 llvm::DIFile *
File = getOrCreateFile(Loc);
6160 llvm::DIGlobalVariableExpression *Debug =
6161 DBuilder.createGlobalVariableExpression(
6162 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6163 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6164 GV->addDebugInfo(Debug);
6167llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6168 if (!LexicalBlockStack.empty())
6169 return LexicalBlockStack.back();
6170 llvm::DIScope *Mod = getParentModuleOrNull(D);
6171 return getContextDescriptor(D, Mod ? Mod : TheCU);
6175 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6179 CGM.getCodeGenOpts().DebugExplicitImport) {
6183 DBuilder.createImportedModule(
6185 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6190 if (llvm::DINode *
Target =
6193 DBuilder.createImportedDeclaration(
6195 getOrCreateFile(Loc), getLineNumber(Loc));
6200 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6203 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6205 for (
const auto *USD : UD.
shadows()) {
6210 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6211 if (
const auto *AT = FD->getType()
6214 if (AT->getDeducedType().isNull())
6225 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6228 "We shouldn't be codegening an invalid UsingEnumDecl"
6229 " containing no decls");
6231 for (
const auto *USD : UD.
shadows())
6236 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6238 if (
Module *M = ID.getImportedModule()) {
6240 auto Loc = ID.getLocation();
6241 DBuilder.createImportedDeclaration(
6242 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6243 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6244 getLineNumber(Loc));
6248llvm::DIImportedEntity *
6250 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6252 auto &VH = NamespaceAliasCache[&NA];
6255 llvm::DIImportedEntity *R;
6257 if (
const auto *Underlying =
6260 R = DBuilder.createImportedDeclaration(
6263 getLineNumber(Loc), NA.
getName());
6265 R = DBuilder.createImportedDeclaration(
6268 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6274CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6278 auto I = NamespaceCache.find(NSDecl);
6279 if (I != NamespaceCache.end())
6282 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6284 llvm::DINamespace *NS =
6285 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6286 NamespaceCache[NSDecl].reset(NS);
6291 assert(TheCU &&
"no main compile unit");
6292 TheCU->setDWOId(Signature);
6298 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6299 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6301 ? CreateTypeDefinition(E.Type, E.Unit)
6303 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6307 for (
const auto &P : ObjCMethodCache) {
6308 if (P.second.empty())
6311 QualType QTy(P.first->getTypeForDecl(), 0);
6313 assert(It != TypeCache.end());
6315 llvm::DICompositeType *InterfaceDecl =
6318 auto CurElts = InterfaceDecl->getElements();
6322 for (
auto &SubprogramDirect : P.second)
6323 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6324 EltTys.push_back(SubprogramDirect.getPointer());
6326 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6327 DBuilder.replaceArrays(InterfaceDecl, Elements);
6330 for (
const auto &P : ReplaceMap) {
6333 assert(Ty->isForwardDecl());
6335 auto It = TypeCache.find(P.first);
6336 assert(It != TypeCache.end());
6339 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6343 for (
const auto &P : FwdDeclReplaceMap) {
6346 llvm::Metadata *Repl;
6348 auto It = DeclCache.find(P.first);
6352 if (It == DeclCache.end())
6357 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6358 Repl = GVE->getVariable();
6364 for (
auto &RT : RetainedTypes)
6365 if (
auto MD = TypeCache[RT])
6368 DBuilder.finalize();
6373 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6374 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6375 DBuilder.retainType(DieTy);
6379 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6380 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6381 DBuilder.retainType(DieTy);
6385 if (LexicalBlockStack.empty())
6386 return llvm::DebugLoc();
6388 llvm::MDNode *
Scope = LexicalBlockStack.back();
6389 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6390 getColumnNumber(Loc),
Scope);
6393llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6397 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6398 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6399 return llvm::DINode::FlagZero;
6404 bool SupportsDWARFv4Ext =
6406 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6407 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6409 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6410 return llvm::DINode::FlagZero;
6412 return llvm::DINode::FlagAllCallsDescribed;
6423 return DBuilder.createConstantValueExpression(
6424 Val.
getFloat().bitcastToAPInt().getZExtValue());
6429 llvm::APSInt
const &ValInt = Val.
getInt();
6430 std::optional<uint64_t> ValIntOpt;
6431 if (ValInt.isUnsigned())
6432 ValIntOpt = ValInt.tryZExtValue();
6433 else if (
auto tmp = ValInt.trySExtValue())
6436 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6439 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6444CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6446 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6447 CGF.CurLexicalScope =
this;
6449 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6454 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6467#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6469 Label = "__ubsan_check_" #Name; \
6473#undef SANITIZER_CHECK
6484#define SANITIZER(NAME, ID) \
6485 case SanitizerKind::SO_##ID: \
6486 Label = "__ubsan_check_" NAME; \
6488#include "clang/Basic/Sanitizers.def"
6490 llvm_unreachable(
"unexpected sanitizer kind");
6495 for (
unsigned int i = 0; i < Label.length(); i++)
6496 if (!std::isalpha(Label[i]))
6505 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6507 if (!DI || !CheckDebugLoc)
6508 return CheckDebugLoc;
6509 const auto &AnnotateDebugInfo =
6510 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6511 if (AnnotateDebugInfo.empty())
6512 return CheckDebugLoc;
6515 if (Ordinals.size() == 1)
6520 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6521 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6523 return CheckDebugLoc;
6531 assert(!CGF->IsSanitizerScope);
6532 CGF->IsSanitizerScope =
true;
6536 assert(CGF->IsSanitizerScope);
6537 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.