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_HIP;
700 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
701 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
702 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
703 else if (LO.CPlusPlus14)
704 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
705 else if (LO.CPlusPlus11)
706 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
708 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
709 }
else if (LO.ObjC) {
710 LangTag = llvm::dwarf::DW_LANG_ObjC;
711 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
712 LangTag = llvm::dwarf::DW_LANG_OpenCL;
713 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
714 LangTag = llvm::dwarf::DW_LANG_C11;
716 LangTag = llvm::dwarf::DW_LANG_C99;
718 LangTag = llvm::dwarf::DW_LANG_C89;
724static llvm::DISourceLanguageName
732 uint32_t LangVersion = 0;
733 llvm::dwarf::SourceLanguageName LangTag;
736 LangTag = llvm::dwarf::DW_LNAME_HIP;
737 }
else if (LO.ObjC) {
738 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
740 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
743 }
else if (LO.ObjC) {
744 LangTag = llvm::dwarf::DW_LNAME_ObjC;
745 }
else if (LO.OpenCL) {
746 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
748 LangTag = llvm::dwarf::DW_LNAME_C;
752 return llvm::DISourceLanguageName(LangTag, LangVersion);
755void CGDebugInfo::CreateCompileUnit() {
756 SmallString<64> Checksum;
757 std::optional<llvm::DIFile::ChecksumKind> CSKind;
758 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
768 SourceManager &
SM = CGM.getContext().getSourceManager();
769 auto &CGO = CGM.getCodeGenOpts();
770 const LangOptions &LO = CGM.getLangOpts();
771 std::string MainFileName = CGO.MainFileName;
772 if (MainFileName.empty())
773 MainFileName =
"<stdin>";
779 std::string MainFileDir;
781 SM.getFileEntryRefForID(
SM.getMainFileID())) {
782 MainFileDir = std::string(MainFile->getDir().getName());
783 if (!llvm::sys::path::is_absolute(MainFileName)) {
784 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
785 llvm::sys::path::Style Style =
787 ? (CGM.getTarget().
getTriple().isOSWindows()
788 ? llvm::sys::path::Style::windows_backslash
789 : llvm::sys::path::Style::posix)
790 : llvm::sys::path::Style::native;
791 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
792 MainFileName = std::string(
793 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
800 if (MainFile->getName() == MainFileName &&
802 MainFile->getName().rsplit(
'.').second)
804 MainFileName = CGM.getModule().getName().str();
806 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
813 unsigned RuntimeVers = 0;
817 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
819 case llvm::codegenoptions::NoDebugInfo:
820 case llvm::codegenoptions::LocTrackingOnly:
821 EmissionKind = llvm::DICompileUnit::NoDebug;
823 case llvm::codegenoptions::DebugLineTablesOnly:
824 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
826 case llvm::codegenoptions::DebugDirectivesOnly:
827 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
829 case llvm::codegenoptions::DebugInfoConstructor:
830 case llvm::codegenoptions::LimitedDebugInfo:
831 case llvm::codegenoptions::FullDebugInfo:
832 case llvm::codegenoptions::UnusedTypeInfo:
833 EmissionKind = llvm::DICompileUnit::FullDebug;
838 auto &CGOpts = CGM.getCodeGenOpts();
844 CSInfo.emplace(*CSKind, Checksum);
845 llvm::DIFile *CUFile = DBuilder.createFile(
847 getSource(
SM,
SM.getMainFileID()));
849 StringRef Sysroot, SDK;
850 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
851 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
852 auto B = llvm::sys::path::rbegin(Sysroot);
853 auto E = llvm::sys::path::rend(Sysroot);
855 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
860 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
861 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
862 CGOpts.DebugNameTable);
863 if (CGM.getTarget().getTriple().isNVPTX())
864 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
865 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
866 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
869 TheCU = DBuilder.createCompileUnit(
871 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
872 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
873 CGOpts.PrepareForThinLTO,
874 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
875 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
876 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
879llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
883#define BUILTIN_TYPE(Id, SingletonId)
884#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
885#include "clang/AST/BuiltinTypes.def"
886 case BuiltinType::Dependent:
887 llvm_unreachable(
"Unexpected builtin type");
888 case BuiltinType::NullPtr:
889 return DBuilder.createNullPtrType();
890 case BuiltinType::Void:
892 case BuiltinType::ObjCClass:
895 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
896 "objc_class", TheCU, TheCU->getFile(), 0);
898 case BuiltinType::ObjCId: {
909 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
910 "objc_class", TheCU, TheCU->getFile(), 0);
912 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
914 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
916 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
917 (uint64_t)0, 0, llvm::DINode::FlagZero,
918 nullptr, llvm::DINodeArray());
920 DBuilder.replaceArrays(
921 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
922 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
923 llvm::DINode::FlagZero, ISATy)));
926 case BuiltinType::ObjCSel: {
928 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
929 "objc_selector", TheCU,
930 TheCU->getFile(), 0);
934#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
935 case BuiltinType::Id: \
936 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
938#include "clang/Basic/OpenCLImageTypes.def"
939 case BuiltinType::OCLSampler:
940 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
941 case BuiltinType::OCLEvent:
942 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
943 case BuiltinType::OCLClkEvent:
944 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
945 case BuiltinType::OCLQueue:
946 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
947 case BuiltinType::OCLReserveID:
948 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
949#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
950 case BuiltinType::Id: \
951 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
952#include "clang/Basic/OpenCLExtensionTypes.def"
953#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
954 case BuiltinType::Id: \
955 return getOrCreateStructPtrType(#Name, SingletonId);
956#include "clang/Basic/HLSLIntangibleTypes.def"
958#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
959#include "clang/Basic/AArch64ACLETypes.def"
961 if (BT->
getKind() == BuiltinType::MFloat8) {
962 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
963 BTName = BT->
getName(CGM.getLangOpts());
966 return DBuilder.createBasicType(BTName, Size, Encoding);
968 ASTContext::BuiltinVectorTypeInfo Info =
970 BT->
getKind() == BuiltinType::SveCount
971 ? ASTContext::BuiltinVectorTypeInfo(
972 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
974 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
981 "Unsupported number of vectors for svcount_t");
983 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
984 llvm::Metadata *BitStride =
nullptr;
985 if (BT->
getKind() == BuiltinType::SveBool) {
986 Info.
ElementType = CGM.getContext().UnsignedCharTy;
987 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
988 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
989 }
else if (BT->
getKind() == BuiltinType::SveCount) {
991 Info.
ElementType = CGM.getContext().UnsignedCharTy;
994 llvm::Metadata *LowerBound, *UpperBound;
995 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
996 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
997 if (Info.
EC.isScalable()) {
998 unsigned NumElemsPerVG = NumElems / 2;
999 SmallVector<uint64_t, 9> Expr(
1000 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1001 46, 0, llvm::dwarf::DW_OP_mul,
1002 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1003 UpperBound = DBuilder.createExpression(Expr);
1005 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1006 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1008 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1009 nullptr, LowerBound, UpperBound,
nullptr);
1010 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1011 llvm::DIType *ElemTy =
1012 getOrCreateType(Info.
ElementType, TheCU->getFile());
1014 return DBuilder.createVectorType( 0, Align, ElemTy,
1015 SubscriptArray, BitStride);
1019#define PPC_VECTOR_TYPE(Name, Id, size) \
1020 case BuiltinType::Id:
1021#include "clang/Basic/PPCTypes.def"
1024#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1025#include "clang/Basic/RISCVVTypes.def"
1027 ASTContext::BuiltinVectorTypeInfo Info =
1028 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1030 unsigned ElementCount = Info.
EC.getKnownMinValue();
1031 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1033 bool Fractional =
false;
1036 unsigned FixedSize = ElementCount * SEW;
1037 if (Info.
ElementType == CGM.getContext().BoolTy) {
1040 }
else if (FixedSize < 64) {
1043 LMUL = 64 / FixedSize;
1045 LMUL = FixedSize / 64;
1049 SmallVector<uint64_t, 12> Expr(
1053 {llvm::dwarf::DW_OP_bregx,
1056 llvm::dwarf::DW_OP_constu,
1058 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1060 Expr.push_back(llvm::dwarf::DW_OP_div);
1062 Expr.push_back(llvm::dwarf::DW_OP_mul);
1065 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1067 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1070 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1071 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1072 auto *UpperBound = DBuilder.createExpression(Expr);
1073 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1074 nullptr, LowerBound, UpperBound,
nullptr);
1075 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1076 llvm::DIType *ElemTy =
1077 getOrCreateType(Info.
ElementType, TheCU->getFile());
1080 return DBuilder.createVectorType(0, Align, ElemTy,
1084#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1085 case BuiltinType::Id: { \
1088 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1089 MangledName, TheCU, TheCU->getFile(), 0); \
1090 return SingletonId; \
1092#include "clang/Basic/WebAssemblyReferenceTypes.def"
1093#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1094 case BuiltinType::Id: { \
1097 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1098 TheCU, TheCU->getFile(), 0); \
1099 return SingletonId; \
1101#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1102 case BuiltinType::Id: { \
1105 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1106 return SingletonId; \
1108#include "clang/Basic/AMDGPUTypes.def"
1109 case BuiltinType::UChar:
1110 case BuiltinType::Char_U:
1111 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1113 case BuiltinType::Char_S:
1114 case BuiltinType::SChar:
1115 Encoding = llvm::dwarf::DW_ATE_signed_char;
1117 case BuiltinType::Char8:
1118 case BuiltinType::Char16:
1119 case BuiltinType::Char32:
1120 Encoding = llvm::dwarf::DW_ATE_UTF;
1122 case BuiltinType::UShort:
1123 case BuiltinType::UInt:
1124 case BuiltinType::UInt128:
1125 case BuiltinType::ULong:
1126 case BuiltinType::WChar_U:
1127 case BuiltinType::ULongLong:
1128 Encoding = llvm::dwarf::DW_ATE_unsigned;
1130 case BuiltinType::Short:
1131 case BuiltinType::Int:
1132 case BuiltinType::Int128:
1133 case BuiltinType::Long:
1134 case BuiltinType::WChar_S:
1135 case BuiltinType::LongLong:
1136 Encoding = llvm::dwarf::DW_ATE_signed;
1138 case BuiltinType::Bool:
1139 Encoding = llvm::dwarf::DW_ATE_boolean;
1141 case BuiltinType::Half:
1142 case BuiltinType::Float:
1143 case BuiltinType::LongDouble:
1144 case BuiltinType::Float16:
1145 case BuiltinType::BFloat16:
1146 case BuiltinType::Float128:
1147 case BuiltinType::Double:
1148 case BuiltinType::Ibm128:
1154 Encoding = llvm::dwarf::DW_ATE_float;
1156 case BuiltinType::ShortAccum:
1157 case BuiltinType::Accum:
1158 case BuiltinType::LongAccum:
1159 case BuiltinType::ShortFract:
1160 case BuiltinType::Fract:
1161 case BuiltinType::LongFract:
1162 case BuiltinType::SatShortFract:
1163 case BuiltinType::SatFract:
1164 case BuiltinType::SatLongFract:
1165 case BuiltinType::SatShortAccum:
1166 case BuiltinType::SatAccum:
1167 case BuiltinType::SatLongAccum:
1168 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1170 case BuiltinType::UShortAccum:
1171 case BuiltinType::UAccum:
1172 case BuiltinType::ULongAccum:
1173 case BuiltinType::UShortFract:
1174 case BuiltinType::UFract:
1175 case BuiltinType::ULongFract:
1176 case BuiltinType::SatUShortAccum:
1177 case BuiltinType::SatUAccum:
1178 case BuiltinType::SatULongAccum:
1179 case BuiltinType::SatUShortFract:
1180 case BuiltinType::SatUFract:
1181 case BuiltinType::SatULongFract:
1182 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1186 BTName = BT->
getName(CGM.getLangOpts());
1189 return DBuilder.createBasicType(BTName, Size, Encoding);
1192llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1193 SmallString<32> Name;
1194 llvm::raw_svector_ostream
OS(Name);
1195 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1198 ? llvm::dwarf::DW_ATE_unsigned
1199 : llvm::dwarf::DW_ATE_signed;
1200 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1201 Encoding, llvm::DINode::FlagZero, 0,
1205llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1207 return getOrCreateType(Ty->getUnderlyingType(), U);
1210llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1212 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1214 Encoding = llvm::dwarf::DW_ATE_lo_user;
1217 return DBuilder.createBasicType(
"complex", Size, Encoding);
1231 return llvm::dwarf::DW_TAG_const_type;
1235 return llvm::dwarf::DW_TAG_volatile_type;
1239 return llvm::dwarf::DW_TAG_restrict_type;
1241 return (llvm::dwarf::Tag)0;
1244llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1245 llvm::DIFile *Unit) {
1246 QualifierCollector Qc;
1260 bool AuthenticatesNullValues =
1263 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1264 llvm::DIType *FromTy = getOrCreateType(QualType(T, 0), Unit);
1265 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1266 ExtraDiscr, IsaPointer,
1267 AuthenticatesNullValues);
1269 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1270 return getOrCreateType(QualType(T, 0), Unit);
1274 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
1278 return DBuilder.createQualifiedType(Tag, FromTy);
1281llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1282 llvm::DIFile *Unit) {
1291 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1296 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1302 return DBuilder.createQualifiedType(Tag, FromTy);
1305llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1306 llvm::DIFile *Unit) {
1312 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1314 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1318llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1319 llvm::DIFile *Unit) {
1320 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1326 case llvm::dwarf::DW_LANG_C_plus_plus:
1327 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1328 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1329 case llvm::dwarf::DW_LANG_HIP:
1331 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1341 case llvm::dwarf::DW_LNAME_C_plus_plus:
1342 case llvm::dwarf::DW_LNAME_HIP:
1344 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1355 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1356 SourceLang.hasVersionedName())
1358 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1362 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1388 llvm::DICompileUnit *TheCU) {
1406 llvm::DICompileUnit *TheCU) {
1412 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1414 if (RD->isDynamicClass() &&
1420 llvm::raw_svector_ostream Out(Identifier);
1427 llvm::dwarf::Tag Tag;
1429 Tag = llvm::dwarf::DW_TAG_structure_type;
1431 Tag = llvm::dwarf::DW_TAG_union_type;
1436 Tag = llvm::dwarf::DW_TAG_class_type;
1441llvm::DICompositeType *
1442CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1443 llvm::DIScope *Ctx) {
1444 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1445 if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
1447 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1448 const unsigned Line =
1450 StringRef RDName = getClassName(RD);
1457 Size = CGM.getContext().getTypeSize(Ty);
1459 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1464 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1465 if (!CXXRD->hasDefinition() ||
1466 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1467 Flags |= llvm::DINode::FlagNonTrivial;
1470 SmallString<256> Identifier;
1472 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1474 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1477 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1478 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1479 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1480 CollectCXXTemplateParams(TSpecial, DefUnit));
1481 ReplaceMap.emplace_back(
1482 std::piecewise_construct, std::make_tuple(Ty),
1483 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1487llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1490 llvm::DIFile *Unit) {
1495 std::optional<unsigned> DWARFAddressSpace =
1496 CGM.getTarget().getDWARFAddressSpace(
1497 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1499 const BTFTagAttributedType *BTFAttrTy;
1500 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1501 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1503 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1504 SmallVector<llvm::Metadata *, 4> Annots;
1506 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1508 llvm::Metadata *Ops[2] = {
1509 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1510 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1511 Annots.insert(Annots.begin(),
1512 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1514 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1517 llvm::DINodeArray Annotations =
nullptr;
1518 if (Annots.size() > 0)
1519 Annotations = DBuilder.getOrCreateArray(Annots);
1521 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1522 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1523 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1524 Size, Align, DWARFAddressSpace);
1526 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1527 Align, DWARFAddressSpace, StringRef(),
1531llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1532 llvm::DIType *&
Cache) {
1535 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1536 TheCU, TheCU->getFile(), 0);
1537 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1538 Cache = DBuilder.createPointerType(
Cache, Size);
1542uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1543 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1544 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1554 if (CGM.getLangOpts().OpenCL) {
1555 FType = CGM.getContext().IntTy;
1556 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1557 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1559 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1560 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1561 FType = CGM.getContext().IntTy;
1562 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1563 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1565 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1566 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1567 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1568 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1569 EltTys.push_back(DBuilder.createMemberType(
1570 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1571 FieldOffset, llvm::DINode::FlagZero, DescTy));
1572 FieldOffset += FieldSize;
1578llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1579 llvm::DIFile *Unit) {
1580 SmallVector<llvm::Metadata *, 8> EltTys;
1583 llvm::DINodeArray Elements;
1586 FType = CGM.getContext().UnsignedLongTy;
1587 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1588 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1590 Elements = DBuilder.getOrCreateArray(EltTys);
1593 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1596 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1597 FieldOffset, 0, Flags,
nullptr, Elements);
1602 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1604 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1607 Elements = DBuilder.getOrCreateArray(EltTys);
1613 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1614 Flags,
nullptr, Elements);
1616 return DBuilder.createPointerType(EltTy, Size);
1619static llvm::SmallVector<TemplateArgument>
1621 assert(Ty->isTypeAlias());
1630 ArrayRef SubstArgs = Ty->template_arguments();
1633 if (Param->isParameterPack()) {
1642 if (SubstArgs.empty()) {
1651 SpecArgs.push_back(SubstArgs.front());
1652 SubstArgs = SubstArgs.drop_front();
1657llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1658 llvm::DIFile *Unit) {
1659 assert(Ty->isTypeAlias());
1660 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1662 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1670 SmallString<128> NS;
1671 llvm::raw_svector_ostream
OS(NS);
1673 auto PP = getPrintingPolicy();
1676 SourceLocation Loc =
AliasDecl->getLocation();
1678 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1679 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1688 llvm::raw_string_ostream
OS(Name);
1690 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1691 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1692 !HasReconstitutableArgs(Args.Args))
1693 printTemplateArgumentList(OS, Args.Args, PP);
1695 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1696 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1697 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1701 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1703 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1720 return llvm::DINode::FlagZero;
1724 return llvm::DINode::FlagPrivate;
1726 return llvm::DINode::FlagProtected;
1728 return llvm::DINode::FlagPublic;
1730 return llvm::DINode::FlagZero;
1732 llvm_unreachable(
"unexpected access enumerator");
1735llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1736 llvm::DIFile *Unit) {
1737 llvm::DIType *Underlying =
1749 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1751 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1756 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1757 getOrCreateFile(Loc), getLineNumber(Loc),
1758 getDeclContextDescriptor(Ty->
getDecl()), Align,
1759 Flags, Annotations);
1769 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1771 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1773 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1775 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1777 return llvm::dwarf::DW_CC_BORLAND_pascal;
1779 return llvm::dwarf::DW_CC_LLVM_Win64;
1781 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1785 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1787 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1789 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1791 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1793 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1795 return llvm::dwarf::DW_CC_LLVM_Swift;
1797 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1799 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1801 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1803 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1805 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1807 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1809 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1810#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1824 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1830 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1832 Flags |= llvm::DINode::FlagLValueReference;
1834 Flags |= llvm::DINode::FlagRValueReference;
1838llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1839 llvm::DIFile *Unit) {
1840 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1842 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1848 SmallVector<llvm::Metadata *, 16> EltTys;
1851 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1853 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1857 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1860 for (
const QualType &ParamType : FPT->param_types())
1861 EltTys.push_back(getOrCreateType(ParamType, Unit));
1862 if (FPT->isVariadic())
1863 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1866 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1867 llvm::DIType *F = DBuilder.createSubroutineType(
1872llvm::DIDerivedType *
1873CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1874 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1875 StringRef Name = BitFieldDecl->
getName();
1876 QualType Ty = BitFieldDecl->
getType();
1877 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1880 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1881 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1884 llvm::DIFile *
File = getOrCreateFile(Loc);
1885 unsigned Line = getLineNumber(Loc);
1887 const CGBitFieldInfo &BitFieldInfo =
1888 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1890 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1897 if (CGM.getDataLayout().isBigEndian())
1899 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1901 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1902 return DBuilder.createBitFieldMemberType(
1903 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1904 Flags, DebugType, Annotations);
1907llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1908 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1909 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1911 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1936 if (PreviousFieldsDI.empty())
1940 auto *PreviousMDEntry =
1941 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1942 auto *PreviousMDField =
1943 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1944 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1945 PreviousMDField->getSizeInBits() == 0)
1949 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1951 assert(PreviousBitfield->isBitField());
1953 if (!PreviousBitfield->isZeroLengthBitField())
1956 QualType Ty = PreviousBitfield->getType();
1957 SourceLocation Loc = PreviousBitfield->getLocation();
1958 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1959 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1960 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1962 llvm::DIFile *
File = getOrCreateFile(Loc);
1963 unsigned Line = getLineNumber(Loc);
1969 llvm::DINode::DIFlags Flags =
1971 llvm::DINodeArray Annotations =
1972 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1973 return DBuilder.createBitFieldMemberType(
1974 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1975 Flags, DebugType, Annotations);
1978llvm::DIType *CGDebugInfo::createFieldType(
1980 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1981 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1982 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1985 llvm::DIFile *file = getOrCreateFile(loc);
1986 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1989 auto Align = AlignInBits;
1990 if (!
type->isIncompleteArrayType()) {
1991 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1992 SizeInBits = TI.
Width;
1998 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1999 offsetInBits, flags, debugType, Annotations);
2003CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2004 llvm::DIFile *FileScope) {
2008 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2011 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2012 SP = DBuilder.createFunction(
2013 FileScope, FuncName, StringRef(),
2014 FileScope, 0, DIFnTy,
2016 llvm::DINode::FlagArtificial,
2017 llvm::DISubprogram::SPFlagDefinition,
2018 nullptr,
nullptr,
nullptr,
2019 nullptr, StringRef(),
2020 CGM.getCodeGenOpts().DebugKeyInstructions);
2027CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2029 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2031 assert(
Capture.capturesVariable());
2033 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2034 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2036 return CaptureDecl->
getName();
2039void CGDebugInfo::CollectRecordLambdaFields(
2040 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2041 llvm::DIType *RecordTy) {
2046 unsigned fieldno = 0;
2049 I != E; ++I, ++Field, ++fieldno) {
2050 const LambdaCapture &
Capture = *I;
2052 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2054 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2064 Loc =
Field->getLocation();
2065 }
else if (
Capture.capturesVariable()) {
2068 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2069 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2076 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2078 elements.push_back(createFieldType(
2080 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2086template <
typename T>
2087static llvm::Constant *
2098 return llvm::ConstantDataArray::get(Ctx, Vals);
2111 const QualType ElemQTy = ArrayTy->getElementType();
2118 switch (ElemBitWidth) {
2134llvm::DIDerivedType *
2135CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2136 const RecordDecl *RD) {
2140 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2141 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2143 unsigned LineNumber = getLineNumber(Var->
getLocation());
2144 StringRef VName = Var->
getName();
2148 llvm::Constant *
C =
nullptr;
2153 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2154 if (
Value->isFloat())
2155 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2156 if (
Value->isArray())
2162 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2163 ? llvm::dwarf::DW_TAG_variable
2164 : llvm::dwarf::DW_TAG_member;
2166 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2167 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2172void CGDebugInfo::CollectRecordNormalField(
2173 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2174 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2175 const RecordDecl *RD) {
2180 if (
name.empty() && !
type->isRecordType())
2183 llvm::DIType *FieldType;
2185 llvm::DIDerivedType *BitFieldType;
2186 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2187 if (llvm::DIType *Separator =
2188 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2189 elements.push_back(Separator);
2192 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2195 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2198 elements.push_back(FieldType);
2201void CGDebugInfo::CollectRecordNestedType(
2202 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2203 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2210 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2211 elements.push_back(nestedType);
2214void CGDebugInfo::CollectRecordFields(
2215 const RecordDecl *record, llvm::DIFile *tunit,
2216 SmallVectorImpl<llvm::Metadata *> &elements,
2217 llvm::DICompositeType *RecordTy) {
2218 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2220 if (CXXDecl && CXXDecl->
isLambda())
2221 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2223 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2226 unsigned fieldNo = 0;
2230 for (
const auto *I : record->
decls())
2231 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2232 if (
V->hasAttr<NoDebugAttr>())
2237 if (CGM.getCodeGenOpts().EmitCodeView &&
2245 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2246 if (MI != StaticDataMemberCache.end()) {
2247 assert(MI->second &&
2248 "Static data member declaration should still exist");
2249 elements.push_back(MI->second);
2251 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2252 elements.push_back(Field);
2254 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2255 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2256 elements, RecordTy, record);
2260 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2263 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2268 if (!nestedType->isImplicit() &&
2269 nestedType->getDeclContext() == record)
2270 CollectRecordNestedType(nestedType, elements);
2276llvm::DISubroutineType *
2277CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2278 llvm::DIFile *Unit) {
2279 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2281 return cast_or_null<llvm::DISubroutineType>(
2282 getOrCreateType(QualType(
Func, 0), Unit));
2285 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2286 ThisType =
Method->getThisType();
2288 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2291llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2292 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2293 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2295 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2298llvm::DISubroutineType *
2299CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2300 const FunctionProtoType *
Func,
2301 llvm::DIFile *Unit,
bool SkipFirst) {
2302 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2317 getOrCreateType(CGM.getContext().getFunctionType(
2318 Func->getReturnType(),
Func->getParamTypes(), EPI),
2320 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2321 assert(Args.size() &&
"Invalid number of arguments!");
2323 SmallVector<llvm::Metadata *, 16> Elts;
2326 Elts.push_back(Args[0]);
2328 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2332 if (!HasExplicitObjectParameter) {
2333 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2336 DBuilder.createObjectPointerType(ThisPtrType,
true);
2337 Elts.push_back(ThisPtrType);
2341 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2342 Elts.push_back(Args[i]);
2345 if (HasExplicitObjectParameter) {
2346 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2347 "Expected at least return type and object parameter.");
2348 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2351 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2353 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2360 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2368CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2371 const bool IsCtorOrDtor =
2374 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2381 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2384 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2387 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2390 return CGM.getMangledName(
Method);
2393bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2396 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2399llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2400 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2403 StringRef MethodName = getFunctionName(
Method);
2404 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2406 StringRef MethodLinkageName;
2413 MethodLinkageName = GetMethodLinkageName(
Method);
2416 llvm::DIFile *MethodDefUnit =
nullptr;
2417 unsigned MethodLine = 0;
2418 if (!
Method->isImplicit()) {
2419 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2420 MethodLine = getLineNumber(
Method->getLocation());
2424 llvm::DIType *ContainingType =
nullptr;
2425 unsigned VIndex = 0;
2426 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2427 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2428 int ThisAdjustment = 0;
2431 if (
Method->isPureVirtual())
2432 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2434 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2436 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2440 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2444 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2447 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2448 CGM.getContext().getLangOpts())
2452 MethodVFTableLocation ML =
2453 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2461 if (
Method->size_overridden_methods() == 0)
2462 Flags |= llvm::DINode::FlagIntroducedVirtual;
2467 ThisAdjustment = CGM.getCXXABI()
2468 .getVirtualFunctionPrologueThisAdjustment(GD)
2471 ContainingType = RecordTy;
2474 if (
Method->getCanonicalDecl()->isDeleted())
2475 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2477 if (
Method->isNoReturn())
2478 Flags |= llvm::DINode::FlagNoReturn;
2481 Flags |= llvm::DINode::FlagStaticMember;
2482 if (
Method->isImplicit())
2483 Flags |= llvm::DINode::FlagArtificial;
2485 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2486 if (CXXC->isExplicit())
2487 Flags |= llvm::DINode::FlagExplicit;
2488 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2489 if (CXXC->isExplicit())
2490 Flags |= llvm::DINode::FlagExplicit;
2492 if (
Method->hasPrototype())
2493 Flags |= llvm::DINode::FlagPrototyped;
2495 Flags |= llvm::DINode::FlagLValueReference;
2497 Flags |= llvm::DINode::FlagRValueReference;
2498 if (!
Method->isExternallyVisible())
2499 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2500 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2501 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2505 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2506 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2509 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2510 llvm::DISubprogram *SP = DBuilder.createMethod(
2511 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2512 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2513 TParamsArray.get(),
nullptr,
2514 CGM.getCodeGenOpts().DebugKeyInstructions);
2516 SPCache[
Method->getCanonicalDecl()].reset(SP);
2521void CGDebugInfo::CollectCXXMemberFunctions(
2522 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2523 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2528 for (
const auto *I : RD->
decls()) {
2529 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2543 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2552 auto MI = SPCache.find(
Method->getCanonicalDecl());
2553 EltTys.push_back(MI == SPCache.end()
2554 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2555 :
static_cast<llvm::Metadata *
>(MI->second));
2559void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2560 SmallVectorImpl<llvm::Metadata *> &EltTys,
2561 llvm::DIType *RecordTy) {
2562 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2563 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2564 llvm::DINode::FlagZero);
2568 if (CGM.getCodeGenOpts().EmitCodeView) {
2569 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2570 llvm::DINode::FlagIndirectVirtualBase);
2574void CGDebugInfo::CollectCXXBasesAux(
2575 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2576 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2578 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2579 llvm::DINode::DIFlags StartingFlags) {
2580 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2581 for (
const auto &BI : Bases) {
2584 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2586 if (!SeenTypes.insert(Base).second)
2588 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2589 llvm::DINode::DIFlags BFlags = StartingFlags;
2593 if (BI.isVirtual()) {
2594 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2597 BaseOffset = 0 - CGM.getItaniumVTableContext()
2598 .getVirtualBaseOffsetOffset(RD, Base)
2604 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2605 VBPtrOffset = CGM.getContext()
2606 .getASTRecordLayout(RD)
2610 BFlags |= llvm::DINode::FlagVirtual;
2617 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2618 VBPtrOffset, BFlags);
2619 EltTys.push_back(DTy);
2624CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2625 llvm::DIFile *Unit) {
2627 return llvm::DINodeArray();
2628 TemplateArgs &Args = *OArgs;
2629 SmallVector<llvm::Metadata *, 16> TemplateParams;
2630 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2631 const TemplateArgument &TA = Args.Args[i];
2635 Name = Args.TList->getParam(i)->getName();
2639 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2640 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2641 TheCU, Name, TTy, defaultParameter));
2646 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2647 TheCU, Name, TTy, defaultParameter,
2648 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2653 llvm::DIType *TTy = getOrCreateType(T, Unit);
2654 llvm::Constant *
V =
nullptr;
2657 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2658 !D->
hasAttr<CUDADeviceAttr>()) {
2661 if (
const auto *VD = dyn_cast<VarDecl>(D))
2662 V = CGM.GetAddrOfGlobalVar(VD);
2665 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2666 MD && MD->isImplicitObjectMemberFunction())
2667 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2668 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2669 V = CGM.GetAddrOfFunction(FD);
2672 else if (
const auto *MPT =
2673 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2677 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2679 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2680 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2681 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2682 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2683 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2685 V = ConstantEmitter(CGM).emitAbstract(
2686 SourceLocation(), TPO->getValue(), TPO->getType());
2688 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2690 assert(
V &&
"Failed to find template parameter pointer");
2691 V =
V->stripPointerCasts();
2693 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2694 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2698 llvm::DIType *TTy = getOrCreateType(T, Unit);
2699 llvm::Constant *
V =
nullptr;
2702 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2708 if (MPT->isMemberDataPointer())
2709 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2711 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2712 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2713 TheCU, Name, TTy, defaultParameter,
V));
2717 llvm::DIType *TTy = getOrCreateType(T, Unit);
2718 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2720 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2721 TheCU, Name, TTy, defaultParameter,
V));
2724 std::string QualName;
2725 llvm::raw_string_ostream
OS(QualName);
2727 OS, getPrintingPolicy());
2728 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2729 TheCU, Name,
nullptr, QualName, defaultParameter));
2733 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2734 TheCU, Name,
nullptr,
2741 T = CGM.getContext().getLValueReferenceType(T);
2742 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2743 assert(
V &&
"Expression in template argument isn't constant");
2744 llvm::DIType *TTy = getOrCreateType(T, Unit);
2745 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2746 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2752 "These argument types shouldn't exist in concrete types");
2755 return DBuilder.getOrCreateArray(TemplateParams);
2758std::optional<CGDebugInfo::TemplateArgs>
2759CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2767 return std::nullopt;
2769std::optional<CGDebugInfo::TemplateArgs>
2770CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2774 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2776 return std::nullopt;
2777 VarTemplateDecl *T = TS->getSpecializedTemplate();
2779 auto TA = TS->getTemplateArgs().asArray();
2780 return {{TList, TA}};
2782std::optional<CGDebugInfo::TemplateArgs>
2783CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2784 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2788 TemplateParameterList *TPList =
2789 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2790 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2791 return {{TPList, TAList.
asArray()}};
2793 return std::nullopt;
2797CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2798 llvm::DIFile *Unit) {
2799 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2802llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2803 llvm::DIFile *Unit) {
2804 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2807llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2808 llvm::DIFile *Unit) {
2809 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2812llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2813 if (!D->
hasAttr<BTFDeclTagAttr>())
2816 SmallVector<llvm::Metadata *, 4> Annotations;
2818 llvm::Metadata *Ops[2] = {
2819 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2820 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2821 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2823 return DBuilder.getOrCreateArray(Annotations);
2826llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2828 return VTablePtrType;
2830 ASTContext &Context = CGM.getContext();
2833 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2834 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2835 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2837 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2838 std::optional<unsigned> DWARFAddressSpace =
2839 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2841 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2842 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2843 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2844 return VTablePtrType;
2847StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2859 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2861 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2871 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2872 VTable->isDeclarationForLinker())
2876 StringRef SymbolName =
"__clang_vtable";
2878 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2887 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2889 llvm::DIFile *Unit = getOrCreateFile(Loc);
2890 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2892 llvm::DINode::FlagArtificial;
2893 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2894 ? llvm::dwarf::DW_TAG_variable
2895 : llvm::dwarf::DW_TAG_member;
2896 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2897 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2901 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2905 llvm::DIGlobalVariableExpression *GVE =
2906 DBuilder.createGlobalVariableExpression(
2907 TheCU, SymbolName, VTable->getName(), Unit, 0,
2908 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2909 true,
nullptr, DT,
nullptr,
2911 VTable->addDebugInfo(GVE);
2914StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2916 llvm::Function *InitFn) {
2921 return InitFn->getName();
2931 llvm::raw_svector_ostream OS(QualifiedGV);
2933 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2935 std::swap(Quals, GVName);
2939 llvm::raw_svector_ostream OS(InitName);
2941 OS << Quals <<
"::";
2946 llvm_unreachable(
"not an initializer");
2948 OS <<
"`dynamic initializer for '";
2951 OS <<
"`dynamic atexit destructor for '";
2958 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2959 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2960 getPrintingPolicy());
2965 return internString(
OS.str());
2968void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2969 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2978 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2985 llvm::DIType *VPtrTy =
nullptr;
2986 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2987 CGM.getTarget().getCXXABI().isMicrosoft();
2988 if (NeedVTableShape) {
2990 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2991 const VTableLayout &VFTLayout =
2992 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2993 unsigned VSlotCount =
2995 unsigned VTableWidth = PtrWidth * VSlotCount;
2996 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2997 std::optional<unsigned> DWARFAddressSpace =
2998 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3001 llvm::DIType *VTableType = DBuilder.createPointerType(
3002 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3003 EltTys.push_back(VTableType);
3006 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3014 VPtrTy = getOrCreateVTablePtrType(Unit);
3016 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3017 llvm::DIType *VPtrMember =
3018 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3019 llvm::DINode::FlagArtificial, VPtrTy);
3020 EltTys.push_back(VPtrMember);
3025 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3026 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3037 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3038 assert(!D.
isNull() &&
"null type");
3039 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3040 assert(T &&
"could not create debug info for type");
3049 if (CGM.getCodeGenOpts().getDebugInfo() <=
3050 llvm::codegenoptions::DebugLineTablesOnly)
3054 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3056 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3058 CI->setMetadata(
"heapallocsite", node);
3062 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3064 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3066 auto I = TypeCache.find(TyPtr);
3069 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3070 assert(!Res->isForwardDecl());
3071 TypeCache[TyPtr].reset(Res);
3075 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3076 !CGM.getLangOpts().CPlusPlus)
3082 if (RD->
hasAttr<DLLImportAttr>())
3085 if (MD->hasAttr<DLLImportAttr>())
3098 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3108 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3109 Explicit = TD->isExplicitInstantiationOrSpecialization();
3113 if (CXXDecl->
fields().empty())
3123 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3124 if (CXXRD->isDynamicClass() &&
3125 CGM.getVTableLinkage(CXXRD) ==
3126 llvm::GlobalValue::AvailableExternallyLinkage &&
3137 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3139 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3141 auto I = TypeCache.find(TyPtr);
3148 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3149 assert(!Res->isForwardDecl());
3150 TypeCache[TyPtr].reset(Res);
3157 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3158 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3181 if (Ctor->isCopyOrMoveConstructor())
3183 if (!Ctor->isDeleted())
3202 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3205 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3206 RD->
hasAttr<StandaloneDebugAttr>())
3209 if (!LangOpts.CPlusPlus)
3215 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3231 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3232 Spec = SD->getSpecializationKind();
3241 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3252 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3253 llvm::DIType *T = getTypeOrNull(Ty);
3254 if (T && T->isForwardDecl())
3258llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3259 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3260 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3264 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3268 auto [Def, Pref] = CreateTypeDefinition(Ty);
3270 return Pref ? Pref : Def;
3273llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3274 llvm::DIFile *Unit) {
3278 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3282 return getOrCreateType(PNA->getTypedefType(), Unit);
3285std::pair<llvm::DIType *, llvm::DIType *>
3286CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3287 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3290 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3298 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3302 return {FwdDecl,
nullptr};
3304 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3305 CollectContainingType(CXXDecl, FwdDecl);
3308 LexicalBlockStack.emplace_back(&*FwdDecl);
3309 RegionMap[RD].reset(FwdDecl);
3312 SmallVector<llvm::Metadata *, 16> EltTys;
3319 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3321 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3322 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3326 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3327 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3328 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3330 LexicalBlockStack.pop_back();
3331 RegionMap.erase(RD);
3333 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3334 DBuilder.replaceArrays(FwdDecl, Elements);
3336 if (FwdDecl->isTemporary())
3338 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3340 RegionMap[RD].reset(FwdDecl);
3342 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3343 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3344 return {FwdDecl, PrefDI};
3346 return {FwdDecl,
nullptr};
3349llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3350 llvm::DIFile *Unit) {
3352 return getOrCreateType(Ty->getBaseType(), Unit);
3355llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3356 llvm::DIFile *Unit) {
3358 SourceLocation Loc = Ty->getDecl()->getLocation();
3361 return DBuilder.createTypedef(
3362 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3363 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3364 getDeclContextDescriptor(Ty->getDecl()));
3391llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3392 llvm::DIFile *Unit) {
3397 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3398 TheCU->getSourceLanguage().getUnversionedName());
3403 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3404 !
ID->getImplementation())
3405 return DBuilder.createForwardDecl(
3406 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3407 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3410 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3411 unsigned Line = getLineNumber(
ID->getLocation());
3415 ObjCInterfaceDecl *Def =
ID->getDefinition();
3417 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3418 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3419 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3420 DefUnit,
Line, RuntimeLang);
3421 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3425 return CreateTypeDefinition(Ty, Unit);
3428llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3429 bool CreateSkeletonCU) {
3434 auto ModRef = ModuleCache.find(M);
3435 if (ModRef != ModuleCache.end())
3439 SmallString<128> ConfigMacros;
3441 llvm::raw_svector_ostream
OS(ConfigMacros);
3442 const auto &PPOpts = CGM.getPreprocessorOpts();
3445 for (
auto &M : PPOpts.Macros) {
3448 const std::string &
Macro = M.first;
3449 bool Undef = M.second;
3450 OS <<
"\"-" << (Undef ?
'U' :
'D');
3466 bool IsRootModule = M ? !M->
Parent :
true;
3470 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3471 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3472 "clang module without ASTFile must be specified by -fmodule-name");
3475 auto RemapPath = [
this](StringRef Path) -> std::string {
3477 StringRef Relative(Remapped);
3478 StringRef CompDir = TheCU->getDirectory();
3479 if (CompDir.empty())
3482 if (Relative.consume_front(CompDir))
3483 Relative.consume_front(llvm::sys::path::get_separator());
3485 return Relative.str();
3488 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3495 Signature = ModSig.truncatedValue();
3499 llvm::DIBuilder DIB(CGM.getModule());
3501 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3502 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3503 PCM = getCurrentDirname();
3507 llvm::sys::path::append(PCM, Mod.
getASTFile());
3508 DIB.createCompileUnit(
3509 TheCU->getSourceLanguage(),
3512 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3513 llvm::DICompileUnit::FullDebug, Signature);
3517 llvm::DIModule *Parent =
3519 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3521 std::string IncludePath = Mod.
getPath().str();
3522 llvm::DIModule *DIMod =
3523 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3524 RemapPath(IncludePath));
3525 ModuleCache[M].reset(DIMod);
3529llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3530 llvm::DIFile *Unit) {
3532 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3533 unsigned Line = getLineNumber(
ID->getLocation());
3535 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3541 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3542 if (
ID->getImplementation())
3543 Flags |= llvm::DINode::FlagObjcClassComplete;
3545 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3546 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3547 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3548 nullptr, llvm::DINodeArray(), RuntimeLang);
3550 QualType QTy(Ty, 0);
3551 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3554 LexicalBlockStack.emplace_back(RealDecl);
3555 RegionMap[Ty->
getDecl()].reset(RealDecl);
3558 SmallVector<llvm::Metadata *, 16> EltTys;
3560 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3562 llvm::DIType *SClassTy =
3563 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3567 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3568 llvm::DINode::FlagZero);
3569 EltTys.push_back(InhTag);
3573 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3574 SourceLocation Loc = PD->getLocation();
3575 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3576 unsigned PLine = getLineNumber(Loc);
3577 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3578 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3579 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3580 PD->getName(), PUnit, PLine,
3582 : getSelectorName(PD->getGetterName()),
3584 : getSelectorName(PD->getSetterName()),
3585 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3586 EltTys.push_back(PropertyNode);
3591 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3595 llvm::DenseSet<IsClassAndIdent> PropertySet;
3597 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3598 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3600 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3601 for (
auto *PD : ClassExt->properties()) {
3602 PropertySet.insert(GetIsClassAndIdent(PD));
3605 for (
const auto *PD :
ID->properties()) {
3608 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3614 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3615 unsigned FieldNo = 0;
3616 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3617 Field =
Field->getNextIvar(), ++FieldNo) {
3618 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3622 StringRef FieldName =
Field->getName();
3625 if (FieldName.empty())
3629 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3630 unsigned FieldLine = getLineNumber(
Field->getLocation());
3631 QualType FType =
Field->getType();
3638 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3639 : CGM.getContext().getTypeSize(FType);
3644 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3648 if (
Field->isBitField()) {
3650 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3651 FieldOffset %= CGM.getContext().getCharWidth();
3659 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3661 Flags = llvm::DINode::FlagProtected;
3663 Flags = llvm::DINode::FlagPrivate;
3665 Flags = llvm::DINode::FlagPublic;
3667 if (
Field->isBitField())
3668 Flags |= llvm::DINode::FlagBitField;
3670 llvm::MDNode *PropertyNode =
nullptr;
3671 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3672 if (ObjCPropertyImplDecl *PImpD =
3673 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3674 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3675 SourceLocation Loc = PD->getLocation();
3676 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3677 unsigned PLine = getLineNumber(Loc);
3678 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3679 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3680 PropertyNode = DBuilder.createObjCProperty(
3681 PD->getName(), PUnit, PLine,
3684 : getSelectorName(PD->getGetterName()),
3687 : getSelectorName(PD->getSetterName()),
3688 PD->getPropertyAttributes(),
3689 getOrCreateType(PD->getType(), PUnit));
3693 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3694 FieldSize, FieldAlign, FieldOffset, Flags,
3695 FieldTy, PropertyNode);
3696 EltTys.push_back(FieldTy);
3699 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3700 DBuilder.replaceArrays(RealDecl, Elements);
3702 LexicalBlockStack.pop_back();
3706llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3707 llvm::DIFile *Unit) {
3715 auto &Ctx = CGM.getContext();
3720 QualType CharVecTy =
3722 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3725 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3728 llvm::Metadata *Subscript;
3729 QualType QTy(Ty, 0);
3730 auto SizeExpr = SizeExprCache.find(QTy);
3731 if (SizeExpr != SizeExprCache.end())
3732 Subscript = DBuilder.getOrCreateSubrange(
3733 SizeExpr->getSecond() ,
nullptr ,
3734 nullptr ,
nullptr );
3737 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3738 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3739 Subscript = DBuilder.getOrCreateSubrange(
3740 CountNode ,
nullptr ,
nullptr ,
3743 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3748 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3751llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3752 llvm::DIFile *Unit) {
3756 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3761 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3762 auto *ColumnCountNode =
3763 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3764 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3765 auto *RowCountNode =
3766 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3767 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3768 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3769 ColumnCountNode ,
nullptr ,
nullptr ,
3771 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3772 RowCountNode ,
nullptr ,
nullptr ,
3774 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3775 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3778llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3783 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3798 Size = CGM.getContext().getTypeSize(Ty);
3805 SmallVector<llvm::Metadata *, 8> Subscripts;
3806 QualType EltTy(Ty, 0);
3807 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3816 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3817 Count = CAT->getZExtSize();
3818 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3819 if (Expr *Size = VAT->getSizeExpr()) {
3821 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3822 Count =
Result.Val.getInt().getExtValue();
3826 auto SizeNode = SizeExprCache.find(EltTy);
3827 if (SizeNode != SizeExprCache.end())
3828 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3829 SizeNode->getSecond() ,
nullptr ,
3830 nullptr ,
nullptr ));
3833 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3834 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3835 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3836 CountNode ,
nullptr ,
nullptr ,
3842 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3844 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3848llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3849 llvm::DIFile *Unit) {
3850 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3854llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3855 llvm::DIFile *Unit) {
3856 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3858 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3859 CGM.getCodeGenOpts().DwarfVersion < 4)
3860 Tag = llvm::dwarf::DW_TAG_reference_type;
3862 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3865llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3867 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3871 Size = CGM.getContext().getTypeSize(Ty);
3874 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3877 Flags |= llvm::DINode::FlagSingleInheritance;
3880 Flags |= llvm::DINode::FlagMultipleInheritance;
3883 Flags |= llvm::DINode::FlagVirtualInheritance;
3893 llvm::DIType *ClassType = getOrCreateType(T, U);
3895 return DBuilder.createMemberPointerType(
3899 const FunctionProtoType *FPT =
3901 return DBuilder.createMemberPointerType(
3902 getOrCreateInstanceMethodType(
3905 ClassType, Size, 0, Flags);
3908llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3910 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3913llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3917llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3919 return getOrCreateType(Ty->getWrappedType(), U);
3922llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3929 const EnumType *Ty) {
3941llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3944 bool isImportedFromModule =
3945 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3949 if (isImportedFromModule || !ED->getDefinition()) {
3956 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3957 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3958 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3959 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3961 unsigned Line = getLineNumber(ED->getLocation());
3962 StringRef EDName = ED->getName();
3963 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3964 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3965 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3967 ReplaceMap.emplace_back(
3968 std::piecewise_construct, std::make_tuple(Ty),
3969 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3973 return CreateTypeDefinition(Ty);
3976llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3979 SmallVector<llvm::Metadata *, 16> Enumerators;
3980 ED = ED->getDefinition();
3981 assert(ED &&
"An enumeration definition is required");
3982 for (
const auto *
Enum : ED->enumerators()) {
3983 Enumerators.push_back(
3984 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3987 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3988 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3989 EnumKind = Attr->getExtensibility();
3992 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3994 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3995 unsigned Line = getLineNumber(ED->getLocation());
3996 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3997 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3998 return DBuilder.createEnumerationType(
3999 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4000 0, Identifier, ED->isScoped(), EnumKind);
4005 StringRef Name, StringRef
Value) {
4006 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4007 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4013 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4014 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4015 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4019 StringRef FuncName) {
4020 llvm::DISubprogram *SP =
4021 createInlinedSubprogram(FuncName, Location->getFile());
4022 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4027 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4033 FuncName += Category;
4035 FuncName += FailureMsg;
4043 Qualifiers InnerQuals = T.getLocalQualifiers();
4047 Quals += InnerQuals;
4049 switch (T->getTypeClass()) {
4051 return C.getQualifiedType(T.getTypePtr(), Quals);
4054 case Type::InjectedClassName:
4055 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4057 case Type::TemplateSpecialization: {
4059 if (Spec->isTypeAlias())
4060 return C.getQualifiedType(T.getTypePtr(), Quals);
4061 T = Spec->desugar();
4064 case Type::TypeOfExpr:
4070 case Type::Decltype:
4073 case Type::UnaryTransform:
4076 case Type::Attributed:
4079 case Type::BTFTagAttributed:
4082 case Type::CountAttributed:
4091 case Type::MacroQualified:
4094 case Type::SubstTemplateTypeParm:
4098 case Type::DeducedTemplateSpecialization: {
4100 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4104 case Type::PackIndexing: {
4108 case Type::Adjusted:
4115 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4120llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4123 if (It != TypeCache.end()) {
4125 if (llvm::Metadata *
V = It->second)
4138 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4145 RetainedTypes.push_back(
4146 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4149llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4153 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4155 llvm::raw_string_ostream OS(Name);
4156 Ty.
print(OS, getPrintingPolicy());
4163 if (
auto *T = getTypeOrNull(Ty))
4166 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4167 void *TyPtr = Ty.getAsOpaquePtr();
4170 TypeCache[TyPtr].reset(Res);
4175llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4183 auto Info = Reader->getSourceDescriptor(Idx);
4185 return getOrCreateModuleRef(*Info,
true);
4186 }
else if (ClangModuleMap) {
4199 auto Info = ASTSourceDescriptor(*M);
4200 return getOrCreateModuleRef(Info,
false);
4203 return getOrCreateModuleRef(PCHDescriptor,
false);
4210llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4213 return CreateQualifiedType(Ty, Unit);
4217#define TYPE(Class, Base)
4218#define ABSTRACT_TYPE(Class, Base)
4219#define NON_CANONICAL_TYPE(Class, Base)
4220#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4221#include "clang/AST/TypeNodes.inc"
4222 llvm_unreachable(
"Dependent types cannot show up in debug information");
4224 case Type::ExtVector:
4227 case Type::ConstantMatrix:
4229 case Type::ObjCObjectPointer:
4231 case Type::ObjCObject:
4233 case Type::ObjCTypeParam:
4235 case Type::ObjCInterface:
4243 case Type::BlockPointer:
4251 case Type::FunctionProto:
4252 case Type::FunctionNoProto:
4254 case Type::ConstantArray:
4255 case Type::VariableArray:
4256 case Type::IncompleteArray:
4257 case Type::ArrayParameter:
4260 case Type::LValueReference:
4262 case Type::RValueReference:
4265 case Type::MemberPointer:
4273 case Type::OverflowBehavior:
4278 case Type::TemplateSpecialization:
4280 case Type::HLSLAttributedResource:
4282 case Type::HLSLInlineSpirv:
4284 case Type::PredefinedSugar:
4286 case Type::CountAttributed:
4288 case Type::Attributed:
4289 case Type::BTFTagAttributed:
4290 case Type::Adjusted:
4292 case Type::DeducedTemplateSpecialization:
4295 case Type::MacroQualified:
4296 case Type::SubstTemplateTypeParm:
4297 case Type::TypeOfExpr:
4299 case Type::Decltype:
4300 case Type::PackIndexing:
4301 case Type::UnaryTransform:
4305 llvm_unreachable(
"type should have been unwrapped!");
4308llvm::DICompositeType *
4309CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4310 QualType QTy(Ty, 0);
4312 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4317 if (T && !T->isForwardDecl())
4321 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4326 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4329 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4334llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4335 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4336 bool NameIsSimplified =
false;
4339 StringRef RDName = getClassName(RD, &NameIsSimplified);
4341 llvm::DIFile *DefUnit =
nullptr;
4344 DefUnit = getOrCreateFile(Loc);
4345 Line = getLineNumber(Loc);
4348 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4352 auto *T = cast_or_null<llvm::DICompositeType>(
4353 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4361 return getOrCreateRecordFwdDecl(Ty, RDContext);
4374 auto Flags = llvm::DINode::FlagZero;
4375 if (NameIsSimplified)
4376 Flags |= llvm::DINode::FlagNameIsSimplified;
4377 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4379 Flags |= llvm::DINode::FlagTypePassByReference;
4381 Flags |= llvm::DINode::FlagTypePassByValue;
4384 if (!CXXRD->isTrivial())
4385 Flags |= llvm::DINode::FlagNonTrivial;
4388 if (CXXRD->isAnonymousStructOrUnion())
4389 Flags |= llvm::DINode::FlagExportSymbols;
4392 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4395 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4396 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4398 Flags, Identifier, Annotations);
4402 switch (RealDecl->getTag()) {
4404 llvm_unreachable(
"invalid composite type tag");
4406 case llvm::dwarf::DW_TAG_array_type:
4407 case llvm::dwarf::DW_TAG_enumeration_type:
4412 if (Identifier.empty())
4416 case llvm::dwarf::DW_TAG_structure_type:
4417 case llvm::dwarf::DW_TAG_union_type:
4418 case llvm::dwarf::DW_TAG_class_type:
4421 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4425 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4426 CXXRecordDecl *TemplateDecl =
4427 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4428 RegionMap[TemplateDecl].reset(RealDecl);
4430 RegionMap[RD].reset(RealDecl);
4432 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4434 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4435 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4436 CollectCXXTemplateParams(TSpecial, DefUnit));
4440void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4441 llvm::DICompositeType *RealDecl) {
4443 llvm::DIType *ContainingType =
nullptr;
4444 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4448 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4455 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4456 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4458 ContainingType = RealDecl;
4460 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4463llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4464 StringRef Name, uint64_t *Offset) {
4465 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4466 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4469 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4470 *Offset, llvm::DINode::FlagZero, FieldTy);
4471 *Offset += FieldSize;
4475void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4477 StringRef &LinkageName,
4478 llvm::DIScope *&FDContext,
4479 llvm::DINodeArray &TParamsArray,
4480 llvm::DINode::DIFlags &Flags) {
4482 bool NameIsSimplified =
false;
4483 Name = getFunctionName(FD, &NameIsSimplified);
4484 if (NameIsSimplified)
4485 Flags |= llvm::DINode::FlagNameIsSimplified;
4486 Name = getFunctionName(FD);
4489 LinkageName = CGM.getMangledName(GD);
4491 Flags |= llvm::DINode::FlagPrototyped;
4495 if (LinkageName == Name ||
4496 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4497 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4498 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4499 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4500 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4501 LinkageName = StringRef();
4505 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4506 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4507 CGM.getCodeGenOpts().EmitCodeView)) {
4508 if (
const NamespaceDecl *NSDecl =
4510 FDContext = getOrCreateNamespace(NSDecl);
4511 else if (
const RecordDecl *RDecl =
4513 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4514 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4517 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4520 Flags |= llvm::DINode::FlagNoReturn;
4522 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4526void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4527 unsigned &LineNo, QualType &T,
4528 StringRef &Name, StringRef &LinkageName,
4529 llvm::MDTuple *&TemplateParameters,
4530 llvm::DIScope *&VDContext) {
4539 llvm::APInt ConstVal(32, 1);
4540 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4542 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4549 LinkageName = CGM.getMangledName(VD);
4550 if (LinkageName == Name)
4551 LinkageName = StringRef();
4554 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4555 TemplateParameters = parameterNodes.get();
4557 TemplateParameters =
nullptr;
4575 DC = CGM.getContext().getTranslationUnitDecl();
4577 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4578 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4581llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4583 llvm::DINodeArray TParamsArray;
4584 StringRef Name, LinkageName;
4585 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4586 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4588 llvm::DIFile *Unit = getOrCreateFile(Loc);
4589 llvm::DIScope *DContext = Unit;
4590 unsigned Line = getLineNumber(Loc);
4591 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4596 SmallVector<QualType, 16> ArgTypes;
4597 for (
const ParmVarDecl *Parm : FD->
parameters())
4598 ArgTypes.push_back(Parm->getType());
4601 QualType FnType = CGM.getContext().getFunctionType(
4602 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4604 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4605 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4606 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4610 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4611 return DBuilder.createFunction(
4612 DContext, Name, LinkageName, Unit,
Line,
4613 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4614 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4616 CGM.getCodeGenOpts().DebugKeyInstructions);
4619 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4620 DContext, Name, LinkageName, Unit,
Line,
4621 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4622 TParamsArray.get(), getFunctionDeclaration(FD));
4624 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4625 std::make_tuple(CanonDecl),
4626 std::make_tuple(SP));
4630llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4631 return getFunctionFwdDeclOrStub(GD,
false);
4634llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4635 return getFunctionFwdDeclOrStub(GD,
true);
4638llvm::DIGlobalVariable *
4639CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4641 StringRef Name, LinkageName;
4643 llvm::DIFile *Unit = getOrCreateFile(Loc);
4644 llvm::DIScope *DContext = Unit;
4645 unsigned Line = getLineNumber(Loc);
4646 llvm::MDTuple *TemplateParameters =
nullptr;
4648 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4651 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4652 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4654 FwdDeclReplaceMap.emplace_back(
4655 std::piecewise_construct,
4657 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4661llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4666 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4667 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4668 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4672 if (I != DeclCache.end()) {
4674 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4675 return GVE->getVariable();
4683 if (IE != ImportedDeclCache.end()) {
4684 auto N = IE->second;
4685 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4687 return dyn_cast_or_null<llvm::DINode>(N);
4692 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4693 return getFunctionForwardDeclaration(FD);
4694 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4695 return getGlobalVariableForwardDeclaration(VD);
4700llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4701 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4704 const auto *FD = dyn_cast<FunctionDecl>(D);
4709 auto *S = getDeclContextDescriptor(D);
4712 if (MI == SPCache.end()) {
4714 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4718 if (MI != SPCache.end()) {
4719 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4720 if (SP && !SP->isDefinition())
4724 for (
auto *NextFD : FD->
redecls()) {
4725 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4726 if (MI != SPCache.end()) {
4727 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4728 if (SP && !SP->isDefinition())
4735llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4736 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4737 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4738 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4741 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4745 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4749 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4758 QualType QTy(
ID->getTypeForDecl(), 0);
4759 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4760 if (It == TypeCache.end())
4763 llvm::DISubprogram *FD = DBuilder.createFunction(
4764 InterfaceType, getObjCMethodName(OMD), StringRef(),
4765 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4766 DBuilder.finalizeSubprogram(FD);
4773llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4778 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4779 !CGM.getCodeGenOpts().EmitCodeView))
4782 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4784 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4787 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4790 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4791 return getOrCreateMethodType(
Method, F);
4793 const auto *FTy = FnType->
getAs<FunctionType>();
4796 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4798 SmallVector<llvm::Metadata *, 16> Elts;
4801 QualType ResultTy = OMethod->getReturnType();
4804 if (ResultTy == CGM.getContext().getObjCInstanceType())
4805 ResultTy = CGM.getContext().getPointerType(
4806 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4808 Elts.push_back(getOrCreateType(ResultTy, F));
4810 QualType SelfDeclTy;
4811 if (
auto *SelfDecl = OMethod->getSelfDecl())
4812 SelfDeclTy = SelfDecl->getType();
4813 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4816 if (!SelfDeclTy.
isNull())
4818 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4820 Elts.push_back(DBuilder.createArtificialType(
4821 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4823 for (
const auto *PI : OMethod->parameters())
4824 Elts.push_back(getOrCreateType(PI->getType(), F));
4826 if (OMethod->isVariadic())
4827 Elts.push_back(DBuilder.createUnspecifiedParameter());
4829 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4830 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4836 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4837 if (FD->isVariadic()) {
4838 SmallVector<llvm::Metadata *, 16> EltTys;
4839 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4840 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4842 EltTys.push_back(getOrCreateType(ParamType, F));
4843 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4844 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4845 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4858 CC = SrcFnTy->getCallConv();
4860 for (
const VarDecl *VD : Args)
4861 ArgTypes.push_back(VD->
getType());
4862 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4868 llvm::Function *Fn,
bool CurFuncIsThunk) {
4870 StringRef LinkageName;
4872 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4875 bool HasDecl = (D !=
nullptr);
4877 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4878 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4879 llvm::DIFile *Unit = getOrCreateFile(Loc);
4880 llvm::DIScope *FDContext = Unit;
4881 llvm::DINodeArray TParamsArray;
4882 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4885 LinkageName = Fn->getName();
4886 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4888 auto FI = SPCache.find(FD->getCanonicalDecl());
4889 if (FI != SPCache.end()) {
4890 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4891 if (SP && SP->isDefinition()) {
4892 LexicalBlockStack.emplace_back(SP);
4893 RegionMap[D].reset(SP);
4897 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4898 TParamsArray, Flags);
4901 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4902 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4903 Name = getObjCMethodName(OMD);
4904 Flags |= llvm::DINode::FlagPrototyped;
4911 Name = Fn->getName();
4916 Flags |= llvm::DINode::FlagPrototyped;
4918 Name.consume_front(
"\01");
4922 "Unexpected DynamicInitKind !");
4926 Flags |= llvm::DINode::FlagArtificial;
4932 Flags |= llvm::DINode::FlagThunk;
4934 if (Fn->hasLocalLinkage())
4935 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4936 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4937 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4940 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4941 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4943 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4944 unsigned ScopeLine = getLineNumber(ScopeLoc);
4945 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4946 llvm::DISubprogram *
Decl =
nullptr;
4947 llvm::DINodeArray Annotations =
nullptr;
4950 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4951 : getFunctionDeclaration(D);
4952 Annotations = CollectBTFDeclTagAnnotations(D);
4960 llvm::DISubprogram *SP = DBuilder.createFunction(
4961 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4962 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4963 Annotations,
"", KeyInstructions);
4964 Fn->setSubprogram(SP);
4973 LexicalBlockStack.emplace_back(SP);
4976 RegionMap[D].reset(SP);
4980 QualType FnType, llvm::Function *Fn) {
4982 StringRef LinkageName;
4988 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4989 return GetName(D,
true);
4992 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4993 llvm::DIFile *Unit = getOrCreateFile(Loc);
4994 bool IsDeclForCallSite = Fn ?
true :
false;
4995 llvm::DIScope *FDContext =
4996 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4997 llvm::DINodeArray TParamsArray;
5000 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5001 TParamsArray, Flags);
5002 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5003 Name = getObjCMethodName(OMD);
5004 Flags |= llvm::DINode::FlagPrototyped;
5006 llvm_unreachable(
"not a function or ObjC method");
5008 Name.consume_front(
"\01");
5011 Flags |= llvm::DINode::FlagArtificial;
5016 unsigned LineNo = getLineNumber(Loc);
5017 unsigned ScopeLine = 0;
5018 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5019 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5020 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5022 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5023 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5025 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5026 llvm::DISubprogram *SP = DBuilder.createFunction(
5027 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5028 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5034 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5035 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5036 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5039 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5040 DBuilder.createParameterVariable(
5041 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5042 llvm::DINode::FlagZero, ParamAnnotations);
5048 if (IsDeclForCallSite)
5049 Fn->setSubprogram(SP);
5053 llvm::CallBase *CI) {
5054 if (!shouldGenerateVirtualCallSite())
5060 assert(CI &&
"Invalid Call Instruction.");
5061 if (!CI->isIndirectCall())
5065 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5066 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5074 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5077 if (
Func->getSubprogram())
5085 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5100 auto FI = SPCache.find(FD->getCanonicalDecl());
5101 llvm::DISubprogram *SP =
nullptr;
5102 if (FI != SPCache.end())
5103 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5104 if (!SP || !SP->isDefinition())
5105 SP = getFunctionStub(GD);
5106 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5107 LexicalBlockStack.emplace_back(SP);
5113 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5122 if (CurLoc.isInvalid() ||
5123 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5124 LexicalBlockStack.empty())
5127 llvm::MDNode *
Scope = LexicalBlockStack.back();
5128 Builder.SetCurrentDebugLocation(
5129 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5130 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5134 llvm::MDNode *Back =
nullptr;
5135 if (!LexicalBlockStack.empty())
5136 Back = LexicalBlockStack.back().get();
5137 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5139 getColumnNumber(CurLoc)));
5142void CGDebugInfo::AppendAddressSpaceXDeref(
5144 std::optional<unsigned> DWARFAddressSpace =
5146 if (!DWARFAddressSpace)
5149 Expr.push_back(llvm::dwarf::DW_OP_constu);
5150 Expr.push_back(*DWARFAddressSpace);
5151 Expr.push_back(llvm::dwarf::DW_OP_swap);
5152 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5161 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5162 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5163 LexicalBlockStack.back(), CurInlinedAt));
5165 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5169 CreateLexicalBlock(Loc);
5174 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5179 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5182 LexicalBlockStack.pop_back();
5186 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5187 unsigned RCount = FnBeginRegionCount.back();
5188 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5191 while (LexicalBlockStack.size() != RCount) {
5194 LexicalBlockStack.pop_back();
5196 FnBeginRegionCount.pop_back();
5198 if (Fn && Fn->getSubprogram())
5199 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5202CGDebugInfo::BlockByRefType
5203CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5204 uint64_t *XOffset) {
5207 uint64_t FieldSize, FieldOffset;
5208 uint32_t FieldAlign;
5210 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5215 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5216 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5218 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5219 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5222 if (HasCopyAndDispose) {
5225 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5227 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5229 bool HasByrefExtendedLayout;
5232 HasByrefExtendedLayout) &&
5233 HasByrefExtendedLayout) {
5236 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5245 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5248 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5251 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5256 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5257 FieldSize = CGM.getContext().getTypeSize(FType);
5258 FieldAlign = CGM.getContext().toBits(Align);
5260 *XOffset = FieldOffset;
5261 llvm::DIType *FieldTy = DBuilder.createMemberType(
5262 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5263 llvm::DINode::FlagZero, WrappedTy);
5264 EltTys.push_back(FieldTy);
5265 FieldOffset += FieldSize;
5267 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5268 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5269 llvm::DINode::FlagZero,
nullptr, Elements),
5273llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5274 llvm::Value *Storage,
5275 std::optional<unsigned> ArgNo,
5277 const bool UsePointerValue) {
5278 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5279 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5280 if (VD->
hasAttr<NoDebugAttr>())
5285 llvm::DIFile *Unit =
nullptr;
5286 if (!VarIsArtificial)
5290 if (VD->
hasAttr<BlocksAttr>())
5291 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5293 Ty = getOrCreateType(VD->
getType(), Unit);
5303 if (!VarIsArtificial) {
5307 SmallVector<uint64_t, 13> Expr;
5308 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5315 Flags |= llvm::DINode::FlagArtificial;
5319 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5320 AppendAddressSpaceXDeref(AddressSpace, Expr);
5324 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5327 Flags |= llvm::DINode::FlagObjectPointer;
5328 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5329 if (PVD->isExplicitObjectParameter())
5330 Flags |= llvm::DINode::FlagObjectPointer;
5338 StringRef Name = VD->
getName();
5339 if (!Name.empty()) {
5345 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5347 offset = CGM.getContext().toCharUnitsFromBits(
5350 Expr.push_back(llvm::dwarf::DW_OP_deref);
5351 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5353 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5356 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5368 for (
const auto *Field : RD->
fields()) {
5369 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5370 StringRef FieldName =
Field->getName();
5378 auto *D = DBuilder.createAutoVariable(
5379 Scope, FieldName, Unit,
Line, FieldTy,
5380 CGM.getCodeGenOpts().OptimizationLevel != 0,
5381 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5384 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5385 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5388 Builder.GetInsertBlock());
5396 if (UsePointerValue) {
5397 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5398 "Debug info already contains DW_OP_deref.");
5399 Expr.push_back(llvm::dwarf::DW_OP_deref);
5403 llvm::DILocalVariable *D =
nullptr;
5405 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5406 D = DBuilder.createParameterVariable(
5407 Scope, Name, *ArgNo, Unit,
Line, Ty,
5408 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5417 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5423 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5424 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5425 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5426 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5428 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5434 if (Iter != CoroutineParameterMappings.end()) {
5435 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5436 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5437 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5439 if (Iter2 != ParamDbgMappings.end())
5440 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5446 D = RemapCoroArgToLocalVar();
5449 D = DBuilder.createAutoVariable(
5450 Scope, Name, Unit,
Line, Ty,
5451 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5454 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5455 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5456 Column, Scope, CurInlinedAt),
5457 Builder.GetInsertBlock());
5462llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5463 llvm::Value *Storage,
5464 std::optional<unsigned> ArgNo,
5466 const bool UsePointerValue) {
5467 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5468 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5469 if (BD->
hasAttr<NoDebugAttr>())
5476 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5477 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5485 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5487 SmallVector<uint64_t, 3> Expr;
5488 AppendAddressSpaceXDeref(AddressSpace, Expr);
5493 if (UsePointerValue) {
5494 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5495 "Debug info already contains DW_OP_deref.");
5496 Expr.push_back(llvm::dwarf::DW_OP_deref);
5501 StringRef Name = BD->
getName();
5504 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5505 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5506 llvm::DINode::FlagZero, Align);
5508 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5509 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5510 const unsigned fieldIndex = FD->getFieldIndex();
5511 const clang::CXXRecordDecl *parent =
5512 (
const CXXRecordDecl *)FD->getParent();
5513 const ASTRecordLayout &layout =
5514 CGM.getContext().getASTRecordLayout(parent);
5516 if (FD->isBitField()) {
5517 const CGRecordLayout &RL =
5518 CGM.getTypes().getCGRecordLayout(FD->getParent());
5523 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5529 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5530 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5531 Expr.push_back(Info.
Offset);
5534 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5535 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5536 }
else if (fieldOffset != 0) {
5537 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5538 "Unexpected non-bitfield with non-byte-aligned offset");
5539 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5541 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5544 }
else if (
const ArraySubscriptExpr *ASE =
5545 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5546 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5547 const uint64_t value = IL->getValue().getZExtValue();
5548 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5551 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5552 Expr.push_back(CGM.getContext()
5553 .toCharUnitsFromBits(value * typeSize)
5560 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5561 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5562 Column, Scope, CurInlinedAt),
5563 Builder.GetInsertBlock());
5568llvm::DILocalVariable *
5571 const bool UsePointerValue) {
5572 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5574 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5576 EmitDeclare(B, Storage, std::nullopt, Builder,
5583 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5587 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5588 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5590 if (D->
hasAttr<NoDebugAttr>())
5594 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5600 StringRef Name = D->
getName();
5606 CGM.getCodeGenOpts().OptimizationLevel != 0);
5609 DBuilder.insertLabel(L,
5610 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5611 Scope, CurInlinedAt),
5612 Builder.GetInsertBlock()->end());
5615llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5617 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5620 return DBuilder.createObjectPointerType(Ty,
true);
5625 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5626 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5627 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5629 if (Builder.GetInsertBlock() ==
nullptr)
5631 if (VD->
hasAttr<NoDebugAttr>())
5634 bool isByRef = VD->
hasAttr<BlocksAttr>();
5636 uint64_t XOffset = 0;
5637 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5640 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5642 Ty = getOrCreateType(VD->
getType(), Unit);
5646 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5648 Ty = CreateSelfType(VD->
getType(), Ty);
5651 const unsigned Line =
5655 const llvm::DataLayout &target = CGM.getDataLayout();
5662 addr.push_back(llvm::dwarf::DW_OP_deref);
5663 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5666 addr.push_back(llvm::dwarf::DW_OP_deref);
5667 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5670 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5672 addr.push_back(llvm::dwarf::DW_OP_deref);
5673 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5675 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5681 auto *D = DBuilder.createAutoVariable(
5683 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5686 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5687 LexicalBlockStack.back(), CurInlinedAt);
5688 auto *
Expr = DBuilder.createExpression(addr);
5690 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5692 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5695llvm::DILocalVariable *
5698 bool UsePointerValue) {
5699 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5700 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5704struct BlockLayoutChunk {
5705 uint64_t OffsetInBits;
5708bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5709 return l.OffsetInBits < r.OffsetInBits;
5713void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5715 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5716 SmallVectorImpl<llvm::Metadata *> &Fields) {
5720 if (CGM.getLangOpts().OpenCL) {
5721 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5722 BlockLayout.getElementOffsetInBits(0),
5724 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5725 BlockLayout.getElementOffsetInBits(1),
5729 BlockLayout.getElementOffsetInBits(0),
5731 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5732 BlockLayout.getElementOffsetInBits(1),
5736 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5737 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5738 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5739 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5740 BlockLayout.getElementOffsetInBits(3),
5742 Fields.push_back(createFieldType(
5747 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5754 llvm::AllocaInst *Alloca,
5756 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5762 llvm::DIFile *tunit = getOrCreateFile(loc);
5763 unsigned line = getLineNumber(loc);
5764 unsigned column = getColumnNumber(loc);
5769 const llvm::StructLayout *blockLayout =
5773 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5782 BlockLayoutChunk chunk;
5783 chunk.OffsetInBits =
5784 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5785 chunk.Capture =
nullptr;
5786 chunks.push_back(chunk);
5790 for (
const auto &capture :
blockDecl->captures()) {
5791 const VarDecl *variable = capture.getVariable();
5798 BlockLayoutChunk chunk;
5799 chunk.OffsetInBits =
5800 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5801 chunk.Capture = &capture;
5802 chunks.push_back(chunk);
5806 llvm::array_pod_sort(chunks.begin(), chunks.end());
5808 for (
const BlockLayoutChunk &Chunk : chunks) {
5809 uint64_t offsetInBits = Chunk.OffsetInBits;
5816 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5818 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5819 type = CGM.getContext().getCanonicalTagType(RDecl);
5821 llvm_unreachable(
"unexpected block declcontext");
5823 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5824 offsetInBits, tunit, tunit));
5829 StringRef name = variable->
getName();
5831 llvm::DIType *fieldType;
5833 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5838 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5839 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5840 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5841 PtrInfo.
Width, Align, offsetInBits,
5842 llvm::DINode::FlagZero, fieldType);
5846 offsetInBits, Align, tunit, tunit);
5848 fields.push_back(fieldType);
5852 llvm::raw_svector_ostream(typeName)
5853 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5855 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5857 llvm::DIType *
type =
5858 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5859 CGM.getContext().toBits(block.
BlockSize), 0,
5860 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5861 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5864 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5868 auto *debugVar = DBuilder.createParameterVariable(
5869 scope, Name, ArgNo, tunit, line,
type,
5870 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5873 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5874 llvm::DILocation::get(CGM.getLLVMContext(), line,
5875 column, scope, CurInlinedAt),
5876 Builder.GetInsertBlock());
5879llvm::DIDerivedType *
5880CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5885 if (MI != StaticDataMemberCache.end()) {
5886 assert(MI->second &&
"Static data member declaration should still exist");
5897llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5898 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5899 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5900 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5902 for (
const auto *Field : RD->
fields()) {
5903 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5904 StringRef FieldName = Field->getName();
5907 if (FieldName.empty()) {
5908 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5909 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5910 LineNo, LinkageName, Var, DContext);
5914 GVE = DBuilder.createGlobalVariableExpression(
5915 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5916 Var->hasLocalLinkage());
5917 Var->addDebugInfo(GVE);
5929 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5934 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5945 struct ReferencesAnonymous
5947 bool RefAnon =
false;
5948 bool VisitRecordType(RecordType *RT) {
5956 ReferencesAnonymous RT;
5969struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5970 bool Reconstitutable =
true;
5971 bool VisitVectorType(VectorType *FT) {
5972 Reconstitutable =
false;
5975 bool VisitAtomicType(AtomicType *FT) {
5976 Reconstitutable =
false;
5979 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5982 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5983 if (!ED->getIdentifier()) {
5984 Reconstitutable =
false;
5987 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5988 Reconstitutable =
false;
5994 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5998 return Reconstitutable;
6000 bool VisitRecordType(RecordType *RT,
bool =
false) {
6002 Reconstitutable =
false;
6012 ReconstitutableType T;
6014 return T.Reconstitutable;
6017bool CGDebugInfo::HasReconstitutableArgs(
6018 ArrayRef<TemplateArgument> Args)
const {
6019 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6059 llvm_unreachable(
"Other, unresolved, template arguments should "
6060 "not be seen here");
6065std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6066 bool *NameIsSimplified)
const {
6068 llvm::raw_string_ostream
OS(Name);
6069 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6072 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6073 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6075 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6076 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6078 std::optional<TemplateArgs> Args;
6080 bool IsOperatorOverload =
false;
6081 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6082 Args = GetTemplateArgs(RD);
6083 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6084 Args = GetTemplateArgs(FD);
6086 IsOperatorOverload |=
6089 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6090 Args = GetTemplateArgs(VD);
6114 bool Reconstitutable =
6115 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6117 PrintingPolicy PP = getPrintingPolicy();
6119 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6124 if (NameIsSimplified)
6125 *NameIsSimplified =
true;
6126 bool Mangled = TemplateNamesKind ==
6127 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6133 std::string EncodedOriginalName;
6134 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6139 printTemplateArgumentList(OS, Args->Args, PP);
6140 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6142 std::string CanonicalOriginalName;
6143 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6145 assert(EncodedOriginalName == CanonicalOriginalName);
6154 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6155 if (D->
hasAttr<NoDebugAttr>())
6158 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6159 return GetName(D,
true);
6165 if (Cached != DeclCache.end())
6166 return Var->addDebugInfo(
6170 llvm::DIFile *Unit =
nullptr;
6171 llvm::DIScope *DContext =
nullptr;
6173 StringRef DeclName, LinkageName;
6175 llvm::MDTuple *TemplateParameters =
nullptr;
6176 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6177 TemplateParameters, DContext);
6181 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6186 if (T->isUnionType() && DeclName.empty()) {
6187 const auto *RD = T->castAsRecordDecl();
6189 "unnamed non-anonymous struct or union?");
6190 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6195 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6196 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6197 if (D->
hasAttr<CUDASharedAttr>())
6200 else if (D->
hasAttr<CUDAConstantAttr>())
6204 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6206 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6207 GVE = DBuilder.createGlobalVariableExpression(
6208 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6209 Var->hasLocalLinkage(),
true,
6210 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6211 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6212 Align, Annotations);
6213 Var->addDebugInfo(GVE);
6219 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6220 if (VD->
hasAttr<NoDebugAttr>())
6222 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6223 return GetName(VD,
true);
6228 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6229 StringRef Name = VD->
getName();
6230 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6232 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6234 if (CGM.getCodeGenOpts().EmitCodeView) {
6245 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6246 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6247 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6257 auto *VarD = dyn_cast<VarDecl>(VD);
6258 if (VarD && VarD->isStaticDataMember()) {
6260 getDeclContextDescriptor(VarD);
6265 RetainedTypes.push_back(
6266 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6270 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6272 auto &GV = DeclCache[VD];
6276 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6277 llvm::MDTuple *TemplateParameters =
nullptr;
6281 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6282 TemplateParameters = parameterNodes.get();
6285 GV.reset(DBuilder.createGlobalVariableExpression(
6286 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6287 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6288 TemplateParameters, Align));
6293 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6294 if (D->
hasAttr<NoDebugAttr>())
6298 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6299 StringRef Name = D->
getName();
6300 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6302 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6303 llvm::DIGlobalVariableExpression *GVE =
6304 DBuilder.createGlobalVariableExpression(
6305 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6306 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6307 Var->addDebugInfo(GVE);
6314 if (CGM.getCodeGenOpts().getDebugInfo() <=
6315 llvm::codegenoptions::DebugLineTablesOnly)
6318 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6322 llvm::DIFile *Unit = DIL->getFile();
6323 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6328 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6329 llvm::Value *Var = Load->getPointerOperand();
6334 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6335 return DbgDeclare->getVariable()->getType() ==
Type;
6337 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6341 llvm::DILocalVariable *D =
6342 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6343 Type,
false, llvm::DINode::FlagArtificial);
6345 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6346 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6356 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6360 if (D->
hasAttr<NoDebugAttr>())
6363 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6378 if (!(DI = getDeclarationOrDefinition(
6379 AliaseeDecl.getCanonicalDecl().getDecl())))
6382 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6385 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6386 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6400 llvm::DIFile *
File = getOrCreateFile(Loc);
6401 llvm::DIGlobalVariableExpression *Debug =
6402 DBuilder.createGlobalVariableExpression(
6403 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6404 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6405 GV->addDebugInfo(Debug);
6408llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6409 if (!LexicalBlockStack.empty())
6410 return LexicalBlockStack.back();
6411 llvm::DIScope *Mod = getParentModuleOrNull(D);
6412 return getContextDescriptor(D, Mod ? Mod : TheCU);
6416 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6420 CGM.getCodeGenOpts().DebugExplicitImport) {
6424 DBuilder.createImportedModule(
6426 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6431 if (llvm::DINode *
Target =
6434 DBuilder.createImportedDeclaration(
6436 getOrCreateFile(Loc), getLineNumber(Loc));
6441 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6444 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6446 for (
const auto *USD : UD.
shadows()) {
6451 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6452 if (
const auto *AT = FD->getType()
6455 if (AT->getDeducedType().isNull())
6466 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6469 "We shouldn't be codegening an invalid UsingEnumDecl"
6470 " containing no decls");
6472 for (
const auto *USD : UD.
shadows())
6477 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6479 if (
Module *M = ID.getImportedModule()) {
6481 auto Loc = ID.getLocation();
6482 DBuilder.createImportedDeclaration(
6483 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6484 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6485 getLineNumber(Loc));
6489llvm::DIImportedEntity *
6491 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6493 auto &VH = NamespaceAliasCache[&NA];
6496 llvm::DIImportedEntity *R;
6498 if (
const auto *Underlying =
6501 R = DBuilder.createImportedDeclaration(
6504 getLineNumber(Loc), NA.
getName());
6506 R = DBuilder.createImportedDeclaration(
6509 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6515CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6519 auto I = NamespaceCache.find(NSDecl);
6520 if (I != NamespaceCache.end())
6523 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6525 llvm::DINamespace *NS =
6526 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6527 NamespaceCache[NSDecl].reset(NS);
6532 assert(TheCU &&
"no main compile unit");
6533 TheCU->setDWOId(Signature);
6539 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6540 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6542 ? CreateTypeDefinition(E.Type, E.Unit)
6544 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6548 for (
const auto &P : ObjCMethodCache) {
6549 if (P.second.empty())
6552 QualType QTy(P.first->getTypeForDecl(), 0);
6554 assert(It != TypeCache.end());
6556 llvm::DICompositeType *InterfaceDecl =
6559 auto CurElts = InterfaceDecl->getElements();
6563 for (
auto &SubprogramDirect : P.second)
6564 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6565 EltTys.push_back(SubprogramDirect.getPointer());
6567 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6568 DBuilder.replaceArrays(InterfaceDecl, Elements);
6571 for (
const auto &P : ReplaceMap) {
6574 assert(Ty->isForwardDecl());
6576 auto It = TypeCache.find(P.first);
6577 assert(It != TypeCache.end());
6580 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6584 for (
const auto &P : FwdDeclReplaceMap) {
6587 llvm::Metadata *Repl;
6589 auto It = DeclCache.find(P.first);
6593 if (It == DeclCache.end())
6598 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6599 Repl = GVE->getVariable();
6605 for (
auto &RT : RetainedTypes)
6606 if (
auto MD = TypeCache[RT])
6609 DBuilder.finalize();
6614 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6615 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6616 DBuilder.retainType(DieTy);
6620 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6621 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6622 DBuilder.retainType(DieTy);
6626 if (LexicalBlockStack.empty())
6627 return llvm::DebugLoc();
6629 llvm::MDNode *
Scope = LexicalBlockStack.back();
6630 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6631 getColumnNumber(Loc),
Scope);
6637 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6638 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6639 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6640 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6641 return llvm::DINode::FlagZero;
6646 bool SupportsDWARFv4Ext =
6647 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6648 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6649 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6651 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6652 return llvm::DINode::FlagZero;
6654 return llvm::DINode::FlagAllCallsDescribed;
6665 return DBuilder.createConstantValueExpression(
6666 Val.
getFloat().bitcastToAPInt().getZExtValue());
6671 llvm::APSInt
const &ValInt = Val.
getInt();
6672 std::optional<uint64_t> ValIntOpt;
6673 if (ValInt.isUnsigned())
6674 ValIntOpt = ValInt.tryZExtValue();
6675 else if (
auto tmp = ValInt.trySExtValue())
6678 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6681 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6686CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6688 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6689 CGF.CurLexicalScope =
this;
6691 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6696 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6709#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6711 Label = "__ubsan_check_" #Name; \
6715#undef SANITIZER_CHECK
6726#define SANITIZER(NAME, ID) \
6727 case SanitizerKind::SO_##ID: \
6728 Label = "__ubsan_check_" NAME; \
6730#include "clang/Basic/Sanitizers.def"
6732 llvm_unreachable(
"unexpected sanitizer kind");
6737 for (
unsigned int i = 0; i < Label.length(); i++)
6738 if (!std::isalpha(Label[i]))
6747 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6749 if (!DI || !CheckDebugLoc)
6750 return CheckDebugLoc;
6751 const auto &AnnotateDebugInfo =
6752 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6753 if (AnnotateDebugInfo.empty())
6754 return CheckDebugLoc;
6757 if (Ordinals.size() == 1)
6762 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6763 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6765 return CheckDebugLoc;
6773 assert(!CGF->IsSanitizerScope);
6774 CGF->IsSanitizerScope =
true;
6778 assert(CGF->IsSanitizerScope);
6779 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static 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 llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static 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
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a 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...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * 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.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
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.
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.