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"
71 if (TI.isAlignRequired())
99 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
103 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
127 if (!llvm::isa<ParmVarDecl>(VD))
137 if (!Method->isImplicit() || !Method->isPropertyAccessor())
148 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
149 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
150 DBuilder(CGM.getModule()) {
155 assert(LexicalBlockStack.empty() &&
156 "Region stack mismatch, stack not empty!");
159void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
160 uint64_t Group, uint8_t Rank) {
161 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
165 Rank = std::min<uint8_t>(Rank, 7);
167 const llvm::DebugLoc &DL = I->getDebugLoc();
172 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
173 Group = DL->getAtomGroup();
174 Rank = DL->getAtomRank();
179 KeyInstructionsInfo.HighestEmittedAtom =
180 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
183 llvm::DILocation *NewDL = llvm::DILocation::get(
184 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
185 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
186 I->setDebugLoc(NewDL);
190 llvm::Value *Backup) {
192 KeyInstructionsInfo.CurrentAtom);
198 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
201 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
202 if (!SP || !SP->getKeyInstructionsEnabled())
205 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
207 llvm::Instruction *BackupI =
208 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
213 addInstSourceAtomMetadata(BackupI, Group, 2);
219 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
220 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
223 addInstSourceAtomMetadata(BackupI, Group, Rank++);
229 KeyInstructionsInfo.NextAtom = 1;
230 KeyInstructionsInfo.HighestEmittedAtom = 0;
231 KeyInstructionsInfo.CurrentAtom = 0;
237 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
238 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
246 DI->KeyInstructionsInfo.NextAtom =
247 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
248 DI->KeyInstructionsInfo.NextAtom);
250 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
256 init(TemporaryLocation);
263 init(TemporaryLocation, DefaultToEmpty);
267 bool DefaultToEmpty) {
274 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
276 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
279 if (TemporaryLocation.
isValid()) {
280 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
284 if (DefaultToEmpty) {
285 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
290 assert(!DI->LexicalBlockStack.empty());
291 CGF->Builder.SetCurrentDebugLocation(
292 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
293 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
303 if (!CGF.getDebugInfo()) {
307 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
311 if (Loc->getAtomGroup())
312 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
313 Loc->getColumn(), Loc->getScope(),
314 Loc->getInlinedAt(), Loc.isImplicitCode());
315 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
323 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
329 if (!CGF.getDebugInfo()) {
333 auto &DI = *CGF.getDebugInfo();
334 SavedLocation = DI.getLocation();
335 assert((DI.getInlinedAt() ==
336 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
337 "CGDebugInfo and IRBuilder are out of sync");
339 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
345 auto &DI = *CGF->getDebugInfo();
346 DI.EmitInlineFunctionEnd(CGF->Builder);
347 DI.EmitLocation(CGF->Builder, SavedLocation);
355 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(
361 if (LexicalBlockStack.empty())
367 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
370 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
371 LexicalBlockStack.pop_back();
372 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
373 LBF->getScope(), getOrCreateFile(CurLoc)));
376 LexicalBlockStack.pop_back();
377 LexicalBlockStack.emplace_back(
378 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
382llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
383 llvm::DIScope *Mod = getParentModuleOrNull(D);
388llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
393 auto I = RegionMap.find(Context);
394 if (I != RegionMap.end()) {
395 llvm::Metadata *
V = I->second;
396 return dyn_cast_or_null<llvm::DIScope>(
V);
400 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
401 return getOrCreateNamespace(NSDecl);
403 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
404 if (!RDecl->isDependentType())
410PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
411 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
418 if (CGM.getCodeGenOpts().EmitCodeView) {
439StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
440 bool *NameIsSimplified) {
441 return internString(GetName(FD,
false, NameIsSimplified));
444StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
445 SmallString<256> MethodName;
446 llvm::raw_svector_ostream
OS(MethodName);
449 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
450 OS << OID->getName();
451 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
452 OS << OID->getName();
453 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
454 if (OC->IsClassExtension()) {
455 OS << OC->getClassInterface()->getName();
457 OS << OC->getIdentifier()->getNameStart() <<
'('
458 << OC->getIdentifier()->getNameStart() <<
')';
460 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
461 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
465 return internString(
OS.str());
468StringRef CGDebugInfo::getSelectorName(Selector S) {
472StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
473 bool *NameIsSimplified) {
476 return internString(GetName(RD,
false, NameIsSimplified));
482 return II->getName();
487 if (CGM.getCodeGenOpts().EmitCodeView) {
490 "Typedef should not be in another decl context!");
491 assert(D->getDeclName().getAsIdentifierInfo() &&
492 "Typedef was not named!");
493 return D->getDeclName().getAsIdentifierInfo()->getName();
496 if (CGM.getLangOpts().CPlusPlus) {
499 ASTContext &Context = CGM.getContext();
503 Name = DD->getName();
504 else if (
const TypedefNameDecl *TND =
508 Name = TND->getName();
511 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
512 if (CXXRD->isLambda())
514 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
517 SmallString<256> UnnamedType(
"<unnamed-type-");
520 return internString(UnnamedType);
528std::optional<llvm::DIFile::ChecksumKind>
529CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
532 if (!CGM.getCodeGenOpts().EmitCodeView &&
533 CGM.getCodeGenOpts().DwarfVersion < 5)
536 SourceManager &
SM = CGM.getContext().getSourceManager();
537 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
541 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
542 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
544 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
545 return llvm::DIFile::CSK_MD5;
547 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
548 return llvm::DIFile::CSK_SHA1;
550 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
551 return llvm::DIFile::CSK_SHA256;
555 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
558std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
560 if (!CGM.getCodeGenOpts().EmbedSource)
563 bool SourceInvalid =
false;
564 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
572llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
573 SourceManager &
SM = CGM.getContext().getSourceManager();
576 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
582 FileName = TheCU->getFile()->getFilename();
583 CSInfo = TheCU->getFile()->getChecksum();
589 FileName = TheCU->getFile()->getFilename();
597 auto It = DIFileCache.find(
FileName.data());
598 if (It != DIFileCache.end()) {
600 if (llvm::Metadata *
V = It->second)
605 SmallString<64> Checksum;
607 std::optional<llvm::DIFile::ChecksumKind> CSKind =
608 computeChecksum(FID, Checksum);
610 CSInfo.emplace(*CSKind, Checksum);
616llvm::DIFile *CGDebugInfo::createFile(
618 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
619 std::optional<StringRef> Source) {
623 std::string CurDir =
remapDIPath(getCurrentDirname());
624 SmallString<128> DirBuf;
625 SmallString<128> FileBuf;
626 if (llvm::sys::path::is_absolute(RemappedFile)) {
629 auto FileIt = llvm::sys::path::begin(RemappedFile);
630 auto FileE = llvm::sys::path::end(RemappedFile);
631 auto CurDirIt = llvm::sys::path::begin(CurDir);
632 auto CurDirE = llvm::sys::path::end(CurDir);
633 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
634 llvm::sys::path::append(DirBuf, *CurDirIt);
635 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
641 for (; FileIt != FileE; ++FileIt)
642 llvm::sys::path::append(FileBuf, *FileIt);
647 if (!llvm::sys::path::is_absolute(
FileName))
651 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
652 DIFileCache[
FileName.data()].reset(F);
658 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
659 if (llvm::sys::path::replace_path_prefix(P, From, To))
661 return P.str().str();
671unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
685StringRef CGDebugInfo::getCurrentDirname() {
693 assert(CGO.DwarfVersion <= 5);
695 llvm::dwarf::SourceLanguage LangTag;
698 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
699 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
700 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
701 else if (LO.CPlusPlus14)
702 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
703 else if (LO.CPlusPlus11)
704 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
706 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
707 }
else if (LO.ObjC) {
708 LangTag = llvm::dwarf::DW_LANG_ObjC;
709 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
710 LangTag = llvm::dwarf::DW_LANG_OpenCL;
711 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
712 LangTag = llvm::dwarf::DW_LANG_C11;
714 LangTag = llvm::dwarf::DW_LANG_C99;
716 LangTag = llvm::dwarf::DW_LANG_C89;
722static llvm::DISourceLanguageName
730 uint32_t LangVersion = 0;
731 llvm::dwarf::SourceLanguageName LangTag;
734 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
736 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
739 }
else if (LO.ObjC) {
740 LangTag = llvm::dwarf::DW_LNAME_ObjC;
741 }
else if (LO.OpenCL) {
742 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
744 LangTag = llvm::dwarf::DW_LNAME_C;
748 return llvm::DISourceLanguageName(LangTag, LangVersion);
751void CGDebugInfo::CreateCompileUnit() {
752 SmallString<64> Checksum;
753 std::optional<llvm::DIFile::ChecksumKind> CSKind;
754 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
764 SourceManager &
SM = CGM.getContext().getSourceManager();
765 auto &CGO = CGM.getCodeGenOpts();
766 const LangOptions &LO = CGM.getLangOpts();
767 std::string MainFileName = CGO.MainFileName;
768 if (MainFileName.empty())
769 MainFileName =
"<stdin>";
775 std::string MainFileDir;
777 SM.getFileEntryRefForID(
SM.getMainFileID())) {
778 MainFileDir = std::string(MainFile->getDir().getName());
779 if (!llvm::sys::path::is_absolute(MainFileName)) {
780 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
781 llvm::sys::path::Style Style =
783 ? (CGM.getTarget().getTriple().isOSWindows()
784 ? llvm::sys::path::Style::windows_backslash
785 : llvm::sys::path::Style::posix)
786 : llvm::sys::path::Style::native;
787 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
788 MainFileName = std::string(
789 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
796 if (MainFile->getName() == MainFileName &&
798 MainFile->getName().rsplit(
'.').second)
800 MainFileName = CGM.getModule().getName().str();
802 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
809 unsigned RuntimeVers = 0;
813 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
815 case llvm::codegenoptions::NoDebugInfo:
816 case llvm::codegenoptions::LocTrackingOnly:
817 EmissionKind = llvm::DICompileUnit::NoDebug;
819 case llvm::codegenoptions::DebugLineTablesOnly:
820 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
822 case llvm::codegenoptions::DebugDirectivesOnly:
823 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
825 case llvm::codegenoptions::DebugInfoConstructor:
826 case llvm::codegenoptions::LimitedDebugInfo:
827 case llvm::codegenoptions::FullDebugInfo:
828 case llvm::codegenoptions::UnusedTypeInfo:
829 EmissionKind = llvm::DICompileUnit::FullDebug;
834 auto &CGOpts = CGM.getCodeGenOpts();
840 CSInfo.emplace(*CSKind, Checksum);
841 llvm::DIFile *CUFile = DBuilder.createFile(
843 getSource(
SM,
SM.getMainFileID()));
845 StringRef Sysroot, SDK;
846 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
847 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
848 auto B = llvm::sys::path::rbegin(Sysroot);
849 auto E = llvm::sys::path::rend(Sysroot);
851 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
856 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
857 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
858 CGOpts.DebugNameTable);
859 if (CGM.getTarget().getTriple().isNVPTX())
860 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
861 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
862 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
865 TheCU = DBuilder.createCompileUnit(
867 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
868 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
869 CGOpts.PrepareForThinLTO,
870 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
871 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
872 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
875llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
879#define BUILTIN_TYPE(Id, SingletonId)
880#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
881#include "clang/AST/BuiltinTypes.def"
882 case BuiltinType::Dependent:
883 llvm_unreachable(
"Unexpected builtin type");
884 case BuiltinType::NullPtr:
885 return DBuilder.createNullPtrType();
886 case BuiltinType::Void:
888 case BuiltinType::ObjCClass:
891 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
892 "objc_class", TheCU, TheCU->getFile(), 0);
894 case BuiltinType::ObjCId: {
905 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
906 "objc_class", TheCU, TheCU->getFile(), 0);
908 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
910 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
912 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
913 (uint64_t)0, 0, llvm::DINode::FlagZero,
914 nullptr, llvm::DINodeArray());
916 DBuilder.replaceArrays(
917 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
918 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
919 llvm::DINode::FlagZero, ISATy)));
922 case BuiltinType::ObjCSel: {
924 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
925 "objc_selector", TheCU,
926 TheCU->getFile(), 0);
930#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
931 case BuiltinType::Id: \
932 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
934#include "clang/Basic/OpenCLImageTypes.def"
935 case BuiltinType::OCLSampler:
936 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
937 case BuiltinType::OCLEvent:
938 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
939 case BuiltinType::OCLClkEvent:
940 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
941 case BuiltinType::OCLQueue:
942 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
943 case BuiltinType::OCLReserveID:
944 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
945#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
946 case BuiltinType::Id: \
947 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
948#include "clang/Basic/OpenCLExtensionTypes.def"
949#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
950 case BuiltinType::Id: \
951 return getOrCreateStructPtrType(#Name, SingletonId);
952#include "clang/Basic/HLSLIntangibleTypes.def"
954#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
955#include "clang/Basic/AArch64ACLETypes.def"
957 if (BT->
getKind() == BuiltinType::MFloat8) {
958 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
959 BTName = BT->
getName(CGM.getLangOpts());
962 return DBuilder.createBasicType(BTName, Size, Encoding);
964 ASTContext::BuiltinVectorTypeInfo Info =
966 BT->
getKind() == BuiltinType::SveCount
967 ? ASTContext::BuiltinVectorTypeInfo(
968 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
970 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
977 "Unsupported number of vectors for svcount_t");
979 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
980 llvm::Metadata *BitStride =
nullptr;
981 if (BT->
getKind() == BuiltinType::SveBool) {
982 Info.
ElementType = CGM.getContext().UnsignedCharTy;
983 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
984 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
985 }
else if (BT->
getKind() == BuiltinType::SveCount) {
987 Info.
ElementType = CGM.getContext().UnsignedCharTy;
990 llvm::Metadata *LowerBound, *UpperBound;
991 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
992 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
993 if (Info.
EC.isScalable()) {
994 unsigned NumElemsPerVG = NumElems / 2;
995 SmallVector<uint64_t, 9> Expr(
996 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
997 46, 0, llvm::dwarf::DW_OP_mul,
998 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
999 UpperBound = DBuilder.createExpression(Expr);
1001 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1002 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1004 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1005 nullptr, LowerBound, UpperBound,
nullptr);
1006 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1007 llvm::DIType *ElemTy =
1008 getOrCreateType(Info.
ElementType, TheCU->getFile());
1010 return DBuilder.createVectorType( 0, Align, ElemTy,
1011 SubscriptArray, BitStride);
1015#define PPC_VECTOR_TYPE(Name, Id, size) \
1016 case BuiltinType::Id:
1017#include "clang/Basic/PPCTypes.def"
1020#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1021#include "clang/Basic/RISCVVTypes.def"
1023 ASTContext::BuiltinVectorTypeInfo Info =
1024 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1026 unsigned ElementCount = Info.
EC.getKnownMinValue();
1027 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1029 bool Fractional =
false;
1032 unsigned FixedSize = ElementCount * SEW;
1033 if (Info.
ElementType == CGM.getContext().BoolTy) {
1036 }
else if (FixedSize < 64) {
1039 LMUL = 64 / FixedSize;
1041 LMUL = FixedSize / 64;
1045 SmallVector<uint64_t, 12> Expr(
1049 {llvm::dwarf::DW_OP_bregx,
1052 llvm::dwarf::DW_OP_constu,
1054 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1056 Expr.push_back(llvm::dwarf::DW_OP_div);
1058 Expr.push_back(llvm::dwarf::DW_OP_mul);
1061 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1063 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1066 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1067 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1068 auto *UpperBound = DBuilder.createExpression(Expr);
1069 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1070 nullptr, LowerBound, UpperBound,
nullptr);
1071 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1072 llvm::DIType *ElemTy =
1073 getOrCreateType(Info.
ElementType, TheCU->getFile());
1076 return DBuilder.createVectorType(0, Align, ElemTy,
1080#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1081 case BuiltinType::Id: { \
1084 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1085 MangledName, TheCU, TheCU->getFile(), 0); \
1086 return SingletonId; \
1088#include "clang/Basic/WebAssemblyReferenceTypes.def"
1089#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1090 case BuiltinType::Id: { \
1093 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1094 TheCU, TheCU->getFile(), 0); \
1095 return SingletonId; \
1097#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1098 case BuiltinType::Id: { \
1101 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1102 return SingletonId; \
1104#include "clang/Basic/AMDGPUTypes.def"
1105 case BuiltinType::UChar:
1106 case BuiltinType::Char_U:
1107 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1109 case BuiltinType::Char_S:
1110 case BuiltinType::SChar:
1111 Encoding = llvm::dwarf::DW_ATE_signed_char;
1113 case BuiltinType::Char8:
1114 case BuiltinType::Char16:
1115 case BuiltinType::Char32:
1116 Encoding = llvm::dwarf::DW_ATE_UTF;
1118 case BuiltinType::UShort:
1119 case BuiltinType::UInt:
1120 case BuiltinType::UInt128:
1121 case BuiltinType::ULong:
1122 case BuiltinType::WChar_U:
1123 case BuiltinType::ULongLong:
1124 Encoding = llvm::dwarf::DW_ATE_unsigned;
1126 case BuiltinType::Short:
1127 case BuiltinType::Int:
1128 case BuiltinType::Int128:
1129 case BuiltinType::Long:
1130 case BuiltinType::WChar_S:
1131 case BuiltinType::LongLong:
1132 Encoding = llvm::dwarf::DW_ATE_signed;
1134 case BuiltinType::Bool:
1135 Encoding = llvm::dwarf::DW_ATE_boolean;
1137 case BuiltinType::Half:
1138 case BuiltinType::Float:
1139 case BuiltinType::LongDouble:
1140 case BuiltinType::Float16:
1141 case BuiltinType::BFloat16:
1142 case BuiltinType::Float128:
1143 case BuiltinType::Double:
1144 case BuiltinType::Ibm128:
1150 Encoding = llvm::dwarf::DW_ATE_float;
1152 case BuiltinType::ShortAccum:
1153 case BuiltinType::Accum:
1154 case BuiltinType::LongAccum:
1155 case BuiltinType::ShortFract:
1156 case BuiltinType::Fract:
1157 case BuiltinType::LongFract:
1158 case BuiltinType::SatShortFract:
1159 case BuiltinType::SatFract:
1160 case BuiltinType::SatLongFract:
1161 case BuiltinType::SatShortAccum:
1162 case BuiltinType::SatAccum:
1163 case BuiltinType::SatLongAccum:
1164 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1166 case BuiltinType::UShortAccum:
1167 case BuiltinType::UAccum:
1168 case BuiltinType::ULongAccum:
1169 case BuiltinType::UShortFract:
1170 case BuiltinType::UFract:
1171 case BuiltinType::ULongFract:
1172 case BuiltinType::SatUShortAccum:
1173 case BuiltinType::SatUAccum:
1174 case BuiltinType::SatULongAccum:
1175 case BuiltinType::SatUShortFract:
1176 case BuiltinType::SatUFract:
1177 case BuiltinType::SatULongFract:
1178 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1182 BTName = BT->
getName(CGM.getLangOpts());
1185 return DBuilder.createBasicType(BTName, Size, Encoding);
1188llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1189 SmallString<32> Name;
1190 llvm::raw_svector_ostream
OS(Name);
1191 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1194 ? llvm::dwarf::DW_ATE_unsigned
1195 : llvm::dwarf::DW_ATE_signed;
1196 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1197 Encoding, llvm::DINode::FlagZero, 0,
1201llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1203 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1205 Encoding = llvm::dwarf::DW_ATE_lo_user;
1208 return DBuilder.createBasicType(
"complex", Size, Encoding);
1222 return llvm::dwarf::DW_TAG_const_type;
1226 return llvm::dwarf::DW_TAG_volatile_type;
1230 return llvm::dwarf::DW_TAG_restrict_type;
1232 return (llvm::dwarf::Tag)0;
1235llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1236 llvm::DIFile *Unit) {
1237 QualifierCollector Qc;
1251 bool AuthenticatesNullValues =
1254 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1255 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1256 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1257 ExtraDiscr, IsaPointer,
1258 AuthenticatesNullValues);
1260 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1261 return getOrCreateType(QualType(
T, 0), Unit);
1265 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1269 return DBuilder.createQualifiedType(Tag, FromTy);
1272llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1273 llvm::DIFile *Unit) {
1282 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1287 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1293 return DBuilder.createQualifiedType(Tag, FromTy);
1296llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1297 llvm::DIFile *Unit) {
1303 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1305 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1309llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1310 llvm::DIFile *Unit) {
1311 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1317 case llvm::dwarf::DW_LANG_C_plus_plus:
1318 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1319 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1321 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1331 case llvm::dwarf::DW_LNAME_C_plus_plus:
1333 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1344 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1345 SourceLang.hasVersionedName())
1347 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1351 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1377 llvm::DICompileUnit *TheCU) {
1395 llvm::DICompileUnit *TheCU) {
1401 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1403 if (RD->isDynamicClass() &&
1409 llvm::raw_svector_ostream Out(Identifier);
1416 llvm::dwarf::Tag Tag;
1418 Tag = llvm::dwarf::DW_TAG_structure_type;
1420 Tag = llvm::dwarf::DW_TAG_union_type;
1425 Tag = llvm::dwarf::DW_TAG_class_type;
1430llvm::DICompositeType *
1431CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1432 llvm::DIScope *Ctx) {
1433 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1434 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1436 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1437 const unsigned Line =
1439 StringRef RDName = getClassName(RD);
1446 Size = CGM.getContext().getTypeSize(Ty);
1448 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1453 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1454 if (!CXXRD->hasDefinition() ||
1455 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1456 Flags |= llvm::DINode::FlagNonTrivial;
1459 SmallString<256> Identifier;
1461 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1463 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1466 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1467 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1468 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1469 CollectCXXTemplateParams(TSpecial, DefUnit));
1470 ReplaceMap.emplace_back(
1471 std::piecewise_construct, std::make_tuple(Ty),
1472 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1476llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1479 llvm::DIFile *Unit) {
1484 std::optional<unsigned> DWARFAddressSpace =
1485 CGM.getTarget().getDWARFAddressSpace(
1486 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1488 const BTFTagAttributedType *BTFAttrTy;
1489 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1490 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1492 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1493 SmallVector<llvm::Metadata *, 4> Annots;
1495 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1497 llvm::Metadata *Ops[2] = {
1498 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1499 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1500 Annots.insert(Annots.begin(),
1501 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1503 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1506 llvm::DINodeArray Annotations =
nullptr;
1507 if (Annots.size() > 0)
1508 Annotations = DBuilder.getOrCreateArray(Annots);
1510 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1511 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1512 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1513 Size, Align, DWARFAddressSpace);
1515 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1516 Align, DWARFAddressSpace, StringRef(),
1520llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1521 llvm::DIType *&
Cache) {
1524 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1525 TheCU, TheCU->getFile(), 0);
1526 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1527 Cache = DBuilder.createPointerType(
Cache, Size);
1531uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1532 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1533 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1543 if (CGM.getLangOpts().OpenCL) {
1544 FType = CGM.getContext().IntTy;
1545 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1546 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1548 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1549 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1550 FType = CGM.getContext().IntTy;
1551 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1552 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1554 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1555 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1556 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1557 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1558 EltTys.push_back(DBuilder.createMemberType(
1559 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1560 FieldOffset, llvm::DINode::FlagZero, DescTy));
1561 FieldOffset += FieldSize;
1567llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1568 llvm::DIFile *Unit) {
1569 SmallVector<llvm::Metadata *, 8> EltTys;
1572 llvm::DINodeArray Elements;
1575 FType = CGM.getContext().UnsignedLongTy;
1576 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1579 Elements = DBuilder.getOrCreateArray(EltTys);
1582 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1585 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1586 FieldOffset, 0, Flags,
nullptr, Elements);
1591 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1593 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1596 Elements = DBuilder.getOrCreateArray(EltTys);
1602 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1603 Flags,
nullptr, Elements);
1605 return DBuilder.createPointerType(EltTy, Size);
1608static llvm::SmallVector<TemplateArgument>
1610 assert(Ty->isTypeAlias());
1619 ArrayRef SubstArgs = Ty->template_arguments();
1622 if (Param->isParameterPack()) {
1631 if (SubstArgs.empty()) {
1640 SpecArgs.push_back(SubstArgs.front());
1641 SubstArgs = SubstArgs.drop_front();
1646llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1647 llvm::DIFile *Unit) {
1648 assert(Ty->isTypeAlias());
1649 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1651 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1659 SmallString<128> NS;
1660 llvm::raw_svector_ostream
OS(NS);
1662 auto PP = getPrintingPolicy();
1665 SourceLocation Loc =
AliasDecl->getLocation();
1667 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1668 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1677 llvm::raw_string_ostream
OS(Name);
1679 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1680 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1681 !HasReconstitutableArgs(Args.Args))
1682 printTemplateArgumentList(OS, Args.Args, PP);
1684 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1685 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1686 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1690 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1692 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1709 return llvm::DINode::FlagZero;
1713 return llvm::DINode::FlagPrivate;
1715 return llvm::DINode::FlagProtected;
1717 return llvm::DINode::FlagPublic;
1719 return llvm::DINode::FlagZero;
1721 llvm_unreachable(
"unexpected access enumerator");
1724llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1725 llvm::DIFile *Unit) {
1726 llvm::DIType *Underlying =
1738 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1740 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1745 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1746 getOrCreateFile(Loc), getLineNumber(Loc),
1747 getDeclContextDescriptor(Ty->
getDecl()), Align,
1748 Flags, Annotations);
1758 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1760 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1762 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1764 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1766 return llvm::dwarf::DW_CC_BORLAND_pascal;
1768 return llvm::dwarf::DW_CC_LLVM_Win64;
1770 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1774 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1776 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1778 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1780 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1782 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1784 return llvm::dwarf::DW_CC_LLVM_Swift;
1786 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1788 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1790 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1792 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1794 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1796 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1798 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1799#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1813 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1819 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1821 Flags |= llvm::DINode::FlagLValueReference;
1823 Flags |= llvm::DINode::FlagRValueReference;
1827llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1828 llvm::DIFile *Unit) {
1829 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1831 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1837 SmallVector<llvm::Metadata *, 16> EltTys;
1840 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1842 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1846 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1849 for (
const QualType &ParamType : FPT->param_types())
1850 EltTys.push_back(getOrCreateType(ParamType, Unit));
1851 if (FPT->isVariadic())
1852 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1855 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1856 llvm::DIType *F = DBuilder.createSubroutineType(
1861llvm::DIDerivedType *
1862CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1863 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1864 StringRef Name = BitFieldDecl->
getName();
1865 QualType Ty = BitFieldDecl->
getType();
1866 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1869 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1870 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1873 llvm::DIFile *
File = getOrCreateFile(Loc);
1874 unsigned Line = getLineNumber(Loc);
1876 const CGBitFieldInfo &BitFieldInfo =
1877 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1879 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1886 if (CGM.getDataLayout().isBigEndian())
1888 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1890 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1891 return DBuilder.createBitFieldMemberType(
1892 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1893 Flags, DebugType, Annotations);
1896llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1897 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1898 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1900 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1925 if (PreviousFieldsDI.empty())
1929 auto *PreviousMDEntry =
1930 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1931 auto *PreviousMDField =
1932 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1933 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1934 PreviousMDField->getSizeInBits() == 0)
1938 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1940 assert(PreviousBitfield->isBitField());
1942 if (!PreviousBitfield->isZeroLengthBitField())
1945 QualType Ty = PreviousBitfield->getType();
1946 SourceLocation Loc = PreviousBitfield->getLocation();
1947 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1948 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1949 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1951 llvm::DIFile *
File = getOrCreateFile(Loc);
1952 unsigned Line = getLineNumber(Loc);
1958 llvm::DINode::DIFlags Flags =
1960 llvm::DINodeArray Annotations =
1961 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1962 return DBuilder.createBitFieldMemberType(
1963 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1964 Flags, DebugType, Annotations);
1967llvm::DIType *CGDebugInfo::createFieldType(
1969 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1970 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1971 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1974 llvm::DIFile *file = getOrCreateFile(loc);
1975 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1978 auto Align = AlignInBits;
1979 if (!
type->isIncompleteArrayType()) {
1980 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1981 SizeInBits = TI.
Width;
1987 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1988 offsetInBits, flags, debugType, Annotations);
1992CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1993 llvm::DIFile *FileScope) {
1997 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2000 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2001 SP = DBuilder.createFunction(
2002 FileScope, FuncName, StringRef(),
2003 FileScope, 0, DIFnTy,
2005 llvm::DINode::FlagArtificial,
2006 llvm::DISubprogram::SPFlagDefinition,
2007 nullptr,
nullptr,
nullptr,
2008 nullptr, StringRef(),
2009 CGM.getCodeGenOpts().DebugKeyInstructions);
2016CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2018 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2020 assert(
Capture.capturesVariable());
2022 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2023 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2025 return CaptureDecl->
getName();
2028void CGDebugInfo::CollectRecordLambdaFields(
2029 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2030 llvm::DIType *RecordTy) {
2035 unsigned fieldno = 0;
2038 I != E; ++I, ++Field, ++fieldno) {
2039 const LambdaCapture &
Capture = *I;
2041 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2043 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2053 Loc =
Field->getLocation();
2054 }
else if (
Capture.capturesVariable()) {
2057 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2058 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2065 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2067 elements.push_back(createFieldType(
2069 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2073llvm::DIDerivedType *
2074CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2075 const RecordDecl *RD) {
2079 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2080 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2082 unsigned LineNumber = getLineNumber(Var->
getLocation());
2083 StringRef VName = Var->
getName();
2087 llvm::Constant *
C =
nullptr;
2092 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2093 if (
Value->isFloat())
2094 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2099 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2100 ? llvm::dwarf::DW_TAG_variable
2101 : llvm::dwarf::DW_TAG_member;
2103 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2104 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2109void CGDebugInfo::CollectRecordNormalField(
2110 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2111 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2112 const RecordDecl *RD) {
2117 if (
name.empty() && !
type->isRecordType())
2120 llvm::DIType *FieldType;
2122 llvm::DIDerivedType *BitFieldType;
2123 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2124 if (llvm::DIType *Separator =
2125 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2126 elements.push_back(Separator);
2129 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2132 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2135 elements.push_back(FieldType);
2138void CGDebugInfo::CollectRecordNestedType(
2139 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2140 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2147 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2148 elements.push_back(nestedType);
2151void CGDebugInfo::CollectRecordFields(
2152 const RecordDecl *record, llvm::DIFile *tunit,
2153 SmallVectorImpl<llvm::Metadata *> &elements,
2154 llvm::DICompositeType *RecordTy) {
2155 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2157 if (CXXDecl && CXXDecl->
isLambda())
2158 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2160 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2163 unsigned fieldNo = 0;
2167 for (
const auto *I : record->
decls())
2168 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2169 if (
V->hasAttr<NoDebugAttr>())
2174 if (CGM.getCodeGenOpts().EmitCodeView &&
2182 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2183 if (MI != StaticDataMemberCache.end()) {
2184 assert(MI->second &&
2185 "Static data member declaration should still exist");
2186 elements.push_back(MI->second);
2188 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2189 elements.push_back(Field);
2191 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2192 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2193 elements, RecordTy, record);
2197 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2200 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2205 if (!nestedType->isImplicit() &&
2206 nestedType->getDeclContext() == record)
2207 CollectRecordNestedType(nestedType, elements);
2213llvm::DISubroutineType *
2214CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2215 llvm::DIFile *Unit) {
2216 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2218 return cast_or_null<llvm::DISubroutineType>(
2219 getOrCreateType(QualType(
Func, 0), Unit));
2222 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2223 ThisType =
Method->getThisType();
2225 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2228llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2229 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2230 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2232 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2235llvm::DISubroutineType *
2236CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2237 const FunctionProtoType *
Func,
2238 llvm::DIFile *Unit,
bool SkipFirst) {
2239 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2254 getOrCreateType(CGM.getContext().getFunctionType(
2255 Func->getReturnType(),
Func->getParamTypes(), EPI),
2257 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2258 assert(Args.size() &&
"Invalid number of arguments!");
2260 SmallVector<llvm::Metadata *, 16> Elts;
2263 Elts.push_back(Args[0]);
2265 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2269 if (!HasExplicitObjectParameter) {
2270 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2273 DBuilder.createObjectPointerType(ThisPtrType,
true);
2274 Elts.push_back(ThisPtrType);
2278 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2279 Elts.push_back(Args[i]);
2282 if (HasExplicitObjectParameter) {
2283 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2284 "Expected at least return type and object parameter.");
2285 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2288 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2290 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2297 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2305CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2308 const bool IsCtorOrDtor =
2311 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2318 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2321 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2324 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2327 return CGM.getMangledName(
Method);
2330llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2331 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2334 StringRef MethodName = getFunctionName(
Method);
2335 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2337 StringRef MethodLinkageName;
2344 MethodLinkageName = GetMethodLinkageName(
Method);
2347 llvm::DIFile *MethodDefUnit =
nullptr;
2348 unsigned MethodLine = 0;
2349 if (!
Method->isImplicit()) {
2350 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2351 MethodLine = getLineNumber(
Method->getLocation());
2355 llvm::DIType *ContainingType =
nullptr;
2356 unsigned VIndex = 0;
2357 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2358 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2359 int ThisAdjustment = 0;
2362 if (
Method->isPureVirtual())
2363 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2365 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2367 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2371 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2375 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2378 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2379 CGM.getContext().getLangOpts())
2383 MethodVFTableLocation ML =
2384 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2392 if (
Method->size_overridden_methods() == 0)
2393 Flags |= llvm::DINode::FlagIntroducedVirtual;
2398 ThisAdjustment = CGM.getCXXABI()
2399 .getVirtualFunctionPrologueThisAdjustment(GD)
2402 ContainingType = RecordTy;
2405 if (
Method->getCanonicalDecl()->isDeleted())
2406 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2408 if (
Method->isNoReturn())
2409 Flags |= llvm::DINode::FlagNoReturn;
2412 Flags |= llvm::DINode::FlagStaticMember;
2413 if (
Method->isImplicit())
2414 Flags |= llvm::DINode::FlagArtificial;
2416 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2417 if (CXXC->isExplicit())
2418 Flags |= llvm::DINode::FlagExplicit;
2419 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2420 if (CXXC->isExplicit())
2421 Flags |= llvm::DINode::FlagExplicit;
2423 if (
Method->hasPrototype())
2424 Flags |= llvm::DINode::FlagPrototyped;
2426 Flags |= llvm::DINode::FlagLValueReference;
2428 Flags |= llvm::DINode::FlagRValueReference;
2429 if (!
Method->isExternallyVisible())
2430 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2431 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2432 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2436 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2437 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2440 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2441 llvm::DISubprogram *SP = DBuilder.createMethod(
2442 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2443 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2444 TParamsArray.get(),
nullptr,
2445 CGM.getCodeGenOpts().DebugKeyInstructions);
2447 SPCache[
Method->getCanonicalDecl()].reset(SP);
2452void CGDebugInfo::CollectCXXMemberFunctions(
2453 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2454 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2459 for (
const auto *I : RD->
decls()) {
2460 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2474 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2483 auto MI = SPCache.find(
Method->getCanonicalDecl());
2484 EltTys.push_back(MI == SPCache.end()
2485 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2486 :
static_cast<llvm::Metadata *
>(MI->second));
2490void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2491 SmallVectorImpl<llvm::Metadata *> &EltTys,
2492 llvm::DIType *RecordTy) {
2493 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2494 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2495 llvm::DINode::FlagZero);
2499 if (CGM.getCodeGenOpts().EmitCodeView) {
2500 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2501 llvm::DINode::FlagIndirectVirtualBase);
2505void CGDebugInfo::CollectCXXBasesAux(
2506 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2507 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2509 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2510 llvm::DINode::DIFlags StartingFlags) {
2511 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2512 for (
const auto &BI : Bases) {
2515 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2517 if (!SeenTypes.insert(Base).second)
2519 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2520 llvm::DINode::DIFlags BFlags = StartingFlags;
2524 if (BI.isVirtual()) {
2525 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2528 BaseOffset = 0 - CGM.getItaniumVTableContext()
2529 .getVirtualBaseOffsetOffset(RD, Base)
2535 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2536 VBPtrOffset = CGM.getContext()
2537 .getASTRecordLayout(RD)
2541 BFlags |= llvm::DINode::FlagVirtual;
2548 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2549 VBPtrOffset, BFlags);
2550 EltTys.push_back(DTy);
2555CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2556 llvm::DIFile *Unit) {
2558 return llvm::DINodeArray();
2559 TemplateArgs &Args = *OArgs;
2560 SmallVector<llvm::Metadata *, 16> TemplateParams;
2561 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2562 const TemplateArgument &TA = Args.Args[i];
2566 Name = Args.TList->getParam(i)->getName();
2570 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2571 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2572 TheCU, Name, TTy, defaultParameter));
2577 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2578 TheCU, Name, TTy, defaultParameter,
2579 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2584 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2585 llvm::Constant *
V =
nullptr;
2588 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2589 !D->
hasAttr<CUDADeviceAttr>()) {
2592 if (
const auto *VD = dyn_cast<VarDecl>(D))
2593 V = CGM.GetAddrOfGlobalVar(VD);
2596 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2597 MD && MD->isImplicitObjectMemberFunction())
2598 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2599 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2600 V = CGM.GetAddrOfFunction(FD);
2603 else if (
const auto *MPT =
2604 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2608 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2610 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2611 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2612 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2613 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2614 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2616 V = ConstantEmitter(CGM).emitAbstract(
2617 SourceLocation(), TPO->getValue(), TPO->getType());
2619 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2621 assert(
V &&
"Failed to find template parameter pointer");
2622 V =
V->stripPointerCasts();
2624 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2625 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2629 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2630 llvm::Constant *
V =
nullptr;
2633 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2639 if (MPT->isMemberDataPointer())
2640 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2642 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2643 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2644 TheCU, Name, TTy, defaultParameter,
V));
2648 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2649 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2651 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2652 TheCU, Name, TTy, defaultParameter,
V));
2655 std::string QualName;
2656 llvm::raw_string_ostream
OS(QualName);
2658 OS, getPrintingPolicy());
2659 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2660 TheCU, Name,
nullptr, QualName, defaultParameter));
2664 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2665 TheCU, Name,
nullptr,
2672 T = CGM.getContext().getLValueReferenceType(
T);
2673 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2674 assert(
V &&
"Expression in template argument isn't constant");
2675 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2676 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2677 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2683 "These argument types shouldn't exist in concrete types");
2686 return DBuilder.getOrCreateArray(TemplateParams);
2689std::optional<CGDebugInfo::TemplateArgs>
2690CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2698 return std::nullopt;
2700std::optional<CGDebugInfo::TemplateArgs>
2701CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2705 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2707 return std::nullopt;
2708 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2709 const TemplateParameterList *TList =
T->getTemplateParameters();
2710 auto TA = TS->getTemplateArgs().asArray();
2711 return {{TList, TA}};
2713std::optional<CGDebugInfo::TemplateArgs>
2714CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2715 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2719 TemplateParameterList *TPList =
2720 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2721 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2722 return {{TPList, TAList.
asArray()}};
2724 return std::nullopt;
2728CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2729 llvm::DIFile *Unit) {
2730 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2733llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2734 llvm::DIFile *Unit) {
2735 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2738llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2739 llvm::DIFile *Unit) {
2740 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2743llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2744 if (!D->
hasAttr<BTFDeclTagAttr>())
2747 SmallVector<llvm::Metadata *, 4> Annotations;
2749 llvm::Metadata *Ops[2] = {
2750 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2751 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2752 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2754 return DBuilder.getOrCreateArray(Annotations);
2757llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2759 return VTablePtrType;
2761 ASTContext &Context = CGM.getContext();
2764 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2765 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2766 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2768 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2769 std::optional<unsigned> DWARFAddressSpace =
2770 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2772 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2773 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2774 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2775 return VTablePtrType;
2778StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2790 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2792 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2802 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2803 VTable->isDeclarationForLinker())
2807 StringRef SymbolName =
"_vtable$";
2809 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2818 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2820 llvm::DIFile *Unit = getOrCreateFile(Loc);
2821 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2823 llvm::DINode::FlagArtificial;
2824 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2825 ? llvm::dwarf::DW_TAG_variable
2826 : llvm::dwarf::DW_TAG_member;
2827 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2828 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2832 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2836 llvm::DIGlobalVariableExpression *GVE =
2837 DBuilder.createGlobalVariableExpression(
2838 TheCU, SymbolName, VTable->getName(), Unit, 0,
2839 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2840 true,
nullptr, DT,
nullptr,
2842 VTable->addDebugInfo(GVE);
2845StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2847 llvm::Function *InitFn) {
2852 return InitFn->getName();
2862 llvm::raw_svector_ostream OS(QualifiedGV);
2864 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2866 std::swap(Quals, GVName);
2870 llvm::raw_svector_ostream OS(InitName);
2872 OS << Quals <<
"::";
2877 llvm_unreachable(
"not an initializer");
2879 OS <<
"`dynamic initializer for '";
2882 OS <<
"`dynamic atexit destructor for '";
2889 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2890 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2891 getPrintingPolicy());
2896 return internString(
OS.str());
2899void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2900 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2909 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2916 llvm::DIType *VPtrTy =
nullptr;
2917 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2918 CGM.getTarget().getCXXABI().isMicrosoft();
2919 if (NeedVTableShape) {
2921 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2922 const VTableLayout &VFTLayout =
2923 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2924 unsigned VSlotCount =
2926 unsigned VTableWidth = PtrWidth * VSlotCount;
2927 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2928 std::optional<unsigned> DWARFAddressSpace =
2929 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2932 llvm::DIType *VTableType = DBuilder.createPointerType(
2933 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2934 EltTys.push_back(VTableType);
2937 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2945 VPtrTy = getOrCreateVTablePtrType(Unit);
2947 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2948 llvm::DIType *VPtrMember =
2949 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2950 llvm::DINode::FlagArtificial, VPtrTy);
2951 EltTys.push_back(VPtrMember);
2956 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2957 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2968 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2969 assert(!D.
isNull() &&
"null type");
2970 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2971 assert(
T &&
"could not create debug info for type");
2980 if (CGM.getCodeGenOpts().getDebugInfo() <=
2981 llvm::codegenoptions::DebugLineTablesOnly)
2985 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2987 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2989 CI->setMetadata(
"heapallocsite", node);
2993 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2995 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2997 auto I = TypeCache.find(TyPtr);
3000 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3001 assert(!Res->isForwardDecl());
3002 TypeCache[TyPtr].reset(Res);
3006 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3007 !CGM.getLangOpts().CPlusPlus)
3013 if (RD->
hasAttr<DLLImportAttr>())
3016 if (MD->hasAttr<DLLImportAttr>())
3029 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3039 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3040 Explicit = TD->isExplicitInstantiationOrSpecialization();
3044 if (CXXDecl->
fields().empty())
3054 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3055 if (CXXRD->isDynamicClass() &&
3056 CGM.getVTableLinkage(CXXRD) ==
3057 llvm::GlobalValue::AvailableExternallyLinkage &&
3068 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3070 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3072 auto I = TypeCache.find(TyPtr);
3079 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3080 assert(!Res->isForwardDecl());
3081 TypeCache[TyPtr].reset(Res);
3088 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3089 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3112 if (Ctor->isCopyOrMoveConstructor())
3114 if (!Ctor->isDeleted())
3133 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3136 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3137 RD->
hasAttr<StandaloneDebugAttr>())
3140 if (!LangOpts.CPlusPlus)
3146 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3162 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3163 Spec = SD->getSpecializationKind();
3172 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3183 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3184 llvm::DIType *
T = getTypeOrNull(Ty);
3185 if (
T &&
T->isForwardDecl())
3189llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3190 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3191 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3195 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3199 auto [Def, Pref] = CreateTypeDefinition(Ty);
3201 return Pref ? Pref : Def;
3204llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3205 llvm::DIFile *Unit) {
3209 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3213 return getOrCreateType(PNA->getTypedefType(), Unit);
3216std::pair<llvm::DIType *, llvm::DIType *>
3217CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3218 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3221 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3229 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3233 return {FwdDecl,
nullptr};
3235 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3236 CollectContainingType(CXXDecl, FwdDecl);
3239 LexicalBlockStack.emplace_back(&*FwdDecl);
3240 RegionMap[RD].reset(FwdDecl);
3243 SmallVector<llvm::Metadata *, 16> EltTys;
3250 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3252 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3253 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3257 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3258 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3259 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3261 LexicalBlockStack.pop_back();
3262 RegionMap.erase(RD);
3264 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3265 DBuilder.replaceArrays(FwdDecl, Elements);
3267 if (FwdDecl->isTemporary())
3269 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3271 RegionMap[RD].reset(FwdDecl);
3273 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3274 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3275 return {FwdDecl, PrefDI};
3277 return {FwdDecl,
nullptr};
3280llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3281 llvm::DIFile *Unit) {
3283 return getOrCreateType(Ty->getBaseType(), Unit);
3286llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3287 llvm::DIFile *Unit) {
3289 SourceLocation Loc = Ty->getDecl()->getLocation();
3292 return DBuilder.createTypedef(
3293 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3294 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3295 getDeclContextDescriptor(Ty->getDecl()));
3322llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3323 llvm::DIFile *Unit) {
3328 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3329 TheCU->getSourceLanguage().getUnversionedName());
3334 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3335 !
ID->getImplementation())
3336 return DBuilder.createForwardDecl(
3337 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3338 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3341 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3342 unsigned Line = getLineNumber(
ID->getLocation());
3346 ObjCInterfaceDecl *Def =
ID->getDefinition();
3348 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3349 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3350 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3351 DefUnit,
Line, RuntimeLang);
3352 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3356 return CreateTypeDefinition(Ty, Unit);
3359llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3360 bool CreateSkeletonCU) {
3365 auto ModRef = ModuleCache.find(M);
3366 if (ModRef != ModuleCache.end())
3370 SmallString<128> ConfigMacros;
3372 llvm::raw_svector_ostream
OS(ConfigMacros);
3373 const auto &PPOpts = CGM.getPreprocessorOpts();
3376 for (
auto &M : PPOpts.Macros) {
3379 const std::string &
Macro = M.first;
3380 bool Undef = M.second;
3381 OS <<
"\"-" << (Undef ?
'U' :
'D');
3397 bool IsRootModule = M ? !M->
Parent :
true;
3401 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3402 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3403 "clang module without ASTFile must be specified by -fmodule-name");
3406 auto RemapPath = [
this](StringRef Path) -> std::string {
3408 StringRef Relative(Remapped);
3409 StringRef CompDir = TheCU->getDirectory();
3410 if (CompDir.empty())
3413 if (Relative.consume_front(CompDir))
3414 Relative.consume_front(llvm::sys::path::get_separator());
3416 return Relative.str();
3419 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3426 Signature = ModSig.truncatedValue();
3430 llvm::DIBuilder DIB(CGM.getModule());
3432 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3433 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3434 PCM = getCurrentDirname();
3438 llvm::sys::path::append(PCM, Mod.
getASTFile());
3439 DIB.createCompileUnit(
3440 TheCU->getSourceLanguage(),
3443 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3444 llvm::DICompileUnit::FullDebug, Signature);
3448 llvm::DIModule *Parent =
3450 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3452 std::string IncludePath = Mod.
getPath().str();
3453 llvm::DIModule *DIMod =
3454 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3455 RemapPath(IncludePath));
3456 ModuleCache[M].reset(DIMod);
3460llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3461 llvm::DIFile *Unit) {
3463 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3464 unsigned Line = getLineNumber(
ID->getLocation());
3466 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3472 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3473 if (
ID->getImplementation())
3474 Flags |= llvm::DINode::FlagObjcClassComplete;
3476 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3477 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3478 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3479 nullptr, llvm::DINodeArray(), RuntimeLang);
3481 QualType QTy(Ty, 0);
3482 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3485 LexicalBlockStack.emplace_back(RealDecl);
3486 RegionMap[Ty->
getDecl()].reset(RealDecl);
3489 SmallVector<llvm::Metadata *, 16> EltTys;
3491 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3493 llvm::DIType *SClassTy =
3494 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3498 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3499 llvm::DINode::FlagZero);
3500 EltTys.push_back(InhTag);
3504 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3505 SourceLocation Loc = PD->getLocation();
3506 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3507 unsigned PLine = getLineNumber(Loc);
3508 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3509 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3510 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3511 PD->getName(), PUnit, PLine,
3513 : getSelectorName(PD->getGetterName()),
3515 : getSelectorName(PD->getSetterName()),
3516 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3517 EltTys.push_back(PropertyNode);
3522 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3526 llvm::DenseSet<IsClassAndIdent> PropertySet;
3528 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3529 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3531 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3532 for (
auto *PD : ClassExt->properties()) {
3533 PropertySet.insert(GetIsClassAndIdent(PD));
3536 for (
const auto *PD :
ID->properties()) {
3539 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3545 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3546 unsigned FieldNo = 0;
3547 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3548 Field =
Field->getNextIvar(), ++FieldNo) {
3549 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3553 StringRef FieldName =
Field->getName();
3556 if (FieldName.empty())
3560 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3561 unsigned FieldLine = getLineNumber(
Field->getLocation());
3562 QualType FType =
Field->getType();
3569 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3570 : CGM.getContext().getTypeSize(FType);
3575 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3579 if (
Field->isBitField()) {
3581 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3582 FieldOffset %= CGM.getContext().getCharWidth();
3590 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3592 Flags = llvm::DINode::FlagProtected;
3594 Flags = llvm::DINode::FlagPrivate;
3596 Flags = llvm::DINode::FlagPublic;
3598 if (
Field->isBitField())
3599 Flags |= llvm::DINode::FlagBitField;
3601 llvm::MDNode *PropertyNode =
nullptr;
3602 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3603 if (ObjCPropertyImplDecl *PImpD =
3604 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3605 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3606 SourceLocation Loc = PD->getLocation();
3607 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3608 unsigned PLine = getLineNumber(Loc);
3609 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3610 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3611 PropertyNode = DBuilder.createObjCProperty(
3612 PD->getName(), PUnit, PLine,
3615 : getSelectorName(PD->getGetterName()),
3618 : getSelectorName(PD->getSetterName()),
3619 PD->getPropertyAttributes(),
3620 getOrCreateType(PD->getType(), PUnit));
3624 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3625 FieldSize, FieldAlign, FieldOffset, Flags,
3626 FieldTy, PropertyNode);
3627 EltTys.push_back(FieldTy);
3630 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3631 DBuilder.replaceArrays(RealDecl, Elements);
3633 LexicalBlockStack.pop_back();
3637llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3638 llvm::DIFile *Unit) {
3646 auto &Ctx = CGM.getContext();
3651 QualType CharVecTy =
3653 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3656 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3659 llvm::Metadata *Subscript;
3660 QualType QTy(Ty, 0);
3661 auto SizeExpr = SizeExprCache.find(QTy);
3662 if (SizeExpr != SizeExprCache.end())
3663 Subscript = DBuilder.getOrCreateSubrange(
3664 SizeExpr->getSecond() ,
nullptr ,
3665 nullptr ,
nullptr );
3668 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3669 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3670 Subscript = DBuilder.getOrCreateSubrange(
3671 CountNode ,
nullptr ,
nullptr ,
3674 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3679 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3682llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3683 llvm::DIFile *Unit) {
3687 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3692 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3693 auto *ColumnCountNode =
3694 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3695 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3696 auto *RowCountNode =
3697 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3698 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3699 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3700 ColumnCountNode ,
nullptr ,
nullptr ,
3702 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3703 RowCountNode ,
nullptr ,
nullptr ,
3705 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3706 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3709llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3714 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3729 Size = CGM.getContext().getTypeSize(Ty);
3736 SmallVector<llvm::Metadata *, 8> Subscripts;
3737 QualType EltTy(Ty, 0);
3738 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3747 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3748 Count = CAT->getZExtSize();
3749 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3750 if (Expr *Size = VAT->getSizeExpr()) {
3752 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3753 Count =
Result.Val.getInt().getExtValue();
3757 auto SizeNode = SizeExprCache.find(EltTy);
3758 if (SizeNode != SizeExprCache.end())
3759 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3760 SizeNode->getSecond() ,
nullptr ,
3761 nullptr ,
nullptr ));
3764 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3765 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3766 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3767 CountNode ,
nullptr ,
nullptr ,
3773 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3775 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3779llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3780 llvm::DIFile *Unit) {
3781 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3785llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3786 llvm::DIFile *Unit) {
3787 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3789 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3790 CGM.getCodeGenOpts().DwarfVersion < 4)
3791 Tag = llvm::dwarf::DW_TAG_reference_type;
3793 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3796llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3798 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3802 Size = CGM.getContext().getTypeSize(Ty);
3805 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3808 Flags |= llvm::DINode::FlagSingleInheritance;
3811 Flags |= llvm::DINode::FlagMultipleInheritance;
3814 Flags |= llvm::DINode::FlagVirtualInheritance;
3824 llvm::DIType *ClassType = getOrCreateType(
T, U);
3826 return DBuilder.createMemberPointerType(
3830 const FunctionProtoType *FPT =
3832 return DBuilder.createMemberPointerType(
3833 getOrCreateInstanceMethodType(
3836 ClassType, Size, 0, Flags);
3839llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3841 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3844llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3848llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3850 return getOrCreateType(Ty->getWrappedType(), U);
3853llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3860 const EnumType *Ty) {
3872llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3875 bool isImportedFromModule =
3876 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3880 if (isImportedFromModule || !ED->getDefinition()) {
3887 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3888 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3889 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3890 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3892 unsigned Line = getLineNumber(ED->getLocation());
3893 StringRef EDName = ED->getName();
3894 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3895 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3896 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3898 ReplaceMap.emplace_back(
3899 std::piecewise_construct, std::make_tuple(Ty),
3900 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3904 return CreateTypeDefinition(Ty);
3907llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3910 SmallVector<llvm::Metadata *, 16> Enumerators;
3911 ED = ED->getDefinition();
3912 assert(ED &&
"An enumeration definition is required");
3913 for (
const auto *
Enum : ED->enumerators()) {
3914 Enumerators.push_back(
3915 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3918 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3919 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3920 EnumKind = Attr->getExtensibility();
3923 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3925 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3926 unsigned Line = getLineNumber(ED->getLocation());
3927 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3928 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3929 return DBuilder.createEnumerationType(
3930 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3931 0, Identifier, ED->isScoped(), EnumKind);
3936 StringRef Name, StringRef
Value) {
3937 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3938 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3944 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3945 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3946 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3950 StringRef FuncName) {
3951 llvm::DISubprogram *SP =
3952 createInlinedSubprogram(FuncName, Location->getFile());
3953 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3958 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3964 FuncName += Category;
3966 FuncName += FailureMsg;
3978 Quals += InnerQuals;
3980 switch (
T->getTypeClass()) {
3982 return C.getQualifiedType(
T.getTypePtr(), Quals);
3985 case Type::InjectedClassName:
3986 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3988 case Type::TemplateSpecialization: {
3990 if (Spec->isTypeAlias())
3991 return C.getQualifiedType(
T.getTypePtr(), Quals);
3992 T = Spec->desugar();
3995 case Type::TypeOfExpr:
4001 case Type::Decltype:
4004 case Type::UnaryTransform:
4007 case Type::Attributed:
4010 case Type::BTFTagAttributed:
4013 case Type::CountAttributed:
4022 case Type::MacroQualified:
4025 case Type::SubstTemplateTypeParm:
4029 case Type::DeducedTemplateSpecialization: {
4031 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4035 case Type::PackIndexing: {
4039 case Type::Adjusted:
4046 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4051llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4054 if (It != TypeCache.end()) {
4056 if (llvm::Metadata *
V = It->second)
4069 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4076 RetainedTypes.push_back(
4077 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4080llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4084 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4086 llvm::raw_string_ostream OS(Name);
4087 Ty.
print(OS, getPrintingPolicy());
4094 if (
auto *
T = getTypeOrNull(Ty))
4097 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4098 void *TyPtr = Ty.getAsOpaquePtr();
4101 TypeCache[TyPtr].reset(Res);
4106llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4114 auto Info = Reader->getSourceDescriptor(Idx);
4116 return getOrCreateModuleRef(*Info,
true);
4117 }
else if (ClangModuleMap) {
4130 auto Info = ASTSourceDescriptor(*M);
4131 return getOrCreateModuleRef(Info,
false);
4134 return getOrCreateModuleRef(PCHDescriptor,
false);
4141llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4144 return CreateQualifiedType(Ty, Unit);
4148#define TYPE(Class, Base)
4149#define ABSTRACT_TYPE(Class, Base)
4150#define NON_CANONICAL_TYPE(Class, Base)
4151#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4152#include "clang/AST/TypeNodes.inc"
4153 llvm_unreachable(
"Dependent types cannot show up in debug information");
4155 case Type::ExtVector:
4158 case Type::ConstantMatrix:
4160 case Type::ObjCObjectPointer:
4162 case Type::ObjCObject:
4164 case Type::ObjCTypeParam:
4166 case Type::ObjCInterface:
4174 case Type::BlockPointer:
4182 case Type::FunctionProto:
4183 case Type::FunctionNoProto:
4185 case Type::ConstantArray:
4186 case Type::VariableArray:
4187 case Type::IncompleteArray:
4188 case Type::ArrayParameter:
4191 case Type::LValueReference:
4193 case Type::RValueReference:
4196 case Type::MemberPointer:
4207 case Type::TemplateSpecialization:
4209 case Type::HLSLAttributedResource:
4211 case Type::HLSLInlineSpirv:
4213 case Type::PredefinedSugar:
4215 case Type::CountAttributed:
4217 case Type::Attributed:
4218 case Type::BTFTagAttributed:
4219 case Type::Adjusted:
4221 case Type::DeducedTemplateSpecialization:
4224 case Type::MacroQualified:
4225 case Type::SubstTemplateTypeParm:
4226 case Type::TypeOfExpr:
4228 case Type::Decltype:
4229 case Type::PackIndexing:
4230 case Type::UnaryTransform:
4234 llvm_unreachable(
"type should have been unwrapped!");
4237llvm::DICompositeType *
4238CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4239 QualType QTy(Ty, 0);
4241 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4246 if (
T && !
T->isForwardDecl())
4250 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4255 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4258 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4263llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4264 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4265 bool NameIsSimplified =
false;
4268 StringRef RDName = getClassName(RD, &NameIsSimplified);
4270 llvm::DIFile *DefUnit =
nullptr;
4273 DefUnit = getOrCreateFile(Loc);
4274 Line = getLineNumber(Loc);
4277 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4281 auto *
T = cast_or_null<llvm::DICompositeType>(
4282 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4290 return getOrCreateRecordFwdDecl(Ty, RDContext);
4303 auto Flags = llvm::DINode::FlagZero;
4304 if (NameIsSimplified)
4305 Flags |= llvm::DINode::FlagNameIsSimplified;
4306 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4308 Flags |= llvm::DINode::FlagTypePassByReference;
4310 Flags |= llvm::DINode::FlagTypePassByValue;
4313 if (!CXXRD->isTrivial())
4314 Flags |= llvm::DINode::FlagNonTrivial;
4317 if (CXXRD->isAnonymousStructOrUnion())
4318 Flags |= llvm::DINode::FlagExportSymbols;
4321 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4324 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4325 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4327 Flags, Identifier, Annotations);
4331 switch (RealDecl->getTag()) {
4333 llvm_unreachable(
"invalid composite type tag");
4335 case llvm::dwarf::DW_TAG_array_type:
4336 case llvm::dwarf::DW_TAG_enumeration_type:
4341 if (Identifier.empty())
4345 case llvm::dwarf::DW_TAG_structure_type:
4346 case llvm::dwarf::DW_TAG_union_type:
4347 case llvm::dwarf::DW_TAG_class_type:
4350 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4354 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4355 CXXRecordDecl *TemplateDecl =
4356 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4357 RegionMap[TemplateDecl].reset(RealDecl);
4359 RegionMap[RD].reset(RealDecl);
4361 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4363 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4364 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4365 CollectCXXTemplateParams(TSpecial, DefUnit));
4369void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4370 llvm::DICompositeType *RealDecl) {
4372 llvm::DIType *ContainingType =
nullptr;
4373 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4377 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4384 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4385 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4387 ContainingType = RealDecl;
4389 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4392llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4393 StringRef Name, uint64_t *Offset) {
4394 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4395 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4398 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4399 *Offset, llvm::DINode::FlagZero, FieldTy);
4400 *Offset += FieldSize;
4404void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4406 StringRef &LinkageName,
4407 llvm::DIScope *&FDContext,
4408 llvm::DINodeArray &TParamsArray,
4409 llvm::DINode::DIFlags &Flags) {
4411 bool NameIsSimplified =
false;
4412 Name = getFunctionName(FD, &NameIsSimplified);
4413 if (NameIsSimplified)
4414 Flags |= llvm::DINode::FlagNameIsSimplified;
4415 Name = getFunctionName(FD);
4418 LinkageName = CGM.getMangledName(GD);
4420 Flags |= llvm::DINode::FlagPrototyped;
4424 if (LinkageName == Name ||
4425 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4426 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4427 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4428 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4429 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4430 LinkageName = StringRef();
4434 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4435 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4436 CGM.getCodeGenOpts().EmitCodeView)) {
4437 if (
const NamespaceDecl *NSDecl =
4439 FDContext = getOrCreateNamespace(NSDecl);
4440 else if (
const RecordDecl *RDecl =
4442 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4443 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4446 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4449 Flags |= llvm::DINode::FlagNoReturn;
4451 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4455void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4456 unsigned &LineNo, QualType &
T,
4457 StringRef &Name, StringRef &LinkageName,
4458 llvm::MDTuple *&TemplateParameters,
4459 llvm::DIScope *&VDContext) {
4468 llvm::APInt ConstVal(32, 1);
4469 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4471 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4478 LinkageName = CGM.getMangledName(VD);
4479 if (LinkageName == Name)
4480 LinkageName = StringRef();
4483 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4484 TemplateParameters = parameterNodes.get();
4486 TemplateParameters =
nullptr;
4504 DC = CGM.getContext().getTranslationUnitDecl();
4506 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4507 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4510llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4512 llvm::DINodeArray TParamsArray;
4513 StringRef Name, LinkageName;
4514 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4515 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4517 llvm::DIFile *Unit = getOrCreateFile(Loc);
4518 llvm::DIScope *DContext = Unit;
4519 unsigned Line = getLineNumber(Loc);
4520 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4525 SmallVector<QualType, 16> ArgTypes;
4526 for (
const ParmVarDecl *Parm : FD->
parameters())
4527 ArgTypes.push_back(Parm->getType());
4530 QualType FnType = CGM.getContext().getFunctionType(
4531 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4533 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4534 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4535 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4539 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4540 return DBuilder.createFunction(
4541 DContext, Name, LinkageName, Unit,
Line,
4542 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4543 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4545 CGM.getCodeGenOpts().DebugKeyInstructions);
4548 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4549 DContext, Name, LinkageName, Unit,
Line,
4550 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4551 TParamsArray.get(), getFunctionDeclaration(FD));
4553 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4554 std::make_tuple(CanonDecl),
4555 std::make_tuple(SP));
4559llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4560 return getFunctionFwdDeclOrStub(GD,
false);
4563llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4564 return getFunctionFwdDeclOrStub(GD,
true);
4567llvm::DIGlobalVariable *
4568CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4570 StringRef Name, LinkageName;
4572 llvm::DIFile *Unit = getOrCreateFile(Loc);
4573 llvm::DIScope *DContext = Unit;
4574 unsigned Line = getLineNumber(Loc);
4575 llvm::MDTuple *TemplateParameters =
nullptr;
4577 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4580 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4581 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4583 FwdDeclReplaceMap.emplace_back(
4584 std::piecewise_construct,
4586 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4590llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4595 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4596 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4597 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4601 if (I != DeclCache.end()) {
4603 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4604 return GVE->getVariable();
4612 if (IE != ImportedDeclCache.end()) {
4613 auto N = IE->second;
4614 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4616 return dyn_cast_or_null<llvm::DINode>(N);
4621 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4622 return getFunctionForwardDeclaration(FD);
4623 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4624 return getGlobalVariableForwardDeclaration(VD);
4629llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4630 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4633 const auto *FD = dyn_cast<FunctionDecl>(D);
4638 auto *S = getDeclContextDescriptor(D);
4641 if (MI == SPCache.end()) {
4643 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4647 if (MI != SPCache.end()) {
4648 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4649 if (SP && !SP->isDefinition())
4653 for (
auto *NextFD : FD->
redecls()) {
4654 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4655 if (MI != SPCache.end()) {
4656 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4657 if (SP && !SP->isDefinition())
4664llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4665 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4666 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4667 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4670 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4674 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4678 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4687 QualType QTy(
ID->getTypeForDecl(), 0);
4688 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4689 if (It == TypeCache.end())
4692 llvm::DISubprogram *FD = DBuilder.createFunction(
4693 InterfaceType, getObjCMethodName(OMD), StringRef(),
4694 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4695 DBuilder.finalizeSubprogram(FD);
4702llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4707 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4708 !CGM.getCodeGenOpts().EmitCodeView))
4711 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4713 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4716 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4719 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4720 return getOrCreateMethodType(
Method, F);
4722 const auto *FTy = FnType->
getAs<FunctionType>();
4725 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4727 SmallVector<llvm::Metadata *, 16> Elts;
4730 QualType ResultTy = OMethod->getReturnType();
4733 if (ResultTy == CGM.getContext().getObjCInstanceType())
4734 ResultTy = CGM.getContext().getPointerType(
4735 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4737 Elts.push_back(getOrCreateType(ResultTy, F));
4739 QualType SelfDeclTy;
4740 if (
auto *SelfDecl = OMethod->getSelfDecl())
4741 SelfDeclTy = SelfDecl->getType();
4742 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4745 if (!SelfDeclTy.
isNull())
4747 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4749 Elts.push_back(DBuilder.createArtificialType(
4750 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4752 for (
const auto *PI : OMethod->parameters())
4753 Elts.push_back(getOrCreateType(PI->getType(), F));
4755 if (OMethod->isVariadic())
4756 Elts.push_back(DBuilder.createUnspecifiedParameter());
4758 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4759 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4765 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4766 if (FD->isVariadic()) {
4767 SmallVector<llvm::Metadata *, 16> EltTys;
4768 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4769 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4771 EltTys.push_back(getOrCreateType(ParamType, F));
4772 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4773 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4774 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4787 CC = SrcFnTy->getCallConv();
4789 for (
const VarDecl *VD : Args)
4790 ArgTypes.push_back(VD->
getType());
4791 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4797 llvm::Function *Fn,
bool CurFuncIsThunk) {
4799 StringRef LinkageName;
4801 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4804 bool HasDecl = (D !=
nullptr);
4806 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4807 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4808 llvm::DIFile *Unit = getOrCreateFile(Loc);
4809 llvm::DIScope *FDContext = Unit;
4810 llvm::DINodeArray TParamsArray;
4811 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4814 LinkageName = Fn->getName();
4815 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4817 auto FI = SPCache.find(FD->getCanonicalDecl());
4818 if (FI != SPCache.end()) {
4819 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4820 if (SP && SP->isDefinition()) {
4821 LexicalBlockStack.emplace_back(SP);
4822 RegionMap[D].reset(SP);
4826 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4827 TParamsArray, Flags);
4830 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4831 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4832 Name = getObjCMethodName(OMD);
4833 Flags |= llvm::DINode::FlagPrototyped;
4840 Name = Fn->getName();
4845 Flags |= llvm::DINode::FlagPrototyped;
4847 Name.consume_front(
"\01");
4851 "Unexpected DynamicInitKind !");
4855 Flags |= llvm::DINode::FlagArtificial;
4861 Flags |= llvm::DINode::FlagThunk;
4863 if (Fn->hasLocalLinkage())
4864 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4865 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4866 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4869 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4870 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4872 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4873 unsigned ScopeLine = getLineNumber(ScopeLoc);
4874 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4875 llvm::DISubprogram *
Decl =
nullptr;
4876 llvm::DINodeArray Annotations =
nullptr;
4879 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4880 : getFunctionDeclaration(D);
4881 Annotations = CollectBTFDeclTagAnnotations(D);
4889 llvm::DISubprogram *SP = DBuilder.createFunction(
4890 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4891 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4892 Annotations,
"", KeyInstructions);
4893 Fn->setSubprogram(SP);
4902 LexicalBlockStack.emplace_back(SP);
4905 RegionMap[D].reset(SP);
4909 QualType FnType, llvm::Function *Fn) {
4911 StringRef LinkageName;
4917 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4918 return GetName(D,
true);
4921 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4922 llvm::DIFile *Unit = getOrCreateFile(Loc);
4923 bool IsDeclForCallSite = Fn ?
true :
false;
4924 llvm::DIScope *FDContext =
4925 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4926 llvm::DINodeArray TParamsArray;
4929 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4930 TParamsArray, Flags);
4931 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4932 Name = getObjCMethodName(OMD);
4933 Flags |= llvm::DINode::FlagPrototyped;
4935 llvm_unreachable(
"not a function or ObjC method");
4937 Name.consume_front(
"\01");
4940 Flags |= llvm::DINode::FlagArtificial;
4945 unsigned LineNo = getLineNumber(Loc);
4946 unsigned ScopeLine = 0;
4947 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4948 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4949 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4951 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4952 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4954 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4955 llvm::DISubprogram *SP = DBuilder.createFunction(
4956 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4957 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4963 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4964 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4965 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4968 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4969 DBuilder.createParameterVariable(
4970 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4971 llvm::DINode::FlagZero, ParamAnnotations);
4977 if (IsDeclForCallSite)
4978 Fn->setSubprogram(SP);
4986 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4989 if (
Func->getSubprogram())
4997 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5012 auto FI = SPCache.find(FD->getCanonicalDecl());
5013 llvm::DISubprogram *SP =
nullptr;
5014 if (FI != SPCache.end())
5015 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5016 if (!SP || !SP->isDefinition())
5017 SP = getFunctionStub(GD);
5018 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5019 LexicalBlockStack.emplace_back(SP);
5025 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5034 if (CurLoc.isInvalid() ||
5035 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5036 LexicalBlockStack.empty())
5039 llvm::MDNode *
Scope = LexicalBlockStack.back();
5040 Builder.SetCurrentDebugLocation(
5041 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5042 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5046 llvm::MDNode *Back =
nullptr;
5047 if (!LexicalBlockStack.empty())
5048 Back = LexicalBlockStack.back().get();
5049 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5051 getColumnNumber(CurLoc)));
5054void CGDebugInfo::AppendAddressSpaceXDeref(
5056 std::optional<unsigned> DWARFAddressSpace =
5058 if (!DWARFAddressSpace)
5061 Expr.push_back(llvm::dwarf::DW_OP_constu);
5062 Expr.push_back(*DWARFAddressSpace);
5063 Expr.push_back(llvm::dwarf::DW_OP_swap);
5064 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5073 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5074 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5075 LexicalBlockStack.back(), CurInlinedAt));
5077 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5081 CreateLexicalBlock(Loc);
5086 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5091 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5094 LexicalBlockStack.pop_back();
5098 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5099 unsigned RCount = FnBeginRegionCount.back();
5100 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5103 while (LexicalBlockStack.size() != RCount) {
5106 LexicalBlockStack.pop_back();
5108 FnBeginRegionCount.pop_back();
5110 if (Fn && Fn->getSubprogram())
5111 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5114CGDebugInfo::BlockByRefType
5115CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5116 uint64_t *XOffset) {
5119 uint64_t FieldSize, FieldOffset;
5120 uint32_t FieldAlign;
5122 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5127 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5128 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5130 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5131 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5134 if (HasCopyAndDispose) {
5137 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5139 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5141 bool HasByrefExtendedLayout;
5144 HasByrefExtendedLayout) &&
5145 HasByrefExtendedLayout) {
5148 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5157 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5160 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5163 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5168 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5169 FieldSize = CGM.getContext().getTypeSize(FType);
5170 FieldAlign = CGM.getContext().toBits(Align);
5172 *XOffset = FieldOffset;
5173 llvm::DIType *FieldTy = DBuilder.createMemberType(
5174 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5175 llvm::DINode::FlagZero, WrappedTy);
5176 EltTys.push_back(FieldTy);
5177 FieldOffset += FieldSize;
5179 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5180 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5181 llvm::DINode::FlagZero,
nullptr, Elements),
5185llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5186 llvm::Value *Storage,
5187 std::optional<unsigned> ArgNo,
5189 const bool UsePointerValue) {
5190 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5191 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5192 if (VD->
hasAttr<NoDebugAttr>())
5197 llvm::DIFile *Unit =
nullptr;
5198 if (!VarIsArtificial)
5202 if (VD->
hasAttr<BlocksAttr>())
5203 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5205 Ty = getOrCreateType(VD->
getType(), Unit);
5215 if (!VarIsArtificial) {
5219 SmallVector<uint64_t, 13> Expr;
5220 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5227 Flags |= llvm::DINode::FlagArtificial;
5231 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5232 AppendAddressSpaceXDeref(AddressSpace, Expr);
5236 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5239 Flags |= llvm::DINode::FlagObjectPointer;
5240 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5241 if (PVD->isExplicitObjectParameter())
5242 Flags |= llvm::DINode::FlagObjectPointer;
5250 StringRef Name = VD->
getName();
5251 if (!Name.empty()) {
5257 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5259 offset = CGM.getContext().toCharUnitsFromBits(
5262 Expr.push_back(llvm::dwarf::DW_OP_deref);
5263 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5265 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5268 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5280 for (
const auto *Field : RD->
fields()) {
5281 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5282 StringRef FieldName =
Field->getName();
5290 auto *D = DBuilder.createAutoVariable(
5291 Scope, FieldName, Unit,
Line, FieldTy,
5292 CGM.getCodeGenOpts().OptimizationLevel != 0,
5293 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5296 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5297 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5300 Builder.GetInsertBlock());
5308 if (UsePointerValue) {
5309 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5310 "Debug info already contains DW_OP_deref.");
5311 Expr.push_back(llvm::dwarf::DW_OP_deref);
5315 llvm::DILocalVariable *D =
nullptr;
5317 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5318 D = DBuilder.createParameterVariable(
5319 Scope, Name, *ArgNo, Unit,
Line, Ty,
5320 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5329 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5335 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5336 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5337 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5338 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5340 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5346 if (Iter != CoroutineParameterMappings.end()) {
5347 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5348 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5349 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5351 if (Iter2 != ParamDbgMappings.end())
5352 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5358 D = RemapCoroArgToLocalVar();
5361 D = DBuilder.createAutoVariable(
5362 Scope, Name, Unit,
Line, Ty,
5363 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5366 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5367 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5368 Column, Scope, CurInlinedAt),
5369 Builder.GetInsertBlock());
5374llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5375 llvm::Value *Storage,
5376 std::optional<unsigned> ArgNo,
5378 const bool UsePointerValue) {
5379 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5380 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5381 if (BD->
hasAttr<NoDebugAttr>())
5388 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5389 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5397 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5399 SmallVector<uint64_t, 3> Expr;
5400 AppendAddressSpaceXDeref(AddressSpace, Expr);
5405 if (UsePointerValue) {
5406 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5407 "Debug info already contains DW_OP_deref.");
5408 Expr.push_back(llvm::dwarf::DW_OP_deref);
5413 StringRef Name = BD->
getName();
5416 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5417 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5418 llvm::DINode::FlagZero, Align);
5420 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5421 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5422 const unsigned fieldIndex = FD->getFieldIndex();
5423 const clang::CXXRecordDecl *parent =
5424 (
const CXXRecordDecl *)FD->getParent();
5425 const ASTRecordLayout &layout =
5426 CGM.getContext().getASTRecordLayout(parent);
5428 if (FD->isBitField()) {
5429 const CGRecordLayout &RL =
5430 CGM.getTypes().getCGRecordLayout(FD->getParent());
5435 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5441 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5442 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5443 Expr.push_back(Info.
Offset);
5446 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5447 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5448 }
else if (fieldOffset != 0) {
5449 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5450 "Unexpected non-bitfield with non-byte-aligned offset");
5451 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5453 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5456 }
else if (
const ArraySubscriptExpr *ASE =
5457 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5458 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5459 const uint64_t value = IL->getValue().getZExtValue();
5460 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5463 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5464 Expr.push_back(CGM.getContext()
5465 .toCharUnitsFromBits(value * typeSize)
5472 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5473 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5474 Column, Scope, CurInlinedAt),
5475 Builder.GetInsertBlock());
5480llvm::DILocalVariable *
5483 const bool UsePointerValue) {
5484 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5486 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5488 EmitDeclare(B, Storage, std::nullopt, Builder,
5495 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5499 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5500 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5502 if (D->
hasAttr<NoDebugAttr>())
5506 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5512 StringRef Name = D->
getName();
5518 CGM.getCodeGenOpts().OptimizationLevel != 0);
5521 DBuilder.insertLabel(L,
5522 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5523 Scope, CurInlinedAt),
5524 Builder.GetInsertBlock()->end());
5527llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5529 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5532 return DBuilder.createObjectPointerType(Ty,
true);
5537 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5538 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5539 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5541 if (Builder.GetInsertBlock() ==
nullptr)
5543 if (VD->
hasAttr<NoDebugAttr>())
5546 bool isByRef = VD->
hasAttr<BlocksAttr>();
5548 uint64_t XOffset = 0;
5549 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5552 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5554 Ty = getOrCreateType(VD->
getType(), Unit);
5558 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5560 Ty = CreateSelfType(VD->
getType(), Ty);
5563 const unsigned Line =
5567 const llvm::DataLayout &target = CGM.getDataLayout();
5574 addr.push_back(llvm::dwarf::DW_OP_deref);
5575 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5578 addr.push_back(llvm::dwarf::DW_OP_deref);
5579 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5582 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5584 addr.push_back(llvm::dwarf::DW_OP_deref);
5585 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5587 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5593 auto *D = DBuilder.createAutoVariable(
5595 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5598 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5599 LexicalBlockStack.back(), CurInlinedAt);
5600 auto *
Expr = DBuilder.createExpression(addr);
5602 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5604 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5607llvm::DILocalVariable *
5610 bool UsePointerValue) {
5611 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5612 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5616struct BlockLayoutChunk {
5617 uint64_t OffsetInBits;
5620bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5621 return l.OffsetInBits < r.OffsetInBits;
5625void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5627 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5628 SmallVectorImpl<llvm::Metadata *> &Fields) {
5632 if (CGM.getLangOpts().OpenCL) {
5633 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5634 BlockLayout.getElementOffsetInBits(0),
5636 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5637 BlockLayout.getElementOffsetInBits(1),
5641 BlockLayout.getElementOffsetInBits(0),
5643 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5644 BlockLayout.getElementOffsetInBits(1),
5648 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5649 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5650 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5651 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5652 BlockLayout.getElementOffsetInBits(3),
5654 Fields.push_back(createFieldType(
5659 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5666 llvm::AllocaInst *Alloca,
5668 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5674 llvm::DIFile *tunit = getOrCreateFile(loc);
5675 unsigned line = getLineNumber(loc);
5676 unsigned column = getColumnNumber(loc);
5681 const llvm::StructLayout *blockLayout =
5685 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5694 BlockLayoutChunk chunk;
5695 chunk.OffsetInBits =
5696 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5697 chunk.Capture =
nullptr;
5698 chunks.push_back(chunk);
5702 for (
const auto &capture :
blockDecl->captures()) {
5703 const VarDecl *variable = capture.getVariable();
5710 BlockLayoutChunk chunk;
5711 chunk.OffsetInBits =
5712 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5713 chunk.Capture = &capture;
5714 chunks.push_back(chunk);
5718 llvm::array_pod_sort(chunks.begin(), chunks.end());
5720 for (
const BlockLayoutChunk &Chunk : chunks) {
5721 uint64_t offsetInBits = Chunk.OffsetInBits;
5728 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5730 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5731 type = CGM.getContext().getCanonicalTagType(RDecl);
5733 llvm_unreachable(
"unexpected block declcontext");
5735 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5736 offsetInBits, tunit, tunit));
5741 StringRef name = variable->
getName();
5743 llvm::DIType *fieldType;
5745 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5750 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5751 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5752 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5753 PtrInfo.
Width, Align, offsetInBits,
5754 llvm::DINode::FlagZero, fieldType);
5758 offsetInBits, Align, tunit, tunit);
5760 fields.push_back(fieldType);
5764 llvm::raw_svector_ostream(typeName)
5765 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5767 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5769 llvm::DIType *
type =
5770 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5771 CGM.getContext().toBits(block.
BlockSize), 0,
5772 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5773 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5776 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5780 auto *debugVar = DBuilder.createParameterVariable(
5781 scope, Name, ArgNo, tunit, line,
type,
5782 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5785 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5786 llvm::DILocation::get(CGM.getLLVMContext(), line,
5787 column, scope, CurInlinedAt),
5788 Builder.GetInsertBlock());
5791llvm::DIDerivedType *
5792CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5797 if (MI != StaticDataMemberCache.end()) {
5798 assert(MI->second &&
"Static data member declaration should still exist");
5809llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5810 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5811 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5812 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5814 for (
const auto *Field : RD->
fields()) {
5815 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5816 StringRef FieldName = Field->getName();
5819 if (FieldName.empty()) {
5820 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5821 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5822 LineNo, LinkageName, Var, DContext);
5826 GVE = DBuilder.createGlobalVariableExpression(
5827 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5828 Var->hasLocalLinkage());
5829 Var->addDebugInfo(GVE);
5841 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5846 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5857 struct ReferencesAnonymous
5859 bool RefAnon =
false;
5860 bool VisitRecordType(RecordType *RT) {
5868 ReferencesAnonymous RT;
5881struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5882 bool Reconstitutable =
true;
5883 bool VisitVectorType(VectorType *FT) {
5884 Reconstitutable =
false;
5887 bool VisitAtomicType(AtomicType *FT) {
5888 Reconstitutable =
false;
5891 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5894 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5895 if (!ED->getIdentifier()) {
5896 Reconstitutable =
false;
5899 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5900 Reconstitutable =
false;
5906 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5910 return Reconstitutable;
5912 bool VisitRecordType(RecordType *RT,
bool =
false) {
5914 Reconstitutable =
false;
5924 ReconstitutableType
T;
5926 return T.Reconstitutable;
5929bool CGDebugInfo::HasReconstitutableArgs(
5930 ArrayRef<TemplateArgument> Args)
const {
5931 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5971 llvm_unreachable(
"Other, unresolved, template arguments should "
5972 "not be seen here");
5977std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
5978 bool *NameIsSimplified)
const {
5980 llvm::raw_string_ostream
OS(Name);
5981 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5984 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5985 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5987 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5988 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5990 std::optional<TemplateArgs> Args;
5992 bool IsOperatorOverload =
false;
5993 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5994 Args = GetTemplateArgs(RD);
5995 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5996 Args = GetTemplateArgs(FD);
5998 IsOperatorOverload |=
6001 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6002 Args = GetTemplateArgs(VD);
6026 bool Reconstitutable =
6027 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6029 PrintingPolicy PP = getPrintingPolicy();
6031 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6036 if (NameIsSimplified)
6037 *NameIsSimplified =
true;
6038 bool Mangled = TemplateNamesKind ==
6039 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6045 std::string EncodedOriginalName;
6046 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6051 printTemplateArgumentList(OS, Args->Args, PP);
6052 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6054 std::string CanonicalOriginalName;
6055 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6057 assert(EncodedOriginalName == CanonicalOriginalName);
6066 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6067 if (D->
hasAttr<NoDebugAttr>())
6070 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6071 return GetName(D,
true);
6077 if (Cached != DeclCache.end())
6078 return Var->addDebugInfo(
6082 llvm::DIFile *Unit =
nullptr;
6083 llvm::DIScope *DContext =
nullptr;
6085 StringRef DeclName, LinkageName;
6087 llvm::MDTuple *TemplateParameters =
nullptr;
6088 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6089 TemplateParameters, DContext);
6093 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6098 if (
T->isUnionType() && DeclName.empty()) {
6099 const auto *RD =
T->castAsRecordDecl();
6101 "unnamed non-anonymous struct or union?");
6102 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6107 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6108 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6109 if (D->
hasAttr<CUDASharedAttr>())
6112 else if (D->
hasAttr<CUDAConstantAttr>())
6116 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6118 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6119 GVE = DBuilder.createGlobalVariableExpression(
6120 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6121 Var->hasLocalLinkage(),
true,
6122 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6123 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6124 Align, Annotations);
6125 Var->addDebugInfo(GVE);
6131 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6132 if (VD->
hasAttr<NoDebugAttr>())
6134 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6135 return GetName(VD,
true);
6140 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6141 StringRef Name = VD->
getName();
6142 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6144 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6146 if (CGM.getCodeGenOpts().EmitCodeView) {
6157 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6158 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6159 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6169 auto *VarD = dyn_cast<VarDecl>(VD);
6170 if (VarD && VarD->isStaticDataMember()) {
6172 getDeclContextDescriptor(VarD);
6177 RetainedTypes.push_back(
6178 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6182 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6184 auto &GV = DeclCache[VD];
6188 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6189 llvm::MDTuple *TemplateParameters =
nullptr;
6193 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6194 TemplateParameters = parameterNodes.get();
6197 GV.reset(DBuilder.createGlobalVariableExpression(
6198 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6199 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6200 TemplateParameters, Align));
6205 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6206 if (D->
hasAttr<NoDebugAttr>())
6210 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6211 StringRef Name = D->
getName();
6212 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6214 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6215 llvm::DIGlobalVariableExpression *GVE =
6216 DBuilder.createGlobalVariableExpression(
6217 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6218 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6219 Var->addDebugInfo(GVE);
6226 if (CGM.getCodeGenOpts().getDebugInfo() <=
6227 llvm::codegenoptions::DebugLineTablesOnly)
6230 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6234 llvm::DIFile *Unit = DIL->getFile();
6235 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6240 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6241 llvm::Value *Var = Load->getPointerOperand();
6246 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6247 return DbgDeclare->getVariable()->getType() ==
Type;
6249 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6253 llvm::DILocalVariable *D =
6254 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6255 Type,
false, llvm::DINode::FlagArtificial);
6257 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6258 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6268 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6272 if (D->
hasAttr<NoDebugAttr>())
6275 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6290 if (!(DI = getDeclarationOrDefinition(
6291 AliaseeDecl.getCanonicalDecl().getDecl())))
6294 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6297 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6298 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6312 llvm::DIFile *
File = getOrCreateFile(Loc);
6313 llvm::DIGlobalVariableExpression *Debug =
6314 DBuilder.createGlobalVariableExpression(
6315 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6316 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6317 GV->addDebugInfo(Debug);
6320llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6321 if (!LexicalBlockStack.empty())
6322 return LexicalBlockStack.back();
6323 llvm::DIScope *Mod = getParentModuleOrNull(D);
6324 return getContextDescriptor(D, Mod ? Mod : TheCU);
6328 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6332 CGM.getCodeGenOpts().DebugExplicitImport) {
6336 DBuilder.createImportedModule(
6338 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6343 if (llvm::DINode *
Target =
6346 DBuilder.createImportedDeclaration(
6348 getOrCreateFile(Loc), getLineNumber(Loc));
6353 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6356 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6358 for (
const auto *USD : UD.
shadows()) {
6363 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6364 if (
const auto *AT = FD->getType()
6367 if (AT->getDeducedType().isNull())
6378 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6381 "We shouldn't be codegening an invalid UsingEnumDecl"
6382 " containing no decls");
6384 for (
const auto *USD : UD.
shadows())
6389 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6391 if (
Module *M = ID.getImportedModule()) {
6393 auto Loc = ID.getLocation();
6394 DBuilder.createImportedDeclaration(
6395 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6396 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6397 getLineNumber(Loc));
6401llvm::DIImportedEntity *
6403 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6405 auto &VH = NamespaceAliasCache[&NA];
6408 llvm::DIImportedEntity *R;
6410 if (
const auto *Underlying =
6413 R = DBuilder.createImportedDeclaration(
6416 getLineNumber(Loc), NA.
getName());
6418 R = DBuilder.createImportedDeclaration(
6421 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6427CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6431 auto I = NamespaceCache.find(NSDecl);
6432 if (I != NamespaceCache.end())
6435 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6437 llvm::DINamespace *NS =
6438 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6439 NamespaceCache[NSDecl].reset(NS);
6444 assert(TheCU &&
"no main compile unit");
6445 TheCU->setDWOId(Signature);
6451 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6452 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6454 ? CreateTypeDefinition(E.Type, E.Unit)
6456 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6460 for (
const auto &P : ObjCMethodCache) {
6461 if (P.second.empty())
6464 QualType QTy(P.first->getTypeForDecl(), 0);
6466 assert(It != TypeCache.end());
6468 llvm::DICompositeType *InterfaceDecl =
6471 auto CurElts = InterfaceDecl->getElements();
6475 for (
auto &SubprogramDirect : P.second)
6476 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6477 EltTys.push_back(SubprogramDirect.getPointer());
6479 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6480 DBuilder.replaceArrays(InterfaceDecl, Elements);
6483 for (
const auto &P : ReplaceMap) {
6486 assert(Ty->isForwardDecl());
6488 auto It = TypeCache.find(P.first);
6489 assert(It != TypeCache.end());
6492 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6496 for (
const auto &P : FwdDeclReplaceMap) {
6499 llvm::Metadata *Repl;
6501 auto It = DeclCache.find(P.first);
6505 if (It == DeclCache.end())
6510 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6511 Repl = GVE->getVariable();
6517 for (
auto &RT : RetainedTypes)
6518 if (
auto MD = TypeCache[RT])
6521 DBuilder.finalize();
6526 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6527 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6528 DBuilder.retainType(DieTy);
6532 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6533 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6534 DBuilder.retainType(DieTy);
6538 if (LexicalBlockStack.empty())
6539 return llvm::DebugLoc();
6541 llvm::MDNode *
Scope = LexicalBlockStack.back();
6542 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6543 getColumnNumber(Loc),
Scope);
6549 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6550 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6551 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6552 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6553 return llvm::DINode::FlagZero;
6558 bool SupportsDWARFv4Ext =
6559 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6560 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6561 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6563 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6564 return llvm::DINode::FlagZero;
6566 return llvm::DINode::FlagAllCallsDescribed;
6577 return DBuilder.createConstantValueExpression(
6578 Val.
getFloat().bitcastToAPInt().getZExtValue());
6583 llvm::APSInt
const &ValInt = Val.
getInt();
6584 std::optional<uint64_t> ValIntOpt;
6585 if (ValInt.isUnsigned())
6586 ValIntOpt = ValInt.tryZExtValue();
6587 else if (
auto tmp = ValInt.trySExtValue())
6590 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6593 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6598CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6600 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6601 CGF.CurLexicalScope =
this;
6603 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6608 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6621#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6623 Label = "__ubsan_check_" #Name; \
6627#undef SANITIZER_CHECK
6638#define SANITIZER(NAME, ID) \
6639 case SanitizerKind::SO_##ID: \
6640 Label = "__ubsan_check_" NAME; \
6642#include "clang/Basic/Sanitizers.def"
6644 llvm_unreachable(
"unexpected sanitizer kind");
6649 for (
unsigned int i = 0; i < Label.length(); i++)
6650 if (!std::isalpha(Label[i]))
6659 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6661 if (!DI || !CheckDebugLoc)
6662 return CheckDebugLoc;
6663 const auto &AnnotateDebugInfo =
6664 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6665 if (AnnotateDebugInfo.empty())
6666 return CheckDebugLoc;
6669 if (Ordinals.size() == 1)
6674 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6675 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6677 return CheckDebugLoc;
6685 assert(!CGF->IsSanitizerScope);
6686 CGF->IsSanitizerScope =
true;
6690 assert(CGF->IsSanitizerScope);
6691 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 SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
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 EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an include directive.
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about an external variable.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
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.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
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 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_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
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.