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));
2084llvm::DIDerivedType *
2085CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2086 const RecordDecl *RD) {
2090 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2091 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2093 unsigned LineNumber = getLineNumber(Var->
getLocation());
2094 StringRef VName = Var->
getName();
2098 llvm::Constant *
C =
nullptr;
2103 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2104 if (
Value->isFloat())
2105 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2110 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2111 ? llvm::dwarf::DW_TAG_variable
2112 : llvm::dwarf::DW_TAG_member;
2114 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2115 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2120void CGDebugInfo::CollectRecordNormalField(
2121 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2122 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2123 const RecordDecl *RD) {
2128 if (
name.empty() && !
type->isRecordType())
2131 llvm::DIType *FieldType;
2133 llvm::DIDerivedType *BitFieldType;
2134 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2135 if (llvm::DIType *Separator =
2136 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2137 elements.push_back(Separator);
2140 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2143 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2146 elements.push_back(FieldType);
2149void CGDebugInfo::CollectRecordNestedType(
2150 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2151 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2158 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2159 elements.push_back(nestedType);
2162void CGDebugInfo::CollectRecordFields(
2163 const RecordDecl *record, llvm::DIFile *tunit,
2164 SmallVectorImpl<llvm::Metadata *> &elements,
2165 llvm::DICompositeType *RecordTy) {
2166 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2168 if (CXXDecl && CXXDecl->
isLambda())
2169 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2171 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2174 unsigned fieldNo = 0;
2178 for (
const auto *I : record->
decls())
2179 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2180 if (
V->hasAttr<NoDebugAttr>())
2185 if (CGM.getCodeGenOpts().EmitCodeView &&
2193 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2194 if (MI != StaticDataMemberCache.end()) {
2195 assert(MI->second &&
2196 "Static data member declaration should still exist");
2197 elements.push_back(MI->second);
2199 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2200 elements.push_back(Field);
2202 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2203 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2204 elements, RecordTy, record);
2208 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2211 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2216 if (!nestedType->isImplicit() &&
2217 nestedType->getDeclContext() == record)
2218 CollectRecordNestedType(nestedType, elements);
2224llvm::DISubroutineType *
2225CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2226 llvm::DIFile *Unit) {
2227 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2229 return cast_or_null<llvm::DISubroutineType>(
2230 getOrCreateType(QualType(
Func, 0), Unit));
2233 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2234 ThisType =
Method->getThisType();
2236 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2239llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2240 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2241 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2243 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2246llvm::DISubroutineType *
2247CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2248 const FunctionProtoType *
Func,
2249 llvm::DIFile *Unit,
bool SkipFirst) {
2250 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2265 getOrCreateType(CGM.getContext().getFunctionType(
2266 Func->getReturnType(),
Func->getParamTypes(), EPI),
2268 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2269 assert(Args.size() &&
"Invalid number of arguments!");
2271 SmallVector<llvm::Metadata *, 16> Elts;
2274 Elts.push_back(Args[0]);
2276 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2280 if (!HasExplicitObjectParameter) {
2281 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2284 DBuilder.createObjectPointerType(ThisPtrType,
true);
2285 Elts.push_back(ThisPtrType);
2289 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2290 Elts.push_back(Args[i]);
2293 if (HasExplicitObjectParameter) {
2294 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2295 "Expected at least return type and object parameter.");
2296 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2299 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2301 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2308 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2316CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2319 const bool IsCtorOrDtor =
2322 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2329 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2332 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2335 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2338 return CGM.getMangledName(
Method);
2341bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2344 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2347llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2348 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2351 StringRef MethodName = getFunctionName(
Method);
2352 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2354 StringRef MethodLinkageName;
2361 MethodLinkageName = GetMethodLinkageName(
Method);
2364 llvm::DIFile *MethodDefUnit =
nullptr;
2365 unsigned MethodLine = 0;
2366 if (!
Method->isImplicit()) {
2367 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2368 MethodLine = getLineNumber(
Method->getLocation());
2372 llvm::DIType *ContainingType =
nullptr;
2373 unsigned VIndex = 0;
2374 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2375 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2376 int ThisAdjustment = 0;
2379 if (
Method->isPureVirtual())
2380 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2382 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2384 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2388 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2392 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2395 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2396 CGM.getContext().getLangOpts())
2400 MethodVFTableLocation ML =
2401 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2409 if (
Method->size_overridden_methods() == 0)
2410 Flags |= llvm::DINode::FlagIntroducedVirtual;
2415 ThisAdjustment = CGM.getCXXABI()
2416 .getVirtualFunctionPrologueThisAdjustment(GD)
2419 ContainingType = RecordTy;
2422 if (
Method->getCanonicalDecl()->isDeleted())
2423 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2425 if (
Method->isNoReturn())
2426 Flags |= llvm::DINode::FlagNoReturn;
2429 Flags |= llvm::DINode::FlagStaticMember;
2430 if (
Method->isImplicit())
2431 Flags |= llvm::DINode::FlagArtificial;
2433 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2434 if (CXXC->isExplicit())
2435 Flags |= llvm::DINode::FlagExplicit;
2436 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2437 if (CXXC->isExplicit())
2438 Flags |= llvm::DINode::FlagExplicit;
2440 if (
Method->hasPrototype())
2441 Flags |= llvm::DINode::FlagPrototyped;
2443 Flags |= llvm::DINode::FlagLValueReference;
2445 Flags |= llvm::DINode::FlagRValueReference;
2446 if (!
Method->isExternallyVisible())
2447 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2448 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2449 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2453 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2454 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2457 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2458 llvm::DISubprogram *SP = DBuilder.createMethod(
2459 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2460 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2461 TParamsArray.get(),
nullptr,
2462 CGM.getCodeGenOpts().DebugKeyInstructions);
2464 SPCache[
Method->getCanonicalDecl()].reset(SP);
2469void CGDebugInfo::CollectCXXMemberFunctions(
2470 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2471 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2476 for (
const auto *I : RD->
decls()) {
2477 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2491 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2500 auto MI = SPCache.find(
Method->getCanonicalDecl());
2501 EltTys.push_back(MI == SPCache.end()
2502 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2503 :
static_cast<llvm::Metadata *
>(MI->second));
2507void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2508 SmallVectorImpl<llvm::Metadata *> &EltTys,
2509 llvm::DIType *RecordTy) {
2510 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2511 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2512 llvm::DINode::FlagZero);
2516 if (CGM.getCodeGenOpts().EmitCodeView) {
2517 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2518 llvm::DINode::FlagIndirectVirtualBase);
2522void CGDebugInfo::CollectCXXBasesAux(
2523 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2524 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2526 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2527 llvm::DINode::DIFlags StartingFlags) {
2528 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2529 for (
const auto &BI : Bases) {
2532 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2534 if (!SeenTypes.insert(Base).second)
2536 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2537 llvm::DINode::DIFlags BFlags = StartingFlags;
2541 if (BI.isVirtual()) {
2542 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2545 BaseOffset = 0 - CGM.getItaniumVTableContext()
2546 .getVirtualBaseOffsetOffset(RD, Base)
2552 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2553 VBPtrOffset = CGM.getContext()
2554 .getASTRecordLayout(RD)
2558 BFlags |= llvm::DINode::FlagVirtual;
2565 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2566 VBPtrOffset, BFlags);
2567 EltTys.push_back(DTy);
2572CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2573 llvm::DIFile *Unit) {
2575 return llvm::DINodeArray();
2576 TemplateArgs &Args = *OArgs;
2577 SmallVector<llvm::Metadata *, 16> TemplateParams;
2578 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2579 const TemplateArgument &TA = Args.Args[i];
2583 Name = Args.TList->getParam(i)->getName();
2587 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2588 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2589 TheCU, Name, TTy, defaultParameter));
2594 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2595 TheCU, Name, TTy, defaultParameter,
2596 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2601 llvm::DIType *TTy = getOrCreateType(T, Unit);
2602 llvm::Constant *
V =
nullptr;
2605 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2606 !D->
hasAttr<CUDADeviceAttr>()) {
2609 if (
const auto *VD = dyn_cast<VarDecl>(D))
2610 V = CGM.GetAddrOfGlobalVar(VD);
2613 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2614 MD && MD->isImplicitObjectMemberFunction())
2615 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2616 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2617 V = CGM.GetAddrOfFunction(FD);
2620 else if (
const auto *MPT =
2621 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2625 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2627 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2628 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2629 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2630 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2631 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2633 V = ConstantEmitter(CGM).emitAbstract(
2634 SourceLocation(), TPO->getValue(), TPO->getType());
2636 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2638 assert(
V &&
"Failed to find template parameter pointer");
2639 V =
V->stripPointerCasts();
2641 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2642 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2646 llvm::DIType *TTy = getOrCreateType(T, Unit);
2647 llvm::Constant *
V =
nullptr;
2650 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2656 if (MPT->isMemberDataPointer())
2657 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2659 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2660 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2661 TheCU, Name, TTy, defaultParameter,
V));
2665 llvm::DIType *TTy = getOrCreateType(T, Unit);
2666 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2668 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2669 TheCU, Name, TTy, defaultParameter,
V));
2672 std::string QualName;
2673 llvm::raw_string_ostream
OS(QualName);
2675 OS, getPrintingPolicy());
2676 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2677 TheCU, Name,
nullptr, QualName, defaultParameter));
2681 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2682 TheCU, Name,
nullptr,
2689 T = CGM.getContext().getLValueReferenceType(T);
2690 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2691 assert(
V &&
"Expression in template argument isn't constant");
2692 llvm::DIType *TTy = getOrCreateType(T, Unit);
2693 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2694 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2700 "These argument types shouldn't exist in concrete types");
2703 return DBuilder.getOrCreateArray(TemplateParams);
2706std::optional<CGDebugInfo::TemplateArgs>
2707CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2715 return std::nullopt;
2717std::optional<CGDebugInfo::TemplateArgs>
2718CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2722 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2724 return std::nullopt;
2725 VarTemplateDecl *T = TS->getSpecializedTemplate();
2727 auto TA = TS->getTemplateArgs().asArray();
2728 return {{TList, TA}};
2730std::optional<CGDebugInfo::TemplateArgs>
2731CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2732 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2736 TemplateParameterList *TPList =
2737 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2738 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2739 return {{TPList, TAList.
asArray()}};
2741 return std::nullopt;
2745CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2746 llvm::DIFile *Unit) {
2747 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2750llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2751 llvm::DIFile *Unit) {
2752 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2755llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2756 llvm::DIFile *Unit) {
2757 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2760llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2761 if (!D->
hasAttr<BTFDeclTagAttr>())
2764 SmallVector<llvm::Metadata *, 4> Annotations;
2766 llvm::Metadata *Ops[2] = {
2767 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2768 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2769 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2771 return DBuilder.getOrCreateArray(Annotations);
2774llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2776 return VTablePtrType;
2778 ASTContext &Context = CGM.getContext();
2781 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2782 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2783 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2785 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2786 std::optional<unsigned> DWARFAddressSpace =
2787 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2789 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2790 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2791 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2792 return VTablePtrType;
2795StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2807 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2809 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2819 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2820 VTable->isDeclarationForLinker())
2824 StringRef SymbolName =
"__clang_vtable";
2826 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2835 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2837 llvm::DIFile *Unit = getOrCreateFile(Loc);
2838 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2840 llvm::DINode::FlagArtificial;
2841 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2842 ? llvm::dwarf::DW_TAG_variable
2843 : llvm::dwarf::DW_TAG_member;
2844 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2845 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2849 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2853 llvm::DIGlobalVariableExpression *GVE =
2854 DBuilder.createGlobalVariableExpression(
2855 TheCU, SymbolName, VTable->getName(), Unit, 0,
2856 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2857 true,
nullptr, DT,
nullptr,
2859 VTable->addDebugInfo(GVE);
2862StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2864 llvm::Function *InitFn) {
2869 return InitFn->getName();
2879 llvm::raw_svector_ostream OS(QualifiedGV);
2881 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2883 std::swap(Quals, GVName);
2887 llvm::raw_svector_ostream OS(InitName);
2889 OS << Quals <<
"::";
2894 llvm_unreachable(
"not an initializer");
2896 OS <<
"`dynamic initializer for '";
2899 OS <<
"`dynamic atexit destructor for '";
2906 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2907 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2908 getPrintingPolicy());
2913 return internString(
OS.str());
2916void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2917 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2926 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2933 llvm::DIType *VPtrTy =
nullptr;
2934 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2935 CGM.getTarget().getCXXABI().isMicrosoft();
2936 if (NeedVTableShape) {
2938 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2939 const VTableLayout &VFTLayout =
2940 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2941 unsigned VSlotCount =
2943 unsigned VTableWidth = PtrWidth * VSlotCount;
2944 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2945 std::optional<unsigned> DWARFAddressSpace =
2946 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2949 llvm::DIType *VTableType = DBuilder.createPointerType(
2950 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2951 EltTys.push_back(VTableType);
2954 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2962 VPtrTy = getOrCreateVTablePtrType(Unit);
2964 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2965 llvm::DIType *VPtrMember =
2966 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2967 llvm::DINode::FlagArtificial, VPtrTy);
2968 EltTys.push_back(VPtrMember);
2973 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2974 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
2985 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2986 assert(!D.
isNull() &&
"null type");
2987 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
2988 assert(T &&
"could not create debug info for type");
2997 if (CGM.getCodeGenOpts().getDebugInfo() <=
2998 llvm::codegenoptions::DebugLineTablesOnly)
3002 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3004 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3006 CI->setMetadata(
"heapallocsite", node);
3010 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3012 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3014 auto I = TypeCache.find(TyPtr);
3017 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3018 assert(!Res->isForwardDecl());
3019 TypeCache[TyPtr].reset(Res);
3023 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3024 !CGM.getLangOpts().CPlusPlus)
3030 if (RD->
hasAttr<DLLImportAttr>())
3033 if (MD->hasAttr<DLLImportAttr>())
3046 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3056 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3057 Explicit = TD->isExplicitInstantiationOrSpecialization();
3061 if (CXXDecl->
fields().empty())
3071 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3072 if (CXXRD->isDynamicClass() &&
3073 CGM.getVTableLinkage(CXXRD) ==
3074 llvm::GlobalValue::AvailableExternallyLinkage &&
3085 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3087 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3089 auto I = TypeCache.find(TyPtr);
3096 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3097 assert(!Res->isForwardDecl());
3098 TypeCache[TyPtr].reset(Res);
3105 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3106 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3129 if (Ctor->isCopyOrMoveConstructor())
3131 if (!Ctor->isDeleted())
3150 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3153 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3154 RD->
hasAttr<StandaloneDebugAttr>())
3157 if (!LangOpts.CPlusPlus)
3163 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3179 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3180 Spec = SD->getSpecializationKind();
3189 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3200 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3201 llvm::DIType *T = getTypeOrNull(Ty);
3202 if (T && T->isForwardDecl())
3206llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3207 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3208 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3212 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3216 auto [Def, Pref] = CreateTypeDefinition(Ty);
3218 return Pref ? Pref : Def;
3221llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3222 llvm::DIFile *Unit) {
3226 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3230 return getOrCreateType(PNA->getTypedefType(), Unit);
3233std::pair<llvm::DIType *, llvm::DIType *>
3234CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3235 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3238 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3246 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3250 return {FwdDecl,
nullptr};
3252 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3253 CollectContainingType(CXXDecl, FwdDecl);
3256 LexicalBlockStack.emplace_back(&*FwdDecl);
3257 RegionMap[RD].reset(FwdDecl);
3260 SmallVector<llvm::Metadata *, 16> EltTys;
3267 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3269 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3270 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3274 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3275 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3276 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3278 LexicalBlockStack.pop_back();
3279 RegionMap.erase(RD);
3281 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3282 DBuilder.replaceArrays(FwdDecl, Elements);
3284 if (FwdDecl->isTemporary())
3286 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3288 RegionMap[RD].reset(FwdDecl);
3290 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3291 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3292 return {FwdDecl, PrefDI};
3294 return {FwdDecl,
nullptr};
3297llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3298 llvm::DIFile *Unit) {
3300 return getOrCreateType(Ty->getBaseType(), Unit);
3303llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3304 llvm::DIFile *Unit) {
3306 SourceLocation Loc = Ty->getDecl()->getLocation();
3309 return DBuilder.createTypedef(
3310 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3311 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3312 getDeclContextDescriptor(Ty->getDecl()));
3339llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3340 llvm::DIFile *Unit) {
3345 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3346 TheCU->getSourceLanguage().getUnversionedName());
3351 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3352 !
ID->getImplementation())
3353 return DBuilder.createForwardDecl(
3354 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3355 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3358 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3359 unsigned Line = getLineNumber(
ID->getLocation());
3363 ObjCInterfaceDecl *Def =
ID->getDefinition();
3365 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3366 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3367 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3368 DefUnit,
Line, RuntimeLang);
3369 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3373 return CreateTypeDefinition(Ty, Unit);
3376llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3377 bool CreateSkeletonCU) {
3382 auto ModRef = ModuleCache.find(M);
3383 if (ModRef != ModuleCache.end())
3387 SmallString<128> ConfigMacros;
3389 llvm::raw_svector_ostream
OS(ConfigMacros);
3390 const auto &PPOpts = CGM.getPreprocessorOpts();
3393 for (
auto &M : PPOpts.Macros) {
3396 const std::string &
Macro = M.first;
3397 bool Undef = M.second;
3398 OS <<
"\"-" << (Undef ?
'U' :
'D');
3414 bool IsRootModule = M ? !M->
Parent :
true;
3418 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3419 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3420 "clang module without ASTFile must be specified by -fmodule-name");
3423 auto RemapPath = [
this](StringRef Path) -> std::string {
3425 StringRef Relative(Remapped);
3426 StringRef CompDir = TheCU->getDirectory();
3427 if (CompDir.empty())
3430 if (Relative.consume_front(CompDir))
3431 Relative.consume_front(llvm::sys::path::get_separator());
3433 return Relative.str();
3436 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3443 Signature = ModSig.truncatedValue();
3447 llvm::DIBuilder DIB(CGM.getModule());
3449 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3450 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3451 PCM = getCurrentDirname();
3455 llvm::sys::path::append(PCM, Mod.
getASTFile());
3456 DIB.createCompileUnit(
3457 TheCU->getSourceLanguage(),
3460 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3461 llvm::DICompileUnit::FullDebug, Signature);
3465 llvm::DIModule *Parent =
3467 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3469 std::string IncludePath = Mod.
getPath().str();
3470 llvm::DIModule *DIMod =
3471 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3472 RemapPath(IncludePath));
3473 ModuleCache[M].reset(DIMod);
3477llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3478 llvm::DIFile *Unit) {
3480 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3481 unsigned Line = getLineNumber(
ID->getLocation());
3483 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3489 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3490 if (
ID->getImplementation())
3491 Flags |= llvm::DINode::FlagObjcClassComplete;
3493 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3494 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3495 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3496 nullptr, llvm::DINodeArray(), RuntimeLang);
3498 QualType QTy(Ty, 0);
3499 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3502 LexicalBlockStack.emplace_back(RealDecl);
3503 RegionMap[Ty->
getDecl()].reset(RealDecl);
3506 SmallVector<llvm::Metadata *, 16> EltTys;
3508 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3510 llvm::DIType *SClassTy =
3511 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3515 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3516 llvm::DINode::FlagZero);
3517 EltTys.push_back(InhTag);
3521 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3522 SourceLocation Loc = PD->getLocation();
3523 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3524 unsigned PLine = getLineNumber(Loc);
3525 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3526 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3527 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3528 PD->getName(), PUnit, PLine,
3530 : getSelectorName(PD->getGetterName()),
3532 : getSelectorName(PD->getSetterName()),
3533 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3534 EltTys.push_back(PropertyNode);
3539 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3543 llvm::DenseSet<IsClassAndIdent> PropertySet;
3545 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3546 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3548 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3549 for (
auto *PD : ClassExt->properties()) {
3550 PropertySet.insert(GetIsClassAndIdent(PD));
3553 for (
const auto *PD :
ID->properties()) {
3556 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3562 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3563 unsigned FieldNo = 0;
3564 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3565 Field =
Field->getNextIvar(), ++FieldNo) {
3566 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3570 StringRef FieldName =
Field->getName();
3573 if (FieldName.empty())
3577 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3578 unsigned FieldLine = getLineNumber(
Field->getLocation());
3579 QualType FType =
Field->getType();
3586 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3587 : CGM.getContext().getTypeSize(FType);
3592 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3596 if (
Field->isBitField()) {
3598 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3599 FieldOffset %= CGM.getContext().getCharWidth();
3607 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3609 Flags = llvm::DINode::FlagProtected;
3611 Flags = llvm::DINode::FlagPrivate;
3613 Flags = llvm::DINode::FlagPublic;
3615 if (
Field->isBitField())
3616 Flags |= llvm::DINode::FlagBitField;
3618 llvm::MDNode *PropertyNode =
nullptr;
3619 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3620 if (ObjCPropertyImplDecl *PImpD =
3621 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3622 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3623 SourceLocation Loc = PD->getLocation();
3624 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3625 unsigned PLine = getLineNumber(Loc);
3626 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3627 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3628 PropertyNode = DBuilder.createObjCProperty(
3629 PD->getName(), PUnit, PLine,
3632 : getSelectorName(PD->getGetterName()),
3635 : getSelectorName(PD->getSetterName()),
3636 PD->getPropertyAttributes(),
3637 getOrCreateType(PD->getType(), PUnit));
3641 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3642 FieldSize, FieldAlign, FieldOffset, Flags,
3643 FieldTy, PropertyNode);
3644 EltTys.push_back(FieldTy);
3647 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3648 DBuilder.replaceArrays(RealDecl, Elements);
3650 LexicalBlockStack.pop_back();
3654llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3655 llvm::DIFile *Unit) {
3663 auto &Ctx = CGM.getContext();
3668 QualType CharVecTy =
3670 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3673 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3676 llvm::Metadata *Subscript;
3677 QualType QTy(Ty, 0);
3678 auto SizeExpr = SizeExprCache.find(QTy);
3679 if (SizeExpr != SizeExprCache.end())
3680 Subscript = DBuilder.getOrCreateSubrange(
3681 SizeExpr->getSecond() ,
nullptr ,
3682 nullptr ,
nullptr );
3685 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3686 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3687 Subscript = DBuilder.getOrCreateSubrange(
3688 CountNode ,
nullptr ,
nullptr ,
3691 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3696 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3699llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3700 llvm::DIFile *Unit) {
3704 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3709 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3710 auto *ColumnCountNode =
3711 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3712 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3713 auto *RowCountNode =
3714 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3715 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3716 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3717 ColumnCountNode ,
nullptr ,
nullptr ,
3719 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3720 RowCountNode ,
nullptr ,
nullptr ,
3722 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3723 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3726llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3731 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3746 Size = CGM.getContext().getTypeSize(Ty);
3753 SmallVector<llvm::Metadata *, 8> Subscripts;
3754 QualType EltTy(Ty, 0);
3755 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3764 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3765 Count = CAT->getZExtSize();
3766 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3767 if (Expr *Size = VAT->getSizeExpr()) {
3769 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3770 Count =
Result.Val.getInt().getExtValue();
3774 auto SizeNode = SizeExprCache.find(EltTy);
3775 if (SizeNode != SizeExprCache.end())
3776 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3777 SizeNode->getSecond() ,
nullptr ,
3778 nullptr ,
nullptr ));
3781 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3782 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3783 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3784 CountNode ,
nullptr ,
nullptr ,
3790 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3792 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3796llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3797 llvm::DIFile *Unit) {
3798 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3802llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3803 llvm::DIFile *Unit) {
3804 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3806 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3807 CGM.getCodeGenOpts().DwarfVersion < 4)
3808 Tag = llvm::dwarf::DW_TAG_reference_type;
3810 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3813llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3815 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3819 Size = CGM.getContext().getTypeSize(Ty);
3822 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3825 Flags |= llvm::DINode::FlagSingleInheritance;
3828 Flags |= llvm::DINode::FlagMultipleInheritance;
3831 Flags |= llvm::DINode::FlagVirtualInheritance;
3841 llvm::DIType *ClassType = getOrCreateType(T, U);
3843 return DBuilder.createMemberPointerType(
3847 const FunctionProtoType *FPT =
3849 return DBuilder.createMemberPointerType(
3850 getOrCreateInstanceMethodType(
3853 ClassType, Size, 0, Flags);
3856llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3858 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3861llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3865llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3867 return getOrCreateType(Ty->getWrappedType(), U);
3870llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3877 const EnumType *Ty) {
3889llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3892 bool isImportedFromModule =
3893 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3897 if (isImportedFromModule || !ED->getDefinition()) {
3904 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3905 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3906 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3907 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3909 unsigned Line = getLineNumber(ED->getLocation());
3910 StringRef EDName = ED->getName();
3911 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3912 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3913 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3915 ReplaceMap.emplace_back(
3916 std::piecewise_construct, std::make_tuple(Ty),
3917 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3921 return CreateTypeDefinition(Ty);
3924llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3927 SmallVector<llvm::Metadata *, 16> Enumerators;
3928 ED = ED->getDefinition();
3929 assert(ED &&
"An enumeration definition is required");
3930 for (
const auto *
Enum : ED->enumerators()) {
3931 Enumerators.push_back(
3932 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3935 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3936 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3937 EnumKind = Attr->getExtensibility();
3940 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3942 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3943 unsigned Line = getLineNumber(ED->getLocation());
3944 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3945 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3946 return DBuilder.createEnumerationType(
3947 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3948 0, Identifier, ED->isScoped(), EnumKind);
3953 StringRef Name, StringRef
Value) {
3954 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3955 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3961 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3962 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3963 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3967 StringRef FuncName) {
3968 llvm::DISubprogram *SP =
3969 createInlinedSubprogram(FuncName, Location->getFile());
3970 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3975 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3981 FuncName += Category;
3983 FuncName += FailureMsg;
3991 Qualifiers InnerQuals = T.getLocalQualifiers();
3995 Quals += InnerQuals;
3997 switch (T->getTypeClass()) {
3999 return C.getQualifiedType(T.getTypePtr(), Quals);
4002 case Type::InjectedClassName:
4003 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4005 case Type::TemplateSpecialization: {
4007 if (Spec->isTypeAlias())
4008 return C.getQualifiedType(T.getTypePtr(), Quals);
4009 T = Spec->desugar();
4012 case Type::TypeOfExpr:
4018 case Type::Decltype:
4021 case Type::UnaryTransform:
4024 case Type::Attributed:
4027 case Type::BTFTagAttributed:
4030 case Type::CountAttributed:
4039 case Type::MacroQualified:
4042 case Type::SubstTemplateTypeParm:
4046 case Type::DeducedTemplateSpecialization: {
4048 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4052 case Type::PackIndexing: {
4056 case Type::Adjusted:
4063 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4068llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4071 if (It != TypeCache.end()) {
4073 if (llvm::Metadata *
V = It->second)
4086 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4093 RetainedTypes.push_back(
4094 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4097llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4101 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4103 llvm::raw_string_ostream OS(Name);
4104 Ty.
print(OS, getPrintingPolicy());
4111 if (
auto *T = getTypeOrNull(Ty))
4114 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4115 void *TyPtr = Ty.getAsOpaquePtr();
4118 TypeCache[TyPtr].reset(Res);
4123llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4131 auto Info = Reader->getSourceDescriptor(Idx);
4133 return getOrCreateModuleRef(*Info,
true);
4134 }
else if (ClangModuleMap) {
4147 auto Info = ASTSourceDescriptor(*M);
4148 return getOrCreateModuleRef(Info,
false);
4151 return getOrCreateModuleRef(PCHDescriptor,
false);
4158llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4161 return CreateQualifiedType(Ty, Unit);
4165#define TYPE(Class, Base)
4166#define ABSTRACT_TYPE(Class, Base)
4167#define NON_CANONICAL_TYPE(Class, Base)
4168#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4169#include "clang/AST/TypeNodes.inc"
4170 llvm_unreachable(
"Dependent types cannot show up in debug information");
4172 case Type::ExtVector:
4175 case Type::ConstantMatrix:
4177 case Type::ObjCObjectPointer:
4179 case Type::ObjCObject:
4181 case Type::ObjCTypeParam:
4183 case Type::ObjCInterface:
4191 case Type::BlockPointer:
4199 case Type::FunctionProto:
4200 case Type::FunctionNoProto:
4202 case Type::ConstantArray:
4203 case Type::VariableArray:
4204 case Type::IncompleteArray:
4205 case Type::ArrayParameter:
4208 case Type::LValueReference:
4210 case Type::RValueReference:
4213 case Type::MemberPointer:
4221 case Type::OverflowBehavior:
4226 case Type::TemplateSpecialization:
4228 case Type::HLSLAttributedResource:
4230 case Type::HLSLInlineSpirv:
4232 case Type::PredefinedSugar:
4234 case Type::CountAttributed:
4236 case Type::Attributed:
4237 case Type::BTFTagAttributed:
4238 case Type::Adjusted:
4240 case Type::DeducedTemplateSpecialization:
4243 case Type::MacroQualified:
4244 case Type::SubstTemplateTypeParm:
4245 case Type::TypeOfExpr:
4247 case Type::Decltype:
4248 case Type::PackIndexing:
4249 case Type::UnaryTransform:
4253 llvm_unreachable(
"type should have been unwrapped!");
4256llvm::DICompositeType *
4257CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4258 QualType QTy(Ty, 0);
4260 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4265 if (T && !T->isForwardDecl())
4269 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4274 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4277 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4282llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4283 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4284 bool NameIsSimplified =
false;
4287 StringRef RDName = getClassName(RD, &NameIsSimplified);
4289 llvm::DIFile *DefUnit =
nullptr;
4292 DefUnit = getOrCreateFile(Loc);
4293 Line = getLineNumber(Loc);
4296 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4300 auto *T = cast_or_null<llvm::DICompositeType>(
4301 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4309 return getOrCreateRecordFwdDecl(Ty, RDContext);
4322 auto Flags = llvm::DINode::FlagZero;
4323 if (NameIsSimplified)
4324 Flags |= llvm::DINode::FlagNameIsSimplified;
4325 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4327 Flags |= llvm::DINode::FlagTypePassByReference;
4329 Flags |= llvm::DINode::FlagTypePassByValue;
4332 if (!CXXRD->isTrivial())
4333 Flags |= llvm::DINode::FlagNonTrivial;
4336 if (CXXRD->isAnonymousStructOrUnion())
4337 Flags |= llvm::DINode::FlagExportSymbols;
4340 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4343 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4344 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4346 Flags, Identifier, Annotations);
4350 switch (RealDecl->getTag()) {
4352 llvm_unreachable(
"invalid composite type tag");
4354 case llvm::dwarf::DW_TAG_array_type:
4355 case llvm::dwarf::DW_TAG_enumeration_type:
4360 if (Identifier.empty())
4364 case llvm::dwarf::DW_TAG_structure_type:
4365 case llvm::dwarf::DW_TAG_union_type:
4366 case llvm::dwarf::DW_TAG_class_type:
4369 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4373 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4374 CXXRecordDecl *TemplateDecl =
4375 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4376 RegionMap[TemplateDecl].reset(RealDecl);
4378 RegionMap[RD].reset(RealDecl);
4380 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4382 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4383 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4384 CollectCXXTemplateParams(TSpecial, DefUnit));
4388void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4389 llvm::DICompositeType *RealDecl) {
4391 llvm::DIType *ContainingType =
nullptr;
4392 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4396 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4403 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4404 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4406 ContainingType = RealDecl;
4408 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4411llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4412 StringRef Name, uint64_t *Offset) {
4413 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4414 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4417 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4418 *Offset, llvm::DINode::FlagZero, FieldTy);
4419 *Offset += FieldSize;
4423void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4425 StringRef &LinkageName,
4426 llvm::DIScope *&FDContext,
4427 llvm::DINodeArray &TParamsArray,
4428 llvm::DINode::DIFlags &Flags) {
4430 bool NameIsSimplified =
false;
4431 Name = getFunctionName(FD, &NameIsSimplified);
4432 if (NameIsSimplified)
4433 Flags |= llvm::DINode::FlagNameIsSimplified;
4434 Name = getFunctionName(FD);
4437 LinkageName = CGM.getMangledName(GD);
4439 Flags |= llvm::DINode::FlagPrototyped;
4443 if (LinkageName == Name ||
4444 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4445 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4446 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4447 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4448 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4449 LinkageName = StringRef();
4453 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4454 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4455 CGM.getCodeGenOpts().EmitCodeView)) {
4456 if (
const NamespaceDecl *NSDecl =
4458 FDContext = getOrCreateNamespace(NSDecl);
4459 else if (
const RecordDecl *RDecl =
4461 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4462 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4465 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4468 Flags |= llvm::DINode::FlagNoReturn;
4470 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4474void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4475 unsigned &LineNo, QualType &T,
4476 StringRef &Name, StringRef &LinkageName,
4477 llvm::MDTuple *&TemplateParameters,
4478 llvm::DIScope *&VDContext) {
4487 llvm::APInt ConstVal(32, 1);
4488 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4490 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4497 LinkageName = CGM.getMangledName(VD);
4498 if (LinkageName == Name)
4499 LinkageName = StringRef();
4502 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4503 TemplateParameters = parameterNodes.get();
4505 TemplateParameters =
nullptr;
4523 DC = CGM.getContext().getTranslationUnitDecl();
4525 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4526 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4529llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4531 llvm::DINodeArray TParamsArray;
4532 StringRef Name, LinkageName;
4533 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4534 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4536 llvm::DIFile *Unit = getOrCreateFile(Loc);
4537 llvm::DIScope *DContext = Unit;
4538 unsigned Line = getLineNumber(Loc);
4539 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4544 SmallVector<QualType, 16> ArgTypes;
4545 for (
const ParmVarDecl *Parm : FD->
parameters())
4546 ArgTypes.push_back(Parm->getType());
4549 QualType FnType = CGM.getContext().getFunctionType(
4550 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4552 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4553 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4554 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4558 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4559 return DBuilder.createFunction(
4560 DContext, Name, LinkageName, Unit,
Line,
4561 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4562 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4564 CGM.getCodeGenOpts().DebugKeyInstructions);
4567 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4568 DContext, Name, LinkageName, Unit,
Line,
4569 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4570 TParamsArray.get(), getFunctionDeclaration(FD));
4572 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4573 std::make_tuple(CanonDecl),
4574 std::make_tuple(SP));
4578llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4579 return getFunctionFwdDeclOrStub(GD,
false);
4582llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4583 return getFunctionFwdDeclOrStub(GD,
true);
4586llvm::DIGlobalVariable *
4587CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4589 StringRef Name, LinkageName;
4591 llvm::DIFile *Unit = getOrCreateFile(Loc);
4592 llvm::DIScope *DContext = Unit;
4593 unsigned Line = getLineNumber(Loc);
4594 llvm::MDTuple *TemplateParameters =
nullptr;
4596 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4599 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4600 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4602 FwdDeclReplaceMap.emplace_back(
4603 std::piecewise_construct,
4605 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4609llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4614 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4615 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4616 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4620 if (I != DeclCache.end()) {
4622 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4623 return GVE->getVariable();
4631 if (IE != ImportedDeclCache.end()) {
4632 auto N = IE->second;
4633 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4635 return dyn_cast_or_null<llvm::DINode>(N);
4640 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4641 return getFunctionForwardDeclaration(FD);
4642 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4643 return getGlobalVariableForwardDeclaration(VD);
4648llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4649 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4652 const auto *FD = dyn_cast<FunctionDecl>(D);
4657 auto *S = getDeclContextDescriptor(D);
4660 if (MI == SPCache.end()) {
4662 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4666 if (MI != SPCache.end()) {
4667 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4668 if (SP && !SP->isDefinition())
4672 for (
auto *NextFD : FD->
redecls()) {
4673 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4674 if (MI != SPCache.end()) {
4675 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4676 if (SP && !SP->isDefinition())
4683llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4684 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4685 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4686 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4689 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4693 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4697 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4706 QualType QTy(
ID->getTypeForDecl(), 0);
4707 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4708 if (It == TypeCache.end())
4711 llvm::DISubprogram *FD = DBuilder.createFunction(
4712 InterfaceType, getObjCMethodName(OMD), StringRef(),
4713 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4714 DBuilder.finalizeSubprogram(FD);
4721llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4726 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4727 !CGM.getCodeGenOpts().EmitCodeView))
4730 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4732 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4735 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4738 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4739 return getOrCreateMethodType(
Method, F);
4741 const auto *FTy = FnType->
getAs<FunctionType>();
4744 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4746 SmallVector<llvm::Metadata *, 16> Elts;
4749 QualType ResultTy = OMethod->getReturnType();
4752 if (ResultTy == CGM.getContext().getObjCInstanceType())
4753 ResultTy = CGM.getContext().getPointerType(
4754 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4756 Elts.push_back(getOrCreateType(ResultTy, F));
4758 QualType SelfDeclTy;
4759 if (
auto *SelfDecl = OMethod->getSelfDecl())
4760 SelfDeclTy = SelfDecl->getType();
4761 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4764 if (!SelfDeclTy.
isNull())
4766 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4768 Elts.push_back(DBuilder.createArtificialType(
4769 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4771 for (
const auto *PI : OMethod->parameters())
4772 Elts.push_back(getOrCreateType(PI->getType(), F));
4774 if (OMethod->isVariadic())
4775 Elts.push_back(DBuilder.createUnspecifiedParameter());
4777 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4778 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4784 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4785 if (FD->isVariadic()) {
4786 SmallVector<llvm::Metadata *, 16> EltTys;
4787 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4788 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4790 EltTys.push_back(getOrCreateType(ParamType, F));
4791 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4792 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4793 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4806 CC = SrcFnTy->getCallConv();
4808 for (
const VarDecl *VD : Args)
4809 ArgTypes.push_back(VD->
getType());
4810 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4816 llvm::Function *Fn,
bool CurFuncIsThunk) {
4818 StringRef LinkageName;
4820 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4823 bool HasDecl = (D !=
nullptr);
4825 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4826 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4827 llvm::DIFile *Unit = getOrCreateFile(Loc);
4828 llvm::DIScope *FDContext = Unit;
4829 llvm::DINodeArray TParamsArray;
4830 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4833 LinkageName = Fn->getName();
4834 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4836 auto FI = SPCache.find(FD->getCanonicalDecl());
4837 if (FI != SPCache.end()) {
4838 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4839 if (SP && SP->isDefinition()) {
4840 LexicalBlockStack.emplace_back(SP);
4841 RegionMap[D].reset(SP);
4845 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4846 TParamsArray, Flags);
4849 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4850 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4851 Name = getObjCMethodName(OMD);
4852 Flags |= llvm::DINode::FlagPrototyped;
4859 Name = Fn->getName();
4864 Flags |= llvm::DINode::FlagPrototyped;
4866 Name.consume_front(
"\01");
4870 "Unexpected DynamicInitKind !");
4874 Flags |= llvm::DINode::FlagArtificial;
4880 Flags |= llvm::DINode::FlagThunk;
4882 if (Fn->hasLocalLinkage())
4883 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4884 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4885 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4888 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4889 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4891 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4892 unsigned ScopeLine = getLineNumber(ScopeLoc);
4893 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4894 llvm::DISubprogram *
Decl =
nullptr;
4895 llvm::DINodeArray Annotations =
nullptr;
4898 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4899 : getFunctionDeclaration(D);
4900 Annotations = CollectBTFDeclTagAnnotations(D);
4908 llvm::DISubprogram *SP = DBuilder.createFunction(
4909 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4910 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4911 Annotations,
"", KeyInstructions);
4912 Fn->setSubprogram(SP);
4921 LexicalBlockStack.emplace_back(SP);
4924 RegionMap[D].reset(SP);
4928 QualType FnType, llvm::Function *Fn) {
4930 StringRef LinkageName;
4936 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4937 return GetName(D,
true);
4940 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4941 llvm::DIFile *Unit = getOrCreateFile(Loc);
4942 bool IsDeclForCallSite = Fn ?
true :
false;
4943 llvm::DIScope *FDContext =
4944 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4945 llvm::DINodeArray TParamsArray;
4948 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4949 TParamsArray, Flags);
4950 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4951 Name = getObjCMethodName(OMD);
4952 Flags |= llvm::DINode::FlagPrototyped;
4954 llvm_unreachable(
"not a function or ObjC method");
4956 Name.consume_front(
"\01");
4959 Flags |= llvm::DINode::FlagArtificial;
4964 unsigned LineNo = getLineNumber(Loc);
4965 unsigned ScopeLine = 0;
4966 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4967 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4968 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4970 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4971 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4973 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4974 llvm::DISubprogram *SP = DBuilder.createFunction(
4975 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4976 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4982 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4983 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4984 llvm::DITypeArray ParamTypes = STy->getTypeArray();
4987 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4988 DBuilder.createParameterVariable(
4989 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4990 llvm::DINode::FlagZero, ParamAnnotations);
4996 if (IsDeclForCallSite)
4997 Fn->setSubprogram(SP);
5001 llvm::CallBase *CI) {
5002 if (!shouldGenerateVirtualCallSite())
5008 assert(CI &&
"Invalid Call Instruction.");
5009 if (!CI->isIndirectCall())
5013 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5014 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5022 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5025 if (
Func->getSubprogram())
5033 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5048 auto FI = SPCache.find(FD->getCanonicalDecl());
5049 llvm::DISubprogram *SP =
nullptr;
5050 if (FI != SPCache.end())
5051 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5052 if (!SP || !SP->isDefinition())
5053 SP = getFunctionStub(GD);
5054 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5055 LexicalBlockStack.emplace_back(SP);
5061 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5070 if (CurLoc.isInvalid() ||
5071 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5072 LexicalBlockStack.empty())
5075 llvm::MDNode *
Scope = LexicalBlockStack.back();
5076 Builder.SetCurrentDebugLocation(
5077 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5078 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5082 llvm::MDNode *Back =
nullptr;
5083 if (!LexicalBlockStack.empty())
5084 Back = LexicalBlockStack.back().get();
5085 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5087 getColumnNumber(CurLoc)));
5090void CGDebugInfo::AppendAddressSpaceXDeref(
5092 std::optional<unsigned> DWARFAddressSpace =
5094 if (!DWARFAddressSpace)
5097 Expr.push_back(llvm::dwarf::DW_OP_constu);
5098 Expr.push_back(*DWARFAddressSpace);
5099 Expr.push_back(llvm::dwarf::DW_OP_swap);
5100 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5109 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5110 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5111 LexicalBlockStack.back(), CurInlinedAt));
5113 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5117 CreateLexicalBlock(Loc);
5122 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5127 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5130 LexicalBlockStack.pop_back();
5134 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5135 unsigned RCount = FnBeginRegionCount.back();
5136 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5139 while (LexicalBlockStack.size() != RCount) {
5142 LexicalBlockStack.pop_back();
5144 FnBeginRegionCount.pop_back();
5146 if (Fn && Fn->getSubprogram())
5147 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5150CGDebugInfo::BlockByRefType
5151CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5152 uint64_t *XOffset) {
5155 uint64_t FieldSize, FieldOffset;
5156 uint32_t FieldAlign;
5158 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5163 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5164 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5166 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5167 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5170 if (HasCopyAndDispose) {
5173 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5175 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5177 bool HasByrefExtendedLayout;
5180 HasByrefExtendedLayout) &&
5181 HasByrefExtendedLayout) {
5184 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5193 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5196 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5199 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5204 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5205 FieldSize = CGM.getContext().getTypeSize(FType);
5206 FieldAlign = CGM.getContext().toBits(Align);
5208 *XOffset = FieldOffset;
5209 llvm::DIType *FieldTy = DBuilder.createMemberType(
5210 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5211 llvm::DINode::FlagZero, WrappedTy);
5212 EltTys.push_back(FieldTy);
5213 FieldOffset += FieldSize;
5215 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5216 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5217 llvm::DINode::FlagZero,
nullptr, Elements),
5221llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5222 llvm::Value *Storage,
5223 std::optional<unsigned> ArgNo,
5225 const bool UsePointerValue) {
5226 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5227 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5228 if (VD->
hasAttr<NoDebugAttr>())
5233 llvm::DIFile *Unit =
nullptr;
5234 if (!VarIsArtificial)
5238 if (VD->
hasAttr<BlocksAttr>())
5239 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5241 Ty = getOrCreateType(VD->
getType(), Unit);
5251 if (!VarIsArtificial) {
5255 SmallVector<uint64_t, 13> Expr;
5256 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5263 Flags |= llvm::DINode::FlagArtificial;
5267 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5268 AppendAddressSpaceXDeref(AddressSpace, Expr);
5272 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5275 Flags |= llvm::DINode::FlagObjectPointer;
5276 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5277 if (PVD->isExplicitObjectParameter())
5278 Flags |= llvm::DINode::FlagObjectPointer;
5286 StringRef Name = VD->
getName();
5287 if (!Name.empty()) {
5293 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5295 offset = CGM.getContext().toCharUnitsFromBits(
5298 Expr.push_back(llvm::dwarf::DW_OP_deref);
5299 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5301 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5304 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5316 for (
const auto *Field : RD->
fields()) {
5317 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5318 StringRef FieldName =
Field->getName();
5326 auto *D = DBuilder.createAutoVariable(
5327 Scope, FieldName, Unit,
Line, FieldTy,
5328 CGM.getCodeGenOpts().OptimizationLevel != 0,
5329 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5332 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5333 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5336 Builder.GetInsertBlock());
5344 if (UsePointerValue) {
5345 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5346 "Debug info already contains DW_OP_deref.");
5347 Expr.push_back(llvm::dwarf::DW_OP_deref);
5351 llvm::DILocalVariable *D =
nullptr;
5353 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5354 D = DBuilder.createParameterVariable(
5355 Scope, Name, *ArgNo, Unit,
Line, Ty,
5356 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5365 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5371 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5372 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5373 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5374 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5376 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5382 if (Iter != CoroutineParameterMappings.end()) {
5383 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5384 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5385 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5387 if (Iter2 != ParamDbgMappings.end())
5388 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5394 D = RemapCoroArgToLocalVar();
5397 D = DBuilder.createAutoVariable(
5398 Scope, Name, Unit,
Line, Ty,
5399 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5402 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5403 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5404 Column, Scope, CurInlinedAt),
5405 Builder.GetInsertBlock());
5410llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5411 llvm::Value *Storage,
5412 std::optional<unsigned> ArgNo,
5414 const bool UsePointerValue) {
5415 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5416 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5417 if (BD->
hasAttr<NoDebugAttr>())
5424 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5425 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5433 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5435 SmallVector<uint64_t, 3> Expr;
5436 AppendAddressSpaceXDeref(AddressSpace, Expr);
5441 if (UsePointerValue) {
5442 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5443 "Debug info already contains DW_OP_deref.");
5444 Expr.push_back(llvm::dwarf::DW_OP_deref);
5449 StringRef Name = BD->
getName();
5452 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5453 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5454 llvm::DINode::FlagZero, Align);
5456 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5457 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5458 const unsigned fieldIndex = FD->getFieldIndex();
5459 const clang::CXXRecordDecl *parent =
5460 (
const CXXRecordDecl *)FD->getParent();
5461 const ASTRecordLayout &layout =
5462 CGM.getContext().getASTRecordLayout(parent);
5464 if (FD->isBitField()) {
5465 const CGRecordLayout &RL =
5466 CGM.getTypes().getCGRecordLayout(FD->getParent());
5471 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5477 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5478 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5479 Expr.push_back(Info.
Offset);
5482 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5483 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5484 }
else if (fieldOffset != 0) {
5485 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5486 "Unexpected non-bitfield with non-byte-aligned offset");
5487 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5489 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5492 }
else if (
const ArraySubscriptExpr *ASE =
5493 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5494 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5495 const uint64_t value = IL->getValue().getZExtValue();
5496 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5499 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5500 Expr.push_back(CGM.getContext()
5501 .toCharUnitsFromBits(value * typeSize)
5508 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5509 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5510 Column, Scope, CurInlinedAt),
5511 Builder.GetInsertBlock());
5516llvm::DILocalVariable *
5519 const bool UsePointerValue) {
5520 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5522 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5524 EmitDeclare(B, Storage, std::nullopt, Builder,
5531 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5535 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5536 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5538 if (D->
hasAttr<NoDebugAttr>())
5542 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5548 StringRef Name = D->
getName();
5554 CGM.getCodeGenOpts().OptimizationLevel != 0);
5557 DBuilder.insertLabel(L,
5558 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5559 Scope, CurInlinedAt),
5560 Builder.GetInsertBlock()->end());
5563llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5565 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5568 return DBuilder.createObjectPointerType(Ty,
true);
5573 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5574 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5575 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5577 if (Builder.GetInsertBlock() ==
nullptr)
5579 if (VD->
hasAttr<NoDebugAttr>())
5582 bool isByRef = VD->
hasAttr<BlocksAttr>();
5584 uint64_t XOffset = 0;
5585 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5588 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5590 Ty = getOrCreateType(VD->
getType(), Unit);
5594 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5596 Ty = CreateSelfType(VD->
getType(), Ty);
5599 const unsigned Line =
5603 const llvm::DataLayout &target = CGM.getDataLayout();
5610 addr.push_back(llvm::dwarf::DW_OP_deref);
5611 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5614 addr.push_back(llvm::dwarf::DW_OP_deref);
5615 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5618 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5620 addr.push_back(llvm::dwarf::DW_OP_deref);
5621 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5623 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5629 auto *D = DBuilder.createAutoVariable(
5631 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5634 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5635 LexicalBlockStack.back(), CurInlinedAt);
5636 auto *
Expr = DBuilder.createExpression(addr);
5638 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5640 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5643llvm::DILocalVariable *
5646 bool UsePointerValue) {
5647 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5648 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5652struct BlockLayoutChunk {
5653 uint64_t OffsetInBits;
5656bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5657 return l.OffsetInBits < r.OffsetInBits;
5661void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5663 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5664 SmallVectorImpl<llvm::Metadata *> &Fields) {
5668 if (CGM.getLangOpts().OpenCL) {
5669 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5670 BlockLayout.getElementOffsetInBits(0),
5672 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5673 BlockLayout.getElementOffsetInBits(1),
5677 BlockLayout.getElementOffsetInBits(0),
5679 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5680 BlockLayout.getElementOffsetInBits(1),
5684 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5685 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5686 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5687 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5688 BlockLayout.getElementOffsetInBits(3),
5690 Fields.push_back(createFieldType(
5695 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5702 llvm::AllocaInst *Alloca,
5704 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5710 llvm::DIFile *tunit = getOrCreateFile(loc);
5711 unsigned line = getLineNumber(loc);
5712 unsigned column = getColumnNumber(loc);
5717 const llvm::StructLayout *blockLayout =
5721 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5730 BlockLayoutChunk chunk;
5731 chunk.OffsetInBits =
5732 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5733 chunk.Capture =
nullptr;
5734 chunks.push_back(chunk);
5738 for (
const auto &capture :
blockDecl->captures()) {
5739 const VarDecl *variable = capture.getVariable();
5746 BlockLayoutChunk chunk;
5747 chunk.OffsetInBits =
5748 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5749 chunk.Capture = &capture;
5750 chunks.push_back(chunk);
5754 llvm::array_pod_sort(chunks.begin(), chunks.end());
5756 for (
const BlockLayoutChunk &Chunk : chunks) {
5757 uint64_t offsetInBits = Chunk.OffsetInBits;
5764 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5766 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5767 type = CGM.getContext().getCanonicalTagType(RDecl);
5769 llvm_unreachable(
"unexpected block declcontext");
5771 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5772 offsetInBits, tunit, tunit));
5777 StringRef name = variable->
getName();
5779 llvm::DIType *fieldType;
5781 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5786 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5787 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5788 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5789 PtrInfo.
Width, Align, offsetInBits,
5790 llvm::DINode::FlagZero, fieldType);
5794 offsetInBits, Align, tunit, tunit);
5796 fields.push_back(fieldType);
5800 llvm::raw_svector_ostream(typeName)
5801 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5803 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5805 llvm::DIType *
type =
5806 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5807 CGM.getContext().toBits(block.
BlockSize), 0,
5808 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5809 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5812 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5816 auto *debugVar = DBuilder.createParameterVariable(
5817 scope, Name, ArgNo, tunit, line,
type,
5818 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5821 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5822 llvm::DILocation::get(CGM.getLLVMContext(), line,
5823 column, scope, CurInlinedAt),
5824 Builder.GetInsertBlock());
5827llvm::DIDerivedType *
5828CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5833 if (MI != StaticDataMemberCache.end()) {
5834 assert(MI->second &&
"Static data member declaration should still exist");
5845llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5846 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5847 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5848 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5850 for (
const auto *Field : RD->
fields()) {
5851 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5852 StringRef FieldName = Field->getName();
5855 if (FieldName.empty()) {
5856 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5857 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5858 LineNo, LinkageName, Var, DContext);
5862 GVE = DBuilder.createGlobalVariableExpression(
5863 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5864 Var->hasLocalLinkage());
5865 Var->addDebugInfo(GVE);
5877 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5882 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5893 struct ReferencesAnonymous
5895 bool RefAnon =
false;
5896 bool VisitRecordType(RecordType *RT) {
5904 ReferencesAnonymous RT;
5917struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5918 bool Reconstitutable =
true;
5919 bool VisitVectorType(VectorType *FT) {
5920 Reconstitutable =
false;
5923 bool VisitAtomicType(AtomicType *FT) {
5924 Reconstitutable =
false;
5927 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5930 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5931 if (!ED->getIdentifier()) {
5932 Reconstitutable =
false;
5935 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5936 Reconstitutable =
false;
5942 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5946 return Reconstitutable;
5948 bool VisitRecordType(RecordType *RT,
bool =
false) {
5950 Reconstitutable =
false;
5960 ReconstitutableType T;
5962 return T.Reconstitutable;
5965bool CGDebugInfo::HasReconstitutableArgs(
5966 ArrayRef<TemplateArgument> Args)
const {
5967 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6007 llvm_unreachable(
"Other, unresolved, template arguments should "
6008 "not be seen here");
6013std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6014 bool *NameIsSimplified)
const {
6016 llvm::raw_string_ostream
OS(Name);
6017 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6020 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6021 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6023 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6024 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6026 std::optional<TemplateArgs> Args;
6028 bool IsOperatorOverload =
false;
6029 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6030 Args = GetTemplateArgs(RD);
6031 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6032 Args = GetTemplateArgs(FD);
6034 IsOperatorOverload |=
6037 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6038 Args = GetTemplateArgs(VD);
6062 bool Reconstitutable =
6063 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6065 PrintingPolicy PP = getPrintingPolicy();
6067 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6072 if (NameIsSimplified)
6073 *NameIsSimplified =
true;
6074 bool Mangled = TemplateNamesKind ==
6075 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6081 std::string EncodedOriginalName;
6082 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6087 printTemplateArgumentList(OS, Args->Args, PP);
6088 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6090 std::string CanonicalOriginalName;
6091 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6093 assert(EncodedOriginalName == CanonicalOriginalName);
6102 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6103 if (D->
hasAttr<NoDebugAttr>())
6106 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6107 return GetName(D,
true);
6113 if (Cached != DeclCache.end())
6114 return Var->addDebugInfo(
6118 llvm::DIFile *Unit =
nullptr;
6119 llvm::DIScope *DContext =
nullptr;
6121 StringRef DeclName, LinkageName;
6123 llvm::MDTuple *TemplateParameters =
nullptr;
6124 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6125 TemplateParameters, DContext);
6129 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6134 if (T->isUnionType() && DeclName.empty()) {
6135 const auto *RD = T->castAsRecordDecl();
6137 "unnamed non-anonymous struct or union?");
6138 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6143 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6144 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6145 if (D->
hasAttr<CUDASharedAttr>())
6148 else if (D->
hasAttr<CUDAConstantAttr>())
6152 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6154 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6155 GVE = DBuilder.createGlobalVariableExpression(
6156 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6157 Var->hasLocalLinkage(),
true,
6158 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6159 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6160 Align, Annotations);
6161 Var->addDebugInfo(GVE);
6167 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6168 if (VD->
hasAttr<NoDebugAttr>())
6170 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6171 return GetName(VD,
true);
6176 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6177 StringRef Name = VD->
getName();
6178 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6180 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6182 if (CGM.getCodeGenOpts().EmitCodeView) {
6193 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6194 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6195 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6205 auto *VarD = dyn_cast<VarDecl>(VD);
6206 if (VarD && VarD->isStaticDataMember()) {
6208 getDeclContextDescriptor(VarD);
6213 RetainedTypes.push_back(
6214 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6218 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6220 auto &GV = DeclCache[VD];
6224 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6225 llvm::MDTuple *TemplateParameters =
nullptr;
6229 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6230 TemplateParameters = parameterNodes.get();
6233 GV.reset(DBuilder.createGlobalVariableExpression(
6234 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6235 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6236 TemplateParameters, Align));
6241 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6242 if (D->
hasAttr<NoDebugAttr>())
6246 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6247 StringRef Name = D->
getName();
6248 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6250 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6251 llvm::DIGlobalVariableExpression *GVE =
6252 DBuilder.createGlobalVariableExpression(
6253 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6254 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6255 Var->addDebugInfo(GVE);
6262 if (CGM.getCodeGenOpts().getDebugInfo() <=
6263 llvm::codegenoptions::DebugLineTablesOnly)
6266 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6270 llvm::DIFile *Unit = DIL->getFile();
6271 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6276 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6277 llvm::Value *Var = Load->getPointerOperand();
6282 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6283 return DbgDeclare->getVariable()->getType() ==
Type;
6285 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6289 llvm::DILocalVariable *D =
6290 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6291 Type,
false, llvm::DINode::FlagArtificial);
6293 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6294 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6304 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6308 if (D->
hasAttr<NoDebugAttr>())
6311 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6326 if (!(DI = getDeclarationOrDefinition(
6327 AliaseeDecl.getCanonicalDecl().getDecl())))
6330 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6333 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6334 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6348 llvm::DIFile *
File = getOrCreateFile(Loc);
6349 llvm::DIGlobalVariableExpression *Debug =
6350 DBuilder.createGlobalVariableExpression(
6351 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6352 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6353 GV->addDebugInfo(Debug);
6356llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6357 if (!LexicalBlockStack.empty())
6358 return LexicalBlockStack.back();
6359 llvm::DIScope *Mod = getParentModuleOrNull(D);
6360 return getContextDescriptor(D, Mod ? Mod : TheCU);
6364 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6368 CGM.getCodeGenOpts().DebugExplicitImport) {
6372 DBuilder.createImportedModule(
6374 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6379 if (llvm::DINode *
Target =
6382 DBuilder.createImportedDeclaration(
6384 getOrCreateFile(Loc), getLineNumber(Loc));
6389 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6392 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6394 for (
const auto *USD : UD.
shadows()) {
6399 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6400 if (
const auto *AT = FD->getType()
6403 if (AT->getDeducedType().isNull())
6414 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6417 "We shouldn't be codegening an invalid UsingEnumDecl"
6418 " containing no decls");
6420 for (
const auto *USD : UD.
shadows())
6425 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6427 if (
Module *M = ID.getImportedModule()) {
6429 auto Loc = ID.getLocation();
6430 DBuilder.createImportedDeclaration(
6431 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6432 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6433 getLineNumber(Loc));
6437llvm::DIImportedEntity *
6439 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6441 auto &VH = NamespaceAliasCache[&NA];
6444 llvm::DIImportedEntity *R;
6446 if (
const auto *Underlying =
6449 R = DBuilder.createImportedDeclaration(
6452 getLineNumber(Loc), NA.
getName());
6454 R = DBuilder.createImportedDeclaration(
6457 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6463CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6467 auto I = NamespaceCache.find(NSDecl);
6468 if (I != NamespaceCache.end())
6471 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6473 llvm::DINamespace *NS =
6474 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6475 NamespaceCache[NSDecl].reset(NS);
6480 assert(TheCU &&
"no main compile unit");
6481 TheCU->setDWOId(Signature);
6487 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6488 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6490 ? CreateTypeDefinition(E.Type, E.Unit)
6492 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6496 for (
const auto &P : ObjCMethodCache) {
6497 if (P.second.empty())
6500 QualType QTy(P.first->getTypeForDecl(), 0);
6502 assert(It != TypeCache.end());
6504 llvm::DICompositeType *InterfaceDecl =
6507 auto CurElts = InterfaceDecl->getElements();
6511 for (
auto &SubprogramDirect : P.second)
6512 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6513 EltTys.push_back(SubprogramDirect.getPointer());
6515 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6516 DBuilder.replaceArrays(InterfaceDecl, Elements);
6519 for (
const auto &P : ReplaceMap) {
6522 assert(Ty->isForwardDecl());
6524 auto It = TypeCache.find(P.first);
6525 assert(It != TypeCache.end());
6528 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6532 for (
const auto &P : FwdDeclReplaceMap) {
6535 llvm::Metadata *Repl;
6537 auto It = DeclCache.find(P.first);
6541 if (It == DeclCache.end())
6546 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6547 Repl = GVE->getVariable();
6553 for (
auto &RT : RetainedTypes)
6554 if (
auto MD = TypeCache[RT])
6557 DBuilder.finalize();
6562 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6563 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6564 DBuilder.retainType(DieTy);
6568 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6569 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6570 DBuilder.retainType(DieTy);
6574 if (LexicalBlockStack.empty())
6575 return llvm::DebugLoc();
6577 llvm::MDNode *
Scope = LexicalBlockStack.back();
6578 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6579 getColumnNumber(Loc),
Scope);
6585 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6586 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6587 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6588 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6589 return llvm::DINode::FlagZero;
6594 bool SupportsDWARFv4Ext =
6595 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6596 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6597 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6599 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6600 return llvm::DINode::FlagZero;
6602 return llvm::DINode::FlagAllCallsDescribed;
6613 return DBuilder.createConstantValueExpression(
6614 Val.
getFloat().bitcastToAPInt().getZExtValue());
6619 llvm::APSInt
const &ValInt = Val.
getInt();
6620 std::optional<uint64_t> ValIntOpt;
6621 if (ValInt.isUnsigned())
6622 ValIntOpt = ValInt.tryZExtValue();
6623 else if (
auto tmp = ValInt.trySExtValue())
6626 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6629 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6634CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6636 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6637 CGF.CurLexicalScope =
this;
6639 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6644 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6657#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6659 Label = "__ubsan_check_" #Name; \
6663#undef SANITIZER_CHECK
6674#define SANITIZER(NAME, ID) \
6675 case SanitizerKind::SO_##ID: \
6676 Label = "__ubsan_check_" NAME; \
6678#include "clang/Basic/Sanitizers.def"
6680 llvm_unreachable(
"unexpected sanitizer kind");
6685 for (
unsigned int i = 0; i < Label.length(); i++)
6686 if (!std::isalpha(Label[i]))
6695 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6697 if (!DI || !CheckDebugLoc)
6698 return CheckDebugLoc;
6699 const auto &AnnotateDebugInfo =
6700 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6701 if (AnnotateDebugInfo.empty())
6702 return CheckDebugLoc;
6705 if (Ordinals.size() == 1)
6710 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6711 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6713 return CheckDebugLoc;
6721 assert(!CGF->IsSanitizerScope);
6722 CGF->IsSanitizerScope =
true;
6726 assert(CGF->IsSanitizerScope);
6727 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to the current atom group, created using ApplyA...
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file.
void completeFunction()
Reset internal state.
void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl)
Emit information about global variable alias.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)
Emit call to llvm.dbg.label for an label.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
void EmitUsingShadowDecl(const UsingShadowDecl &USD)
Emit a shadow decl brought in by a using or using-enum.
void EmitUsingEnumDecl(const UsingEnumDecl &UD)
Emit C++ using-enum declaration.
void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)
Constructs the debug code for exiting a function.
void EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an include directive.
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about an external variable.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
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::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void removeObjCLifetime()
void removeAddressSpace()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
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.