41#include "llvm/ADT/DenseSet.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DerivedTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/Metadata.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/MD5.h"
53#include "llvm/Support/Path.h"
54#include "llvm/Support/SHA1.h"
55#include "llvm/Support/SHA256.h"
56#include "llvm/Support/TimeProfiler.h"
64 if (TI.isAlignRequired())
92 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
96 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
120 if (!llvm::isa<ParmVarDecl>(VD))
130 if (!Method->isImplicit() || !Method->isPropertyAccessor())
141 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
142 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
143 DBuilder(CGM.getModule()) {
148 assert(LexicalBlockStack.empty() &&
149 "Region stack mismatch, stack not empty!");
152void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
153 uint64_t Group, uint8_t Rank) {
154 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
158 Rank = std::min<uint8_t>(Rank, 7);
160 const llvm::DebugLoc &DL = I->getDebugLoc();
165 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
166 Group = DL->getAtomGroup();
167 Rank = DL->getAtomRank();
172 KeyInstructionsInfo.HighestEmittedAtom =
173 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
176 llvm::DILocation *NewDL = llvm::DILocation::get(
177 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
178 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
179 I->setDebugLoc(NewDL);
183 llvm::Value *Backup) {
185 KeyInstructionsInfo.CurrentAtom);
191 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
194 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
195 if (!SP || !SP->getKeyInstructionsEnabled())
198 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
200 llvm::Instruction *BackupI =
201 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
206 addInstSourceAtomMetadata(BackupI, Group, 2);
212 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
213 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
216 addInstSourceAtomMetadata(BackupI, Group, Rank++);
222 KeyInstructionsInfo.NextAtom = 1;
223 KeyInstructionsInfo.HighestEmittedAtom = 0;
224 KeyInstructionsInfo.CurrentAtom = 0;
230 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
231 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
239 DI->KeyInstructionsInfo.NextAtom =
240 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
241 DI->KeyInstructionsInfo.NextAtom);
243 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
249 init(TemporaryLocation);
256 init(TemporaryLocation, DefaultToEmpty);
260 bool DefaultToEmpty) {
267 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
269 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
272 if (TemporaryLocation.
isValid()) {
273 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
277 if (DefaultToEmpty) {
278 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
283 assert(!DI->LexicalBlockStack.empty());
284 CGF->Builder.SetCurrentDebugLocation(
285 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
286 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
296 if (!CGF.getDebugInfo()) {
300 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
304 if (Loc->getAtomGroup())
305 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
306 Loc->getColumn(), Loc->getScope(),
307 Loc->getInlinedAt(), Loc.isImplicitCode());
308 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
316 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
322 if (!CGF.getDebugInfo()) {
326 auto &DI = *CGF.getDebugInfo();
327 SavedLocation = DI.getLocation();
328 assert((DI.getInlinedAt() ==
329 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
330 "CGDebugInfo and IRBuilder are out of sync");
332 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
338 auto &DI = *CGF->getDebugInfo();
339 DI.EmitInlineFunctionEnd(CGF->Builder);
340 DI.EmitLocation(CGF->Builder, SavedLocation);
348 CurLoc = CGM.getContext().getSourceManager().getFileLoc(Loc);
353 if (LexicalBlockStack.empty())
359 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
362 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
363 LexicalBlockStack.pop_back();
364 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
365 LBF->getScope(), getOrCreateFile(CurLoc)));
368 LexicalBlockStack.pop_back();
369 LexicalBlockStack.emplace_back(
370 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
374llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
375 llvm::DIScope *Mod = getParentModuleOrNull(D);
380llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
385 auto I = RegionMap.find(Context);
386 if (I != RegionMap.end()) {
387 llvm::Metadata *
V = I->second;
388 return dyn_cast_or_null<llvm::DIScope>(
V);
392 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
393 return getOrCreateNamespace(NSDecl);
395 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
396 if (!RDecl->isDependentType())
402PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
403 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
410 if (CGM.getCodeGenOpts().EmitCodeView) {
431StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
432 return internString(GetName(FD));
435StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
436 SmallString<256> MethodName;
437 llvm::raw_svector_ostream
OS(MethodName);
440 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
441 OS << OID->getName();
442 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
443 OS << OID->getName();
444 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
445 if (OC->IsClassExtension()) {
446 OS << OC->getClassInterface()->getName();
448 OS << OC->getIdentifier()->getNameStart() <<
'('
449 << OC->getIdentifier()->getNameStart() <<
')';
451 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
452 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
456 return internString(
OS.str());
459StringRef CGDebugInfo::getSelectorName(Selector S) {
463StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
466 return internString(GetName(RD));
472 return II->getName();
477 if (CGM.getCodeGenOpts().EmitCodeView) {
480 "Typedef should not be in another decl context!");
481 assert(D->getDeclName().getAsIdentifierInfo() &&
482 "Typedef was not named!");
483 return D->getDeclName().getAsIdentifierInfo()->getName();
486 if (CGM.getLangOpts().CPlusPlus) {
489 ASTContext &Context = CGM.getContext();
493 Name = DD->getName();
494 else if (
const TypedefNameDecl *TND =
498 Name = TND->getName();
501 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
502 if (CXXRD->isLambda())
504 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
507 SmallString<256> UnnamedType(
"<unnamed-type-");
510 return internString(UnnamedType);
518std::optional<llvm::DIFile::ChecksumKind>
519CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
522 if (!CGM.getCodeGenOpts().EmitCodeView &&
523 CGM.getCodeGenOpts().DwarfVersion < 5)
526 SourceManager &
SM = CGM.getContext().getSourceManager();
527 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
531 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
532 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
534 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
535 return llvm::DIFile::CSK_MD5;
537 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
538 return llvm::DIFile::CSK_SHA1;
540 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
541 return llvm::DIFile::CSK_SHA256;
545 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
548std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
550 if (!CGM.getCodeGenOpts().EmbedSource)
553 bool SourceInvalid =
false;
554 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
562llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
563 SourceManager &
SM = CGM.getContext().getSourceManager();
566 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
572 FileName = TheCU->getFile()->getFilename();
573 CSInfo = TheCU->getFile()->getChecksum();
575 PresumedLoc PLoc =
SM.getPresumedLoc(
SM.getFileLoc(Loc));
579 FileName = TheCU->getFile()->getFilename();
587 auto It = DIFileCache.find(
FileName.data());
588 if (It != DIFileCache.end()) {
590 if (llvm::Metadata *
V = It->second)
595 SmallString<64> Checksum;
597 std::optional<llvm::DIFile::ChecksumKind> CSKind =
598 computeChecksum(FID, Checksum);
600 CSInfo.emplace(*CSKind, Checksum);
603 getSource(
SM,
SM.getFileID(
SM.getFileLoc(Loc))));
606llvm::DIFile *CGDebugInfo::createFile(
608 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
609 std::optional<StringRef> Source) {
613 std::string CurDir =
remapDIPath(getCurrentDirname());
614 SmallString<128> DirBuf;
615 SmallString<128> FileBuf;
616 if (llvm::sys::path::is_absolute(RemappedFile)) {
619 auto FileIt = llvm::sys::path::begin(RemappedFile);
620 auto FileE = llvm::sys::path::end(RemappedFile);
621 auto CurDirIt = llvm::sys::path::begin(CurDir);
622 auto CurDirE = llvm::sys::path::end(CurDir);
623 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
624 llvm::sys::path::append(DirBuf, *CurDirIt);
625 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
631 for (; FileIt != FileE; ++FileIt)
632 llvm::sys::path::append(FileBuf, *FileIt);
637 if (!llvm::sys::path::is_absolute(
FileName))
641 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
642 DIFileCache[
FileName.data()].reset(F);
648 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
649 if (llvm::sys::path::replace_path_prefix(P, From, To))
651 return P.str().str();
658 return SM.getPresumedLoc(
SM.getFileLoc(Loc)).getLine();
661unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
671 SM.getPresumedLoc(Loc.
isValid() ?
SM.getFileLoc(Loc) : CurLoc);
675StringRef CGDebugInfo::getCurrentDirname() {
683 assert(CGO.DwarfVersion <= 5);
685 llvm::dwarf::SourceLanguage LangTag;
688 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
689 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
690 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
691 else if (LO.CPlusPlus14)
692 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
693 else if (LO.CPlusPlus11)
694 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
696 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
697 }
else if (LO.ObjC) {
698 LangTag = llvm::dwarf::DW_LANG_ObjC;
699 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
700 LangTag = llvm::dwarf::DW_LANG_OpenCL;
701 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
702 LangTag = llvm::dwarf::DW_LANG_C11;
704 LangTag = llvm::dwarf::DW_LANG_C99;
706 LangTag = llvm::dwarf::DW_LANG_C89;
712static llvm::DISourceLanguageName
720 uint32_t LangVersion = 0;
721 llvm::dwarf::SourceLanguageName LangTag;
724 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
726 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
729 }
else if (LO.ObjC) {
730 LangTag = llvm::dwarf::DW_LNAME_ObjC;
731 }
else if (LO.OpenCL) {
732 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
734 LangTag = llvm::dwarf::DW_LNAME_C;
738 return llvm::DISourceLanguageName(LangTag, LangVersion);
741void CGDebugInfo::CreateCompileUnit() {
742 SmallString<64> Checksum;
743 std::optional<llvm::DIFile::ChecksumKind> CSKind;
744 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
754 SourceManager &
SM = CGM.getContext().getSourceManager();
755 auto &CGO = CGM.getCodeGenOpts();
756 const LangOptions &LO = CGM.getLangOpts();
757 std::string MainFileName = CGO.MainFileName;
758 if (MainFileName.empty())
759 MainFileName =
"<stdin>";
765 std::string MainFileDir;
767 SM.getFileEntryRefForID(
SM.getMainFileID())) {
768 MainFileDir = std::string(MainFile->getDir().getName());
769 if (!llvm::sys::path::is_absolute(MainFileName)) {
770 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
771 llvm::sys::path::Style Style =
773 ? (CGM.getTarget().getTriple().isOSWindows()
774 ? llvm::sys::path::Style::windows_backslash
775 : llvm::sys::path::Style::posix)
776 : llvm::sys::path::Style::native;
777 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
778 MainFileName = std::string(
779 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
786 if (MainFile->getName() == MainFileName &&
788 MainFile->getName().rsplit(
'.').second)
790 MainFileName = CGM.getModule().getName().str();
792 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
799 unsigned RuntimeVers = 0;
803 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
805 case llvm::codegenoptions::NoDebugInfo:
806 case llvm::codegenoptions::LocTrackingOnly:
807 EmissionKind = llvm::DICompileUnit::NoDebug;
809 case llvm::codegenoptions::DebugLineTablesOnly:
810 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
812 case llvm::codegenoptions::DebugDirectivesOnly:
813 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
815 case llvm::codegenoptions::DebugInfoConstructor:
816 case llvm::codegenoptions::LimitedDebugInfo:
817 case llvm::codegenoptions::FullDebugInfo:
818 case llvm::codegenoptions::UnusedTypeInfo:
819 EmissionKind = llvm::DICompileUnit::FullDebug;
824 auto &CGOpts = CGM.getCodeGenOpts();
830 CSInfo.emplace(*CSKind, Checksum);
831 llvm::DIFile *CUFile = DBuilder.createFile(
833 getSource(
SM,
SM.getMainFileID()));
835 StringRef Sysroot, SDK;
836 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
837 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
838 auto B = llvm::sys::path::rbegin(Sysroot);
839 auto E = llvm::sys::path::rend(Sysroot);
841 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
846 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
847 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
848 CGOpts.DebugNameTable);
849 if (CGM.getTarget().getTriple().isNVPTX())
850 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
851 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
852 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
855 TheCU = DBuilder.createCompileUnit(
857 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
858 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
859 CGOpts.PrepareForThinLTO,
860 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
861 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
862 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
865llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
869#define BUILTIN_TYPE(Id, SingletonId)
870#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
871#include "clang/AST/BuiltinTypes.def"
872 case BuiltinType::Dependent:
873 llvm_unreachable(
"Unexpected builtin type");
874 case BuiltinType::NullPtr:
875 return DBuilder.createNullPtrType();
876 case BuiltinType::Void:
878 case BuiltinType::ObjCClass:
881 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
882 "objc_class", TheCU, TheCU->getFile(), 0);
884 case BuiltinType::ObjCId: {
895 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
896 "objc_class", TheCU, TheCU->getFile(), 0);
898 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
900 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
902 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
903 (uint64_t)0, 0, llvm::DINode::FlagZero,
904 nullptr, llvm::DINodeArray());
906 DBuilder.replaceArrays(
907 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
908 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
909 llvm::DINode::FlagZero, ISATy)));
912 case BuiltinType::ObjCSel: {
914 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
915 "objc_selector", TheCU,
916 TheCU->getFile(), 0);
920#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
921 case BuiltinType::Id: \
922 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
924#include "clang/Basic/OpenCLImageTypes.def"
925 case BuiltinType::OCLSampler:
926 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
927 case BuiltinType::OCLEvent:
928 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
929 case BuiltinType::OCLClkEvent:
930 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
931 case BuiltinType::OCLQueue:
932 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
933 case BuiltinType::OCLReserveID:
934 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
935#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
936 case BuiltinType::Id: \
937 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
938#include "clang/Basic/OpenCLExtensionTypes.def"
939#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
940 case BuiltinType::Id: \
941 return getOrCreateStructPtrType(#Name, SingletonId);
942#include "clang/Basic/HLSLIntangibleTypes.def"
944#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
945#include "clang/Basic/AArch64ACLETypes.def"
947 if (BT->
getKind() == BuiltinType::MFloat8) {
948 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
949 BTName = BT->
getName(CGM.getLangOpts());
952 return DBuilder.createBasicType(BTName, Size, Encoding);
954 ASTContext::BuiltinVectorTypeInfo Info =
956 BT->
getKind() == BuiltinType::SveCount
957 ? ASTContext::BuiltinVectorTypeInfo(
958 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
960 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
967 "Unsupported number of vectors for svcount_t");
969 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
970 llvm::Metadata *BitStride =
nullptr;
971 if (BT->
getKind() == BuiltinType::SveBool) {
972 Info.
ElementType = CGM.getContext().UnsignedCharTy;
973 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
974 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
975 }
else if (BT->
getKind() == BuiltinType::SveCount) {
977 Info.
ElementType = CGM.getContext().UnsignedCharTy;
980 llvm::Metadata *LowerBound, *UpperBound;
981 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
982 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
983 if (Info.
EC.isScalable()) {
984 unsigned NumElemsPerVG = NumElems / 2;
985 SmallVector<uint64_t, 9> Expr(
986 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
987 46, 0, llvm::dwarf::DW_OP_mul,
988 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
989 UpperBound = DBuilder.createExpression(Expr);
991 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
992 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
994 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
995 nullptr, LowerBound, UpperBound,
nullptr);
996 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
997 llvm::DIType *ElemTy =
998 getOrCreateType(Info.
ElementType, TheCU->getFile());
1000 return DBuilder.createVectorType( 0, Align, ElemTy,
1001 SubscriptArray, BitStride);
1005#define PPC_VECTOR_TYPE(Name, Id, size) \
1006 case BuiltinType::Id:
1007#include "clang/Basic/PPCTypes.def"
1010#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1011#include "clang/Basic/RISCVVTypes.def"
1013 ASTContext::BuiltinVectorTypeInfo Info =
1014 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1016 unsigned ElementCount = Info.
EC.getKnownMinValue();
1017 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1019 bool Fractional =
false;
1022 unsigned FixedSize = ElementCount * SEW;
1023 if (Info.
ElementType == CGM.getContext().BoolTy) {
1026 }
else if (FixedSize < 64) {
1029 LMUL = 64 / FixedSize;
1031 LMUL = FixedSize / 64;
1035 SmallVector<uint64_t, 12> Expr(
1039 {llvm::dwarf::DW_OP_bregx,
1042 llvm::dwarf::DW_OP_constu,
1044 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1046 Expr.push_back(llvm::dwarf::DW_OP_div);
1048 Expr.push_back(llvm::dwarf::DW_OP_mul);
1051 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1053 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1056 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1057 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1058 auto *UpperBound = DBuilder.createExpression(Expr);
1059 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1060 nullptr, LowerBound, UpperBound,
nullptr);
1061 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1062 llvm::DIType *ElemTy =
1063 getOrCreateType(Info.
ElementType, TheCU->getFile());
1066 return DBuilder.createVectorType(0, Align, ElemTy,
1070#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1071 case BuiltinType::Id: { \
1074 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1075 MangledName, TheCU, TheCU->getFile(), 0); \
1076 return SingletonId; \
1078#include "clang/Basic/WebAssemblyReferenceTypes.def"
1079#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1080 case BuiltinType::Id: { \
1083 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1084 TheCU, TheCU->getFile(), 0); \
1085 return SingletonId; \
1087#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1088 case BuiltinType::Id: { \
1091 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1092 return SingletonId; \
1094#include "clang/Basic/AMDGPUTypes.def"
1095 case BuiltinType::UChar:
1096 case BuiltinType::Char_U:
1097 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1099 case BuiltinType::Char_S:
1100 case BuiltinType::SChar:
1101 Encoding = llvm::dwarf::DW_ATE_signed_char;
1103 case BuiltinType::Char8:
1104 case BuiltinType::Char16:
1105 case BuiltinType::Char32:
1106 Encoding = llvm::dwarf::DW_ATE_UTF;
1108 case BuiltinType::UShort:
1109 case BuiltinType::UInt:
1110 case BuiltinType::UInt128:
1111 case BuiltinType::ULong:
1112 case BuiltinType::WChar_U:
1113 case BuiltinType::ULongLong:
1114 Encoding = llvm::dwarf::DW_ATE_unsigned;
1116 case BuiltinType::Short:
1117 case BuiltinType::Int:
1118 case BuiltinType::Int128:
1119 case BuiltinType::Long:
1120 case BuiltinType::WChar_S:
1121 case BuiltinType::LongLong:
1122 Encoding = llvm::dwarf::DW_ATE_signed;
1124 case BuiltinType::Bool:
1125 Encoding = llvm::dwarf::DW_ATE_boolean;
1127 case BuiltinType::Half:
1128 case BuiltinType::Float:
1129 case BuiltinType::LongDouble:
1130 case BuiltinType::Float16:
1131 case BuiltinType::BFloat16:
1132 case BuiltinType::Float128:
1133 case BuiltinType::Double:
1134 case BuiltinType::Ibm128:
1140 Encoding = llvm::dwarf::DW_ATE_float;
1142 case BuiltinType::ShortAccum:
1143 case BuiltinType::Accum:
1144 case BuiltinType::LongAccum:
1145 case BuiltinType::ShortFract:
1146 case BuiltinType::Fract:
1147 case BuiltinType::LongFract:
1148 case BuiltinType::SatShortFract:
1149 case BuiltinType::SatFract:
1150 case BuiltinType::SatLongFract:
1151 case BuiltinType::SatShortAccum:
1152 case BuiltinType::SatAccum:
1153 case BuiltinType::SatLongAccum:
1154 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1156 case BuiltinType::UShortAccum:
1157 case BuiltinType::UAccum:
1158 case BuiltinType::ULongAccum:
1159 case BuiltinType::UShortFract:
1160 case BuiltinType::UFract:
1161 case BuiltinType::ULongFract:
1162 case BuiltinType::SatUShortAccum:
1163 case BuiltinType::SatUAccum:
1164 case BuiltinType::SatULongAccum:
1165 case BuiltinType::SatUShortFract:
1166 case BuiltinType::SatUFract:
1167 case BuiltinType::SatULongFract:
1168 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1172 BTName = BT->
getName(CGM.getLangOpts());
1175 return DBuilder.createBasicType(BTName, Size, Encoding);
1178llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1179 SmallString<32> Name;
1180 llvm::raw_svector_ostream
OS(Name);
1181 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1184 ? llvm::dwarf::DW_ATE_unsigned
1185 : llvm::dwarf::DW_ATE_signed;
1186 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1187 Encoding, llvm::DINode::FlagZero, 0,
1191llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1193 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1195 Encoding = llvm::dwarf::DW_ATE_lo_user;
1198 return DBuilder.createBasicType(
"complex", Size, Encoding);
1212 return llvm::dwarf::DW_TAG_const_type;
1216 return llvm::dwarf::DW_TAG_volatile_type;
1220 return llvm::dwarf::DW_TAG_restrict_type;
1222 return (llvm::dwarf::Tag)0;
1225llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1226 llvm::DIFile *Unit) {
1227 QualifierCollector Qc;
1241 bool AuthenticatesNullValues =
1244 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1245 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1246 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1247 ExtraDiscr, IsaPointer,
1248 AuthenticatesNullValues);
1250 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1251 return getOrCreateType(QualType(
T, 0), Unit);
1255 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1259 return DBuilder.createQualifiedType(Tag, FromTy);
1262llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1263 llvm::DIFile *Unit) {
1272 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1277 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1283 return DBuilder.createQualifiedType(Tag, FromTy);
1286llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1287 llvm::DIFile *Unit) {
1293 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1295 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1299llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1300 llvm::DIFile *Unit) {
1301 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1307 case llvm::dwarf::DW_LANG_C_plus_plus:
1308 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1309 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1311 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1321 case llvm::dwarf::DW_LNAME_C_plus_plus:
1323 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1334 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1335 SourceLang.hasVersionedName())
1337 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1341 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1367 llvm::DICompileUnit *TheCU) {
1385 llvm::DICompileUnit *TheCU) {
1391 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1393 if (RD->isDynamicClass() &&
1399 llvm::raw_svector_ostream Out(Identifier);
1406 llvm::dwarf::Tag Tag;
1408 Tag = llvm::dwarf::DW_TAG_structure_type;
1410 Tag = llvm::dwarf::DW_TAG_union_type;
1415 Tag = llvm::dwarf::DW_TAG_class_type;
1420llvm::DICompositeType *
1421CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1422 llvm::DIScope *Ctx) {
1423 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1424 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1426 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1427 const unsigned Line =
1429 StringRef RDName = getClassName(RD);
1436 Size = CGM.getContext().getTypeSize(Ty);
1438 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1443 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1444 if (!CXXRD->hasDefinition() ||
1445 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1446 Flags |= llvm::DINode::FlagNonTrivial;
1449 SmallString<256> Identifier;
1451 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1453 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1456 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1457 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1458 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1459 CollectCXXTemplateParams(TSpecial, DefUnit));
1460 ReplaceMap.emplace_back(
1461 std::piecewise_construct, std::make_tuple(Ty),
1462 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1466llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1469 llvm::DIFile *Unit) {
1474 std::optional<unsigned> DWARFAddressSpace =
1475 CGM.getTarget().getDWARFAddressSpace(
1476 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1478 const BTFTagAttributedType *BTFAttrTy;
1479 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1480 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1482 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1483 SmallVector<llvm::Metadata *, 4> Annots;
1485 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1487 llvm::Metadata *Ops[2] = {
1488 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1489 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1490 Annots.insert(Annots.begin(),
1491 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1493 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1496 llvm::DINodeArray Annotations =
nullptr;
1497 if (Annots.size() > 0)
1498 Annotations = DBuilder.getOrCreateArray(Annots);
1500 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1501 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1502 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1503 Size, Align, DWARFAddressSpace);
1505 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1506 Align, DWARFAddressSpace, StringRef(),
1510llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1511 llvm::DIType *&
Cache) {
1514 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1515 TheCU, TheCU->getFile(), 0);
1516 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1517 Cache = DBuilder.createPointerType(
Cache, Size);
1521uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1522 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1523 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1533 if (CGM.getLangOpts().OpenCL) {
1534 FType = CGM.getContext().IntTy;
1535 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1536 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1538 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1539 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1540 FType = CGM.getContext().IntTy;
1541 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1542 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1544 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1545 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1546 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1547 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1548 EltTys.push_back(DBuilder.createMemberType(
1549 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1550 FieldOffset, llvm::DINode::FlagZero, DescTy));
1551 FieldOffset += FieldSize;
1557llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1558 llvm::DIFile *Unit) {
1559 SmallVector<llvm::Metadata *, 8> EltTys;
1562 llvm::DINodeArray Elements;
1565 FType = CGM.getContext().UnsignedLongTy;
1566 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1567 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1569 Elements = DBuilder.getOrCreateArray(EltTys);
1572 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1575 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1576 FieldOffset, 0, Flags,
nullptr, Elements);
1581 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1583 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1586 Elements = DBuilder.getOrCreateArray(EltTys);
1592 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1593 Flags,
nullptr, Elements);
1595 return DBuilder.createPointerType(EltTy, Size);
1598static llvm::SmallVector<TemplateArgument>
1600 assert(Ty->isTypeAlias());
1609 ArrayRef SubstArgs = Ty->template_arguments();
1612 if (Param->isParameterPack()) {
1621 if (SubstArgs.empty()) {
1630 SpecArgs.push_back(SubstArgs.front());
1631 SubstArgs = SubstArgs.drop_front();
1636llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1637 llvm::DIFile *Unit) {
1638 assert(Ty->isTypeAlias());
1639 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1641 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1649 SmallString<128> NS;
1650 llvm::raw_svector_ostream
OS(NS);
1652 auto PP = getPrintingPolicy();
1655 SourceLocation Loc =
AliasDecl->getLocation();
1657 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1658 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1667 llvm::raw_string_ostream
OS(Name);
1669 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1670 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1671 !HasReconstitutableArgs(Args.Args))
1672 printTemplateArgumentList(OS, Args.Args, PP);
1674 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1675 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1676 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1680 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1682 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1699 return llvm::DINode::FlagZero;
1703 return llvm::DINode::FlagPrivate;
1705 return llvm::DINode::FlagProtected;
1707 return llvm::DINode::FlagPublic;
1709 return llvm::DINode::FlagZero;
1711 llvm_unreachable(
"unexpected access enumerator");
1714llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1715 llvm::DIFile *Unit) {
1716 llvm::DIType *Underlying =
1728 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1730 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1735 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1736 getOrCreateFile(Loc), getLineNumber(Loc),
1737 getDeclContextDescriptor(Ty->
getDecl()), Align,
1738 Flags, Annotations);
1748 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1750 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1752 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1754 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1756 return llvm::dwarf::DW_CC_BORLAND_pascal;
1758 return llvm::dwarf::DW_CC_LLVM_Win64;
1760 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1764 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1766 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1768 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1770 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1772 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1774 return llvm::dwarf::DW_CC_LLVM_Swift;
1776 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1778 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1780 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1782 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1784 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1786 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1788 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1789#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1803 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1809 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1811 Flags |= llvm::DINode::FlagLValueReference;
1813 Flags |= llvm::DINode::FlagRValueReference;
1817llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1818 llvm::DIFile *Unit) {
1819 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1821 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1827 SmallVector<llvm::Metadata *, 16> EltTys;
1830 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1832 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1836 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1839 for (
const QualType &ParamType : FPT->param_types())
1840 EltTys.push_back(getOrCreateType(ParamType, Unit));
1841 if (FPT->isVariadic())
1842 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1845 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1846 llvm::DIType *F = DBuilder.createSubroutineType(
1851llvm::DIDerivedType *
1852CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1853 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1854 StringRef Name = BitFieldDecl->
getName();
1855 QualType Ty = BitFieldDecl->
getType();
1856 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1859 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1860 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1863 llvm::DIFile *
File = getOrCreateFile(Loc);
1864 unsigned Line = getLineNumber(Loc);
1866 const CGBitFieldInfo &BitFieldInfo =
1867 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1869 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1876 if (CGM.getDataLayout().isBigEndian())
1878 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1880 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1881 return DBuilder.createBitFieldMemberType(
1882 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1883 Flags, DebugType, Annotations);
1886llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1887 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1888 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1890 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1915 if (PreviousFieldsDI.empty())
1919 auto *PreviousMDEntry =
1920 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1921 auto *PreviousMDField =
1922 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1923 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1924 PreviousMDField->getSizeInBits() == 0)
1928 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1930 assert(PreviousBitfield->isBitField());
1932 if (!PreviousBitfield->isZeroLengthBitField())
1935 QualType Ty = PreviousBitfield->getType();
1936 SourceLocation Loc = PreviousBitfield->getLocation();
1937 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1938 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1939 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1941 llvm::DIFile *
File = getOrCreateFile(Loc);
1942 unsigned Line = getLineNumber(Loc);
1948 llvm::DINode::DIFlags Flags =
1950 llvm::DINodeArray Annotations =
1951 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1952 return DBuilder.createBitFieldMemberType(
1953 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1954 Flags, DebugType, Annotations);
1957llvm::DIType *CGDebugInfo::createFieldType(
1959 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1960 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1961 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1964 llvm::DIFile *file = getOrCreateFile(loc);
1965 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1968 auto Align = AlignInBits;
1969 if (!
type->isIncompleteArrayType()) {
1970 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1971 SizeInBits = TI.
Width;
1977 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1978 offsetInBits, flags, debugType, Annotations);
1982CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1983 llvm::DIFile *FileScope) {
1987 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1990 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1991 SP = DBuilder.createFunction(
1992 FileScope, FuncName, StringRef(),
1993 FileScope, 0, DIFnTy,
1995 llvm::DINode::FlagArtificial,
1996 llvm::DISubprogram::SPFlagDefinition,
1997 nullptr,
nullptr,
nullptr,
1998 nullptr, StringRef(),
1999 CGM.getCodeGenOpts().DebugKeyInstructions);
2006CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2008 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2010 assert(
Capture.capturesVariable());
2012 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2013 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2015 return CaptureDecl->
getName();
2018void CGDebugInfo::CollectRecordLambdaFields(
2019 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2020 llvm::DIType *RecordTy) {
2025 unsigned fieldno = 0;
2028 I != E; ++I, ++Field, ++fieldno) {
2029 const LambdaCapture &
Capture = *I;
2031 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2033 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2043 Loc =
Field->getLocation();
2044 }
else if (
Capture.capturesVariable()) {
2047 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2048 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2055 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2057 elements.push_back(createFieldType(
2059 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2063llvm::DIDerivedType *
2064CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2065 const RecordDecl *RD) {
2069 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2070 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2072 unsigned LineNumber = getLineNumber(Var->
getLocation());
2073 StringRef VName = Var->
getName();
2077 llvm::Constant *
C =
nullptr;
2082 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2083 if (
Value->isFloat())
2084 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2089 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2090 ? llvm::dwarf::DW_TAG_variable
2091 : llvm::dwarf::DW_TAG_member;
2093 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2094 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2099void CGDebugInfo::CollectRecordNormalField(
2100 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2101 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2102 const RecordDecl *RD) {
2107 if (
name.empty() && !
type->isRecordType())
2110 llvm::DIType *FieldType;
2112 llvm::DIDerivedType *BitFieldType;
2113 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2114 if (llvm::DIType *Separator =
2115 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2116 elements.push_back(Separator);
2119 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2122 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2125 elements.push_back(FieldType);
2128void CGDebugInfo::CollectRecordNestedType(
2129 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2130 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2137 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2138 elements.push_back(nestedType);
2141void CGDebugInfo::CollectRecordFields(
2142 const RecordDecl *record, llvm::DIFile *tunit,
2143 SmallVectorImpl<llvm::Metadata *> &elements,
2144 llvm::DICompositeType *RecordTy) {
2145 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2147 if (CXXDecl && CXXDecl->
isLambda())
2148 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2150 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2153 unsigned fieldNo = 0;
2157 for (
const auto *I : record->
decls())
2158 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2159 if (
V->hasAttr<NoDebugAttr>())
2164 if (CGM.getCodeGenOpts().EmitCodeView &&
2172 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2173 if (MI != StaticDataMemberCache.end()) {
2174 assert(MI->second &&
2175 "Static data member declaration should still exist");
2176 elements.push_back(MI->second);
2178 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2179 elements.push_back(Field);
2181 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2182 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2183 elements, RecordTy, record);
2187 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2190 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2195 if (!nestedType->isImplicit() &&
2196 nestedType->getDeclContext() == record)
2197 CollectRecordNestedType(nestedType, elements);
2203llvm::DISubroutineType *
2204CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2205 llvm::DIFile *Unit) {
2206 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2208 return cast_or_null<llvm::DISubroutineType>(
2209 getOrCreateType(QualType(
Func, 0), Unit));
2212 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2213 ThisType =
Method->getThisType();
2215 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2218llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2219 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2220 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2222 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2225llvm::DISubroutineType *
2226CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2227 const FunctionProtoType *
Func,
2228 llvm::DIFile *Unit,
bool SkipFirst) {
2229 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2244 getOrCreateType(CGM.getContext().getFunctionType(
2245 Func->getReturnType(),
Func->getParamTypes(), EPI),
2247 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2248 assert(Args.size() &&
"Invalid number of arguments!");
2250 SmallVector<llvm::Metadata *, 16> Elts;
2253 Elts.push_back(Args[0]);
2255 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2259 if (!HasExplicitObjectParameter) {
2260 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2263 DBuilder.createObjectPointerType(ThisPtrType,
true);
2264 Elts.push_back(ThisPtrType);
2268 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2269 Elts.push_back(Args[i]);
2272 if (HasExplicitObjectParameter) {
2273 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2274 "Expected at least return type and object parameter.");
2275 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2278 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2280 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2287 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2295CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2298 const bool IsCtorOrDtor =
2301 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2308 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2311 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2314 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2317 return CGM.getMangledName(
Method);
2320llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2321 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2324 StringRef MethodName = getFunctionName(
Method);
2325 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2327 StringRef MethodLinkageName;
2334 MethodLinkageName = GetMethodLinkageName(
Method);
2337 llvm::DIFile *MethodDefUnit =
nullptr;
2338 unsigned MethodLine = 0;
2339 if (!
Method->isImplicit()) {
2340 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2341 MethodLine = getLineNumber(
Method->getLocation());
2345 llvm::DIType *ContainingType =
nullptr;
2346 unsigned VIndex = 0;
2347 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2348 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2349 int ThisAdjustment = 0;
2352 if (
Method->isPureVirtual())
2353 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2355 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2357 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2361 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2365 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2367 MethodVFTableLocation ML =
2368 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2376 if (
Method->size_overridden_methods() == 0)
2377 Flags |= llvm::DINode::FlagIntroducedVirtual;
2382 ThisAdjustment = CGM.getCXXABI()
2383 .getVirtualFunctionPrologueThisAdjustment(GD)
2386 ContainingType = RecordTy;
2389 if (
Method->getCanonicalDecl()->isDeleted())
2390 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2392 if (
Method->isNoReturn())
2393 Flags |= llvm::DINode::FlagNoReturn;
2396 Flags |= llvm::DINode::FlagStaticMember;
2397 if (
Method->isImplicit())
2398 Flags |= llvm::DINode::FlagArtificial;
2400 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2401 if (CXXC->isExplicit())
2402 Flags |= llvm::DINode::FlagExplicit;
2403 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2404 if (CXXC->isExplicit())
2405 Flags |= llvm::DINode::FlagExplicit;
2407 if (
Method->hasPrototype())
2408 Flags |= llvm::DINode::FlagPrototyped;
2410 Flags |= llvm::DINode::FlagLValueReference;
2412 Flags |= llvm::DINode::FlagRValueReference;
2413 if (!
Method->isExternallyVisible())
2414 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2415 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2416 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2420 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2421 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2424 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2425 llvm::DISubprogram *SP = DBuilder.createMethod(
2426 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2427 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2428 TParamsArray.get(),
nullptr,
2429 CGM.getCodeGenOpts().DebugKeyInstructions);
2431 SPCache[
Method->getCanonicalDecl()].reset(SP);
2436void CGDebugInfo::CollectCXXMemberFunctions(
2437 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2438 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2443 for (
const auto *I : RD->
decls()) {
2444 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2458 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2467 auto MI = SPCache.find(
Method->getCanonicalDecl());
2468 EltTys.push_back(MI == SPCache.end()
2469 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2470 :
static_cast<llvm::Metadata *
>(MI->second));
2474void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2475 SmallVectorImpl<llvm::Metadata *> &EltTys,
2476 llvm::DIType *RecordTy) {
2477 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2478 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2479 llvm::DINode::FlagZero);
2483 if (CGM.getCodeGenOpts().EmitCodeView) {
2484 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2485 llvm::DINode::FlagIndirectVirtualBase);
2489void CGDebugInfo::CollectCXXBasesAux(
2490 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2491 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2493 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2494 llvm::DINode::DIFlags StartingFlags) {
2495 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2496 for (
const auto &BI : Bases) {
2499 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2501 if (!SeenTypes.insert(Base).second)
2503 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2504 llvm::DINode::DIFlags BFlags = StartingFlags;
2508 if (BI.isVirtual()) {
2509 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2512 BaseOffset = 0 - CGM.getItaniumVTableContext()
2513 .getVirtualBaseOffsetOffset(RD, Base)
2519 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2520 VBPtrOffset = CGM.getContext()
2521 .getASTRecordLayout(RD)
2525 BFlags |= llvm::DINode::FlagVirtual;
2532 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2533 VBPtrOffset, BFlags);
2534 EltTys.push_back(DTy);
2539CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2540 llvm::DIFile *Unit) {
2542 return llvm::DINodeArray();
2543 TemplateArgs &Args = *OArgs;
2544 SmallVector<llvm::Metadata *, 16> TemplateParams;
2545 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2546 const TemplateArgument &TA = Args.Args[i];
2550 Name = Args.TList->getParam(i)->getName();
2554 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2555 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2556 TheCU, Name, TTy, defaultParameter));
2561 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2562 TheCU, Name, TTy, defaultParameter,
2563 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2568 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2569 llvm::Constant *
V =
nullptr;
2572 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2573 !D->
hasAttr<CUDADeviceAttr>()) {
2576 if (
const auto *VD = dyn_cast<VarDecl>(D))
2577 V = CGM.GetAddrOfGlobalVar(VD);
2580 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2581 MD && MD->isImplicitObjectMemberFunction())
2582 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2583 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2584 V = CGM.GetAddrOfFunction(FD);
2587 else if (
const auto *MPT =
2588 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2592 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2594 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2595 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2596 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2597 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2598 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2600 V = ConstantEmitter(CGM).emitAbstract(
2601 SourceLocation(), TPO->getValue(), TPO->getType());
2603 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2605 assert(
V &&
"Failed to find template parameter pointer");
2606 V =
V->stripPointerCasts();
2608 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2609 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2613 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2614 llvm::Constant *
V =
nullptr;
2617 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2623 if (MPT->isMemberDataPointer())
2624 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2626 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2627 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2628 TheCU, Name, TTy, defaultParameter,
V));
2632 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2633 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2635 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2636 TheCU, Name, TTy, defaultParameter,
V));
2639 std::string QualName;
2640 llvm::raw_string_ostream
OS(QualName);
2642 OS, getPrintingPolicy());
2643 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2644 TheCU, Name,
nullptr, QualName, defaultParameter));
2648 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2649 TheCU, Name,
nullptr,
2656 T = CGM.getContext().getLValueReferenceType(
T);
2657 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2658 assert(
V &&
"Expression in template argument isn't constant");
2659 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2660 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2661 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2667 "These argument types shouldn't exist in concrete types");
2670 return DBuilder.getOrCreateArray(TemplateParams);
2673std::optional<CGDebugInfo::TemplateArgs>
2674CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2682 return std::nullopt;
2684std::optional<CGDebugInfo::TemplateArgs>
2685CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2689 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2691 return std::nullopt;
2692 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2693 const TemplateParameterList *TList =
T->getTemplateParameters();
2694 auto TA = TS->getTemplateArgs().asArray();
2695 return {{TList, TA}};
2697std::optional<CGDebugInfo::TemplateArgs>
2698CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2699 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2703 TemplateParameterList *TPList =
2704 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2705 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2706 return {{TPList, TAList.
asArray()}};
2708 return std::nullopt;
2712CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2713 llvm::DIFile *Unit) {
2714 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2717llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2718 llvm::DIFile *Unit) {
2719 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2722llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2723 llvm::DIFile *Unit) {
2724 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2727llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2728 if (!D->
hasAttr<BTFDeclTagAttr>())
2731 SmallVector<llvm::Metadata *, 4> Annotations;
2733 llvm::Metadata *Ops[2] = {
2734 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2735 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2736 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2738 return DBuilder.getOrCreateArray(Annotations);
2741llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2743 return VTablePtrType;
2745 ASTContext &Context = CGM.getContext();
2748 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2749 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2750 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2752 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2753 std::optional<unsigned> DWARFAddressSpace =
2754 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2756 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2757 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2758 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2759 return VTablePtrType;
2762StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2774 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2776 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2786 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2787 VTable->isDeclarationForLinker())
2791 StringRef SymbolName =
"_vtable$";
2793 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2802 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2804 llvm::DIFile *Unit = getOrCreateFile(Loc);
2805 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2807 llvm::DINode::FlagArtificial;
2808 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2809 ? llvm::dwarf::DW_TAG_variable
2810 : llvm::dwarf::DW_TAG_member;
2811 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2812 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2816 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2820 llvm::DIGlobalVariableExpression *GVE =
2821 DBuilder.createGlobalVariableExpression(
2822 TheCU, SymbolName, VTable->getName(), Unit, 0,
2823 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2824 true,
nullptr, DT,
nullptr,
2826 VTable->addDebugInfo(GVE);
2829StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2831 llvm::Function *InitFn) {
2836 return InitFn->getName();
2846 llvm::raw_svector_ostream OS(QualifiedGV);
2848 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2850 std::swap(Quals, GVName);
2854 llvm::raw_svector_ostream OS(InitName);
2856 OS << Quals <<
"::";
2861 llvm_unreachable(
"not an initializer");
2863 OS <<
"`dynamic initializer for '";
2866 OS <<
"`dynamic atexit destructor for '";
2873 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2874 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2875 getPrintingPolicy());
2880 return internString(
OS.str());
2883void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2884 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2893 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2900 llvm::DIType *VPtrTy =
nullptr;
2901 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2902 CGM.getTarget().getCXXABI().isMicrosoft();
2903 if (NeedVTableShape) {
2905 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2906 const VTableLayout &VFTLayout =
2907 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2908 unsigned VSlotCount =
2910 unsigned VTableWidth = PtrWidth * VSlotCount;
2911 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2912 std::optional<unsigned> DWARFAddressSpace =
2913 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2916 llvm::DIType *VTableType = DBuilder.createPointerType(
2917 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2918 EltTys.push_back(VTableType);
2921 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2929 VPtrTy = getOrCreateVTablePtrType(Unit);
2931 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2932 llvm::DIType *VPtrMember =
2933 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2934 llvm::DINode::FlagArtificial, VPtrTy);
2935 EltTys.push_back(VPtrMember);
2940 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2941 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2952 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2953 assert(!D.
isNull() &&
"null type");
2954 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2955 assert(
T &&
"could not create debug info for type");
2964 if (CGM.getCodeGenOpts().getDebugInfo() <=
2965 llvm::codegenoptions::DebugLineTablesOnly)
2969 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2971 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2973 CI->setMetadata(
"heapallocsite", node);
2977 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2979 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2981 auto I = TypeCache.find(TyPtr);
2984 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2985 assert(!Res->isForwardDecl());
2986 TypeCache[TyPtr].reset(Res);
2990 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2991 !CGM.getLangOpts().CPlusPlus)
2997 if (RD->
hasAttr<DLLImportAttr>())
3000 if (MD->hasAttr<DLLImportAttr>())
3013 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3023 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3024 Explicit = TD->isExplicitInstantiationOrSpecialization();
3028 if (CXXDecl->
fields().empty())
3038 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3039 if (CXXRD->isDynamicClass() &&
3040 CGM.getVTableLinkage(CXXRD) ==
3041 llvm::GlobalValue::AvailableExternallyLinkage &&
3052 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3054 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3056 auto I = TypeCache.find(TyPtr);
3063 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3064 assert(!Res->isForwardDecl());
3065 TypeCache[TyPtr].reset(Res);
3072 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3073 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3096 if (Ctor->isCopyOrMoveConstructor())
3098 if (!Ctor->isDeleted())
3117 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3120 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3121 RD->
hasAttr<StandaloneDebugAttr>())
3124 if (!LangOpts.CPlusPlus)
3130 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3146 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3147 Spec = SD->getSpecializationKind();
3156 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3167 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3168 llvm::DIType *
T = getTypeOrNull(Ty);
3169 if (
T &&
T->isForwardDecl())
3173llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3174 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3175 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3179 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3183 auto [Def, Pref] = CreateTypeDefinition(Ty);
3185 return Pref ? Pref : Def;
3188llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3189 llvm::DIFile *Unit) {
3193 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3197 return getOrCreateType(PNA->getTypedefType(), Unit);
3200std::pair<llvm::DIType *, llvm::DIType *>
3201CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3202 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3205 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3213 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3217 return {FwdDecl,
nullptr};
3219 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3220 CollectContainingType(CXXDecl, FwdDecl);
3223 LexicalBlockStack.emplace_back(&*FwdDecl);
3224 RegionMap[RD].reset(FwdDecl);
3227 SmallVector<llvm::Metadata *, 16> EltTys;
3234 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3236 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3237 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3241 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3242 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3243 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3245 LexicalBlockStack.pop_back();
3246 RegionMap.erase(RD);
3248 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3249 DBuilder.replaceArrays(FwdDecl, Elements);
3251 if (FwdDecl->isTemporary())
3253 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3255 RegionMap[RD].reset(FwdDecl);
3257 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3258 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3259 return {FwdDecl, PrefDI};
3261 return {FwdDecl,
nullptr};
3264llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3265 llvm::DIFile *Unit) {
3267 return getOrCreateType(Ty->getBaseType(), Unit);
3270llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3271 llvm::DIFile *Unit) {
3273 SourceLocation Loc = Ty->getDecl()->getLocation();
3276 return DBuilder.createTypedef(
3277 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3278 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3279 getDeclContextDescriptor(Ty->getDecl()));
3306llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3307 llvm::DIFile *Unit) {
3312 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3313 TheCU->getSourceLanguage().getUnversionedName());
3318 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3319 !
ID->getImplementation())
3320 return DBuilder.createForwardDecl(
3321 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3322 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3325 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3326 unsigned Line = getLineNumber(
ID->getLocation());
3330 ObjCInterfaceDecl *Def =
ID->getDefinition();
3332 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3333 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3334 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3335 DefUnit,
Line, RuntimeLang);
3336 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3340 return CreateTypeDefinition(Ty, Unit);
3343llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3344 bool CreateSkeletonCU) {
3349 auto ModRef = ModuleCache.find(M);
3350 if (ModRef != ModuleCache.end())
3354 SmallString<128> ConfigMacros;
3356 llvm::raw_svector_ostream
OS(ConfigMacros);
3357 const auto &PPOpts = CGM.getPreprocessorOpts();
3360 for (
auto &M : PPOpts.Macros) {
3363 const std::string &
Macro = M.first;
3364 bool Undef = M.second;
3365 OS <<
"\"-" << (Undef ?
'U' :
'D');
3381 bool IsRootModule = M ? !M->
Parent :
true;
3385 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3386 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3387 "clang module without ASTFile must be specified by -fmodule-name");
3390 auto RemapPath = [
this](StringRef Path) -> std::string {
3392 StringRef Relative(Remapped);
3393 StringRef CompDir = TheCU->getDirectory();
3394 if (CompDir.empty())
3397 if (Relative.consume_front(CompDir))
3398 Relative.consume_front(llvm::sys::path::get_separator());
3400 return Relative.str();
3403 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3410 Signature = ModSig.truncatedValue();
3414 llvm::DIBuilder DIB(CGM.getModule());
3416 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3417 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3418 PCM = getCurrentDirname();
3422 llvm::sys::path::append(PCM, Mod.
getASTFile());
3423 DIB.createCompileUnit(
3424 TheCU->getSourceLanguage(),
3427 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3428 llvm::DICompileUnit::FullDebug, Signature);
3432 llvm::DIModule *Parent =
3434 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3436 std::string IncludePath = Mod.
getPath().str();
3437 llvm::DIModule *DIMod =
3438 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3439 RemapPath(IncludePath));
3440 ModuleCache[M].reset(DIMod);
3444llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3445 llvm::DIFile *Unit) {
3447 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3448 unsigned Line = getLineNumber(
ID->getLocation());
3450 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3456 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3457 if (
ID->getImplementation())
3458 Flags |= llvm::DINode::FlagObjcClassComplete;
3460 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3461 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3462 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3463 nullptr, llvm::DINodeArray(), RuntimeLang);
3465 QualType QTy(Ty, 0);
3466 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3469 LexicalBlockStack.emplace_back(RealDecl);
3470 RegionMap[Ty->
getDecl()].reset(RealDecl);
3473 SmallVector<llvm::Metadata *, 16> EltTys;
3475 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3477 llvm::DIType *SClassTy =
3478 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3482 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3483 llvm::DINode::FlagZero);
3484 EltTys.push_back(InhTag);
3488 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3489 SourceLocation Loc = PD->getLocation();
3490 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3491 unsigned PLine = getLineNumber(Loc);
3492 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3493 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3494 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3495 PD->getName(), PUnit, PLine,
3497 : getSelectorName(PD->getGetterName()),
3499 : getSelectorName(PD->getSetterName()),
3500 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3501 EltTys.push_back(PropertyNode);
3506 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3510 llvm::DenseSet<IsClassAndIdent> PropertySet;
3512 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3513 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3515 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3516 for (
auto *PD : ClassExt->properties()) {
3517 PropertySet.insert(GetIsClassAndIdent(PD));
3520 for (
const auto *PD :
ID->properties()) {
3523 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3529 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3530 unsigned FieldNo = 0;
3531 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3532 Field =
Field->getNextIvar(), ++FieldNo) {
3533 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3537 StringRef FieldName =
Field->getName();
3540 if (FieldName.empty())
3544 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3545 unsigned FieldLine = getLineNumber(
Field->getLocation());
3546 QualType FType =
Field->getType();
3553 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3554 : CGM.getContext().getTypeSize(FType);
3559 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3563 if (
Field->isBitField()) {
3565 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3566 FieldOffset %= CGM.getContext().getCharWidth();
3574 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3576 Flags = llvm::DINode::FlagProtected;
3578 Flags = llvm::DINode::FlagPrivate;
3580 Flags = llvm::DINode::FlagPublic;
3582 if (
Field->isBitField())
3583 Flags |= llvm::DINode::FlagBitField;
3585 llvm::MDNode *PropertyNode =
nullptr;
3586 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3587 if (ObjCPropertyImplDecl *PImpD =
3588 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3589 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3590 SourceLocation Loc = PD->getLocation();
3591 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3592 unsigned PLine = getLineNumber(Loc);
3593 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3594 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3595 PropertyNode = DBuilder.createObjCProperty(
3596 PD->getName(), PUnit, PLine,
3599 : getSelectorName(PD->getGetterName()),
3602 : getSelectorName(PD->getSetterName()),
3603 PD->getPropertyAttributes(),
3604 getOrCreateType(PD->getType(), PUnit));
3608 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3609 FieldSize, FieldAlign, FieldOffset, Flags,
3610 FieldTy, PropertyNode);
3611 EltTys.push_back(FieldTy);
3614 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3615 DBuilder.replaceArrays(RealDecl, Elements);
3617 LexicalBlockStack.pop_back();
3621llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3622 llvm::DIFile *Unit) {
3630 auto &Ctx = CGM.getContext();
3635 QualType CharVecTy =
3637 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3640 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3643 llvm::Metadata *Subscript;
3644 QualType QTy(Ty, 0);
3645 auto SizeExpr = SizeExprCache.find(QTy);
3646 if (SizeExpr != SizeExprCache.end())
3647 Subscript = DBuilder.getOrCreateSubrange(
3648 SizeExpr->getSecond() ,
nullptr ,
3649 nullptr ,
nullptr );
3652 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3653 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3654 Subscript = DBuilder.getOrCreateSubrange(
3655 CountNode ,
nullptr ,
nullptr ,
3658 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3663 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3666llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3667 llvm::DIFile *Unit) {
3671 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3676 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3677 auto *ColumnCountNode =
3678 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3679 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3680 auto *RowCountNode =
3681 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3682 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3683 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3684 ColumnCountNode ,
nullptr ,
nullptr ,
3686 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3687 RowCountNode ,
nullptr ,
nullptr ,
3689 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3690 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3693llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3698 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3713 Size = CGM.getContext().getTypeSize(Ty);
3720 SmallVector<llvm::Metadata *, 8> Subscripts;
3721 QualType EltTy(Ty, 0);
3722 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3731 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3732 Count = CAT->getZExtSize();
3733 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3734 if (Expr *Size = VAT->getSizeExpr()) {
3736 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3737 Count =
Result.Val.getInt().getExtValue();
3741 auto SizeNode = SizeExprCache.find(EltTy);
3742 if (SizeNode != SizeExprCache.end())
3743 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3744 SizeNode->getSecond() ,
nullptr ,
3745 nullptr ,
nullptr ));
3748 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3749 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3750 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3751 CountNode ,
nullptr ,
nullptr ,
3757 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3759 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3763llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3764 llvm::DIFile *Unit) {
3765 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3769llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3770 llvm::DIFile *Unit) {
3771 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3773 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3774 CGM.getCodeGenOpts().DwarfVersion < 4)
3775 Tag = llvm::dwarf::DW_TAG_reference_type;
3777 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3780llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3782 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3786 Size = CGM.getContext().getTypeSize(Ty);
3789 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3792 Flags |= llvm::DINode::FlagSingleInheritance;
3795 Flags |= llvm::DINode::FlagMultipleInheritance;
3798 Flags |= llvm::DINode::FlagVirtualInheritance;
3808 llvm::DIType *ClassType = getOrCreateType(
T, U);
3810 return DBuilder.createMemberPointerType(
3814 const FunctionProtoType *FPT =
3816 return DBuilder.createMemberPointerType(
3817 getOrCreateInstanceMethodType(
3820 ClassType, Size, 0, Flags);
3823llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3825 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3828llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3832llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3834 return getOrCreateType(Ty->getWrappedType(), U);
3837llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3844 const EnumType *Ty) {
3856llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3859 bool isImportedFromModule =
3860 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3864 if (isImportedFromModule || !ED->getDefinition()) {
3871 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3872 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3873 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3874 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3876 unsigned Line = getLineNumber(ED->getLocation());
3877 StringRef EDName = ED->getName();
3878 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3879 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3880 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3882 ReplaceMap.emplace_back(
3883 std::piecewise_construct, std::make_tuple(Ty),
3884 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3888 return CreateTypeDefinition(Ty);
3891llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3894 SmallVector<llvm::Metadata *, 16> Enumerators;
3895 ED = ED->getDefinition();
3896 assert(ED &&
"An enumeration definition is required");
3897 for (
const auto *
Enum : ED->enumerators()) {
3898 Enumerators.push_back(
3899 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3902 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3903 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3904 EnumKind = Attr->getExtensibility();
3907 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3909 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3910 unsigned Line = getLineNumber(ED->getLocation());
3911 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3912 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3913 return DBuilder.createEnumerationType(
3914 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3915 0, Identifier, ED->isScoped(), EnumKind);
3920 StringRef Name, StringRef
Value) {
3921 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3922 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3928 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3929 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3930 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3934 StringRef FuncName) {
3935 llvm::DISubprogram *SP =
3936 createInlinedSubprogram(FuncName, Location->getFile());
3937 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3942 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3948 FuncName += Category;
3950 FuncName += FailureMsg;
3962 Quals += InnerQuals;
3964 switch (
T->getTypeClass()) {
3966 return C.getQualifiedType(
T.getTypePtr(), Quals);
3969 case Type::InjectedClassName:
3970 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3972 case Type::TemplateSpecialization: {
3974 if (Spec->isTypeAlias())
3975 return C.getQualifiedType(
T.getTypePtr(), Quals);
3976 T = Spec->desugar();
3979 case Type::TypeOfExpr:
3985 case Type::Decltype:
3988 case Type::UnaryTransform:
3991 case Type::Attributed:
3994 case Type::BTFTagAttributed:
3997 case Type::CountAttributed:
4006 case Type::MacroQualified:
4009 case Type::SubstTemplateTypeParm:
4013 case Type::DeducedTemplateSpecialization: {
4015 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4019 case Type::PackIndexing: {
4023 case Type::Adjusted:
4030 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4035llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4038 if (It != TypeCache.end()) {
4040 if (llvm::Metadata *
V = It->second)
4053 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4060 RetainedTypes.push_back(
4061 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4064llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4068 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4070 llvm::raw_string_ostream OS(Name);
4071 Ty.
print(OS, getPrintingPolicy());
4078 if (
auto *
T = getTypeOrNull(Ty))
4081 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4082 void *TyPtr = Ty.getAsOpaquePtr();
4085 TypeCache[TyPtr].reset(Res);
4090llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4098 auto Info = Reader->getSourceDescriptor(Idx);
4100 return getOrCreateModuleRef(*Info,
true);
4101 }
else if (ClangModuleMap) {
4114 auto Info = ASTSourceDescriptor(*M);
4115 return getOrCreateModuleRef(Info,
false);
4118 return getOrCreateModuleRef(PCHDescriptor,
false);
4125llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4128 return CreateQualifiedType(Ty, Unit);
4132#define TYPE(Class, Base)
4133#define ABSTRACT_TYPE(Class, Base)
4134#define NON_CANONICAL_TYPE(Class, Base)
4135#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4136#include "clang/AST/TypeNodes.inc"
4137 llvm_unreachable(
"Dependent types cannot show up in debug information");
4139 case Type::ExtVector:
4142 case Type::ConstantMatrix:
4144 case Type::ObjCObjectPointer:
4146 case Type::ObjCObject:
4148 case Type::ObjCTypeParam:
4150 case Type::ObjCInterface:
4158 case Type::BlockPointer:
4166 case Type::FunctionProto:
4167 case Type::FunctionNoProto:
4169 case Type::ConstantArray:
4170 case Type::VariableArray:
4171 case Type::IncompleteArray:
4172 case Type::ArrayParameter:
4175 case Type::LValueReference:
4177 case Type::RValueReference:
4180 case Type::MemberPointer:
4191 case Type::TemplateSpecialization:
4193 case Type::HLSLAttributedResource:
4195 case Type::HLSLInlineSpirv:
4197 case Type::PredefinedSugar:
4199 case Type::CountAttributed:
4201 case Type::Attributed:
4202 case Type::BTFTagAttributed:
4203 case Type::Adjusted:
4205 case Type::DeducedTemplateSpecialization:
4208 case Type::MacroQualified:
4209 case Type::SubstTemplateTypeParm:
4210 case Type::TypeOfExpr:
4212 case Type::Decltype:
4213 case Type::PackIndexing:
4214 case Type::UnaryTransform:
4218 llvm_unreachable(
"type should have been unwrapped!");
4221llvm::DICompositeType *
4222CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4223 QualType QTy(Ty, 0);
4225 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4230 if (
T && !
T->isForwardDecl())
4234 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4239 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4242 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4247llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4248 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4251 StringRef RDName = getClassName(RD);
4253 llvm::DIFile *DefUnit =
nullptr;
4256 DefUnit = getOrCreateFile(Loc);
4257 Line = getLineNumber(Loc);
4260 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4264 auto *
T = cast_or_null<llvm::DICompositeType>(
4265 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4273 return getOrCreateRecordFwdDecl(Ty, RDContext);
4286 auto Flags = llvm::DINode::FlagZero;
4287 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4289 Flags |= llvm::DINode::FlagTypePassByReference;
4291 Flags |= llvm::DINode::FlagTypePassByValue;
4294 if (!CXXRD->isTrivial())
4295 Flags |= llvm::DINode::FlagNonTrivial;
4298 if (CXXRD->isAnonymousStructOrUnion())
4299 Flags |= llvm::DINode::FlagExportSymbols;
4302 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4305 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4306 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4308 Flags, Identifier, Annotations);
4312 switch (RealDecl->getTag()) {
4314 llvm_unreachable(
"invalid composite type tag");
4316 case llvm::dwarf::DW_TAG_array_type:
4317 case llvm::dwarf::DW_TAG_enumeration_type:
4322 if (Identifier.empty())
4326 case llvm::dwarf::DW_TAG_structure_type:
4327 case llvm::dwarf::DW_TAG_union_type:
4328 case llvm::dwarf::DW_TAG_class_type:
4331 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4335 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4336 CXXRecordDecl *TemplateDecl =
4337 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4338 RegionMap[TemplateDecl].reset(RealDecl);
4340 RegionMap[RD].reset(RealDecl);
4342 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4344 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4345 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4346 CollectCXXTemplateParams(TSpecial, DefUnit));
4350void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4351 llvm::DICompositeType *RealDecl) {
4353 llvm::DIType *ContainingType =
nullptr;
4354 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4358 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4365 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4366 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4368 ContainingType = RealDecl;
4370 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4373llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4374 StringRef Name, uint64_t *Offset) {
4375 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4376 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4379 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4380 *Offset, llvm::DINode::FlagZero, FieldTy);
4381 *Offset += FieldSize;
4385void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4387 StringRef &LinkageName,
4388 llvm::DIScope *&FDContext,
4389 llvm::DINodeArray &TParamsArray,
4390 llvm::DINode::DIFlags &Flags) {
4392 Name = getFunctionName(FD);
4395 LinkageName = CGM.getMangledName(GD);
4397 Flags |= llvm::DINode::FlagPrototyped;
4401 if (LinkageName == Name ||
4402 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4403 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4404 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4405 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4406 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4407 LinkageName = StringRef();
4411 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4412 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4413 CGM.getCodeGenOpts().EmitCodeView)) {
4414 if (
const NamespaceDecl *NSDecl =
4416 FDContext = getOrCreateNamespace(NSDecl);
4417 else if (
const RecordDecl *RDecl =
4419 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4420 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4423 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4426 Flags |= llvm::DINode::FlagNoReturn;
4428 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4432void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4433 unsigned &LineNo, QualType &
T,
4434 StringRef &Name, StringRef &LinkageName,
4435 llvm::MDTuple *&TemplateParameters,
4436 llvm::DIScope *&VDContext) {
4445 llvm::APInt ConstVal(32, 1);
4446 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4448 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4455 LinkageName = CGM.getMangledName(VD);
4456 if (LinkageName == Name)
4457 LinkageName = StringRef();
4460 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4461 TemplateParameters = parameterNodes.get();
4463 TemplateParameters =
nullptr;
4481 DC = CGM.getContext().getTranslationUnitDecl();
4483 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4484 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4487llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4489 llvm::DINodeArray TParamsArray;
4490 StringRef Name, LinkageName;
4491 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4492 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4494 llvm::DIFile *Unit = getOrCreateFile(Loc);
4495 llvm::DIScope *DContext = Unit;
4496 unsigned Line = getLineNumber(Loc);
4497 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4502 SmallVector<QualType, 16> ArgTypes;
4503 for (
const ParmVarDecl *Parm : FD->
parameters())
4504 ArgTypes.push_back(Parm->getType());
4507 QualType FnType = CGM.getContext().getFunctionType(
4508 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4510 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4511 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4512 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4515 Flags |= getCallSiteRelatedAttrs();
4516 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4517 return DBuilder.createFunction(
4518 DContext, Name, LinkageName, Unit,
Line,
4519 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4520 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4522 CGM.getCodeGenOpts().DebugKeyInstructions);
4525 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4526 DContext, Name, LinkageName, Unit,
Line,
4527 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4528 TParamsArray.get(), getFunctionDeclaration(FD));
4530 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4531 std::make_tuple(CanonDecl),
4532 std::make_tuple(SP));
4536llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4537 return getFunctionFwdDeclOrStub(GD,
false);
4540llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4541 return getFunctionFwdDeclOrStub(GD,
true);
4544llvm::DIGlobalVariable *
4545CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4547 StringRef Name, LinkageName;
4549 llvm::DIFile *Unit = getOrCreateFile(Loc);
4550 llvm::DIScope *DContext = Unit;
4551 unsigned Line = getLineNumber(Loc);
4552 llvm::MDTuple *TemplateParameters =
nullptr;
4554 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4557 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4558 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4560 FwdDeclReplaceMap.emplace_back(
4561 std::piecewise_construct,
4563 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4567llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4572 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4573 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4574 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4578 if (I != DeclCache.end()) {
4580 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4581 return GVE->getVariable();
4589 if (IE != ImportedDeclCache.end()) {
4590 auto N = IE->second;
4591 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4593 return dyn_cast_or_null<llvm::DINode>(N);
4598 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4599 return getFunctionForwardDeclaration(FD);
4600 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4601 return getGlobalVariableForwardDeclaration(VD);
4606llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4607 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4610 const auto *FD = dyn_cast<FunctionDecl>(D);
4615 auto *S = getDeclContextDescriptor(D);
4618 if (MI == SPCache.end()) {
4620 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4624 if (MI != SPCache.end()) {
4625 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4626 if (SP && !SP->isDefinition())
4630 for (
auto *NextFD : FD->
redecls()) {
4631 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4632 if (MI != SPCache.end()) {
4633 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4634 if (SP && !SP->isDefinition())
4641llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4642 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4643 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4644 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4647 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4651 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4655 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4664 QualType QTy(
ID->getTypeForDecl(), 0);
4665 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4666 if (It == TypeCache.end())
4669 llvm::DISubprogram *FD = DBuilder.createFunction(
4670 InterfaceType, getObjCMethodName(OMD), StringRef(),
4671 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4672 DBuilder.finalizeSubprogram(FD);
4679llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4684 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4685 !CGM.getCodeGenOpts().EmitCodeView))
4688 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4690 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4693 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4696 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4697 return getOrCreateMethodType(
Method, F);
4699 const auto *FTy = FnType->
getAs<FunctionType>();
4702 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4704 SmallVector<llvm::Metadata *, 16> Elts;
4707 QualType ResultTy = OMethod->getReturnType();
4710 if (ResultTy == CGM.getContext().getObjCInstanceType())
4711 ResultTy = CGM.getContext().getPointerType(
4712 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4714 Elts.push_back(getOrCreateType(ResultTy, F));
4716 QualType SelfDeclTy;
4717 if (
auto *SelfDecl = OMethod->getSelfDecl())
4718 SelfDeclTy = SelfDecl->getType();
4719 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4722 if (!SelfDeclTy.
isNull())
4724 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4726 Elts.push_back(DBuilder.createArtificialType(
4727 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4729 for (
const auto *PI : OMethod->parameters())
4730 Elts.push_back(getOrCreateType(PI->getType(), F));
4732 if (OMethod->isVariadic())
4733 Elts.push_back(DBuilder.createUnspecifiedParameter());
4735 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4736 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4742 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4743 if (FD->isVariadic()) {
4744 SmallVector<llvm::Metadata *, 16> EltTys;
4745 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4746 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4748 EltTys.push_back(getOrCreateType(ParamType, F));
4749 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4750 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4751 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4764 CC = SrcFnTy->getCallConv();
4766 for (
const VarDecl *VD : Args)
4767 ArgTypes.push_back(VD->
getType());
4768 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4774 llvm::Function *Fn,
bool CurFuncIsThunk) {
4776 StringRef LinkageName;
4778 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4781 bool HasDecl = (D !=
nullptr);
4783 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4784 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4785 llvm::DIFile *Unit = getOrCreateFile(Loc);
4786 llvm::DIScope *FDContext = Unit;
4787 llvm::DINodeArray TParamsArray;
4788 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4791 LinkageName = Fn->getName();
4792 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4794 auto FI = SPCache.find(FD->getCanonicalDecl());
4795 if (FI != SPCache.end()) {
4796 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4797 if (SP && SP->isDefinition()) {
4798 LexicalBlockStack.emplace_back(SP);
4799 RegionMap[D].reset(SP);
4803 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4804 TParamsArray, Flags);
4807 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4808 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4809 Name = getObjCMethodName(OMD);
4810 Flags |= llvm::DINode::FlagPrototyped;
4817 Name = Fn->getName();
4822 Flags |= llvm::DINode::FlagPrototyped;
4824 Name.consume_front(
"\01");
4828 "Unexpected DynamicInitKind !");
4832 Flags |= llvm::DINode::FlagArtificial;
4838 Flags |= llvm::DINode::FlagThunk;
4840 if (Fn->hasLocalLinkage())
4841 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4842 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4843 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4845 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4846 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4847 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4849 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4850 unsigned ScopeLine = getLineNumber(ScopeLoc);
4851 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4852 llvm::DISubprogram *
Decl =
nullptr;
4853 llvm::DINodeArray Annotations =
nullptr;
4856 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4857 : getFunctionDeclaration(D);
4858 Annotations = CollectBTFDeclTagAnnotations(D);
4866 llvm::DISubprogram *SP = DBuilder.createFunction(
4867 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4868 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4869 Annotations,
"", KeyInstructions);
4870 Fn->setSubprogram(SP);
4879 LexicalBlockStack.emplace_back(SP);
4882 RegionMap[D].reset(SP);
4886 QualType FnType, llvm::Function *Fn) {
4888 StringRef LinkageName;
4894 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4895 return GetName(D,
true);
4898 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4899 llvm::DIFile *Unit = getOrCreateFile(Loc);
4900 bool IsDeclForCallSite = Fn ?
true :
false;
4901 llvm::DIScope *FDContext =
4902 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4903 llvm::DINodeArray TParamsArray;
4906 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4907 TParamsArray, Flags);
4908 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4909 Name = getObjCMethodName(OMD);
4910 Flags |= llvm::DINode::FlagPrototyped;
4912 llvm_unreachable(
"not a function or ObjC method");
4914 Name.consume_front(
"\01");
4917 Flags |= llvm::DINode::FlagArtificial;
4922 unsigned LineNo = getLineNumber(Loc);
4923 unsigned ScopeLine = 0;
4924 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4925 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4926 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4928 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4929 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4931 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4932 llvm::DISubprogram *SP = DBuilder.createFunction(
4933 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4934 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4940 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4941 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4942 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4945 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4946 DBuilder.createParameterVariable(
4947 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4948 llvm::DINode::FlagZero, ParamAnnotations);
4954 if (IsDeclForCallSite)
4955 Fn->setSubprogram(SP);
4963 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4966 if (
Func->getSubprogram())
4971 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4972 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4985 auto FI = SPCache.find(FD->getCanonicalDecl());
4986 llvm::DISubprogram *SP =
nullptr;
4987 if (FI != SPCache.end())
4988 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4989 if (!SP || !SP->isDefinition())
4990 SP = getFunctionStub(GD);
4991 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4992 LexicalBlockStack.emplace_back(SP);
4998 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5007 if (CurLoc.isInvalid() || LexicalBlockStack.empty())
5010 llvm::MDNode *
Scope = LexicalBlockStack.back();
5011 Builder.SetCurrentDebugLocation(
5012 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5013 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5017 llvm::MDNode *Back =
nullptr;
5018 if (!LexicalBlockStack.empty())
5019 Back = LexicalBlockStack.back().get();
5020 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5022 getColumnNumber(CurLoc)));
5025void CGDebugInfo::AppendAddressSpaceXDeref(
5027 std::optional<unsigned> DWARFAddressSpace =
5029 if (!DWARFAddressSpace)
5032 Expr.push_back(llvm::dwarf::DW_OP_constu);
5033 Expr.push_back(*DWARFAddressSpace);
5034 Expr.push_back(llvm::dwarf::DW_OP_swap);
5035 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5044 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5045 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5046 LexicalBlockStack.back(), CurInlinedAt));
5048 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5052 CreateLexicalBlock(Loc);
5057 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5062 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5065 LexicalBlockStack.pop_back();
5069 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5070 unsigned RCount = FnBeginRegionCount.back();
5071 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5074 while (LexicalBlockStack.size() != RCount) {
5077 LexicalBlockStack.pop_back();
5079 FnBeginRegionCount.pop_back();
5081 if (Fn && Fn->getSubprogram())
5082 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5085CGDebugInfo::BlockByRefType
5086CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5087 uint64_t *XOffset) {
5090 uint64_t FieldSize, FieldOffset;
5091 uint32_t FieldAlign;
5093 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5098 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5099 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5101 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5102 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5105 if (HasCopyAndDispose) {
5108 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5110 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5112 bool HasByrefExtendedLayout;
5115 HasByrefExtendedLayout) &&
5116 HasByrefExtendedLayout) {
5119 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5128 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5131 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5134 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5139 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5140 FieldSize = CGM.getContext().getTypeSize(FType);
5141 FieldAlign = CGM.getContext().toBits(Align);
5143 *XOffset = FieldOffset;
5144 llvm::DIType *FieldTy = DBuilder.createMemberType(
5145 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5146 llvm::DINode::FlagZero, WrappedTy);
5147 EltTys.push_back(FieldTy);
5148 FieldOffset += FieldSize;
5150 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5151 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5152 llvm::DINode::FlagZero,
nullptr, Elements),
5156llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5157 llvm::Value *Storage,
5158 std::optional<unsigned> ArgNo,
5160 const bool UsePointerValue) {
5161 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5162 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5163 if (VD->
hasAttr<NoDebugAttr>())
5168 llvm::DIFile *Unit =
nullptr;
5169 if (!VarIsArtificial)
5173 if (VD->
hasAttr<BlocksAttr>())
5174 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5176 Ty = getOrCreateType(VD->
getType(), Unit);
5186 if (!VarIsArtificial) {
5190 SmallVector<uint64_t, 13> Expr;
5191 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5198 Flags |= llvm::DINode::FlagArtificial;
5202 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5203 AppendAddressSpaceXDeref(AddressSpace, Expr);
5207 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5210 Flags |= llvm::DINode::FlagObjectPointer;
5211 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5212 if (PVD->isExplicitObjectParameter())
5213 Flags |= llvm::DINode::FlagObjectPointer;
5221 StringRef Name = VD->
getName();
5222 if (!Name.empty()) {
5228 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5230 offset = CGM.getContext().toCharUnitsFromBits(
5233 Expr.push_back(llvm::dwarf::DW_OP_deref);
5234 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5236 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5239 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5251 for (
const auto *Field : RD->
fields()) {
5252 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5253 StringRef FieldName =
Field->getName();
5261 auto *D = DBuilder.createAutoVariable(
5262 Scope, FieldName, Unit,
Line, FieldTy,
5263 CGM.getCodeGenOpts().OptimizationLevel != 0,
5264 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5267 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5268 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5271 Builder.GetInsertBlock());
5279 if (UsePointerValue) {
5280 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5281 "Debug info already contains DW_OP_deref.");
5282 Expr.push_back(llvm::dwarf::DW_OP_deref);
5286 llvm::DILocalVariable *D =
nullptr;
5288 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5289 D = DBuilder.createParameterVariable(
5290 Scope, Name, *ArgNo, Unit,
Line, Ty,
5291 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5300 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5306 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5307 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5308 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5309 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5311 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5317 if (Iter != CoroutineParameterMappings.end()) {
5318 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5319 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5320 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5322 if (Iter2 != ParamDbgMappings.end())
5323 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5329 D = RemapCoroArgToLocalVar();
5332 D = DBuilder.createAutoVariable(
5333 Scope, Name, Unit,
Line, Ty,
5334 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5337 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5338 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5339 Column, Scope, CurInlinedAt),
5340 Builder.GetInsertBlock());
5345llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5346 llvm::Value *Storage,
5347 std::optional<unsigned> ArgNo,
5349 const bool UsePointerValue) {
5350 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5351 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5352 if (BD->
hasAttr<NoDebugAttr>())
5359 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5360 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5368 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5370 SmallVector<uint64_t, 3> Expr;
5371 AppendAddressSpaceXDeref(AddressSpace, Expr);
5376 if (UsePointerValue) {
5377 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5378 "Debug info already contains DW_OP_deref.");
5379 Expr.push_back(llvm::dwarf::DW_OP_deref);
5384 StringRef Name = BD->
getName();
5387 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5388 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5389 llvm::DINode::FlagZero, Align);
5391 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5392 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5393 const unsigned fieldIndex = FD->getFieldIndex();
5394 const clang::CXXRecordDecl *parent =
5395 (
const CXXRecordDecl *)FD->getParent();
5396 const ASTRecordLayout &layout =
5397 CGM.getContext().getASTRecordLayout(parent);
5399 if (FD->isBitField()) {
5400 const CGRecordLayout &RL =
5401 CGM.getTypes().getCGRecordLayout(FD->getParent());
5406 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5412 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5413 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5414 Expr.push_back(Info.
Offset);
5417 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5418 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5419 }
else if (fieldOffset != 0) {
5420 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5421 "Unexpected non-bitfield with non-byte-aligned offset");
5422 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5424 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5427 }
else if (
const ArraySubscriptExpr *ASE =
5428 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5429 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5430 const uint64_t value = IL->getValue().getZExtValue();
5431 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5434 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5435 Expr.push_back(CGM.getContext()
5436 .toCharUnitsFromBits(value * typeSize)
5443 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5444 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5445 Column, Scope, CurInlinedAt),
5446 Builder.GetInsertBlock());
5451llvm::DILocalVariable *
5454 const bool UsePointerValue) {
5455 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5457 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5459 EmitDeclare(B, Storage, std::nullopt, Builder,
5466 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5470 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5471 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5473 if (D->
hasAttr<NoDebugAttr>())
5477 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5483 StringRef Name = D->
getName();
5489 CGM.getCodeGenOpts().OptimizationLevel != 0);
5492 DBuilder.insertLabel(L,
5493 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5494 Scope, CurInlinedAt),
5495 Builder.GetInsertBlock()->end());
5498llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5500 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5503 return DBuilder.createObjectPointerType(Ty,
true);
5508 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5509 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5510 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5512 if (Builder.GetInsertBlock() ==
nullptr)
5514 if (VD->
hasAttr<NoDebugAttr>())
5517 bool isByRef = VD->
hasAttr<BlocksAttr>();
5519 uint64_t XOffset = 0;
5520 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5523 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5525 Ty = getOrCreateType(VD->
getType(), Unit);
5529 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5531 Ty = CreateSelfType(VD->
getType(), Ty);
5534 const unsigned Line =
5538 const llvm::DataLayout &target = CGM.getDataLayout();
5545 addr.push_back(llvm::dwarf::DW_OP_deref);
5546 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5549 addr.push_back(llvm::dwarf::DW_OP_deref);
5550 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5553 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5555 addr.push_back(llvm::dwarf::DW_OP_deref);
5556 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5558 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5564 auto *D = DBuilder.createAutoVariable(
5566 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5569 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5570 LexicalBlockStack.back(), CurInlinedAt);
5571 auto *
Expr = DBuilder.createExpression(addr);
5573 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5575 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5578llvm::DILocalVariable *
5581 bool UsePointerValue) {
5582 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5583 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5587struct BlockLayoutChunk {
5588 uint64_t OffsetInBits;
5591bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5592 return l.OffsetInBits < r.OffsetInBits;
5596void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5598 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5599 SmallVectorImpl<llvm::Metadata *> &Fields) {
5603 if (CGM.getLangOpts().OpenCL) {
5604 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5605 BlockLayout.getElementOffsetInBits(0),
5607 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5608 BlockLayout.getElementOffsetInBits(1),
5612 BlockLayout.getElementOffsetInBits(0),
5614 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5615 BlockLayout.getElementOffsetInBits(1),
5619 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5620 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5621 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5622 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5623 BlockLayout.getElementOffsetInBits(3),
5625 Fields.push_back(createFieldType(
5630 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5637 llvm::AllocaInst *Alloca,
5639 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5645 llvm::DIFile *tunit = getOrCreateFile(loc);
5646 unsigned line = getLineNumber(loc);
5647 unsigned column = getColumnNumber(loc);
5652 const llvm::StructLayout *blockLayout =
5656 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5665 BlockLayoutChunk chunk;
5666 chunk.OffsetInBits =
5667 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5668 chunk.Capture =
nullptr;
5669 chunks.push_back(chunk);
5673 for (
const auto &capture :
blockDecl->captures()) {
5674 const VarDecl *variable = capture.getVariable();
5681 BlockLayoutChunk chunk;
5682 chunk.OffsetInBits =
5683 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5684 chunk.Capture = &capture;
5685 chunks.push_back(chunk);
5689 llvm::array_pod_sort(chunks.begin(), chunks.end());
5691 for (
const BlockLayoutChunk &Chunk : chunks) {
5692 uint64_t offsetInBits = Chunk.OffsetInBits;
5699 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5701 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5702 type = CGM.getContext().getCanonicalTagType(RDecl);
5704 llvm_unreachable(
"unexpected block declcontext");
5706 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5707 offsetInBits, tunit, tunit));
5712 StringRef name = variable->
getName();
5714 llvm::DIType *fieldType;
5716 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5721 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5722 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5723 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5724 PtrInfo.
Width, Align, offsetInBits,
5725 llvm::DINode::FlagZero, fieldType);
5729 offsetInBits, Align, tunit, tunit);
5731 fields.push_back(fieldType);
5735 llvm::raw_svector_ostream(typeName)
5736 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5738 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5740 llvm::DIType *
type =
5741 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5742 CGM.getContext().toBits(block.
BlockSize), 0,
5743 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5744 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5747 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5751 auto *debugVar = DBuilder.createParameterVariable(
5752 scope, Name, ArgNo, tunit, line,
type,
5753 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5756 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5757 llvm::DILocation::get(CGM.getLLVMContext(), line,
5758 column, scope, CurInlinedAt),
5759 Builder.GetInsertBlock());
5762llvm::DIDerivedType *
5763CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5768 if (MI != StaticDataMemberCache.end()) {
5769 assert(MI->second &&
"Static data member declaration should still exist");
5780llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5781 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5782 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5783 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5785 for (
const auto *Field : RD->
fields()) {
5786 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5787 StringRef FieldName = Field->getName();
5790 if (FieldName.empty()) {
5791 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5792 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5793 LineNo, LinkageName, Var, DContext);
5797 GVE = DBuilder.createGlobalVariableExpression(
5798 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5799 Var->hasLocalLinkage());
5800 Var->addDebugInfo(GVE);
5812 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5817 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5828 struct ReferencesAnonymous
5830 bool RefAnon =
false;
5831 bool VisitRecordType(RecordType *RT) {
5839 ReferencesAnonymous RT;
5852struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5853 bool Reconstitutable =
true;
5854 bool VisitVectorType(VectorType *FT) {
5855 Reconstitutable =
false;
5858 bool VisitAtomicType(AtomicType *FT) {
5859 Reconstitutable =
false;
5862 bool VisitType(
Type *
T) {
5866 Reconstitutable =
false;
5871 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5874 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5875 if (!ED->getIdentifier()) {
5876 Reconstitutable =
false;
5879 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5880 Reconstitutable =
false;
5886 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5890 return Reconstitutable;
5892 bool VisitRecordType(RecordType *RT,
bool =
false) {
5894 Reconstitutable =
false;
5904 ReconstitutableType
T;
5906 return T.Reconstitutable;
5909bool CGDebugInfo::HasReconstitutableArgs(
5910 ArrayRef<TemplateArgument> Args)
const {
5911 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5951 llvm_unreachable(
"Other, unresolved, template arguments should "
5952 "not be seen here");
5957std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5959 llvm::raw_string_ostream
OS(Name);
5960 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5963 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5964 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5966 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5967 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5969 std::optional<TemplateArgs> Args;
5971 bool IsOperatorOverload =
false;
5972 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5973 Args = GetTemplateArgs(RD);
5974 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5975 Args = GetTemplateArgs(FD);
5977 IsOperatorOverload |=
5980 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5981 Args = GetTemplateArgs(VD);
6005 bool Reconstitutable =
6006 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6008 PrintingPolicy PP = getPrintingPolicy();
6010 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6014 bool Mangled = TemplateNamesKind ==
6015 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6021 std::string EncodedOriginalName;
6022 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6027 printTemplateArgumentList(OS, Args->Args, PP);
6028 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6030 std::string CanonicalOriginalName;
6031 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6033 assert(EncodedOriginalName == CanonicalOriginalName);
6042 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6043 if (D->
hasAttr<NoDebugAttr>())
6046 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6047 return GetName(D,
true);
6053 if (Cached != DeclCache.end())
6054 return Var->addDebugInfo(
6058 llvm::DIFile *Unit =
nullptr;
6059 llvm::DIScope *DContext =
nullptr;
6061 StringRef DeclName, LinkageName;
6063 llvm::MDTuple *TemplateParameters =
nullptr;
6064 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6065 TemplateParameters, DContext);
6069 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6074 if (
T->isUnionType() && DeclName.empty()) {
6075 const auto *RD =
T->castAsRecordDecl();
6077 "unnamed non-anonymous struct or union?");
6078 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6083 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6084 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6085 if (D->
hasAttr<CUDASharedAttr>())
6088 else if (D->
hasAttr<CUDAConstantAttr>())
6092 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6094 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6095 GVE = DBuilder.createGlobalVariableExpression(
6096 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6097 Var->hasLocalLinkage(),
true,
6098 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6099 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6100 Align, Annotations);
6101 Var->addDebugInfo(GVE);
6107 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6108 if (VD->
hasAttr<NoDebugAttr>())
6110 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6111 return GetName(VD,
true);
6116 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6117 StringRef Name = VD->
getName();
6118 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6120 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6122 if (CGM.getCodeGenOpts().EmitCodeView) {
6133 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6134 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6135 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6145 auto *VarD = dyn_cast<VarDecl>(VD);
6146 if (VarD && VarD->isStaticDataMember()) {
6148 getDeclContextDescriptor(VarD);
6153 RetainedTypes.push_back(
6154 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6158 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6160 auto &GV = DeclCache[VD];
6164 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6165 llvm::MDTuple *TemplateParameters =
nullptr;
6169 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6170 TemplateParameters = parameterNodes.get();
6173 GV.reset(DBuilder.createGlobalVariableExpression(
6174 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6175 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6176 TemplateParameters, Align));
6181 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6182 if (D->
hasAttr<NoDebugAttr>())
6186 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6187 StringRef Name = D->
getName();
6188 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6190 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6191 llvm::DIGlobalVariableExpression *GVE =
6192 DBuilder.createGlobalVariableExpression(
6193 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6194 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6195 Var->addDebugInfo(GVE);
6202 if (CGM.getCodeGenOpts().getDebugInfo() <=
6203 llvm::codegenoptions::DebugLineTablesOnly)
6206 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6210 llvm::DIFile *Unit = DIL->getFile();
6211 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6216 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6217 llvm::Value *Var = Load->getPointerOperand();
6222 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6223 return DbgDeclare->getVariable()->getType() ==
Type;
6225 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6229 llvm::DILocalVariable *D =
6230 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6231 Type,
false, llvm::DINode::FlagArtificial);
6233 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6234 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6244 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6248 if (D->
hasAttr<NoDebugAttr>())
6251 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6266 if (!(DI = getDeclarationOrDefinition(
6267 AliaseeDecl.getCanonicalDecl().getDecl())))
6270 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6273 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6274 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6288 llvm::DIFile *
File = getOrCreateFile(Loc);
6289 llvm::DIGlobalVariableExpression *Debug =
6290 DBuilder.createGlobalVariableExpression(
6291 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6292 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6293 GV->addDebugInfo(Debug);
6296llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6297 if (!LexicalBlockStack.empty())
6298 return LexicalBlockStack.back();
6299 llvm::DIScope *Mod = getParentModuleOrNull(D);
6300 return getContextDescriptor(D, Mod ? Mod : TheCU);
6304 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6308 CGM.getCodeGenOpts().DebugExplicitImport) {
6312 DBuilder.createImportedModule(
6314 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6319 if (llvm::DINode *
Target =
6322 DBuilder.createImportedDeclaration(
6324 getOrCreateFile(Loc), getLineNumber(Loc));
6329 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6332 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6334 for (
const auto *USD : UD.
shadows()) {
6339 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6340 if (
const auto *AT = FD->getType()
6343 if (AT->getDeducedType().isNull())
6354 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6357 "We shouldn't be codegening an invalid UsingEnumDecl"
6358 " containing no decls");
6360 for (
const auto *USD : UD.
shadows())
6365 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6367 if (
Module *M = ID.getImportedModule()) {
6369 auto Loc = ID.getLocation();
6370 DBuilder.createImportedDeclaration(
6371 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6372 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6373 getLineNumber(Loc));
6377llvm::DIImportedEntity *
6379 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6381 auto &VH = NamespaceAliasCache[&NA];
6384 llvm::DIImportedEntity *R;
6386 if (
const auto *Underlying =
6389 R = DBuilder.createImportedDeclaration(
6392 getLineNumber(Loc), NA.
getName());
6394 R = DBuilder.createImportedDeclaration(
6397 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6403CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6407 auto I = NamespaceCache.find(NSDecl);
6408 if (I != NamespaceCache.end())
6411 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6413 llvm::DINamespace *NS =
6414 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6415 NamespaceCache[NSDecl].reset(NS);
6420 assert(TheCU &&
"no main compile unit");
6421 TheCU->setDWOId(Signature);
6427 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6428 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6430 ? CreateTypeDefinition(E.Type, E.Unit)
6432 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6436 for (
const auto &P : ObjCMethodCache) {
6437 if (P.second.empty())
6440 QualType QTy(P.first->getTypeForDecl(), 0);
6442 assert(It != TypeCache.end());
6444 llvm::DICompositeType *InterfaceDecl =
6447 auto CurElts = InterfaceDecl->getElements();
6451 for (
auto &SubprogramDirect : P.second)
6452 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6453 EltTys.push_back(SubprogramDirect.getPointer());
6455 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6456 DBuilder.replaceArrays(InterfaceDecl, Elements);
6459 for (
const auto &P : ReplaceMap) {
6462 assert(Ty->isForwardDecl());
6464 auto It = TypeCache.find(P.first);
6465 assert(It != TypeCache.end());
6468 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6472 for (
const auto &P : FwdDeclReplaceMap) {
6475 llvm::Metadata *Repl;
6477 auto It = DeclCache.find(P.first);
6481 if (It == DeclCache.end())
6486 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6487 Repl = GVE->getVariable();
6493 for (
auto &RT : RetainedTypes)
6494 if (
auto MD = TypeCache[RT])
6497 DBuilder.finalize();
6502 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6503 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6504 DBuilder.retainType(DieTy);
6508 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6509 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6510 DBuilder.retainType(DieTy);
6514 if (LexicalBlockStack.empty())
6515 return llvm::DebugLoc();
6517 llvm::MDNode *
Scope = LexicalBlockStack.back();
6518 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6519 getColumnNumber(Loc),
Scope);
6522llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6526 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6527 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6528 return llvm::DINode::FlagZero;
6533 bool SupportsDWARFv4Ext =
6535 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6536 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6538 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6539 return llvm::DINode::FlagZero;
6541 return llvm::DINode::FlagAllCallsDescribed;
6552 return DBuilder.createConstantValueExpression(
6553 Val.
getFloat().bitcastToAPInt().getZExtValue());
6558 llvm::APSInt
const &ValInt = Val.
getInt();
6559 std::optional<uint64_t> ValIntOpt;
6560 if (ValInt.isUnsigned())
6561 ValIntOpt = ValInt.tryZExtValue();
6562 else if (
auto tmp = ValInt.trySExtValue())
6565 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6568 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6573CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6575 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6576 CGF.CurLexicalScope =
this;
6578 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6583 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6596#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6598 Label = "__ubsan_check_" #Name; \
6602#undef SANITIZER_CHECK
6613#define SANITIZER(NAME, ID) \
6614 case SanitizerKind::SO_##ID: \
6615 Label = "__ubsan_check_" NAME; \
6617#include "clang/Basic/Sanitizers.def"
6619 llvm_unreachable(
"unexpected sanitizer kind");
6624 for (
unsigned int i = 0; i < Label.length(); i++)
6625 if (!std::isalpha(Label[i]))
6634 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6636 if (!DI || !CheckDebugLoc)
6637 return CheckDebugLoc;
6638 const auto &AnnotateDebugInfo =
6639 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6640 if (AnnotateDebugInfo.empty())
6641 return CheckDebugLoc;
6644 if (Ordinals.size() == 1)
6649 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6650 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6652 return CheckDebugLoc;
6660 assert(!CGF->IsSanitizerScope);
6661 CGF->IsSanitizerScope =
true;
6665 assert(CGF->IsSanitizerScope);
6666 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 IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static 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)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
#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.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a 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...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
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...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
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.