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#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1109 case BuiltinType::Id: { \
1112 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1113 return SingletonId; \
1115#include "clang/Basic/AMDGPUTypes.def"
1116 case BuiltinType::UChar:
1117 case BuiltinType::Char_U:
1118 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1120 case BuiltinType::Char_S:
1121 case BuiltinType::SChar:
1122 Encoding = llvm::dwarf::DW_ATE_signed_char;
1124 case BuiltinType::Char8:
1125 case BuiltinType::Char16:
1126 case BuiltinType::Char32:
1127 Encoding = llvm::dwarf::DW_ATE_UTF;
1129 case BuiltinType::UShort:
1130 case BuiltinType::UInt:
1131 case BuiltinType::UInt128:
1132 case BuiltinType::ULong:
1133 case BuiltinType::WChar_U:
1134 case BuiltinType::ULongLong:
1135 Encoding = llvm::dwarf::DW_ATE_unsigned;
1137 case BuiltinType::Short:
1138 case BuiltinType::Int:
1139 case BuiltinType::Int128:
1140 case BuiltinType::Long:
1141 case BuiltinType::WChar_S:
1142 case BuiltinType::LongLong:
1143 Encoding = llvm::dwarf::DW_ATE_signed;
1145 case BuiltinType::Bool:
1146 Encoding = llvm::dwarf::DW_ATE_boolean;
1148 case BuiltinType::Half:
1149 case BuiltinType::Float:
1150 case BuiltinType::LongDouble:
1151 case BuiltinType::Float16:
1152 case BuiltinType::BFloat16:
1153 case BuiltinType::Float128:
1154 case BuiltinType::Double:
1155 case BuiltinType::Ibm128:
1161 Encoding = llvm::dwarf::DW_ATE_float;
1163 case BuiltinType::ShortAccum:
1164 case BuiltinType::Accum:
1165 case BuiltinType::LongAccum:
1166 case BuiltinType::ShortFract:
1167 case BuiltinType::Fract:
1168 case BuiltinType::LongFract:
1169 case BuiltinType::SatShortFract:
1170 case BuiltinType::SatFract:
1171 case BuiltinType::SatLongFract:
1172 case BuiltinType::SatShortAccum:
1173 case BuiltinType::SatAccum:
1174 case BuiltinType::SatLongAccum:
1175 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1177 case BuiltinType::UShortAccum:
1178 case BuiltinType::UAccum:
1179 case BuiltinType::ULongAccum:
1180 case BuiltinType::UShortFract:
1181 case BuiltinType::UFract:
1182 case BuiltinType::ULongFract:
1183 case BuiltinType::SatUShortAccum:
1184 case BuiltinType::SatUAccum:
1185 case BuiltinType::SatULongAccum:
1186 case BuiltinType::SatUShortFract:
1187 case BuiltinType::SatUFract:
1188 case BuiltinType::SatULongFract:
1189 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1193 BTName = BT->
getName(CGM.getLangOpts());
1196 return DBuilder.createBasicType(BTName, Size, Encoding);
1199llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1200 SmallString<32> Name;
1201 llvm::raw_svector_ostream
OS(Name);
1202 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1205 ? llvm::dwarf::DW_ATE_unsigned
1206 : llvm::dwarf::DW_ATE_signed;
1207 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1208 Encoding, llvm::DINode::FlagZero, 0,
1212llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1214 return getOrCreateType(Ty->getUnderlyingType(), U);
1217llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1219 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1221 Encoding = llvm::dwarf::DW_ATE_lo_user;
1224 return DBuilder.createBasicType(
"complex", Size, Encoding);
1238 return llvm::dwarf::DW_TAG_const_type;
1242 return llvm::dwarf::DW_TAG_volatile_type;
1246 return llvm::dwarf::DW_TAG_restrict_type;
1248 return (llvm::dwarf::Tag)0;
1251llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1252 llvm::DIFile *Unit) {
1253 QualifierCollector Qc;
1267 bool AuthenticatesNullValues =
1270 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1271 llvm::DIType *FromTy = getOrCreateType(QualType(T, 0), Unit);
1272 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1273 ExtraDiscr, IsaPointer,
1274 AuthenticatesNullValues);
1276 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1277 return getOrCreateType(QualType(T, 0), Unit);
1281 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
1285 return DBuilder.createQualifiedType(Tag, FromTy);
1288llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1289 llvm::DIFile *Unit) {
1298 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1303 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1309 return DBuilder.createQualifiedType(Tag, FromTy);
1312llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1313 llvm::DIFile *Unit) {
1319 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1321 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1325llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1326 llvm::DIFile *Unit) {
1327 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1333 case llvm::dwarf::DW_LANG_C_plus_plus:
1334 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1335 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1336 case llvm::dwarf::DW_LANG_HIP:
1338 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1348 case llvm::dwarf::DW_LNAME_C_plus_plus:
1349 case llvm::dwarf::DW_LNAME_HIP:
1351 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1362 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1363 SourceLang.hasVersionedName())
1365 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1369 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1395 llvm::DICompileUnit *TheCU) {
1413 llvm::DICompileUnit *TheCU) {
1419 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1421 if (RD->isDynamicClass() &&
1427 llvm::raw_svector_ostream Out(Identifier);
1434 llvm::dwarf::Tag Tag;
1436 Tag = llvm::dwarf::DW_TAG_structure_type;
1438 Tag = llvm::dwarf::DW_TAG_union_type;
1443 Tag = llvm::dwarf::DW_TAG_class_type;
1448llvm::DICompositeType *
1449CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1450 llvm::DIScope *Ctx) {
1451 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1452 if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
1454 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1455 const unsigned Line =
1457 StringRef RDName = getClassName(RD);
1464 Size = CGM.getContext().getTypeSize(Ty);
1466 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1471 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1472 if (!CXXRD->hasDefinition() ||
1473 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1474 Flags |= llvm::DINode::FlagNonTrivial;
1477 SmallString<256> Identifier;
1479 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1481 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1484 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1485 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1486 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1487 CollectCXXTemplateParams(TSpecial, DefUnit));
1488 ReplaceMap.emplace_back(
1489 std::piecewise_construct, std::make_tuple(Ty),
1490 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1494llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1497 llvm::DIFile *Unit) {
1502 std::optional<unsigned> DWARFAddressSpace =
1503 CGM.getTarget().getDWARFAddressSpace(
1504 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1506 const BTFTagAttributedType *BTFAttrTy;
1507 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1508 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1510 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1511 SmallVector<llvm::Metadata *, 4> Annots;
1513 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1515 llvm::Metadata *Ops[2] = {
1516 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1517 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1518 Annots.insert(Annots.begin(),
1519 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1521 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1524 llvm::DINodeArray Annotations =
nullptr;
1525 if (Annots.size() > 0)
1526 Annotations = DBuilder.getOrCreateArray(Annots);
1528 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1529 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1530 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1531 Size, Align, DWARFAddressSpace);
1533 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1534 Align, DWARFAddressSpace, StringRef(),
1538llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1539 llvm::DIType *&
Cache) {
1542 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1543 TheCU, TheCU->getFile(), 0);
1544 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1545 Cache = DBuilder.createPointerType(
Cache, Size);
1549uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1550 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1551 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1561 if (CGM.getLangOpts().OpenCL) {
1562 FType = CGM.getContext().IntTy;
1563 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1564 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1566 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1567 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1568 FType = CGM.getContext().IntTy;
1569 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1570 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1572 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1573 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1574 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1575 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1576 EltTys.push_back(DBuilder.createMemberType(
1577 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1578 FieldOffset, llvm::DINode::FlagZero, DescTy));
1579 FieldOffset += FieldSize;
1585llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1586 llvm::DIFile *Unit) {
1587 SmallVector<llvm::Metadata *, 8> EltTys;
1590 llvm::DINodeArray Elements;
1593 FType = CGM.getContext().UnsignedLongTy;
1594 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1595 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1597 Elements = DBuilder.getOrCreateArray(EltTys);
1600 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1603 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1604 FieldOffset, 0, Flags,
nullptr, Elements);
1609 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1611 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1614 Elements = DBuilder.getOrCreateArray(EltTys);
1620 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1621 Flags,
nullptr, Elements);
1623 return DBuilder.createPointerType(EltTy, Size);
1626static llvm::SmallVector<TemplateArgument>
1628 assert(Ty->isTypeAlias());
1637 ArrayRef SubstArgs = Ty->template_arguments();
1640 if (Param->isParameterPack()) {
1649 if (SubstArgs.empty()) {
1658 SpecArgs.push_back(SubstArgs.front());
1659 SubstArgs = SubstArgs.drop_front();
1664llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1665 llvm::DIFile *Unit) {
1666 assert(Ty->isTypeAlias());
1667 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1669 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1677 SmallString<128> NS;
1678 llvm::raw_svector_ostream
OS(NS);
1680 auto PP = getPrintingPolicy();
1683 SourceLocation Loc =
AliasDecl->getLocation();
1685 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1686 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1695 llvm::raw_string_ostream
OS(Name);
1697 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1698 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1699 !HasReconstitutableArgs(Args.Args))
1700 printTemplateArgumentList(OS, Args.Args, PP);
1702 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1703 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1704 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1708 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1710 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1727 return llvm::DINode::FlagZero;
1731 return llvm::DINode::FlagPrivate;
1733 return llvm::DINode::FlagProtected;
1735 return llvm::DINode::FlagPublic;
1737 return llvm::DINode::FlagZero;
1739 llvm_unreachable(
"unexpected access enumerator");
1742llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1743 llvm::DIFile *Unit) {
1744 llvm::DIType *Underlying =
1756 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1758 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1763 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1764 getOrCreateFile(Loc), getLineNumber(Loc),
1765 getDeclContextDescriptor(Ty->
getDecl()), Align,
1766 Flags, Annotations);
1776 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1778 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1780 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1782 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1784 return llvm::dwarf::DW_CC_BORLAND_pascal;
1786 return llvm::dwarf::DW_CC_LLVM_Win64;
1788 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1792 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1794 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1796 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1798 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1800 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1802 return llvm::dwarf::DW_CC_LLVM_Swift;
1804 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1806 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1808 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1810 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1812 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1814 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1816 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1817#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1831 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1837 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1839 Flags |= llvm::DINode::FlagLValueReference;
1841 Flags |= llvm::DINode::FlagRValueReference;
1845llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1846 llvm::DIFile *Unit) {
1847 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1849 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1855 SmallVector<llvm::Metadata *, 16> EltTys;
1858 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1860 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1864 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1867 for (
const QualType &ParamType : FPT->param_types())
1868 EltTys.push_back(getOrCreateType(ParamType, Unit));
1869 if (FPT->isVariadic())
1870 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1873 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1874 llvm::DIType *F = DBuilder.createSubroutineType(
1879llvm::DIDerivedType *
1880CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1881 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1882 StringRef Name = BitFieldDecl->
getName();
1883 QualType Ty = BitFieldDecl->
getType();
1884 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1887 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1888 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1891 llvm::DIFile *
File = getOrCreateFile(Loc);
1892 unsigned Line = getLineNumber(Loc);
1894 const CGBitFieldInfo &BitFieldInfo =
1895 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1897 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1904 if (CGM.getDataLayout().isBigEndian())
1906 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1908 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1909 return DBuilder.createBitFieldMemberType(
1910 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1911 Flags, DebugType, Annotations);
1914llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1915 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1916 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1918 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1943 if (PreviousFieldsDI.empty())
1947 auto *PreviousMDEntry =
1948 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1949 auto *PreviousMDField =
1950 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1951 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1952 PreviousMDField->getSizeInBits() == 0)
1956 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1958 assert(PreviousBitfield->isBitField());
1960 if (!PreviousBitfield->isZeroLengthBitField())
1963 QualType Ty = PreviousBitfield->getType();
1964 SourceLocation Loc = PreviousBitfield->getLocation();
1965 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1966 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1967 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1969 llvm::DIFile *
File = getOrCreateFile(Loc);
1970 unsigned Line = getLineNumber(Loc);
1976 llvm::DINode::DIFlags Flags =
1978 llvm::DINodeArray Annotations =
1979 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1980 return DBuilder.createBitFieldMemberType(
1981 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1982 Flags, DebugType, Annotations);
1985llvm::DIType *CGDebugInfo::createFieldType(
1987 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1988 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1989 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1992 llvm::DIFile *file = getOrCreateFile(loc);
1993 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1996 auto Align = AlignInBits;
1997 if (!
type->isIncompleteArrayType()) {
1998 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1999 SizeInBits = TI.
Width;
2005 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2006 offsetInBits, flags, debugType, Annotations);
2010CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2011 llvm::DIFile *FileScope) {
2015 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2018 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2019 SP = DBuilder.createFunction(
2020 FileScope, FuncName, StringRef(),
2021 FileScope, 0, DIFnTy,
2023 llvm::DINode::FlagArtificial,
2024 llvm::DISubprogram::SPFlagDefinition,
2025 nullptr,
nullptr,
nullptr,
2026 nullptr, StringRef(),
2027 CGM.getCodeGenOpts().DebugKeyInstructions);
2034CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2036 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2038 assert(
Capture.capturesVariable());
2040 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2041 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2043 return CaptureDecl->
getName();
2046void CGDebugInfo::CollectRecordLambdaFields(
2047 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2048 llvm::DIType *RecordTy) {
2053 unsigned fieldno = 0;
2056 I != E; ++I, ++Field, ++fieldno) {
2057 const LambdaCapture &
Capture = *I;
2059 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2061 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2071 Loc =
Field->getLocation();
2072 }
else if (
Capture.capturesVariable()) {
2075 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2076 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2083 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2085 elements.push_back(createFieldType(
2087 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2093template <
typename T>
2094static llvm::Constant *
2105 return llvm::ConstantDataArray::get(Ctx, Vals);
2118 const QualType ElemQTy = ArrayTy->getElementType();
2125 switch (ElemBitWidth) {
2141llvm::DIDerivedType *
2142CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2143 const RecordDecl *RD) {
2147 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2148 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2150 unsigned LineNumber = getLineNumber(Var->
getLocation());
2151 StringRef VName = Var->
getName();
2155 llvm::Constant *
C =
nullptr;
2160 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2161 if (
Value->isFloat())
2162 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2163 if (
Value->isArray())
2169 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2170 ? llvm::dwarf::DW_TAG_variable
2171 : llvm::dwarf::DW_TAG_member;
2173 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2174 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2179void CGDebugInfo::CollectRecordNormalField(
2180 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2181 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2182 const RecordDecl *RD) {
2187 if (
name.empty() && !
type->isRecordType())
2190 llvm::DIType *FieldType;
2192 llvm::DIDerivedType *BitFieldType;
2193 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2194 if (llvm::DIType *Separator =
2195 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2196 elements.push_back(Separator);
2199 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2202 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2205 elements.push_back(FieldType);
2208void CGDebugInfo::CollectRecordNestedType(
2209 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2210 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2217 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2218 elements.push_back(nestedType);
2221void CGDebugInfo::CollectRecordFields(
2222 const RecordDecl *record, llvm::DIFile *tunit,
2223 SmallVectorImpl<llvm::Metadata *> &elements,
2224 llvm::DICompositeType *RecordTy) {
2225 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2227 if (CXXDecl && CXXDecl->
isLambda())
2228 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2230 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2233 unsigned fieldNo = 0;
2237 for (
const auto *I : record->
decls())
2238 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2239 if (
V->hasAttr<NoDebugAttr>())
2244 if (CGM.getCodeGenOpts().EmitCodeView &&
2252 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2253 if (MI != StaticDataMemberCache.end()) {
2254 assert(MI->second &&
2255 "Static data member declaration should still exist");
2256 elements.push_back(MI->second);
2258 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2259 elements.push_back(Field);
2261 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2262 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2263 elements, RecordTy, record);
2267 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2270 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2275 if (!nestedType->isImplicit() &&
2276 nestedType->getDeclContext() == record)
2277 CollectRecordNestedType(nestedType, elements);
2283llvm::DISubroutineType *
2284CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2285 llvm::DIFile *Unit) {
2286 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2288 return cast_or_null<llvm::DISubroutineType>(
2289 getOrCreateType(QualType(
Func, 0), Unit));
2292 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2293 ThisType =
Method->getThisType();
2295 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2298llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2299 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2300 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2302 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2305llvm::DISubroutineType *
2306CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2307 const FunctionProtoType *
Func,
2308 llvm::DIFile *Unit,
bool SkipFirst) {
2309 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2324 getOrCreateType(CGM.getContext().getFunctionType(
2325 Func->getReturnType(),
Func->getParamTypes(), EPI),
2327 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2328 assert(Args.size() &&
"Invalid number of arguments!");
2330 SmallVector<llvm::Metadata *, 16> Elts;
2333 Elts.push_back(Args[0]);
2335 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2339 if (!HasExplicitObjectParameter) {
2340 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2343 DBuilder.createObjectPointerType(ThisPtrType,
true);
2344 Elts.push_back(ThisPtrType);
2348 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2349 Elts.push_back(Args[i]);
2352 if (HasExplicitObjectParameter) {
2353 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2354 "Expected at least return type and object parameter.");
2355 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2358 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2360 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2367 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2375CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2378 const bool IsCtorOrDtor =
2381 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2388 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2391 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2394 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2397 return CGM.getMangledName(
Method);
2400bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2403 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2406llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2407 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2410 StringRef MethodName = getFunctionName(
Method);
2411 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2413 StringRef MethodLinkageName;
2420 MethodLinkageName = GetMethodLinkageName(
Method);
2423 llvm::DIFile *MethodDefUnit =
nullptr;
2424 unsigned MethodLine = 0;
2425 if (!
Method->isImplicit()) {
2426 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2427 MethodLine = getLineNumber(
Method->getLocation());
2431 llvm::DIType *ContainingType =
nullptr;
2432 unsigned VIndex = 0;
2433 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2434 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2435 int ThisAdjustment = 0;
2438 if (
Method->isPureVirtual())
2439 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2441 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2443 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2447 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2451 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2454 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2455 CGM.getContext().getLangOpts())
2459 MethodVFTableLocation ML =
2460 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2468 if (
Method->size_overridden_methods() == 0)
2469 Flags |= llvm::DINode::FlagIntroducedVirtual;
2474 ThisAdjustment = CGM.getCXXABI()
2475 .getVirtualFunctionPrologueThisAdjustment(GD)
2478 ContainingType = RecordTy;
2481 if (
Method->getCanonicalDecl()->isDeleted())
2482 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2484 if (
Method->isNoReturn())
2485 Flags |= llvm::DINode::FlagNoReturn;
2488 Flags |= llvm::DINode::FlagStaticMember;
2489 if (
Method->isImplicit())
2490 Flags |= llvm::DINode::FlagArtificial;
2492 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2493 if (CXXC->isExplicit())
2494 Flags |= llvm::DINode::FlagExplicit;
2495 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2496 if (CXXC->isExplicit())
2497 Flags |= llvm::DINode::FlagExplicit;
2499 if (
Method->hasPrototype())
2500 Flags |= llvm::DINode::FlagPrototyped;
2502 Flags |= llvm::DINode::FlagLValueReference;
2504 Flags |= llvm::DINode::FlagRValueReference;
2505 if (!
Method->isExternallyVisible())
2506 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2507 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2508 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2512 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2513 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2516 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2517 llvm::DISubprogram *SP = DBuilder.createMethod(
2518 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2519 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2520 TParamsArray.get(),
nullptr,
2521 CGM.getCodeGenOpts().DebugKeyInstructions);
2523 SPCache[
Method->getCanonicalDecl()].reset(SP);
2528void CGDebugInfo::CollectCXXMemberFunctions(
2529 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2530 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2535 for (
const auto *I : RD->
decls()) {
2536 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2550 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2559 auto MI = SPCache.find(
Method->getCanonicalDecl());
2560 EltTys.push_back(MI == SPCache.end()
2561 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2562 :
static_cast<llvm::Metadata *
>(MI->second));
2566void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2567 SmallVectorImpl<llvm::Metadata *> &EltTys,
2568 llvm::DIType *RecordTy) {
2569 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2570 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2571 llvm::DINode::FlagZero);
2575 if (CGM.getCodeGenOpts().EmitCodeView) {
2576 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2577 llvm::DINode::FlagIndirectVirtualBase);
2581void CGDebugInfo::CollectCXXBasesAux(
2582 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2583 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2585 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2586 llvm::DINode::DIFlags StartingFlags) {
2587 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2588 for (
const auto &BI : Bases) {
2591 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2593 if (!SeenTypes.insert(Base).second)
2595 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2596 llvm::DINode::DIFlags BFlags = StartingFlags;
2600 if (BI.isVirtual()) {
2601 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2604 BaseOffset = 0 - CGM.getItaniumVTableContext()
2605 .getVirtualBaseOffsetOffset(RD, Base)
2611 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2612 VBPtrOffset = CGM.getContext()
2613 .getASTRecordLayout(RD)
2617 BFlags |= llvm::DINode::FlagVirtual;
2624 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2625 VBPtrOffset, BFlags);
2626 EltTys.push_back(DTy);
2631CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2632 llvm::DIFile *Unit) {
2634 return llvm::DINodeArray();
2635 TemplateArgs &Args = *OArgs;
2636 SmallVector<llvm::Metadata *, 16> TemplateParams;
2637 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2638 const TemplateArgument &TA = Args.Args[i];
2642 Name = Args.TList->getParam(i)->getName();
2646 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2647 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2648 TheCU, Name, TTy, defaultParameter));
2653 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2654 TheCU, Name, TTy, defaultParameter,
2655 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2660 llvm::DIType *TTy = getOrCreateType(T, Unit);
2661 llvm::Constant *
V =
nullptr;
2664 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2665 !D->
hasAttr<CUDADeviceAttr>()) {
2668 if (
const auto *VD = dyn_cast<VarDecl>(D))
2669 V = CGM.GetAddrOfGlobalVar(VD);
2672 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2673 MD && MD->isImplicitObjectMemberFunction())
2674 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2675 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2676 V = CGM.GetAddrOfFunction(FD);
2679 else if (
const auto *MPT =
2680 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2684 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2686 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2687 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2688 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2689 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2690 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2692 V = ConstantEmitter(CGM).emitAbstract(
2693 SourceLocation(), TPO->getValue(), TPO->getType());
2695 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2697 assert(
V &&
"Failed to find template parameter pointer");
2698 V =
V->stripPointerCasts();
2700 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2701 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2705 llvm::DIType *TTy = getOrCreateType(T, Unit);
2706 llvm::Constant *
V =
nullptr;
2709 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2715 if (MPT->isMemberDataPointer())
2716 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2718 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2719 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2720 TheCU, Name, TTy, defaultParameter,
V));
2724 llvm::DIType *TTy = getOrCreateType(T, Unit);
2725 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2727 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2728 TheCU, Name, TTy, defaultParameter,
V));
2731 std::string QualName;
2732 llvm::raw_string_ostream
OS(QualName);
2734 OS, getPrintingPolicy());
2735 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2736 TheCU, Name,
nullptr, QualName, defaultParameter));
2740 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2741 TheCU, Name,
nullptr,
2748 T = CGM.getContext().getLValueReferenceType(T);
2749 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2750 assert(
V &&
"Expression in template argument isn't constant");
2751 llvm::DIType *TTy = getOrCreateType(T, Unit);
2752 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2753 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2759 "These argument types shouldn't exist in concrete types");
2762 return DBuilder.getOrCreateArray(TemplateParams);
2765std::optional<CGDebugInfo::TemplateArgs>
2766CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2774 return std::nullopt;
2776std::optional<CGDebugInfo::TemplateArgs>
2777CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2781 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2783 return std::nullopt;
2784 VarTemplateDecl *T = TS->getSpecializedTemplate();
2786 auto TA = TS->getTemplateArgs().asArray();
2787 return {{TList, TA}};
2789std::optional<CGDebugInfo::TemplateArgs>
2790CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2791 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2795 TemplateParameterList *TPList =
2796 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2797 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2798 return {{TPList, TAList.
asArray()}};
2800 return std::nullopt;
2804CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2805 llvm::DIFile *Unit) {
2806 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2809llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2810 llvm::DIFile *Unit) {
2811 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2814llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2815 llvm::DIFile *Unit) {
2816 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2819llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2820 if (!D->
hasAttr<BTFDeclTagAttr>())
2823 SmallVector<llvm::Metadata *, 4> Annotations;
2825 llvm::Metadata *Ops[2] = {
2826 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2827 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2828 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2830 return DBuilder.getOrCreateArray(Annotations);
2833llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2835 return VTablePtrType;
2837 ASTContext &Context = CGM.getContext();
2840 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2841 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2842 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2844 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2845 std::optional<unsigned> DWARFAddressSpace =
2846 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2848 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2849 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2850 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2851 return VTablePtrType;
2854StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2866 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2868 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2878 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2879 VTable->isDeclarationForLinker())
2883 StringRef SymbolName =
"__clang_vtable";
2885 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2894 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2896 llvm::DIFile *Unit = getOrCreateFile(Loc);
2897 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2899 llvm::DINode::FlagArtificial;
2900 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2901 ? llvm::dwarf::DW_TAG_variable
2902 : llvm::dwarf::DW_TAG_member;
2903 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2904 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2908 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2912 llvm::DIGlobalVariableExpression *GVE =
2913 DBuilder.createGlobalVariableExpression(
2914 TheCU, SymbolName, VTable->getName(), Unit, 0,
2915 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2916 true,
nullptr, DT,
nullptr,
2918 VTable->addDebugInfo(GVE);
2921StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2923 llvm::Function *InitFn) {
2928 return InitFn->getName();
2938 llvm::raw_svector_ostream OS(QualifiedGV);
2940 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2942 std::swap(Quals, GVName);
2946 llvm::raw_svector_ostream OS(InitName);
2948 OS << Quals <<
"::";
2953 llvm_unreachable(
"not an initializer");
2955 OS <<
"`dynamic initializer for '";
2958 OS <<
"`dynamic atexit destructor for '";
2965 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2966 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2967 getPrintingPolicy());
2972 return internString(
OS.str());
2975void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2976 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2985 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2992 llvm::DIType *VPtrTy =
nullptr;
2993 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2994 CGM.getTarget().getCXXABI().isMicrosoft();
2995 if (NeedVTableShape) {
2997 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2998 const VTableLayout &VFTLayout =
2999 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3000 unsigned VSlotCount =
3002 unsigned VTableWidth = PtrWidth * VSlotCount;
3003 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3004 std::optional<unsigned> DWARFAddressSpace =
3005 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3008 llvm::DIType *VTableType = DBuilder.createPointerType(
3009 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3010 EltTys.push_back(VTableType);
3013 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3021 VPtrTy = getOrCreateVTablePtrType(Unit);
3023 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3024 llvm::DIType *VPtrMember =
3025 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3026 llvm::DINode::FlagArtificial, VPtrTy);
3027 EltTys.push_back(VPtrMember);
3032 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3033 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3044 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3045 assert(!D.
isNull() &&
"null type");
3046 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3047 assert(T &&
"could not create debug info for type");
3056 if (CGM.getCodeGenOpts().getDebugInfo() <=
3057 llvm::codegenoptions::DebugLineTablesOnly)
3061 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3063 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3065 CI->setMetadata(
"heapallocsite", node);
3069 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3071 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3073 auto I = TypeCache.find(TyPtr);
3076 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3077 assert(!Res->isForwardDecl());
3078 TypeCache[TyPtr].reset(Res);
3082 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3083 !CGM.getLangOpts().CPlusPlus)
3089 if (RD->
hasAttr<DLLImportAttr>())
3092 if (MD->hasAttr<DLLImportAttr>())
3105 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3115 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3116 Explicit = TD->isExplicitInstantiationOrSpecialization();
3120 if (CXXDecl->
fields().empty())
3130 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3131 if (CXXRD->isDynamicClass() &&
3132 CGM.getVTableLinkage(CXXRD) ==
3133 llvm::GlobalValue::AvailableExternallyLinkage &&
3144 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3146 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3148 auto I = TypeCache.find(TyPtr);
3155 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3156 assert(!Res->isForwardDecl());
3157 TypeCache[TyPtr].reset(Res);
3164 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3165 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3188 if (Ctor->isCopyOrMoveConstructor())
3190 if (!Ctor->isDeleted())
3209 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3212 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3213 RD->
hasAttr<StandaloneDebugAttr>())
3216 if (!LangOpts.CPlusPlus)
3222 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3238 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3239 Spec = SD->getSpecializationKind();
3248 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3259 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3260 llvm::DIType *T = getTypeOrNull(Ty);
3261 if (T && T->isForwardDecl())
3265llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3266 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3267 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3271 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3275 auto [Def, Pref] = CreateTypeDefinition(Ty);
3277 return Pref ? Pref : Def;
3280llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3281 llvm::DIFile *Unit) {
3285 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3289 return getOrCreateType(PNA->getTypedefType(), Unit);
3292std::pair<llvm::DIType *, llvm::DIType *>
3293CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3294 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3297 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3305 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3309 return {FwdDecl,
nullptr};
3311 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3312 CollectContainingType(CXXDecl, FwdDecl);
3315 LexicalBlockStack.emplace_back(&*FwdDecl);
3316 RegionMap[RD].reset(FwdDecl);
3319 SmallVector<llvm::Metadata *, 16> EltTys;
3326 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3328 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3329 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3333 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3334 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3335 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3337 LexicalBlockStack.pop_back();
3338 RegionMap.erase(RD);
3340 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3341 DBuilder.replaceArrays(FwdDecl, Elements);
3343 if (FwdDecl->isTemporary())
3345 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3347 RegionMap[RD].reset(FwdDecl);
3349 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3350 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3351 return {FwdDecl, PrefDI};
3353 return {FwdDecl,
nullptr};
3356llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3357 llvm::DIFile *Unit) {
3359 return getOrCreateType(Ty->getBaseType(), Unit);
3362llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3363 llvm::DIFile *Unit) {
3365 SourceLocation Loc = Ty->getDecl()->getLocation();
3368 return DBuilder.createTypedef(
3369 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3370 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3371 getDeclContextDescriptor(Ty->getDecl()));
3398llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3399 llvm::DIFile *Unit) {
3404 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3405 TheCU->getSourceLanguage().getUnversionedName());
3410 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3411 !
ID->getImplementation())
3412 return DBuilder.createForwardDecl(
3413 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3414 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3417 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3418 unsigned Line = getLineNumber(
ID->getLocation());
3422 ObjCInterfaceDecl *Def =
ID->getDefinition();
3424 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3425 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3426 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3427 DefUnit,
Line, RuntimeLang);
3428 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3432 return CreateTypeDefinition(Ty, Unit);
3435llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3436 bool CreateSkeletonCU) {
3441 auto ModRef = ModuleCache.find(M);
3442 if (ModRef != ModuleCache.end())
3446 SmallString<128> ConfigMacros;
3448 llvm::raw_svector_ostream
OS(ConfigMacros);
3449 const auto &PPOpts = CGM.getPreprocessorOpts();
3452 for (
auto &M : PPOpts.Macros) {
3455 const std::string &
Macro = M.first;
3456 bool Undef = M.second;
3457 OS <<
"\"-" << (Undef ?
'U' :
'D');
3473 bool IsRootModule = M ? !M->
Parent :
true;
3477 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3478 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3479 "clang module without ASTFile must be specified by -fmodule-name");
3482 auto RemapPath = [
this](StringRef Path) -> std::string {
3484 StringRef Relative(Remapped);
3485 StringRef CompDir = TheCU->getDirectory();
3486 if (CompDir.empty())
3489 if (Relative.consume_front(CompDir))
3490 Relative.consume_front(llvm::sys::path::get_separator());
3492 return Relative.str();
3495 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3502 Signature = ModSig.truncatedValue();
3506 llvm::DIBuilder DIB(CGM.getModule());
3508 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3509 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3510 PCM = getCurrentDirname();
3514 llvm::sys::path::append(PCM, Mod.
getASTFile());
3515 DIB.createCompileUnit(
3516 TheCU->getSourceLanguage(),
3519 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3520 llvm::DICompileUnit::FullDebug, Signature);
3524 llvm::DIModule *Parent =
3526 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3528 std::string IncludePath = Mod.
getPath().str();
3529 llvm::DIModule *DIMod =
3530 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3531 RemapPath(IncludePath));
3532 ModuleCache[M].reset(DIMod);
3536llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3537 llvm::DIFile *Unit) {
3539 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3540 unsigned Line = getLineNumber(
ID->getLocation());
3542 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3548 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3549 if (
ID->getImplementation())
3550 Flags |= llvm::DINode::FlagObjcClassComplete;
3552 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3553 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3554 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3555 nullptr, llvm::DINodeArray(), RuntimeLang);
3557 QualType QTy(Ty, 0);
3558 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3561 LexicalBlockStack.emplace_back(RealDecl);
3562 RegionMap[Ty->
getDecl()].reset(RealDecl);
3565 SmallVector<llvm::Metadata *, 16> EltTys;
3567 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3569 llvm::DIType *SClassTy =
3570 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3574 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3575 llvm::DINode::FlagZero);
3576 EltTys.push_back(InhTag);
3580 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3581 SourceLocation Loc = PD->getLocation();
3582 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3583 unsigned PLine = getLineNumber(Loc);
3584 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3585 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3586 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3587 PD->getName(), PUnit, PLine,
3589 : getSelectorName(PD->getGetterName()),
3591 : getSelectorName(PD->getSetterName()),
3592 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3593 EltTys.push_back(PropertyNode);
3598 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3602 llvm::DenseSet<IsClassAndIdent> PropertySet;
3604 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3605 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3607 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3608 for (
auto *PD : ClassExt->properties()) {
3609 PropertySet.insert(GetIsClassAndIdent(PD));
3612 for (
const auto *PD :
ID->properties()) {
3615 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3621 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3622 unsigned FieldNo = 0;
3623 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3624 Field =
Field->getNextIvar(), ++FieldNo) {
3625 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3629 StringRef FieldName =
Field->getName();
3632 if (FieldName.empty())
3636 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3637 unsigned FieldLine = getLineNumber(
Field->getLocation());
3638 QualType FType =
Field->getType();
3645 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3646 : CGM.getContext().getTypeSize(FType);
3651 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3655 if (
Field->isBitField()) {
3657 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3658 FieldOffset %= CGM.getContext().getCharWidth();
3666 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3668 Flags = llvm::DINode::FlagProtected;
3670 Flags = llvm::DINode::FlagPrivate;
3672 Flags = llvm::DINode::FlagPublic;
3674 if (
Field->isBitField())
3675 Flags |= llvm::DINode::FlagBitField;
3677 llvm::MDNode *PropertyNode =
nullptr;
3678 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3679 if (ObjCPropertyImplDecl *PImpD =
3680 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3681 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3682 SourceLocation Loc = PD->getLocation();
3683 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3684 unsigned PLine = getLineNumber(Loc);
3685 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3686 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3687 PropertyNode = DBuilder.createObjCProperty(
3688 PD->getName(), PUnit, PLine,
3691 : getSelectorName(PD->getGetterName()),
3694 : getSelectorName(PD->getSetterName()),
3695 PD->getPropertyAttributes(),
3696 getOrCreateType(PD->getType(), PUnit));
3700 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3701 FieldSize, FieldAlign, FieldOffset, Flags,
3702 FieldTy, PropertyNode);
3703 EltTys.push_back(FieldTy);
3706 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3707 DBuilder.replaceArrays(RealDecl, Elements);
3709 LexicalBlockStack.pop_back();
3713llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3714 llvm::DIFile *Unit) {
3722 auto &Ctx = CGM.getContext();
3727 QualType CharVecTy =
3729 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3732 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3735 llvm::Metadata *Subscript;
3736 QualType QTy(Ty, 0);
3737 auto SizeExpr = SizeExprCache.find(QTy);
3738 if (SizeExpr != SizeExprCache.end())
3739 Subscript = DBuilder.getOrCreateSubrange(
3740 SizeExpr->getSecond() ,
nullptr ,
3741 nullptr ,
nullptr );
3744 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3745 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3746 Subscript = DBuilder.getOrCreateSubrange(
3747 CountNode ,
nullptr ,
nullptr ,
3750 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3755 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3758llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3759 llvm::DIFile *Unit) {
3763 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3768 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3769 auto *ColumnCountNode =
3770 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3771 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3772 auto *RowCountNode =
3773 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3774 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3775 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3776 ColumnCountNode ,
nullptr ,
nullptr ,
3778 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3779 RowCountNode ,
nullptr ,
nullptr ,
3781 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3782 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3785llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3790 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3805 Size = CGM.getContext().getTypeSize(Ty);
3812 SmallVector<llvm::Metadata *, 8> Subscripts;
3813 QualType EltTy(Ty, 0);
3814 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3823 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3824 Count = CAT->getZExtSize();
3825 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3826 if (Expr *Size = VAT->getSizeExpr()) {
3828 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3829 Count =
Result.Val.getInt().getExtValue();
3833 auto SizeNode = SizeExprCache.find(EltTy);
3834 if (SizeNode != SizeExprCache.end())
3835 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3836 SizeNode->getSecond() ,
nullptr ,
3837 nullptr ,
nullptr ));
3840 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3841 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3842 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3843 CountNode ,
nullptr ,
nullptr ,
3849 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3851 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3855llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3856 llvm::DIFile *Unit) {
3857 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3861llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3862 llvm::DIFile *Unit) {
3863 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3865 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3866 CGM.getCodeGenOpts().DwarfVersion < 4)
3867 Tag = llvm::dwarf::DW_TAG_reference_type;
3869 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3872llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3874 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3878 Size = CGM.getContext().getTypeSize(Ty);
3881 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3884 Flags |= llvm::DINode::FlagSingleInheritance;
3887 Flags |= llvm::DINode::FlagMultipleInheritance;
3890 Flags |= llvm::DINode::FlagVirtualInheritance;
3900 llvm::DIType *ClassType = getOrCreateType(T, U);
3902 return DBuilder.createMemberPointerType(
3906 const FunctionProtoType *FPT =
3908 return DBuilder.createMemberPointerType(
3909 getOrCreateInstanceMethodType(
3912 ClassType, Size, 0, Flags);
3915llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3917 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3920llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3924llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3926 return getOrCreateType(Ty->getWrappedType(), U);
3929llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3936 const EnumType *Ty) {
3948llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3951 bool isImportedFromModule =
3952 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3956 if (isImportedFromModule || !ED->getDefinition()) {
3963 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3964 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3965 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3966 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3968 unsigned Line = getLineNumber(ED->getLocation());
3969 StringRef EDName = ED->getName();
3970 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3971 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3972 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3974 ReplaceMap.emplace_back(
3975 std::piecewise_construct, std::make_tuple(Ty),
3976 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3980 return CreateTypeDefinition(Ty);
3983llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3986 SmallVector<llvm::Metadata *, 16> Enumerators;
3987 ED = ED->getDefinition();
3988 assert(ED &&
"An enumeration definition is required");
3989 for (
const auto *
Enum : ED->enumerators()) {
3990 Enumerators.push_back(
3991 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3994 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3995 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3996 EnumKind = Attr->getExtensibility();
3999 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4001 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4002 unsigned Line = getLineNumber(ED->getLocation());
4003 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4004 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4005 return DBuilder.createEnumerationType(
4006 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4007 0, Identifier, ED->isScoped(), EnumKind);
4012 StringRef Name, StringRef
Value) {
4013 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4014 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4020 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4021 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4022 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4026 StringRef FuncName) {
4027 llvm::DISubprogram *SP =
4028 createInlinedSubprogram(FuncName, Location->getFile());
4029 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4034 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4040 FuncName += Category;
4042 FuncName += FailureMsg;
4050 Qualifiers InnerQuals = T.getLocalQualifiers();
4054 Quals += InnerQuals;
4056 switch (T->getTypeClass()) {
4058 return C.getQualifiedType(T.getTypePtr(), Quals);
4061 case Type::InjectedClassName:
4062 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4064 case Type::TemplateSpecialization: {
4066 if (Spec->isTypeAlias())
4067 return C.getQualifiedType(T.getTypePtr(), Quals);
4068 T = Spec->desugar();
4071 case Type::TypeOfExpr:
4077 case Type::Decltype:
4080 case Type::UnaryTransform:
4083 case Type::Attributed:
4086 case Type::BTFTagAttributed:
4089 case Type::CountAttributed:
4098 case Type::MacroQualified:
4101 case Type::SubstTemplateTypeParm:
4105 case Type::DeducedTemplateSpecialization: {
4107 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4111 case Type::PackIndexing: {
4115 case Type::Adjusted:
4122 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4127llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4130 if (It != TypeCache.end()) {
4132 if (llvm::Metadata *
V = It->second)
4145 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4152 RetainedTypes.push_back(
4153 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4156llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4160 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4162 llvm::raw_string_ostream OS(Name);
4163 Ty.
print(OS, getPrintingPolicy());
4170 if (
auto *T = getTypeOrNull(Ty))
4173 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4174 void *TyPtr = Ty.getAsOpaquePtr();
4177 TypeCache[TyPtr].reset(Res);
4182llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4190 auto Info = Reader->getSourceDescriptor(Idx);
4192 return getOrCreateModuleRef(*Info,
true);
4193 }
else if (ClangModuleMap) {
4206 auto Info = ASTSourceDescriptor(*M);
4207 return getOrCreateModuleRef(Info,
false);
4210 return getOrCreateModuleRef(PCHDescriptor,
false);
4217llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4220 return CreateQualifiedType(Ty, Unit);
4224#define TYPE(Class, Base)
4225#define ABSTRACT_TYPE(Class, Base)
4226#define NON_CANONICAL_TYPE(Class, Base)
4227#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4228#include "clang/AST/TypeNodes.inc"
4229 llvm_unreachable(
"Dependent types cannot show up in debug information");
4231 case Type::ExtVector:
4234 case Type::ConstantMatrix:
4236 case Type::ObjCObjectPointer:
4238 case Type::ObjCObject:
4240 case Type::ObjCTypeParam:
4242 case Type::ObjCInterface:
4250 case Type::BlockPointer:
4258 case Type::FunctionProto:
4259 case Type::FunctionNoProto:
4261 case Type::ConstantArray:
4262 case Type::VariableArray:
4263 case Type::IncompleteArray:
4264 case Type::ArrayParameter:
4267 case Type::LValueReference:
4269 case Type::RValueReference:
4272 case Type::MemberPointer:
4280 case Type::OverflowBehavior:
4285 case Type::TemplateSpecialization:
4287 case Type::HLSLAttributedResource:
4289 case Type::HLSLInlineSpirv:
4291 case Type::PredefinedSugar:
4293 case Type::CountAttributed:
4295 case Type::Attributed:
4296 case Type::BTFTagAttributed:
4297 case Type::Adjusted:
4299 case Type::DeducedTemplateSpecialization:
4302 case Type::MacroQualified:
4303 case Type::SubstTemplateTypeParm:
4304 case Type::TypeOfExpr:
4306 case Type::Decltype:
4307 case Type::PackIndexing:
4308 case Type::UnaryTransform:
4312 llvm_unreachable(
"type should have been unwrapped!");
4315llvm::DICompositeType *
4316CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4317 QualType QTy(Ty, 0);
4319 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4324 if (T && !T->isForwardDecl())
4328 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4333 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4336 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4341llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4342 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4343 bool NameIsSimplified =
false;
4346 StringRef RDName = getClassName(RD, &NameIsSimplified);
4348 llvm::DIFile *DefUnit =
nullptr;
4351 DefUnit = getOrCreateFile(Loc);
4352 Line = getLineNumber(Loc);
4355 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4359 auto *T = cast_or_null<llvm::DICompositeType>(
4360 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4368 return getOrCreateRecordFwdDecl(Ty, RDContext);
4381 auto Flags = llvm::DINode::FlagZero;
4382 if (NameIsSimplified)
4383 Flags |= llvm::DINode::FlagNameIsSimplified;
4384 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4386 Flags |= llvm::DINode::FlagTypePassByReference;
4388 Flags |= llvm::DINode::FlagTypePassByValue;
4391 if (!CXXRD->isTrivial())
4392 Flags |= llvm::DINode::FlagNonTrivial;
4395 if (CXXRD->isAnonymousStructOrUnion())
4396 Flags |= llvm::DINode::FlagExportSymbols;
4399 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4402 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4403 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4405 Flags, Identifier, Annotations);
4409 switch (RealDecl->getTag()) {
4411 llvm_unreachable(
"invalid composite type tag");
4413 case llvm::dwarf::DW_TAG_array_type:
4414 case llvm::dwarf::DW_TAG_enumeration_type:
4419 if (Identifier.empty())
4423 case llvm::dwarf::DW_TAG_structure_type:
4424 case llvm::dwarf::DW_TAG_union_type:
4425 case llvm::dwarf::DW_TAG_class_type:
4428 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4432 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4433 CXXRecordDecl *TemplateDecl =
4434 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4435 RegionMap[TemplateDecl].reset(RealDecl);
4437 RegionMap[RD].reset(RealDecl);
4439 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4441 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4442 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4443 CollectCXXTemplateParams(TSpecial, DefUnit));
4447void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4448 llvm::DICompositeType *RealDecl) {
4450 llvm::DIType *ContainingType =
nullptr;
4451 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4455 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4462 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4463 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4465 ContainingType = RealDecl;
4467 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4470llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4471 StringRef Name, uint64_t *Offset) {
4472 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4473 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4476 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4477 *Offset, llvm::DINode::FlagZero, FieldTy);
4478 *Offset += FieldSize;
4482void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4484 StringRef &LinkageName,
4485 llvm::DIScope *&FDContext,
4486 llvm::DINodeArray &TParamsArray,
4487 llvm::DINode::DIFlags &Flags) {
4489 bool NameIsSimplified =
false;
4490 Name = getFunctionName(FD, &NameIsSimplified);
4491 if (NameIsSimplified)
4492 Flags |= llvm::DINode::FlagNameIsSimplified;
4493 Name = getFunctionName(FD);
4496 LinkageName = CGM.getMangledName(GD);
4498 Flags |= llvm::DINode::FlagPrototyped;
4502 if (LinkageName == Name ||
4503 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4504 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4505 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4506 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4507 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4508 LinkageName = StringRef();
4512 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4513 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4514 CGM.getCodeGenOpts().EmitCodeView)) {
4515 if (
const NamespaceDecl *NSDecl =
4517 FDContext = getOrCreateNamespace(NSDecl);
4518 else if (
const RecordDecl *RDecl =
4520 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4521 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4524 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4527 Flags |= llvm::DINode::FlagNoReturn;
4529 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4533void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4534 unsigned &LineNo, QualType &T,
4535 StringRef &Name, StringRef &LinkageName,
4536 llvm::MDTuple *&TemplateParameters,
4537 llvm::DIScope *&VDContext) {
4546 llvm::APInt ConstVal(32, 1);
4547 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4549 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4556 LinkageName = CGM.getMangledName(VD);
4557 if (LinkageName == Name)
4558 LinkageName = StringRef();
4561 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4562 TemplateParameters = parameterNodes.get();
4564 TemplateParameters =
nullptr;
4582 DC = CGM.getContext().getTranslationUnitDecl();
4584 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4585 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4588llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4590 llvm::DINodeArray TParamsArray;
4591 StringRef Name, LinkageName;
4592 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4593 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4595 llvm::DIFile *Unit = getOrCreateFile(Loc);
4596 llvm::DIScope *DContext = Unit;
4597 unsigned Line = getLineNumber(Loc);
4598 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4603 SmallVector<QualType, 16> ArgTypes;
4604 for (
const ParmVarDecl *Parm : FD->
parameters())
4605 ArgTypes.push_back(Parm->getType());
4608 QualType FnType = CGM.getContext().getFunctionType(
4609 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4611 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4612 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4613 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4617 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4618 return DBuilder.createFunction(
4619 DContext, Name, LinkageName, Unit,
Line,
4620 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4621 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4623 CGM.getCodeGenOpts().DebugKeyInstructions);
4626 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4627 DContext, Name, LinkageName, Unit,
Line,
4628 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4629 TParamsArray.get(), getFunctionDeclaration(FD));
4631 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4632 std::make_tuple(CanonDecl),
4633 std::make_tuple(SP));
4637llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4638 return getFunctionFwdDeclOrStub(GD,
false);
4641llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4642 return getFunctionFwdDeclOrStub(GD,
true);
4645llvm::DIGlobalVariable *
4646CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4648 StringRef Name, LinkageName;
4650 llvm::DIFile *Unit = getOrCreateFile(Loc);
4651 llvm::DIScope *DContext = Unit;
4652 unsigned Line = getLineNumber(Loc);
4653 llvm::MDTuple *TemplateParameters =
nullptr;
4655 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4658 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4659 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4661 FwdDeclReplaceMap.emplace_back(
4662 std::piecewise_construct,
4664 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4668llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4673 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4674 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4675 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4679 if (I != DeclCache.end()) {
4681 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4682 return GVE->getVariable();
4690 if (IE != ImportedDeclCache.end()) {
4691 auto N = IE->second;
4692 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4694 return dyn_cast_or_null<llvm::DINode>(N);
4699 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4700 return getFunctionForwardDeclaration(FD);
4701 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4702 return getGlobalVariableForwardDeclaration(VD);
4707llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4708 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4711 const auto *FD = dyn_cast<FunctionDecl>(D);
4716 auto *S = getDeclContextDescriptor(D);
4719 if (MI == SPCache.end()) {
4721 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4725 if (MI != SPCache.end()) {
4726 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4727 if (SP && !SP->isDefinition())
4731 for (
auto *NextFD : FD->
redecls()) {
4732 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4733 if (MI != SPCache.end()) {
4734 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4735 if (SP && !SP->isDefinition())
4742llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4743 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4744 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4745 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4748 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4752 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4756 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4765 QualType QTy(
ID->getTypeForDecl(), 0);
4766 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4767 if (It == TypeCache.end())
4770 llvm::DISubprogram *FD = DBuilder.createFunction(
4771 InterfaceType, getObjCMethodName(OMD), StringRef(),
4772 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4773 DBuilder.finalizeSubprogram(FD);
4780llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4785 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4786 !CGM.getCodeGenOpts().EmitCodeView))
4789 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4791 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4794 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4797 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4798 return getOrCreateMethodType(
Method, F);
4800 const auto *FTy = FnType->
getAs<FunctionType>();
4803 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4805 SmallVector<llvm::Metadata *, 16> Elts;
4808 QualType ResultTy = OMethod->getReturnType();
4811 if (ResultTy == CGM.getContext().getObjCInstanceType())
4812 ResultTy = CGM.getContext().getPointerType(
4813 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4815 Elts.push_back(getOrCreateType(ResultTy, F));
4817 QualType SelfDeclTy;
4818 if (
auto *SelfDecl = OMethod->getSelfDecl())
4819 SelfDeclTy = SelfDecl->getType();
4820 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4823 if (!SelfDeclTy.
isNull())
4825 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4827 Elts.push_back(DBuilder.createArtificialType(
4828 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4830 for (
const auto *PI : OMethod->parameters())
4831 Elts.push_back(getOrCreateType(PI->getType(), F));
4833 if (OMethod->isVariadic())
4834 Elts.push_back(DBuilder.createUnspecifiedParameter());
4836 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4837 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4843 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4844 if (FD->isVariadic()) {
4845 SmallVector<llvm::Metadata *, 16> EltTys;
4846 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4847 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4849 EltTys.push_back(getOrCreateType(ParamType, F));
4850 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4851 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4852 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4865 CC = SrcFnTy->getCallConv();
4867 for (
const VarDecl *VD : Args)
4868 ArgTypes.push_back(VD->
getType());
4869 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4875 llvm::Function *Fn,
bool CurFuncIsThunk) {
4877 StringRef LinkageName;
4879 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4882 bool HasDecl = (D !=
nullptr);
4884 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4885 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4886 llvm::DIFile *Unit = getOrCreateFile(Loc);
4887 llvm::DIScope *FDContext = Unit;
4888 llvm::DINodeArray TParamsArray;
4889 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4892 LinkageName = Fn->getName();
4893 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4895 auto FI = SPCache.find(FD->getCanonicalDecl());
4896 if (FI != SPCache.end()) {
4897 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4898 if (SP && SP->isDefinition()) {
4899 LexicalBlockStack.emplace_back(SP);
4900 RegionMap[D].reset(SP);
4904 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4905 TParamsArray, Flags);
4908 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4909 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4910 Name = getObjCMethodName(OMD);
4911 Flags |= llvm::DINode::FlagPrototyped;
4918 Name = Fn->getName();
4923 Flags |= llvm::DINode::FlagPrototyped;
4925 Name.consume_front(
"\01");
4929 "Unexpected DynamicInitKind !");
4933 Flags |= llvm::DINode::FlagArtificial;
4939 Flags |= llvm::DINode::FlagThunk;
4941 if (Fn->hasLocalLinkage())
4942 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4943 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4944 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4947 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4948 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4950 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4951 unsigned ScopeLine = getLineNumber(ScopeLoc);
4952 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4953 llvm::DISubprogram *
Decl =
nullptr;
4954 llvm::DINodeArray Annotations =
nullptr;
4957 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4958 : getFunctionDeclaration(D);
4959 Annotations = CollectBTFDeclTagAnnotations(D);
4967 llvm::DISubprogram *SP = DBuilder.createFunction(
4968 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4969 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4970 Annotations,
"", KeyInstructions);
4971 Fn->setSubprogram(SP);
4980 LexicalBlockStack.emplace_back(SP);
4983 RegionMap[D].reset(SP);
4987 QualType FnType, llvm::Function *Fn) {
4989 StringRef LinkageName;
4995 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4996 return GetName(D,
true);
4999 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5000 llvm::DIFile *Unit = getOrCreateFile(Loc);
5001 bool IsDeclForCallSite = Fn ?
true :
false;
5002 llvm::DIScope *FDContext =
5003 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5004 llvm::DINodeArray TParamsArray;
5007 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5008 TParamsArray, Flags);
5009 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5010 Name = getObjCMethodName(OMD);
5011 Flags |= llvm::DINode::FlagPrototyped;
5013 llvm_unreachable(
"not a function or ObjC method");
5015 Name.consume_front(
"\01");
5018 Flags |= llvm::DINode::FlagArtificial;
5023 unsigned LineNo = getLineNumber(Loc);
5024 unsigned ScopeLine = 0;
5025 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5026 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5027 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5029 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5030 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5032 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5033 llvm::DISubprogram *SP = DBuilder.createFunction(
5034 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5035 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5041 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5042 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5043 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5046 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5047 DBuilder.createParameterVariable(
5048 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5049 llvm::DINode::FlagZero, ParamAnnotations);
5055 if (IsDeclForCallSite)
5056 Fn->setSubprogram(SP);
5060 llvm::CallBase *CI) {
5061 if (!shouldGenerateVirtualCallSite())
5067 assert(CI &&
"Invalid Call Instruction.");
5068 if (!CI->isIndirectCall())
5072 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5073 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5081 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5084 if (
Func->getSubprogram())
5092 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5107 auto FI = SPCache.find(FD->getCanonicalDecl());
5108 llvm::DISubprogram *SP =
nullptr;
5109 if (FI != SPCache.end())
5110 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5111 if (!SP || !SP->isDefinition())
5112 SP = getFunctionStub(GD);
5113 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5114 LexicalBlockStack.emplace_back(SP);
5120 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5129 if (CurLoc.isInvalid() ||
5130 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5131 LexicalBlockStack.empty())
5134 llvm::MDNode *
Scope = LexicalBlockStack.back();
5135 Builder.SetCurrentDebugLocation(
5136 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5137 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5141 llvm::MDNode *Back =
nullptr;
5142 if (!LexicalBlockStack.empty())
5143 Back = LexicalBlockStack.back().get();
5144 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5146 getColumnNumber(CurLoc)));
5149void CGDebugInfo::AppendAddressSpaceXDeref(
5151 std::optional<unsigned> DWARFAddressSpace =
5153 if (!DWARFAddressSpace)
5156 Expr.push_back(llvm::dwarf::DW_OP_constu);
5157 Expr.push_back(*DWARFAddressSpace);
5158 Expr.push_back(llvm::dwarf::DW_OP_swap);
5159 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5168 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5169 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5170 LexicalBlockStack.back(), CurInlinedAt));
5172 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5176 CreateLexicalBlock(Loc);
5181 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5186 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5189 LexicalBlockStack.pop_back();
5193 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5194 unsigned RCount = FnBeginRegionCount.back();
5195 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5198 while (LexicalBlockStack.size() != RCount) {
5201 LexicalBlockStack.pop_back();
5203 FnBeginRegionCount.pop_back();
5205 if (Fn && Fn->getSubprogram())
5206 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5209CGDebugInfo::BlockByRefType
5210CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5211 uint64_t *XOffset) {
5214 uint64_t FieldSize, FieldOffset;
5215 uint32_t FieldAlign;
5217 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5222 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5223 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5225 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5226 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5229 if (HasCopyAndDispose) {
5232 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5234 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5236 bool HasByrefExtendedLayout;
5239 HasByrefExtendedLayout) &&
5240 HasByrefExtendedLayout) {
5243 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5252 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5255 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5258 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5263 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5264 FieldSize = CGM.getContext().getTypeSize(FType);
5265 FieldAlign = CGM.getContext().toBits(Align);
5267 *XOffset = FieldOffset;
5268 llvm::DIType *FieldTy = DBuilder.createMemberType(
5269 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5270 llvm::DINode::FlagZero, WrappedTy);
5271 EltTys.push_back(FieldTy);
5272 FieldOffset += FieldSize;
5274 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5275 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5276 llvm::DINode::FlagZero,
nullptr, Elements),
5280llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5281 llvm::Value *Storage,
5282 std::optional<unsigned> ArgNo,
5284 const bool UsePointerValue) {
5285 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5286 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5287 if (VD->
hasAttr<NoDebugAttr>())
5292 llvm::DIFile *Unit =
nullptr;
5293 if (!VarIsArtificial)
5297 if (VD->
hasAttr<BlocksAttr>())
5298 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5300 Ty = getOrCreateType(VD->
getType(), Unit);
5310 if (!VarIsArtificial) {
5314 SmallVector<uint64_t, 13> Expr;
5315 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5322 Flags |= llvm::DINode::FlagArtificial;
5326 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5327 AppendAddressSpaceXDeref(AddressSpace, Expr);
5331 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5334 Flags |= llvm::DINode::FlagObjectPointer;
5335 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5336 if (PVD->isExplicitObjectParameter())
5337 Flags |= llvm::DINode::FlagObjectPointer;
5345 StringRef Name = VD->
getName();
5346 if (!Name.empty()) {
5352 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5354 offset = CGM.getContext().toCharUnitsFromBits(
5357 Expr.push_back(llvm::dwarf::DW_OP_deref);
5358 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5360 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5363 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5375 for (
const auto *Field : RD->
fields()) {
5376 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5377 StringRef FieldName =
Field->getName();
5385 auto *D = DBuilder.createAutoVariable(
5386 Scope, FieldName, Unit,
Line, FieldTy,
5387 CGM.getCodeGenOpts().OptimizationLevel != 0,
5388 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5391 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5392 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5395 Builder.GetInsertBlock());
5403 if (UsePointerValue) {
5404 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5405 "Debug info already contains DW_OP_deref.");
5406 Expr.push_back(llvm::dwarf::DW_OP_deref);
5410 llvm::DILocalVariable *D =
nullptr;
5412 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5413 D = DBuilder.createParameterVariable(
5414 Scope, Name, *ArgNo, Unit,
Line, Ty,
5415 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5424 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5430 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5431 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5432 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5433 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5435 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5441 if (Iter != CoroutineParameterMappings.end()) {
5442 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5443 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5444 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5446 if (Iter2 != ParamDbgMappings.end())
5447 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5453 D = RemapCoroArgToLocalVar();
5456 D = DBuilder.createAutoVariable(
5457 Scope, Name, Unit,
Line, Ty,
5458 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5461 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5462 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5463 Column, Scope, CurInlinedAt),
5464 Builder.GetInsertBlock());
5469llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5470 llvm::Value *Storage,
5471 std::optional<unsigned> ArgNo,
5473 const bool UsePointerValue) {
5474 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5475 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5476 if (BD->
hasAttr<NoDebugAttr>())
5483 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5484 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5492 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5494 SmallVector<uint64_t, 3> Expr;
5495 AppendAddressSpaceXDeref(AddressSpace, Expr);
5500 if (UsePointerValue) {
5501 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5502 "Debug info already contains DW_OP_deref.");
5503 Expr.push_back(llvm::dwarf::DW_OP_deref);
5508 StringRef Name = BD->
getName();
5511 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5512 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5513 llvm::DINode::FlagZero, Align);
5515 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5516 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5517 const unsigned fieldIndex = FD->getFieldIndex();
5518 const clang::CXXRecordDecl *parent =
5519 (
const CXXRecordDecl *)FD->getParent();
5520 const ASTRecordLayout &layout =
5521 CGM.getContext().getASTRecordLayout(parent);
5523 if (FD->isBitField()) {
5524 const CGRecordLayout &RL =
5525 CGM.getTypes().getCGRecordLayout(FD->getParent());
5530 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5536 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5537 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5538 Expr.push_back(Info.
Offset);
5541 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5542 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5543 }
else if (fieldOffset != 0) {
5544 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5545 "Unexpected non-bitfield with non-byte-aligned offset");
5546 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5548 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5551 }
else if (
const ArraySubscriptExpr *ASE =
5552 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5553 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5554 const uint64_t value = IL->getValue().getZExtValue();
5555 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5558 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5559 Expr.push_back(CGM.getContext()
5560 .toCharUnitsFromBits(value * typeSize)
5567 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5568 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5569 Column, Scope, CurInlinedAt),
5570 Builder.GetInsertBlock());
5575llvm::DILocalVariable *
5578 const bool UsePointerValue) {
5579 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5581 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5583 EmitDeclare(B, Storage, std::nullopt, Builder,
5590 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5594 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5595 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5597 if (D->
hasAttr<NoDebugAttr>())
5601 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5607 StringRef Name = D->
getName();
5613 CGM.getCodeGenOpts().OptimizationLevel != 0);
5616 DBuilder.insertLabel(L,
5617 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5618 Scope, CurInlinedAt),
5619 Builder.GetInsertBlock()->end());
5622llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5624 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5627 return DBuilder.createObjectPointerType(Ty,
true);
5632 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5633 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5634 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5636 if (Builder.GetInsertBlock() ==
nullptr)
5638 if (VD->
hasAttr<NoDebugAttr>())
5641 bool isByRef = VD->
hasAttr<BlocksAttr>();
5643 uint64_t XOffset = 0;
5644 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5647 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5649 Ty = getOrCreateType(VD->
getType(), Unit);
5653 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5655 Ty = CreateSelfType(VD->
getType(), Ty);
5658 const unsigned Line =
5662 const llvm::DataLayout &target = CGM.getDataLayout();
5669 addr.push_back(llvm::dwarf::DW_OP_deref);
5670 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5673 addr.push_back(llvm::dwarf::DW_OP_deref);
5674 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5677 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5679 addr.push_back(llvm::dwarf::DW_OP_deref);
5680 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5682 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5688 auto *D = DBuilder.createAutoVariable(
5690 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5693 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5694 LexicalBlockStack.back(), CurInlinedAt);
5695 auto *
Expr = DBuilder.createExpression(addr);
5697 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5699 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5702llvm::DILocalVariable *
5705 bool UsePointerValue) {
5706 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5707 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5711struct BlockLayoutChunk {
5712 uint64_t OffsetInBits;
5715bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5716 return l.OffsetInBits < r.OffsetInBits;
5720void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5722 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5723 SmallVectorImpl<llvm::Metadata *> &Fields) {
5727 if (CGM.getLangOpts().OpenCL) {
5728 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5729 BlockLayout.getElementOffsetInBits(0),
5731 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5732 BlockLayout.getElementOffsetInBits(1),
5736 BlockLayout.getElementOffsetInBits(0),
5738 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5739 BlockLayout.getElementOffsetInBits(1),
5743 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5744 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5745 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5746 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5747 BlockLayout.getElementOffsetInBits(3),
5749 Fields.push_back(createFieldType(
5754 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5761 llvm::AllocaInst *Alloca,
5763 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5769 llvm::DIFile *tunit = getOrCreateFile(loc);
5770 unsigned line = getLineNumber(loc);
5771 unsigned column = getColumnNumber(loc);
5776 const llvm::StructLayout *blockLayout =
5780 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5789 BlockLayoutChunk chunk;
5790 chunk.OffsetInBits =
5791 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5792 chunk.Capture =
nullptr;
5793 chunks.push_back(chunk);
5797 for (
const auto &capture :
blockDecl->captures()) {
5798 const VarDecl *variable = capture.getVariable();
5805 BlockLayoutChunk chunk;
5806 chunk.OffsetInBits =
5807 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5808 chunk.Capture = &capture;
5809 chunks.push_back(chunk);
5813 llvm::array_pod_sort(chunks.begin(), chunks.end());
5815 for (
const BlockLayoutChunk &Chunk : chunks) {
5816 uint64_t offsetInBits = Chunk.OffsetInBits;
5823 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5825 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5826 type = CGM.getContext().getCanonicalTagType(RDecl);
5828 llvm_unreachable(
"unexpected block declcontext");
5830 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5831 offsetInBits, tunit, tunit));
5836 StringRef name = variable->
getName();
5838 llvm::DIType *fieldType;
5840 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5845 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5846 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5847 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5848 PtrInfo.
Width, Align, offsetInBits,
5849 llvm::DINode::FlagZero, fieldType);
5853 offsetInBits, Align, tunit, tunit);
5855 fields.push_back(fieldType);
5859 llvm::raw_svector_ostream(typeName)
5860 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5862 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5864 llvm::DIType *
type =
5865 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5866 CGM.getContext().toBits(block.
BlockSize), 0,
5867 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5868 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5871 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5875 auto *debugVar = DBuilder.createParameterVariable(
5876 scope, Name, ArgNo, tunit, line,
type,
5877 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5880 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5881 llvm::DILocation::get(CGM.getLLVMContext(), line,
5882 column, scope, CurInlinedAt),
5883 Builder.GetInsertBlock());
5886llvm::DIDerivedType *
5887CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5892 if (MI != StaticDataMemberCache.end()) {
5893 assert(MI->second &&
"Static data member declaration should still exist");
5904llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5905 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5906 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5907 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5909 for (
const auto *Field : RD->
fields()) {
5910 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5911 StringRef FieldName = Field->getName();
5914 if (FieldName.empty()) {
5915 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5916 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5917 LineNo, LinkageName, Var, DContext);
5921 GVE = DBuilder.createGlobalVariableExpression(
5922 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5923 Var->hasLocalLinkage());
5924 Var->addDebugInfo(GVE);
5936 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5941 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5952 struct ReferencesAnonymous
5954 bool RefAnon =
false;
5955 bool VisitRecordType(RecordType *RT) {
5963 ReferencesAnonymous RT;
5976struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5977 bool Reconstitutable =
true;
5978 bool VisitVectorType(VectorType *FT) {
5979 Reconstitutable =
false;
5982 bool VisitAtomicType(AtomicType *FT) {
5983 Reconstitutable =
false;
5986 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5989 const EnumDecl *ED = ET->getDecl();
5991 Reconstitutable =
false;
5995 Reconstitutable =
false;
6000 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6004 return Reconstitutable;
6006 bool VisitRecordType(RecordType *RT,
bool =
false) {
6008 Reconstitutable =
false;
6018 ReconstitutableType T;
6020 return T.Reconstitutable;
6023bool CGDebugInfo::HasReconstitutableArgs(
6024 ArrayRef<TemplateArgument> Args)
const {
6025 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6065 llvm_unreachable(
"Other, unresolved, template arguments should "
6066 "not be seen here");
6071std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6072 bool *NameIsSimplified)
const {
6074 llvm::raw_string_ostream
OS(Name);
6075 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6078 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6079 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6081 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6082 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6084 std::optional<TemplateArgs> Args;
6086 bool IsOperatorOverload =
false;
6087 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6088 Args = GetTemplateArgs(RD);
6089 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6090 Args = GetTemplateArgs(FD);
6092 IsOperatorOverload |=
6095 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6096 Args = GetTemplateArgs(VD);
6120 bool Reconstitutable =
6121 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6123 PrintingPolicy PP = getPrintingPolicy();
6125 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6130 if (NameIsSimplified)
6131 *NameIsSimplified =
true;
6132 bool Mangled = TemplateNamesKind ==
6133 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6139 std::string EncodedOriginalName;
6140 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6145 printTemplateArgumentList(OS, Args->Args, PP);
6146 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6148 std::string CanonicalOriginalName;
6149 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6151 assert(EncodedOriginalName == CanonicalOriginalName);
6160 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6161 if (D->
hasAttr<NoDebugAttr>())
6164 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6165 return GetName(D,
true);
6171 if (Cached != DeclCache.end())
6172 return Var->addDebugInfo(
6176 llvm::DIFile *Unit =
nullptr;
6177 llvm::DIScope *DContext =
nullptr;
6179 StringRef DeclName, LinkageName;
6181 llvm::MDTuple *TemplateParameters =
nullptr;
6182 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6183 TemplateParameters, DContext);
6187 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6192 if (T->isUnionType() && DeclName.empty()) {
6193 const auto *RD = T->castAsRecordDecl();
6195 "unnamed non-anonymous struct or union?");
6196 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6201 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6202 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6203 if (D->
hasAttr<CUDASharedAttr>())
6206 else if (D->
hasAttr<CUDAConstantAttr>())
6210 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6212 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6213 GVE = DBuilder.createGlobalVariableExpression(
6214 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6215 Var->hasLocalLinkage(),
true,
6216 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6217 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6218 Align, Annotations);
6219 Var->addDebugInfo(GVE);
6225 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6226 if (VD->
hasAttr<NoDebugAttr>())
6228 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6229 return GetName(VD,
true);
6234 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6235 StringRef Name = VD->
getName();
6236 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6238 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6240 if (CGM.getCodeGenOpts().EmitCodeView) {
6251 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6252 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6253 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6263 auto *VarD = dyn_cast<VarDecl>(VD);
6264 if (VarD && VarD->isStaticDataMember()) {
6266 getDeclContextDescriptor(VarD);
6271 RetainedTypes.push_back(
6272 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6276 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6278 auto &GV = DeclCache[VD];
6282 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6283 llvm::MDTuple *TemplateParameters =
nullptr;
6287 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6288 TemplateParameters = parameterNodes.get();
6291 GV.reset(DBuilder.createGlobalVariableExpression(
6292 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6293 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6294 TemplateParameters, Align));
6299 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6300 if (D->
hasAttr<NoDebugAttr>())
6304 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6305 StringRef Name = D->
getName();
6306 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6308 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6309 llvm::DIGlobalVariableExpression *GVE =
6310 DBuilder.createGlobalVariableExpression(
6311 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6312 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6313 Var->addDebugInfo(GVE);
6320 if (CGM.getCodeGenOpts().getDebugInfo() <=
6321 llvm::codegenoptions::DebugLineTablesOnly)
6324 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6328 llvm::DIFile *Unit = DIL->getFile();
6329 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6334 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6335 llvm::Value *Var = Load->getPointerOperand();
6340 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6341 return DbgDeclare->getVariable()->getType() ==
Type;
6343 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6347 llvm::DILocalVariable *D =
6348 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6349 Type,
false, llvm::DINode::FlagArtificial);
6351 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6352 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6362 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6366 if (D->
hasAttr<NoDebugAttr>())
6369 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6384 if (!(DI = getDeclarationOrDefinition(
6385 AliaseeDecl.getCanonicalDecl().getDecl())))
6388 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6391 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6392 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6406 llvm::DIFile *
File = getOrCreateFile(Loc);
6407 llvm::DIGlobalVariableExpression *Debug =
6408 DBuilder.createGlobalVariableExpression(
6409 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6410 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6411 GV->addDebugInfo(Debug);
6414llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6415 if (!LexicalBlockStack.empty())
6416 return LexicalBlockStack.back();
6417 llvm::DIScope *Mod = getParentModuleOrNull(D);
6418 return getContextDescriptor(D, Mod ? Mod : TheCU);
6422 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6426 CGM.getCodeGenOpts().DebugExplicitImport) {
6430 DBuilder.createImportedModule(
6432 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6437 if (llvm::DINode *
Target =
6440 DBuilder.createImportedDeclaration(
6442 getOrCreateFile(Loc), getLineNumber(Loc));
6447 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6450 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6452 for (
const auto *USD : UD.
shadows()) {
6457 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6458 if (
const auto *AT = FD->getType()
6461 if (AT->getDeducedType().isNull())
6472 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6475 "We shouldn't be codegening an invalid UsingEnumDecl"
6476 " containing no decls");
6478 for (
const auto *USD : UD.
shadows())
6483 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6485 if (
Module *M = ID.getImportedModule()) {
6487 auto Loc = ID.getLocation();
6488 DBuilder.createImportedDeclaration(
6489 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6490 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6491 getLineNumber(Loc));
6495llvm::DIImportedEntity *
6497 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6499 auto &VH = NamespaceAliasCache[&NA];
6502 llvm::DIImportedEntity *R;
6504 if (
const auto *Underlying =
6507 R = DBuilder.createImportedDeclaration(
6510 getLineNumber(Loc), NA.
getName());
6512 R = DBuilder.createImportedDeclaration(
6515 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6521CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6525 auto I = NamespaceCache.find(NSDecl);
6526 if (I != NamespaceCache.end())
6529 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6531 llvm::DINamespace *NS =
6532 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6533 NamespaceCache[NSDecl].reset(NS);
6538 assert(TheCU &&
"no main compile unit");
6539 TheCU->setDWOId(Signature);
6545 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6546 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6548 ? CreateTypeDefinition(E.Type, E.Unit)
6550 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6554 for (
const auto &P : ObjCMethodCache) {
6555 if (P.second.empty())
6558 QualType QTy(P.first->getTypeForDecl(), 0);
6560 assert(It != TypeCache.end());
6562 llvm::DICompositeType *InterfaceDecl =
6565 auto CurElts = InterfaceDecl->getElements();
6569 for (
auto &SubprogramDirect : P.second)
6570 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6571 EltTys.push_back(SubprogramDirect.getPointer());
6573 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6574 DBuilder.replaceArrays(InterfaceDecl, Elements);
6577 for (
const auto &P : ReplaceMap) {
6580 assert(Ty->isForwardDecl());
6582 auto It = TypeCache.find(P.first);
6583 assert(It != TypeCache.end());
6586 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6590 for (
const auto &P : FwdDeclReplaceMap) {
6593 llvm::Metadata *Repl;
6595 auto It = DeclCache.find(P.first);
6599 if (It == DeclCache.end())
6604 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6605 Repl = GVE->getVariable();
6611 for (
auto &RT : RetainedTypes)
6612 if (
auto MD = TypeCache[RT])
6615 DBuilder.finalize();
6620 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6621 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6622 DBuilder.retainType(DieTy);
6626 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6627 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6628 DBuilder.retainType(DieTy);
6632 if (LexicalBlockStack.empty())
6633 return llvm::DebugLoc();
6635 llvm::MDNode *
Scope = LexicalBlockStack.back();
6636 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6637 getColumnNumber(Loc),
Scope);
6643 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6644 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6645 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6646 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6647 return llvm::DINode::FlagZero;
6652 bool SupportsDWARFv4Ext =
6653 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6654 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6655 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6657 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6658 return llvm::DINode::FlagZero;
6660 return llvm::DINode::FlagAllCallsDescribed;
6671 return DBuilder.createConstantValueExpression(
6672 Val.
getFloat().bitcastToAPInt().getZExtValue());
6677 llvm::APSInt
const &ValInt = Val.
getInt();
6678 std::optional<uint64_t> ValIntOpt;
6679 if (ValInt.isUnsigned())
6680 ValIntOpt = ValInt.tryZExtValue();
6681 else if (
auto tmp = ValInt.trySExtValue())
6684 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6687 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6692CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6694 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6695 CGF.CurLexicalScope =
this;
6697 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6702 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6715#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6717 Label = "__ubsan_check_" #Name; \
6721#undef SANITIZER_CHECK
6732#define SANITIZER(NAME, ID) \
6733 case SanitizerKind::SO_##ID: \
6734 Label = "__ubsan_check_" NAME; \
6736#include "clang/Basic/Sanitizers.def"
6738 llvm_unreachable(
"unexpected sanitizer kind");
6743 for (
unsigned int i = 0; i < Label.length(); i++)
6744 if (!std::isalpha(Label[i]))
6753 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6755 if (!DI || !CheckDebugLoc)
6756 return CheckDebugLoc;
6757 const auto &AnnotateDebugInfo =
6758 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6759 if (AnnotateDebugInfo.empty())
6760 return CheckDebugLoc;
6763 if (Ordinals.size() == 1)
6768 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6769 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6771 return CheckDebugLoc;
6779 assert(!CGF->IsSanitizerScope);
6780 CGF->IsSanitizerScope =
true;
6784 assert(CGF->IsSanitizerScope);
6785 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to the current atom group, created using ApplyA...
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file.
void completeFunction()
Reset internal state.
void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl)
Emit information about global variable alias.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)
Emit call to llvm.dbg.label for an label.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
void EmitUsingShadowDecl(const UsingShadowDecl &USD)
Emit a shadow decl brought in by a using or using-enum.
void EmitUsingEnumDecl(const UsingEnumDecl &UD)
Emit C++ using-enum declaration.
void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)
Constructs the debug code for exiting a function.
void EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an include directive.
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about an external variable.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void removeObjCLifetime()
void removeAddressSpace()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.