41#include "llvm/ADT/DenseSet.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DerivedTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/Metadata.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/MD5.h"
53#include "llvm/Support/Path.h"
54#include "llvm/Support/SHA1.h"
55#include "llvm/Support/SHA256.h"
56#include "llvm/Support/TimeProfiler.h"
64 if (TI.isAlignRequired())
92 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
96 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
120 if (!llvm::isa<ParmVarDecl>(VD))
130 if (!Method->isImplicit() || !Method->isPropertyAccessor())
141 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
142 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
143 DBuilder(CGM.getModule()) {
148 assert(LexicalBlockStack.empty() &&
149 "Region stack mismatch, stack not empty!");
152void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
153 uint64_t Group, uint8_t Rank) {
154 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
158 Rank = std::min<uint8_t>(Rank, 7);
160 const llvm::DebugLoc &DL = I->getDebugLoc();
165 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
166 Group = DL->getAtomGroup();
167 Rank = DL->getAtomRank();
172 KeyInstructionsInfo.HighestEmittedAtom =
173 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
176 llvm::DILocation *NewDL = llvm::DILocation::get(
177 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
178 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
179 I->setDebugLoc(NewDL);
183 llvm::Value *Backup) {
185 KeyInstructionsInfo.CurrentAtom);
191 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
194 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
195 if (!SP || !SP->getKeyInstructionsEnabled())
198 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
200 llvm::Instruction *BackupI =
201 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
206 addInstSourceAtomMetadata(BackupI, Group, 2);
212 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
213 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
216 addInstSourceAtomMetadata(BackupI, Group, Rank++);
222 KeyInstructionsInfo.NextAtom = 1;
223 KeyInstructionsInfo.HighestEmittedAtom = 0;
224 KeyInstructionsInfo.CurrentAtom = 0;
230 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
231 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
239 DI->KeyInstructionsInfo.NextAtom =
240 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
241 DI->KeyInstructionsInfo.NextAtom);
243 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
249 init(TemporaryLocation);
256 init(TemporaryLocation, DefaultToEmpty);
260 bool DefaultToEmpty) {
267 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
269 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
272 if (TemporaryLocation.
isValid()) {
273 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
277 if (DefaultToEmpty) {
278 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
283 assert(!DI->LexicalBlockStack.empty());
284 CGF->Builder.SetCurrentDebugLocation(
285 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
286 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
296 if (!CGF.getDebugInfo()) {
300 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
304 if (Loc->getAtomGroup())
305 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
306 Loc->getColumn(), Loc->getScope(),
307 Loc->getInlinedAt(), Loc.isImplicitCode());
308 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
316 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
322 if (!CGF.getDebugInfo()) {
326 auto &DI = *CGF.getDebugInfo();
327 SavedLocation = DI.getLocation();
328 assert((DI.getInlinedAt() ==
329 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
330 "CGDebugInfo and IRBuilder are out of sync");
332 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
338 auto &DI = *CGF->getDebugInfo();
339 DI.EmitInlineFunctionEnd(CGF->Builder);
340 DI.EmitLocation(CGF->Builder, SavedLocation);
348 CurLoc = CGM.getContext().getSourceManager().getFileLoc(Loc);
353 if (LexicalBlockStack.empty())
359 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
362 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
363 LexicalBlockStack.pop_back();
364 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
365 LBF->getScope(), getOrCreateFile(CurLoc)));
368 LexicalBlockStack.pop_back();
369 LexicalBlockStack.emplace_back(
370 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
374llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
375 llvm::DIScope *Mod = getParentModuleOrNull(D);
380llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
385 auto I = RegionMap.find(Context);
386 if (I != RegionMap.end()) {
387 llvm::Metadata *
V = I->second;
388 return dyn_cast_or_null<llvm::DIScope>(
V);
392 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
393 return getOrCreateNamespace(NSDecl);
395 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
396 if (!RDecl->isDependentType())
402PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
403 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
410 if (CGM.getCodeGenOpts().EmitCodeView) {
431StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
432 return internString(GetName(FD));
435StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
436 SmallString<256> MethodName;
437 llvm::raw_svector_ostream
OS(MethodName);
440 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
441 OS << OID->getName();
442 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
443 OS << OID->getName();
444 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
445 if (OC->IsClassExtension()) {
446 OS << OC->getClassInterface()->getName();
448 OS << OC->getIdentifier()->getNameStart() <<
'('
449 << OC->getIdentifier()->getNameStart() <<
')';
451 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
452 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
456 return internString(
OS.str());
459StringRef CGDebugInfo::getSelectorName(Selector S) {
463StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
466 return internString(GetName(RD));
472 return II->getName();
477 if (CGM.getCodeGenOpts().EmitCodeView) {
480 "Typedef should not be in another decl context!");
481 assert(D->getDeclName().getAsIdentifierInfo() &&
482 "Typedef was not named!");
483 return D->getDeclName().getAsIdentifierInfo()->getName();
486 if (CGM.getLangOpts().CPlusPlus) {
489 ASTContext &Context = CGM.getContext();
493 Name = DD->getName();
494 else if (
const TypedefNameDecl *TND =
498 Name = TND->getName();
501 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
502 if (CXXRD->isLambda())
504 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
507 SmallString<256> UnnamedType(
"<unnamed-type-");
510 return internString(UnnamedType);
518std::optional<llvm::DIFile::ChecksumKind>
519CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
522 if (!CGM.getCodeGenOpts().EmitCodeView &&
523 CGM.getCodeGenOpts().DwarfVersion < 5)
526 SourceManager &
SM = CGM.getContext().getSourceManager();
527 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
531 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
532 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
534 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
535 return llvm::DIFile::CSK_MD5;
537 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
538 return llvm::DIFile::CSK_SHA1;
540 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
541 return llvm::DIFile::CSK_SHA256;
545 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
548std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
550 if (!CGM.getCodeGenOpts().EmbedSource)
553 bool SourceInvalid =
false;
554 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
562llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
563 SourceManager &
SM = CGM.getContext().getSourceManager();
566 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
572 FileName = TheCU->getFile()->getFilename();
573 CSInfo = TheCU->getFile()->getChecksum();
575 PresumedLoc PLoc =
SM.getPresumedLoc(
SM.getFileLoc(Loc));
579 FileName = TheCU->getFile()->getFilename();
587 auto It = DIFileCache.find(
FileName.data());
588 if (It != DIFileCache.end()) {
590 if (llvm::Metadata *
V = It->second)
595 SmallString<64> Checksum;
597 std::optional<llvm::DIFile::ChecksumKind> CSKind =
598 computeChecksum(FID, Checksum);
600 CSInfo.emplace(*CSKind, Checksum);
603 getSource(
SM,
SM.getFileID(
SM.getFileLoc(Loc))));
606llvm::DIFile *CGDebugInfo::createFile(
608 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
609 std::optional<StringRef> Source) {
613 std::string CurDir =
remapDIPath(getCurrentDirname());
614 SmallString<128> DirBuf;
615 SmallString<128> FileBuf;
616 if (llvm::sys::path::is_absolute(RemappedFile)) {
619 auto FileIt = llvm::sys::path::begin(RemappedFile);
620 auto FileE = llvm::sys::path::end(RemappedFile);
621 auto CurDirIt = llvm::sys::path::begin(CurDir);
622 auto CurDirE = llvm::sys::path::end(CurDir);
623 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
624 llvm::sys::path::append(DirBuf, *CurDirIt);
625 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
631 for (; FileIt != FileE; ++FileIt)
632 llvm::sys::path::append(FileBuf, *FileIt);
637 if (!llvm::sys::path::is_absolute(
FileName))
641 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
642 DIFileCache[
FileName.data()].reset(F);
648 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
649 if (llvm::sys::path::replace_path_prefix(P, From, To))
651 return P.str().str();
658 return SM.getPresumedLoc(
SM.getFileLoc(Loc)).getLine();
661unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
671 SM.getPresumedLoc(Loc.
isValid() ?
SM.getFileLoc(Loc) : CurLoc);
675StringRef CGDebugInfo::getCurrentDirname() {
683 assert(CGO.DwarfVersion <= 5);
685 llvm::dwarf::SourceLanguage LangTag;
688 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
689 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
690 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
691 else if (LO.CPlusPlus14)
692 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
693 else if (LO.CPlusPlus11)
694 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
696 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
697 }
else if (LO.ObjC) {
698 LangTag = llvm::dwarf::DW_LANG_ObjC;
699 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
700 LangTag = llvm::dwarf::DW_LANG_OpenCL;
701 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
702 LangTag = llvm::dwarf::DW_LANG_C11;
704 LangTag = llvm::dwarf::DW_LANG_C99;
706 LangTag = llvm::dwarf::DW_LANG_C89;
712static llvm::DISourceLanguageName
720 uint32_t LangVersion = 0;
721 llvm::dwarf::SourceLanguageName LangTag;
724 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
726 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
729 }
else if (LO.ObjC) {
730 LangTag = llvm::dwarf::DW_LNAME_ObjC;
731 }
else if (LO.OpenCL) {
732 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
734 LangTag = llvm::dwarf::DW_LNAME_C;
738 return llvm::DISourceLanguageName(LangTag, LangVersion);
741void CGDebugInfo::CreateCompileUnit() {
742 SmallString<64> Checksum;
743 std::optional<llvm::DIFile::ChecksumKind> CSKind;
744 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
754 SourceManager &
SM = CGM.getContext().getSourceManager();
755 auto &CGO = CGM.getCodeGenOpts();
756 const LangOptions &LO = CGM.getLangOpts();
757 std::string MainFileName = CGO.MainFileName;
758 if (MainFileName.empty())
759 MainFileName =
"<stdin>";
765 std::string MainFileDir;
767 SM.getFileEntryRefForID(
SM.getMainFileID())) {
768 MainFileDir = std::string(MainFile->getDir().getName());
769 if (!llvm::sys::path::is_absolute(MainFileName)) {
770 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
771 llvm::sys::path::Style Style =
773 ? (CGM.getTarget().getTriple().isOSWindows()
774 ? llvm::sys::path::Style::windows_backslash
775 : llvm::sys::path::Style::posix)
776 : llvm::sys::path::Style::native;
777 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
778 MainFileName = std::string(
779 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
786 if (MainFile->getName() == MainFileName &&
788 MainFile->getName().rsplit(
'.').second)
790 MainFileName = CGM.getModule().getName().str();
792 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
799 unsigned RuntimeVers = 0;
803 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
805 case llvm::codegenoptions::NoDebugInfo:
806 case llvm::codegenoptions::LocTrackingOnly:
807 EmissionKind = llvm::DICompileUnit::NoDebug;
809 case llvm::codegenoptions::DebugLineTablesOnly:
810 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
812 case llvm::codegenoptions::DebugDirectivesOnly:
813 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
815 case llvm::codegenoptions::DebugInfoConstructor:
816 case llvm::codegenoptions::LimitedDebugInfo:
817 case llvm::codegenoptions::FullDebugInfo:
818 case llvm::codegenoptions::UnusedTypeInfo:
819 EmissionKind = llvm::DICompileUnit::FullDebug;
824 auto &CGOpts = CGM.getCodeGenOpts();
830 CSInfo.emplace(*CSKind, Checksum);
831 llvm::DIFile *CUFile = DBuilder.createFile(
833 getSource(
SM,
SM.getMainFileID()));
835 StringRef Sysroot, SDK;
836 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
837 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
838 auto B = llvm::sys::path::rbegin(Sysroot);
839 auto E = llvm::sys::path::rend(Sysroot);
841 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
846 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
847 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
848 CGOpts.DebugNameTable);
849 if (CGM.getTarget().getTriple().isNVPTX())
850 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
851 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
852 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
855 TheCU = DBuilder.createCompileUnit(
857 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
858 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
859 CGOpts.PrepareForThinLTO,
860 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
861 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
862 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
865llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
869#define BUILTIN_TYPE(Id, SingletonId)
870#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
871#include "clang/AST/BuiltinTypes.def"
872 case BuiltinType::Dependent:
873 llvm_unreachable(
"Unexpected builtin type");
874 case BuiltinType::NullPtr:
875 return DBuilder.createNullPtrType();
876 case BuiltinType::Void:
878 case BuiltinType::ObjCClass:
881 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
882 "objc_class", TheCU, TheCU->getFile(), 0);
884 case BuiltinType::ObjCId: {
895 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
896 "objc_class", TheCU, TheCU->getFile(), 0);
898 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
900 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
902 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
903 (uint64_t)0, 0, llvm::DINode::FlagZero,
904 nullptr, llvm::DINodeArray());
906 DBuilder.replaceArrays(
907 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
908 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
909 llvm::DINode::FlagZero, ISATy)));
912 case BuiltinType::ObjCSel: {
914 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
915 "objc_selector", TheCU,
916 TheCU->getFile(), 0);
920#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
921 case BuiltinType::Id: \
922 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
924#include "clang/Basic/OpenCLImageTypes.def"
925 case BuiltinType::OCLSampler:
926 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
927 case BuiltinType::OCLEvent:
928 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
929 case BuiltinType::OCLClkEvent:
930 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
931 case BuiltinType::OCLQueue:
932 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
933 case BuiltinType::OCLReserveID:
934 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
935#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
936 case BuiltinType::Id: \
937 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
938#include "clang/Basic/OpenCLExtensionTypes.def"
939#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
940 case BuiltinType::Id: \
941 return getOrCreateStructPtrType(#Name, SingletonId);
942#include "clang/Basic/HLSLIntangibleTypes.def"
944#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
945#include "clang/Basic/AArch64ACLETypes.def"
947 if (BT->
getKind() == BuiltinType::MFloat8) {
948 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
949 BTName = BT->
getName(CGM.getLangOpts());
952 return DBuilder.createBasicType(BTName, Size, Encoding);
954 ASTContext::BuiltinVectorTypeInfo Info =
956 BT->
getKind() == BuiltinType::SveCount
957 ? ASTContext::BuiltinVectorTypeInfo(
958 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
960 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
967 "Unsupported number of vectors for svcount_t");
969 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
970 llvm::Metadata *BitStride =
nullptr;
971 if (BT->
getKind() == BuiltinType::SveBool) {
972 Info.
ElementType = CGM.getContext().UnsignedCharTy;
973 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
974 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
975 }
else if (BT->
getKind() == BuiltinType::SveCount) {
977 Info.
ElementType = CGM.getContext().UnsignedCharTy;
980 llvm::Metadata *LowerBound, *UpperBound;
981 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
982 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
983 if (Info.
EC.isScalable()) {
984 unsigned NumElemsPerVG = NumElems / 2;
985 SmallVector<uint64_t, 9> Expr(
986 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
987 46, 0, llvm::dwarf::DW_OP_mul,
988 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
989 UpperBound = DBuilder.createExpression(Expr);
991 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
992 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
994 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
995 nullptr, LowerBound, UpperBound,
nullptr);
996 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
997 llvm::DIType *ElemTy =
998 getOrCreateType(Info.
ElementType, TheCU->getFile());
1000 return DBuilder.createVectorType( 0, Align, ElemTy,
1001 SubscriptArray, BitStride);
1005#define PPC_VECTOR_TYPE(Name, Id, size) \
1006 case BuiltinType::Id:
1007#include "clang/Basic/PPCTypes.def"
1010#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1011#include "clang/Basic/RISCVVTypes.def"
1013 ASTContext::BuiltinVectorTypeInfo Info =
1014 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1016 unsigned ElementCount = Info.
EC.getKnownMinValue();
1017 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1019 bool Fractional =
false;
1022 unsigned FixedSize = ElementCount * SEW;
1023 if (Info.
ElementType == CGM.getContext().BoolTy) {
1026 }
else if (FixedSize < 64) {
1029 LMUL = 64 / FixedSize;
1031 LMUL = FixedSize / 64;
1035 SmallVector<uint64_t, 12> Expr(
1039 {llvm::dwarf::DW_OP_bregx,
1042 llvm::dwarf::DW_OP_constu,
1044 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1046 Expr.push_back(llvm::dwarf::DW_OP_div);
1048 Expr.push_back(llvm::dwarf::DW_OP_mul);
1051 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1053 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1056 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1057 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1058 auto *UpperBound = DBuilder.createExpression(Expr);
1059 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1060 nullptr, LowerBound, UpperBound,
nullptr);
1061 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1062 llvm::DIType *ElemTy =
1063 getOrCreateType(Info.
ElementType, TheCU->getFile());
1066 return DBuilder.createVectorType(0, Align, ElemTy,
1070#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1071 case BuiltinType::Id: { \
1074 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1075 MangledName, TheCU, TheCU->getFile(), 0); \
1076 return SingletonId; \
1078#include "clang/Basic/WebAssemblyReferenceTypes.def"
1079#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1080 case BuiltinType::Id: { \
1083 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1084 TheCU, TheCU->getFile(), 0); \
1085 return SingletonId; \
1087#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1088 case BuiltinType::Id: { \
1091 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1092 return SingletonId; \
1094#include "clang/Basic/AMDGPUTypes.def"
1095 case BuiltinType::UChar:
1096 case BuiltinType::Char_U:
1097 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1099 case BuiltinType::Char_S:
1100 case BuiltinType::SChar:
1101 Encoding = llvm::dwarf::DW_ATE_signed_char;
1103 case BuiltinType::Char8:
1104 case BuiltinType::Char16:
1105 case BuiltinType::Char32:
1106 Encoding = llvm::dwarf::DW_ATE_UTF;
1108 case BuiltinType::UShort:
1109 case BuiltinType::UInt:
1110 case BuiltinType::UInt128:
1111 case BuiltinType::ULong:
1112 case BuiltinType::WChar_U:
1113 case BuiltinType::ULongLong:
1114 Encoding = llvm::dwarf::DW_ATE_unsigned;
1116 case BuiltinType::Short:
1117 case BuiltinType::Int:
1118 case BuiltinType::Int128:
1119 case BuiltinType::Long:
1120 case BuiltinType::WChar_S:
1121 case BuiltinType::LongLong:
1122 Encoding = llvm::dwarf::DW_ATE_signed;
1124 case BuiltinType::Bool:
1125 Encoding = llvm::dwarf::DW_ATE_boolean;
1127 case BuiltinType::Half:
1128 case BuiltinType::Float:
1129 case BuiltinType::LongDouble:
1130 case BuiltinType::Float16:
1131 case BuiltinType::BFloat16:
1132 case BuiltinType::Float128:
1133 case BuiltinType::Double:
1134 case BuiltinType::Ibm128:
1140 Encoding = llvm::dwarf::DW_ATE_float;
1142 case BuiltinType::ShortAccum:
1143 case BuiltinType::Accum:
1144 case BuiltinType::LongAccum:
1145 case BuiltinType::ShortFract:
1146 case BuiltinType::Fract:
1147 case BuiltinType::LongFract:
1148 case BuiltinType::SatShortFract:
1149 case BuiltinType::SatFract:
1150 case BuiltinType::SatLongFract:
1151 case BuiltinType::SatShortAccum:
1152 case BuiltinType::SatAccum:
1153 case BuiltinType::SatLongAccum:
1154 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1156 case BuiltinType::UShortAccum:
1157 case BuiltinType::UAccum:
1158 case BuiltinType::ULongAccum:
1159 case BuiltinType::UShortFract:
1160 case BuiltinType::UFract:
1161 case BuiltinType::ULongFract:
1162 case BuiltinType::SatUShortAccum:
1163 case BuiltinType::SatUAccum:
1164 case BuiltinType::SatULongAccum:
1165 case BuiltinType::SatUShortFract:
1166 case BuiltinType::SatUFract:
1167 case BuiltinType::SatULongFract:
1168 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1172 BTName = BT->
getName(CGM.getLangOpts());
1175 return DBuilder.createBasicType(BTName, Size, Encoding);
1178llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1179 SmallString<32> Name;
1180 llvm::raw_svector_ostream
OS(Name);
1181 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1184 ? llvm::dwarf::DW_ATE_unsigned
1185 : llvm::dwarf::DW_ATE_signed;
1186 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1187 Encoding, llvm::DINode::FlagZero, 0,
1191llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1193 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1195 Encoding = llvm::dwarf::DW_ATE_lo_user;
1198 return DBuilder.createBasicType(
"complex", Size, Encoding);
1212 return llvm::dwarf::DW_TAG_const_type;
1216 return llvm::dwarf::DW_TAG_volatile_type;
1220 return llvm::dwarf::DW_TAG_restrict_type;
1222 return (llvm::dwarf::Tag)0;
1225llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1226 llvm::DIFile *Unit) {
1227 QualifierCollector Qc;
1241 bool AuthenticatesNullValues =
1244 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1245 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1246 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1247 ExtraDiscr, IsaPointer,
1248 AuthenticatesNullValues);
1250 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1251 return getOrCreateType(QualType(
T, 0), Unit);
1255 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1259 return DBuilder.createQualifiedType(Tag, FromTy);
1262llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1263 llvm::DIFile *Unit) {
1272 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1277 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1283 return DBuilder.createQualifiedType(Tag, FromTy);
1286llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1287 llvm::DIFile *Unit) {
1293 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1295 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1299llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1300 llvm::DIFile *Unit) {
1301 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1307 case llvm::dwarf::DW_LANG_C_plus_plus:
1308 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1309 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1311 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1321 case llvm::dwarf::DW_LNAME_C_plus_plus:
1323 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1334 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1335 SourceLang.hasVersionedName())
1337 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1341 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1367 llvm::DICompileUnit *TheCU) {
1385 llvm::DICompileUnit *TheCU) {
1391 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1393 if (RD->isDynamicClass() &&
1399 llvm::raw_svector_ostream Out(Identifier);
1406 llvm::dwarf::Tag Tag;
1408 Tag = llvm::dwarf::DW_TAG_structure_type;
1410 Tag = llvm::dwarf::DW_TAG_union_type;
1415 Tag = llvm::dwarf::DW_TAG_class_type;
1420llvm::DICompositeType *
1421CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1422 llvm::DIScope *Ctx) {
1423 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1424 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1426 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1427 const unsigned Line =
1429 StringRef RDName = getClassName(RD);
1436 Size = CGM.getContext().getTypeSize(Ty);
1438 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1443 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1444 if (!CXXRD->hasDefinition() ||
1445 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1446 Flags |= llvm::DINode::FlagNonTrivial;
1449 SmallString<256> Identifier;
1451 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1453 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1456 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1457 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1458 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1459 CollectCXXTemplateParams(TSpecial, DefUnit));
1460 ReplaceMap.emplace_back(
1461 std::piecewise_construct, std::make_tuple(Ty),
1462 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1466llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1469 llvm::DIFile *Unit) {
1474 std::optional<unsigned> DWARFAddressSpace =
1475 CGM.getTarget().getDWARFAddressSpace(
1476 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1478 const BTFTagAttributedType *BTFAttrTy;
1479 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1480 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1482 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1483 SmallVector<llvm::Metadata *, 4> Annots;
1485 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1487 llvm::Metadata *Ops[2] = {
1488 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1489 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1490 Annots.insert(Annots.begin(),
1491 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1493 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1496 llvm::DINodeArray Annotations =
nullptr;
1497 if (Annots.size() > 0)
1498 Annotations = DBuilder.getOrCreateArray(Annots);
1500 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1501 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1502 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1503 Size, Align, DWARFAddressSpace);
1505 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1506 Align, DWARFAddressSpace, StringRef(),
1510llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1511 llvm::DIType *&
Cache) {
1514 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1515 TheCU, TheCU->getFile(), 0);
1516 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1517 Cache = DBuilder.createPointerType(
Cache, Size);
1521uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1522 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1523 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1533 if (CGM.getLangOpts().OpenCL) {
1534 FType = CGM.getContext().IntTy;
1535 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1536 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1538 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1539 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1540 FType = CGM.getContext().IntTy;
1541 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1542 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1544 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1545 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1546 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1547 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1548 EltTys.push_back(DBuilder.createMemberType(
1549 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1550 FieldOffset, llvm::DINode::FlagZero, DescTy));
1551 FieldOffset += FieldSize;
1557llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1558 llvm::DIFile *Unit) {
1559 SmallVector<llvm::Metadata *, 8> EltTys;
1562 llvm::DINodeArray Elements;
1565 FType = CGM.getContext().UnsignedLongTy;
1566 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1567 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1569 Elements = DBuilder.getOrCreateArray(EltTys);
1572 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1575 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1576 FieldOffset, 0, Flags,
nullptr, Elements);
1581 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1583 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1586 Elements = DBuilder.getOrCreateArray(EltTys);
1592 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1593 Flags,
nullptr, Elements);
1595 return DBuilder.createPointerType(EltTy, Size);
1598static llvm::SmallVector<TemplateArgument>
1600 assert(Ty->isTypeAlias());
1609 ArrayRef SubstArgs = Ty->template_arguments();
1612 if (Param->isParameterPack()) {
1621 if (SubstArgs.empty()) {
1630 SpecArgs.push_back(SubstArgs.front());
1631 SubstArgs = SubstArgs.drop_front();
1636llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1637 llvm::DIFile *Unit) {
1638 assert(Ty->isTypeAlias());
1639 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1641 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1649 SmallString<128> NS;
1650 llvm::raw_svector_ostream
OS(NS);
1652 auto PP = getPrintingPolicy();
1655 SourceLocation Loc =
AliasDecl->getLocation();
1657 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1658 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1667 llvm::raw_string_ostream
OS(Name);
1669 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1670 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1671 !HasReconstitutableArgs(Args.Args))
1672 printTemplateArgumentList(OS, Args.Args, PP);
1674 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1675 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1676 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1680 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1682 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1699 return llvm::DINode::FlagZero;
1703 return llvm::DINode::FlagPrivate;
1705 return llvm::DINode::FlagProtected;
1707 return llvm::DINode::FlagPublic;
1709 return llvm::DINode::FlagZero;
1711 llvm_unreachable(
"unexpected access enumerator");
1714llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1715 llvm::DIFile *Unit) {
1716 llvm::DIType *Underlying =
1728 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1730 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1735 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1736 getOrCreateFile(Loc), getLineNumber(Loc),
1737 getDeclContextDescriptor(Ty->
getDecl()), Align,
1738 Flags, Annotations);
1748 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1750 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1752 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1754 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1756 return llvm::dwarf::DW_CC_BORLAND_pascal;
1758 return llvm::dwarf::DW_CC_LLVM_Win64;
1760 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1764 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1766 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1768 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1770 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1772 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1774 return llvm::dwarf::DW_CC_LLVM_Swift;
1776 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1778 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1780 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1782 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1784 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1786 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1788 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1789#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1803 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1809 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1811 Flags |= llvm::DINode::FlagLValueReference;
1813 Flags |= llvm::DINode::FlagRValueReference;
1817llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1818 llvm::DIFile *Unit) {
1819 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1821 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1827 SmallVector<llvm::Metadata *, 16> EltTys;
1830 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1832 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1836 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1839 for (
const QualType &ParamType : FPT->param_types())
1840 EltTys.push_back(getOrCreateType(ParamType, Unit));
1841 if (FPT->isVariadic())
1842 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1845 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1846 llvm::DIType *F = DBuilder.createSubroutineType(
1851llvm::DIDerivedType *
1852CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1853 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1854 StringRef Name = BitFieldDecl->
getName();
1855 QualType Ty = BitFieldDecl->
getType();
1856 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1859 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1860 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1863 llvm::DIFile *
File = getOrCreateFile(Loc);
1864 unsigned Line = getLineNumber(Loc);
1866 const CGBitFieldInfo &BitFieldInfo =
1867 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1869 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1876 if (CGM.getDataLayout().isBigEndian())
1878 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1880 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1881 return DBuilder.createBitFieldMemberType(
1882 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1883 Flags, DebugType, Annotations);
1886llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1887 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1888 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1890 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1915 if (PreviousFieldsDI.empty())
1919 auto *PreviousMDEntry =
1920 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1921 auto *PreviousMDField =
1922 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1923 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1924 PreviousMDField->getSizeInBits() == 0)
1928 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1930 assert(PreviousBitfield->isBitField());
1932 if (!PreviousBitfield->isZeroLengthBitField())
1935 QualType Ty = PreviousBitfield->getType();
1936 SourceLocation Loc = PreviousBitfield->getLocation();
1937 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1938 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1939 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1941 llvm::DIFile *
File = getOrCreateFile(Loc);
1942 unsigned Line = getLineNumber(Loc);
1948 llvm::DINode::DIFlags Flags =
1950 llvm::DINodeArray Annotations =
1951 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1952 return DBuilder.createBitFieldMemberType(
1953 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1954 Flags, DebugType, Annotations);
1957llvm::DIType *CGDebugInfo::createFieldType(
1959 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1960 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1961 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1964 llvm::DIFile *file = getOrCreateFile(loc);
1965 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1968 auto Align = AlignInBits;
1969 if (!
type->isIncompleteArrayType()) {
1970 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
1971 SizeInBits = TI.
Width;
1977 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1978 offsetInBits, flags, debugType, Annotations);
1982CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1983 llvm::DIFile *FileScope) {
1987 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1990 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1991 SP = DBuilder.createFunction(
1992 FileScope, FuncName, StringRef(),
1993 FileScope, 0, DIFnTy,
1995 llvm::DINode::FlagArtificial,
1996 llvm::DISubprogram::SPFlagDefinition,
1997 nullptr,
nullptr,
nullptr,
1998 nullptr, StringRef(),
1999 CGM.getCodeGenOpts().DebugKeyInstructions);
2006CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2008 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2010 assert(
Capture.capturesVariable());
2012 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2013 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2015 return CaptureDecl->
getName();
2018void CGDebugInfo::CollectRecordLambdaFields(
2019 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2020 llvm::DIType *RecordTy) {
2025 unsigned fieldno = 0;
2028 I != E; ++I, ++Field, ++fieldno) {
2029 const LambdaCapture &
Capture = *I;
2031 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2033 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2043 Loc =
Field->getLocation();
2044 }
else if (
Capture.capturesVariable()) {
2047 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2048 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2055 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2057 elements.push_back(createFieldType(
2059 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2063llvm::DIDerivedType *
2064CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2065 const RecordDecl *RD) {
2069 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2070 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2072 unsigned LineNumber = getLineNumber(Var->
getLocation());
2073 StringRef VName = Var->
getName();
2077 llvm::Constant *
C =
nullptr;
2082 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2083 if (
Value->isFloat())
2084 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2089 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2090 ? llvm::dwarf::DW_TAG_variable
2091 : llvm::dwarf::DW_TAG_member;
2093 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2094 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2099void CGDebugInfo::CollectRecordNormalField(
2100 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2101 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2102 const RecordDecl *RD) {
2107 if (
name.empty() && !
type->isRecordType())
2110 llvm::DIType *FieldType;
2112 llvm::DIDerivedType *BitFieldType;
2113 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2114 if (llvm::DIType *Separator =
2115 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2116 elements.push_back(Separator);
2119 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2122 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2125 elements.push_back(FieldType);
2128void CGDebugInfo::CollectRecordNestedType(
2129 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2130 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2137 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2138 elements.push_back(nestedType);
2141void CGDebugInfo::CollectRecordFields(
2142 const RecordDecl *record, llvm::DIFile *tunit,
2143 SmallVectorImpl<llvm::Metadata *> &elements,
2144 llvm::DICompositeType *RecordTy) {
2145 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2147 if (CXXDecl && CXXDecl->
isLambda())
2148 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2150 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2153 unsigned fieldNo = 0;
2157 for (
const auto *I : record->
decls())
2158 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2159 if (
V->hasAttr<NoDebugAttr>())
2164 if (CGM.getCodeGenOpts().EmitCodeView &&
2172 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2173 if (MI != StaticDataMemberCache.end()) {
2174 assert(MI->second &&
2175 "Static data member declaration should still exist");
2176 elements.push_back(MI->second);
2178 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2179 elements.push_back(Field);
2181 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2182 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2183 elements, RecordTy, record);
2187 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2190 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2195 if (!nestedType->isImplicit() &&
2196 nestedType->getDeclContext() == record)
2197 CollectRecordNestedType(nestedType, elements);
2203llvm::DISubroutineType *
2204CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2205 llvm::DIFile *Unit) {
2206 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2208 return cast_or_null<llvm::DISubroutineType>(
2209 getOrCreateType(QualType(
Func, 0), Unit));
2212 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2213 ThisType =
Method->getThisType();
2215 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2218llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2219 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2220 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2222 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2225llvm::DISubroutineType *
2226CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2227 const FunctionProtoType *
Func,
2228 llvm::DIFile *Unit,
bool SkipFirst) {
2229 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2244 getOrCreateType(CGM.getContext().getFunctionType(
2245 Func->getReturnType(),
Func->getParamTypes(), EPI),
2247 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2248 assert(Args.size() &&
"Invalid number of arguments!");
2250 SmallVector<llvm::Metadata *, 16> Elts;
2253 Elts.push_back(Args[0]);
2255 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2259 if (!HasExplicitObjectParameter) {
2260 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2263 DBuilder.createObjectPointerType(ThisPtrType,
true);
2264 Elts.push_back(ThisPtrType);
2268 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2269 Elts.push_back(Args[i]);
2272 if (HasExplicitObjectParameter) {
2273 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2274 "Expected at least return type and object parameter.");
2275 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2278 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2280 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2287 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2295CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2298 const bool IsCtorOrDtor =
2301 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2308 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2311 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2314 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2317 return CGM.getMangledName(
Method);
2320llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2321 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2324 StringRef MethodName = getFunctionName(
Method);
2325 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2327 StringRef MethodLinkageName;
2334 MethodLinkageName = GetMethodLinkageName(
Method);
2337 llvm::DIFile *MethodDefUnit =
nullptr;
2338 unsigned MethodLine = 0;
2339 if (!
Method->isImplicit()) {
2340 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2341 MethodLine = getLineNumber(
Method->getLocation());
2345 llvm::DIType *ContainingType =
nullptr;
2346 unsigned VIndex = 0;
2347 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2348 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2349 int ThisAdjustment = 0;
2352 if (
Method->isPureVirtual())
2353 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2355 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2357 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2361 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2365 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2368 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2369 CGM.getContext().getLangOpts())
2373 MethodVFTableLocation ML =
2374 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2382 if (
Method->size_overridden_methods() == 0)
2383 Flags |= llvm::DINode::FlagIntroducedVirtual;
2388 ThisAdjustment = CGM.getCXXABI()
2389 .getVirtualFunctionPrologueThisAdjustment(GD)
2392 ContainingType = RecordTy;
2395 if (
Method->getCanonicalDecl()->isDeleted())
2396 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2398 if (
Method->isNoReturn())
2399 Flags |= llvm::DINode::FlagNoReturn;
2402 Flags |= llvm::DINode::FlagStaticMember;
2403 if (
Method->isImplicit())
2404 Flags |= llvm::DINode::FlagArtificial;
2406 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2407 if (CXXC->isExplicit())
2408 Flags |= llvm::DINode::FlagExplicit;
2409 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2410 if (CXXC->isExplicit())
2411 Flags |= llvm::DINode::FlagExplicit;
2413 if (
Method->hasPrototype())
2414 Flags |= llvm::DINode::FlagPrototyped;
2416 Flags |= llvm::DINode::FlagLValueReference;
2418 Flags |= llvm::DINode::FlagRValueReference;
2419 if (!
Method->isExternallyVisible())
2420 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2421 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2422 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2426 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2427 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2430 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2431 llvm::DISubprogram *SP = DBuilder.createMethod(
2432 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2433 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2434 TParamsArray.get(),
nullptr,
2435 CGM.getCodeGenOpts().DebugKeyInstructions);
2437 SPCache[
Method->getCanonicalDecl()].reset(SP);
2442void CGDebugInfo::CollectCXXMemberFunctions(
2443 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2444 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2449 for (
const auto *I : RD->
decls()) {
2450 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2464 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2473 auto MI = SPCache.find(
Method->getCanonicalDecl());
2474 EltTys.push_back(MI == SPCache.end()
2475 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2476 :
static_cast<llvm::Metadata *
>(MI->second));
2480void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2481 SmallVectorImpl<llvm::Metadata *> &EltTys,
2482 llvm::DIType *RecordTy) {
2483 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2484 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2485 llvm::DINode::FlagZero);
2489 if (CGM.getCodeGenOpts().EmitCodeView) {
2490 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2491 llvm::DINode::FlagIndirectVirtualBase);
2495void CGDebugInfo::CollectCXXBasesAux(
2496 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2497 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2499 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2500 llvm::DINode::DIFlags StartingFlags) {
2501 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2502 for (
const auto &BI : Bases) {
2505 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2507 if (!SeenTypes.insert(Base).second)
2509 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2510 llvm::DINode::DIFlags BFlags = StartingFlags;
2514 if (BI.isVirtual()) {
2515 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2518 BaseOffset = 0 - CGM.getItaniumVTableContext()
2519 .getVirtualBaseOffsetOffset(RD, Base)
2525 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2526 VBPtrOffset = CGM.getContext()
2527 .getASTRecordLayout(RD)
2531 BFlags |= llvm::DINode::FlagVirtual;
2538 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2539 VBPtrOffset, BFlags);
2540 EltTys.push_back(DTy);
2545CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2546 llvm::DIFile *Unit) {
2548 return llvm::DINodeArray();
2549 TemplateArgs &Args = *OArgs;
2550 SmallVector<llvm::Metadata *, 16> TemplateParams;
2551 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2552 const TemplateArgument &TA = Args.Args[i];
2556 Name = Args.TList->getParam(i)->getName();
2560 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2561 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2562 TheCU, Name, TTy, defaultParameter));
2567 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2568 TheCU, Name, TTy, defaultParameter,
2569 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2574 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2575 llvm::Constant *
V =
nullptr;
2578 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2579 !D->
hasAttr<CUDADeviceAttr>()) {
2582 if (
const auto *VD = dyn_cast<VarDecl>(D))
2583 V = CGM.GetAddrOfGlobalVar(VD);
2586 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2587 MD && MD->isImplicitObjectMemberFunction())
2588 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2589 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2590 V = CGM.GetAddrOfFunction(FD);
2593 else if (
const auto *MPT =
2594 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2598 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2600 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2601 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2602 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2603 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2604 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2606 V = ConstantEmitter(CGM).emitAbstract(
2607 SourceLocation(), TPO->getValue(), TPO->getType());
2609 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2611 assert(
V &&
"Failed to find template parameter pointer");
2612 V =
V->stripPointerCasts();
2614 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2615 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2619 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2620 llvm::Constant *
V =
nullptr;
2623 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2629 if (MPT->isMemberDataPointer())
2630 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2632 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2633 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2634 TheCU, Name, TTy, defaultParameter,
V));
2638 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2639 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2641 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2642 TheCU, Name, TTy, defaultParameter,
V));
2645 std::string QualName;
2646 llvm::raw_string_ostream
OS(QualName);
2648 OS, getPrintingPolicy());
2649 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2650 TheCU, Name,
nullptr, QualName, defaultParameter));
2654 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2655 TheCU, Name,
nullptr,
2662 T = CGM.getContext().getLValueReferenceType(
T);
2663 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2664 assert(
V &&
"Expression in template argument isn't constant");
2665 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2666 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2667 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2673 "These argument types shouldn't exist in concrete types");
2676 return DBuilder.getOrCreateArray(TemplateParams);
2679std::optional<CGDebugInfo::TemplateArgs>
2680CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2688 return std::nullopt;
2690std::optional<CGDebugInfo::TemplateArgs>
2691CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2695 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2697 return std::nullopt;
2698 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2699 const TemplateParameterList *TList =
T->getTemplateParameters();
2700 auto TA = TS->getTemplateArgs().asArray();
2701 return {{TList, TA}};
2703std::optional<CGDebugInfo::TemplateArgs>
2704CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2705 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2709 TemplateParameterList *TPList =
2710 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2711 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2712 return {{TPList, TAList.
asArray()}};
2714 return std::nullopt;
2718CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2719 llvm::DIFile *Unit) {
2720 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2723llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2724 llvm::DIFile *Unit) {
2725 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2728llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2729 llvm::DIFile *Unit) {
2730 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2733llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2734 if (!D->
hasAttr<BTFDeclTagAttr>())
2737 SmallVector<llvm::Metadata *, 4> Annotations;
2739 llvm::Metadata *Ops[2] = {
2740 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2741 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2742 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2744 return DBuilder.getOrCreateArray(Annotations);
2747llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2749 return VTablePtrType;
2751 ASTContext &Context = CGM.getContext();
2754 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2755 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2756 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2758 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2759 std::optional<unsigned> DWARFAddressSpace =
2760 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2762 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2763 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2764 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2765 return VTablePtrType;
2768StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2780 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2782 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2792 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2793 VTable->isDeclarationForLinker())
2797 StringRef SymbolName =
"_vtable$";
2799 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2808 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2810 llvm::DIFile *Unit = getOrCreateFile(Loc);
2811 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2813 llvm::DINode::FlagArtificial;
2814 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2815 ? llvm::dwarf::DW_TAG_variable
2816 : llvm::dwarf::DW_TAG_member;
2817 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2818 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2822 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2826 llvm::DIGlobalVariableExpression *GVE =
2827 DBuilder.createGlobalVariableExpression(
2828 TheCU, SymbolName, VTable->getName(), Unit, 0,
2829 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2830 true,
nullptr, DT,
nullptr,
2832 VTable->addDebugInfo(GVE);
2835StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2837 llvm::Function *InitFn) {
2842 return InitFn->getName();
2852 llvm::raw_svector_ostream OS(QualifiedGV);
2854 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2856 std::swap(Quals, GVName);
2860 llvm::raw_svector_ostream OS(InitName);
2862 OS << Quals <<
"::";
2867 llvm_unreachable(
"not an initializer");
2869 OS <<
"`dynamic initializer for '";
2872 OS <<
"`dynamic atexit destructor for '";
2879 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2880 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2881 getPrintingPolicy());
2886 return internString(
OS.str());
2889void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2890 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2899 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2906 llvm::DIType *VPtrTy =
nullptr;
2907 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2908 CGM.getTarget().getCXXABI().isMicrosoft();
2909 if (NeedVTableShape) {
2911 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2912 const VTableLayout &VFTLayout =
2913 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
2914 unsigned VSlotCount =
2916 unsigned VTableWidth = PtrWidth * VSlotCount;
2917 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2918 std::optional<unsigned> DWARFAddressSpace =
2919 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2922 llvm::DIType *VTableType = DBuilder.createPointerType(
2923 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2924 EltTys.push_back(VTableType);
2927 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2935 VPtrTy = getOrCreateVTablePtrType(Unit);
2937 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
2938 llvm::DIType *VPtrMember =
2939 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2940 llvm::DINode::FlagArtificial, VPtrTy);
2941 EltTys.push_back(VPtrMember);
2946 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2947 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2958 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
2959 assert(!D.
isNull() &&
"null type");
2960 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2961 assert(
T &&
"could not create debug info for type");
2970 if (CGM.getCodeGenOpts().getDebugInfo() <=
2971 llvm::codegenoptions::DebugLineTablesOnly)
2975 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
2977 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2979 CI->setMetadata(
"heapallocsite", node);
2983 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2985 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
2987 auto I = TypeCache.find(TyPtr);
2990 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2991 assert(!Res->isForwardDecl());
2992 TypeCache[TyPtr].reset(Res);
2996 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2997 !CGM.getLangOpts().CPlusPlus)
3003 if (RD->
hasAttr<DLLImportAttr>())
3006 if (MD->hasAttr<DLLImportAttr>())
3019 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3029 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3030 Explicit = TD->isExplicitInstantiationOrSpecialization();
3034 if (CXXDecl->
fields().empty())
3044 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3045 if (CXXRD->isDynamicClass() &&
3046 CGM.getVTableLinkage(CXXRD) ==
3047 llvm::GlobalValue::AvailableExternallyLinkage &&
3058 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3060 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3062 auto I = TypeCache.find(TyPtr);
3069 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3070 assert(!Res->isForwardDecl());
3071 TypeCache[TyPtr].reset(Res);
3078 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3079 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3102 if (Ctor->isCopyOrMoveConstructor())
3104 if (!Ctor->isDeleted())
3123 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3126 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3127 RD->
hasAttr<StandaloneDebugAttr>())
3130 if (!LangOpts.CPlusPlus)
3136 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3152 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3153 Spec = SD->getSpecializationKind();
3162 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3173 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3174 llvm::DIType *
T = getTypeOrNull(Ty);
3175 if (
T &&
T->isForwardDecl())
3179llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3180 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3181 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3185 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3189 auto [Def, Pref] = CreateTypeDefinition(Ty);
3191 return Pref ? Pref : Def;
3194llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3195 llvm::DIFile *Unit) {
3199 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3203 return getOrCreateType(PNA->getTypedefType(), Unit);
3206std::pair<llvm::DIType *, llvm::DIType *>
3207CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3208 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3211 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3219 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3223 return {FwdDecl,
nullptr};
3225 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3226 CollectContainingType(CXXDecl, FwdDecl);
3229 LexicalBlockStack.emplace_back(&*FwdDecl);
3230 RegionMap[RD].reset(FwdDecl);
3233 SmallVector<llvm::Metadata *, 16> EltTys;
3240 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3242 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3243 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3247 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3248 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3249 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3251 LexicalBlockStack.pop_back();
3252 RegionMap.erase(RD);
3254 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3255 DBuilder.replaceArrays(FwdDecl, Elements);
3257 if (FwdDecl->isTemporary())
3259 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3261 RegionMap[RD].reset(FwdDecl);
3263 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3264 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3265 return {FwdDecl, PrefDI};
3267 return {FwdDecl,
nullptr};
3270llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3271 llvm::DIFile *Unit) {
3273 return getOrCreateType(Ty->getBaseType(), Unit);
3276llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3277 llvm::DIFile *Unit) {
3279 SourceLocation Loc = Ty->getDecl()->getLocation();
3282 return DBuilder.createTypedef(
3283 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3284 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3285 getDeclContextDescriptor(Ty->getDecl()));
3312llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3313 llvm::DIFile *Unit) {
3318 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3319 TheCU->getSourceLanguage().getUnversionedName());
3324 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3325 !
ID->getImplementation())
3326 return DBuilder.createForwardDecl(
3327 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3328 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3331 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3332 unsigned Line = getLineNumber(
ID->getLocation());
3336 ObjCInterfaceDecl *Def =
ID->getDefinition();
3338 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3339 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3340 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3341 DefUnit,
Line, RuntimeLang);
3342 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3346 return CreateTypeDefinition(Ty, Unit);
3349llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3350 bool CreateSkeletonCU) {
3355 auto ModRef = ModuleCache.find(M);
3356 if (ModRef != ModuleCache.end())
3360 SmallString<128> ConfigMacros;
3362 llvm::raw_svector_ostream
OS(ConfigMacros);
3363 const auto &PPOpts = CGM.getPreprocessorOpts();
3366 for (
auto &M : PPOpts.Macros) {
3369 const std::string &
Macro = M.first;
3370 bool Undef = M.second;
3371 OS <<
"\"-" << (Undef ?
'U' :
'D');
3387 bool IsRootModule = M ? !M->
Parent :
true;
3391 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3392 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3393 "clang module without ASTFile must be specified by -fmodule-name");
3396 auto RemapPath = [
this](StringRef Path) -> std::string {
3398 StringRef Relative(Remapped);
3399 StringRef CompDir = TheCU->getDirectory();
3400 if (CompDir.empty())
3403 if (Relative.consume_front(CompDir))
3404 Relative.consume_front(llvm::sys::path::get_separator());
3406 return Relative.str();
3409 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3416 Signature = ModSig.truncatedValue();
3420 llvm::DIBuilder DIB(CGM.getModule());
3422 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3423 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3424 PCM = getCurrentDirname();
3428 llvm::sys::path::append(PCM, Mod.
getASTFile());
3429 DIB.createCompileUnit(
3430 TheCU->getSourceLanguage(),
3433 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3434 llvm::DICompileUnit::FullDebug, Signature);
3438 llvm::DIModule *Parent =
3440 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3442 std::string IncludePath = Mod.
getPath().str();
3443 llvm::DIModule *DIMod =
3444 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3445 RemapPath(IncludePath));
3446 ModuleCache[M].reset(DIMod);
3450llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3451 llvm::DIFile *Unit) {
3453 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3454 unsigned Line = getLineNumber(
ID->getLocation());
3456 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3462 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3463 if (
ID->getImplementation())
3464 Flags |= llvm::DINode::FlagObjcClassComplete;
3466 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3467 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3468 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3469 nullptr, llvm::DINodeArray(), RuntimeLang);
3471 QualType QTy(Ty, 0);
3472 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3475 LexicalBlockStack.emplace_back(RealDecl);
3476 RegionMap[Ty->
getDecl()].reset(RealDecl);
3479 SmallVector<llvm::Metadata *, 16> EltTys;
3481 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3483 llvm::DIType *SClassTy =
3484 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3488 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3489 llvm::DINode::FlagZero);
3490 EltTys.push_back(InhTag);
3494 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3495 SourceLocation Loc = PD->getLocation();
3496 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3497 unsigned PLine = getLineNumber(Loc);
3498 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3499 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3500 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3501 PD->getName(), PUnit, PLine,
3503 : getSelectorName(PD->getGetterName()),
3505 : getSelectorName(PD->getSetterName()),
3506 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3507 EltTys.push_back(PropertyNode);
3512 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3516 llvm::DenseSet<IsClassAndIdent> PropertySet;
3518 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3519 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3521 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3522 for (
auto *PD : ClassExt->properties()) {
3523 PropertySet.insert(GetIsClassAndIdent(PD));
3526 for (
const auto *PD :
ID->properties()) {
3529 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3535 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3536 unsigned FieldNo = 0;
3537 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3538 Field =
Field->getNextIvar(), ++FieldNo) {
3539 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3543 StringRef FieldName =
Field->getName();
3546 if (FieldName.empty())
3550 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3551 unsigned FieldLine = getLineNumber(
Field->getLocation());
3552 QualType FType =
Field->getType();
3559 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3560 : CGM.getContext().getTypeSize(FType);
3565 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3569 if (
Field->isBitField()) {
3571 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3572 FieldOffset %= CGM.getContext().getCharWidth();
3580 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3582 Flags = llvm::DINode::FlagProtected;
3584 Flags = llvm::DINode::FlagPrivate;
3586 Flags = llvm::DINode::FlagPublic;
3588 if (
Field->isBitField())
3589 Flags |= llvm::DINode::FlagBitField;
3591 llvm::MDNode *PropertyNode =
nullptr;
3592 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3593 if (ObjCPropertyImplDecl *PImpD =
3594 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3595 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3596 SourceLocation Loc = PD->getLocation();
3597 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3598 unsigned PLine = getLineNumber(Loc);
3599 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3600 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3601 PropertyNode = DBuilder.createObjCProperty(
3602 PD->getName(), PUnit, PLine,
3605 : getSelectorName(PD->getGetterName()),
3608 : getSelectorName(PD->getSetterName()),
3609 PD->getPropertyAttributes(),
3610 getOrCreateType(PD->getType(), PUnit));
3614 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3615 FieldSize, FieldAlign, FieldOffset, Flags,
3616 FieldTy, PropertyNode);
3617 EltTys.push_back(FieldTy);
3620 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3621 DBuilder.replaceArrays(RealDecl, Elements);
3623 LexicalBlockStack.pop_back();
3627llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3628 llvm::DIFile *Unit) {
3636 auto &Ctx = CGM.getContext();
3641 QualType CharVecTy =
3643 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3646 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3649 llvm::Metadata *Subscript;
3650 QualType QTy(Ty, 0);
3651 auto SizeExpr = SizeExprCache.find(QTy);
3652 if (SizeExpr != SizeExprCache.end())
3653 Subscript = DBuilder.getOrCreateSubrange(
3654 SizeExpr->getSecond() ,
nullptr ,
3655 nullptr ,
nullptr );
3658 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3659 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3660 Subscript = DBuilder.getOrCreateSubrange(
3661 CountNode ,
nullptr ,
nullptr ,
3664 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3669 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3672llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3673 llvm::DIFile *Unit) {
3677 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3682 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3683 auto *ColumnCountNode =
3684 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3685 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3686 auto *RowCountNode =
3687 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3688 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3689 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3690 ColumnCountNode ,
nullptr ,
nullptr ,
3692 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3693 RowCountNode ,
nullptr ,
nullptr ,
3695 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3696 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3699llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3704 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3719 Size = CGM.getContext().getTypeSize(Ty);
3726 SmallVector<llvm::Metadata *, 8> Subscripts;
3727 QualType EltTy(Ty, 0);
3728 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3737 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3738 Count = CAT->getZExtSize();
3739 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3740 if (Expr *Size = VAT->getSizeExpr()) {
3742 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3743 Count =
Result.Val.getInt().getExtValue();
3747 auto SizeNode = SizeExprCache.find(EltTy);
3748 if (SizeNode != SizeExprCache.end())
3749 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3750 SizeNode->getSecond() ,
nullptr ,
3751 nullptr ,
nullptr ));
3754 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3755 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3756 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3757 CountNode ,
nullptr ,
nullptr ,
3763 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3765 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3769llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3770 llvm::DIFile *Unit) {
3771 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3775llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3776 llvm::DIFile *Unit) {
3777 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3779 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3780 CGM.getCodeGenOpts().DwarfVersion < 4)
3781 Tag = llvm::dwarf::DW_TAG_reference_type;
3783 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3786llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3788 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3792 Size = CGM.getContext().getTypeSize(Ty);
3795 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3798 Flags |= llvm::DINode::FlagSingleInheritance;
3801 Flags |= llvm::DINode::FlagMultipleInheritance;
3804 Flags |= llvm::DINode::FlagVirtualInheritance;
3814 llvm::DIType *ClassType = getOrCreateType(
T, U);
3816 return DBuilder.createMemberPointerType(
3820 const FunctionProtoType *FPT =
3822 return DBuilder.createMemberPointerType(
3823 getOrCreateInstanceMethodType(
3826 ClassType, Size, 0, Flags);
3829llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3831 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3834llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3838llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3840 return getOrCreateType(Ty->getWrappedType(), U);
3843llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3850 const EnumType *Ty) {
3862llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3865 bool isImportedFromModule =
3866 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3870 if (isImportedFromModule || !ED->getDefinition()) {
3877 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3878 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3879 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3880 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3882 unsigned Line = getLineNumber(ED->getLocation());
3883 StringRef EDName = ED->getName();
3884 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3885 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3886 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3888 ReplaceMap.emplace_back(
3889 std::piecewise_construct, std::make_tuple(Ty),
3890 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3894 return CreateTypeDefinition(Ty);
3897llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3900 SmallVector<llvm::Metadata *, 16> Enumerators;
3901 ED = ED->getDefinition();
3902 assert(ED &&
"An enumeration definition is required");
3903 for (
const auto *
Enum : ED->enumerators()) {
3904 Enumerators.push_back(
3905 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3908 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3909 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
3910 EnumKind = Attr->getExtensibility();
3913 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3915 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3916 unsigned Line = getLineNumber(ED->getLocation());
3917 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3918 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3919 return DBuilder.createEnumerationType(
3920 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3921 0, Identifier, ED->isScoped(), EnumKind);
3926 StringRef Name, StringRef
Value) {
3927 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3928 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
3934 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3935 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3936 return DBuilder.createTempMacroFile(Parent,
Line, FName);
3940 StringRef FuncName) {
3941 llvm::DISubprogram *SP =
3942 createInlinedSubprogram(FuncName, Location->getFile());
3943 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
3948 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
3954 FuncName += Category;
3956 FuncName += FailureMsg;
3968 Quals += InnerQuals;
3970 switch (
T->getTypeClass()) {
3972 return C.getQualifiedType(
T.getTypePtr(), Quals);
3975 case Type::InjectedClassName:
3976 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
3978 case Type::TemplateSpecialization: {
3980 if (Spec->isTypeAlias())
3981 return C.getQualifiedType(
T.getTypePtr(), Quals);
3982 T = Spec->desugar();
3985 case Type::TypeOfExpr:
3991 case Type::Decltype:
3994 case Type::UnaryTransform:
3997 case Type::Attributed:
4000 case Type::BTFTagAttributed:
4003 case Type::CountAttributed:
4012 case Type::MacroQualified:
4015 case Type::SubstTemplateTypeParm:
4019 case Type::DeducedTemplateSpecialization: {
4021 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4025 case Type::PackIndexing: {
4029 case Type::Adjusted:
4036 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4041llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4044 if (It != TypeCache.end()) {
4046 if (llvm::Metadata *
V = It->second)
4059 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4066 RetainedTypes.push_back(
4067 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4070llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4074 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4076 llvm::raw_string_ostream OS(Name);
4077 Ty.
print(OS, getPrintingPolicy());
4084 if (
auto *
T = getTypeOrNull(Ty))
4087 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4088 void *TyPtr = Ty.getAsOpaquePtr();
4091 TypeCache[TyPtr].reset(Res);
4096llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4104 auto Info = Reader->getSourceDescriptor(Idx);
4106 return getOrCreateModuleRef(*Info,
true);
4107 }
else if (ClangModuleMap) {
4120 auto Info = ASTSourceDescriptor(*M);
4121 return getOrCreateModuleRef(Info,
false);
4124 return getOrCreateModuleRef(PCHDescriptor,
false);
4131llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4134 return CreateQualifiedType(Ty, Unit);
4138#define TYPE(Class, Base)
4139#define ABSTRACT_TYPE(Class, Base)
4140#define NON_CANONICAL_TYPE(Class, Base)
4141#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4142#include "clang/AST/TypeNodes.inc"
4143 llvm_unreachable(
"Dependent types cannot show up in debug information");
4145 case Type::ExtVector:
4148 case Type::ConstantMatrix:
4150 case Type::ObjCObjectPointer:
4152 case Type::ObjCObject:
4154 case Type::ObjCTypeParam:
4156 case Type::ObjCInterface:
4164 case Type::BlockPointer:
4172 case Type::FunctionProto:
4173 case Type::FunctionNoProto:
4175 case Type::ConstantArray:
4176 case Type::VariableArray:
4177 case Type::IncompleteArray:
4178 case Type::ArrayParameter:
4181 case Type::LValueReference:
4183 case Type::RValueReference:
4186 case Type::MemberPointer:
4197 case Type::TemplateSpecialization:
4199 case Type::HLSLAttributedResource:
4201 case Type::HLSLInlineSpirv:
4203 case Type::PredefinedSugar:
4205 case Type::CountAttributed:
4207 case Type::Attributed:
4208 case Type::BTFTagAttributed:
4209 case Type::Adjusted:
4211 case Type::DeducedTemplateSpecialization:
4214 case Type::MacroQualified:
4215 case Type::SubstTemplateTypeParm:
4216 case Type::TypeOfExpr:
4218 case Type::Decltype:
4219 case Type::PackIndexing:
4220 case Type::UnaryTransform:
4224 llvm_unreachable(
"type should have been unwrapped!");
4227llvm::DICompositeType *
4228CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4229 QualType QTy(Ty, 0);
4231 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4236 if (
T && !
T->isForwardDecl())
4240 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4245 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4248 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4253llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4254 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4257 StringRef RDName = getClassName(RD);
4259 llvm::DIFile *DefUnit =
nullptr;
4262 DefUnit = getOrCreateFile(Loc);
4263 Line = getLineNumber(Loc);
4266 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4270 auto *
T = cast_or_null<llvm::DICompositeType>(
4271 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4279 return getOrCreateRecordFwdDecl(Ty, RDContext);
4292 auto Flags = llvm::DINode::FlagZero;
4293 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4295 Flags |= llvm::DINode::FlagTypePassByReference;
4297 Flags |= llvm::DINode::FlagTypePassByValue;
4300 if (!CXXRD->isTrivial())
4301 Flags |= llvm::DINode::FlagNonTrivial;
4304 if (CXXRD->isAnonymousStructOrUnion())
4305 Flags |= llvm::DINode::FlagExportSymbols;
4308 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4311 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4312 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4314 Flags, Identifier, Annotations);
4318 switch (RealDecl->getTag()) {
4320 llvm_unreachable(
"invalid composite type tag");
4322 case llvm::dwarf::DW_TAG_array_type:
4323 case llvm::dwarf::DW_TAG_enumeration_type:
4328 if (Identifier.empty())
4332 case llvm::dwarf::DW_TAG_structure_type:
4333 case llvm::dwarf::DW_TAG_union_type:
4334 case llvm::dwarf::DW_TAG_class_type:
4337 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4341 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4342 CXXRecordDecl *TemplateDecl =
4343 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4344 RegionMap[TemplateDecl].reset(RealDecl);
4346 RegionMap[RD].reset(RealDecl);
4348 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4350 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4351 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4352 CollectCXXTemplateParams(TSpecial, DefUnit));
4356void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4357 llvm::DICompositeType *RealDecl) {
4359 llvm::DIType *ContainingType =
nullptr;
4360 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4364 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4371 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4372 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4374 ContainingType = RealDecl;
4376 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4379llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4380 StringRef Name, uint64_t *Offset) {
4381 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4382 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4385 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4386 *Offset, llvm::DINode::FlagZero, FieldTy);
4387 *Offset += FieldSize;
4391void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4393 StringRef &LinkageName,
4394 llvm::DIScope *&FDContext,
4395 llvm::DINodeArray &TParamsArray,
4396 llvm::DINode::DIFlags &Flags) {
4398 Name = getFunctionName(FD);
4401 LinkageName = CGM.getMangledName(GD);
4403 Flags |= llvm::DINode::FlagPrototyped;
4407 if (LinkageName == Name ||
4408 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4409 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4410 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4411 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4412 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4413 LinkageName = StringRef();
4417 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4418 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4419 CGM.getCodeGenOpts().EmitCodeView)) {
4420 if (
const NamespaceDecl *NSDecl =
4422 FDContext = getOrCreateNamespace(NSDecl);
4423 else if (
const RecordDecl *RDecl =
4425 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4426 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4429 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4432 Flags |= llvm::DINode::FlagNoReturn;
4434 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4438void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4439 unsigned &LineNo, QualType &
T,
4440 StringRef &Name, StringRef &LinkageName,
4441 llvm::MDTuple *&TemplateParameters,
4442 llvm::DIScope *&VDContext) {
4451 llvm::APInt ConstVal(32, 1);
4452 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4454 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4461 LinkageName = CGM.getMangledName(VD);
4462 if (LinkageName == Name)
4463 LinkageName = StringRef();
4466 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4467 TemplateParameters = parameterNodes.get();
4469 TemplateParameters =
nullptr;
4487 DC = CGM.getContext().getTranslationUnitDecl();
4489 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4490 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4493llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4495 llvm::DINodeArray TParamsArray;
4496 StringRef Name, LinkageName;
4497 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4498 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4500 llvm::DIFile *Unit = getOrCreateFile(Loc);
4501 llvm::DIScope *DContext = Unit;
4502 unsigned Line = getLineNumber(Loc);
4503 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4508 SmallVector<QualType, 16> ArgTypes;
4509 for (
const ParmVarDecl *Parm : FD->
parameters())
4510 ArgTypes.push_back(Parm->getType());
4513 QualType FnType = CGM.getContext().getFunctionType(
4514 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4516 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4517 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4518 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4522 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4523 return DBuilder.createFunction(
4524 DContext, Name, LinkageName, Unit,
Line,
4525 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4526 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4528 CGM.getCodeGenOpts().DebugKeyInstructions);
4531 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4532 DContext, Name, LinkageName, Unit,
Line,
4533 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4534 TParamsArray.get(), getFunctionDeclaration(FD));
4536 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4537 std::make_tuple(CanonDecl),
4538 std::make_tuple(SP));
4542llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4543 return getFunctionFwdDeclOrStub(GD,
false);
4546llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4547 return getFunctionFwdDeclOrStub(GD,
true);
4550llvm::DIGlobalVariable *
4551CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4553 StringRef Name, LinkageName;
4555 llvm::DIFile *Unit = getOrCreateFile(Loc);
4556 llvm::DIScope *DContext = Unit;
4557 unsigned Line = getLineNumber(Loc);
4558 llvm::MDTuple *TemplateParameters =
nullptr;
4560 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4563 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4564 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4566 FwdDeclReplaceMap.emplace_back(
4567 std::piecewise_construct,
4569 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4573llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4578 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4579 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4580 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4584 if (I != DeclCache.end()) {
4586 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4587 return GVE->getVariable();
4595 if (IE != ImportedDeclCache.end()) {
4596 auto N = IE->second;
4597 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4599 return dyn_cast_or_null<llvm::DINode>(N);
4604 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4605 return getFunctionForwardDeclaration(FD);
4606 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4607 return getGlobalVariableForwardDeclaration(VD);
4612llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4613 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4616 const auto *FD = dyn_cast<FunctionDecl>(D);
4621 auto *S = getDeclContextDescriptor(D);
4624 if (MI == SPCache.end()) {
4626 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4630 if (MI != SPCache.end()) {
4631 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4632 if (SP && !SP->isDefinition())
4636 for (
auto *NextFD : FD->
redecls()) {
4637 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4638 if (MI != SPCache.end()) {
4639 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4640 if (SP && !SP->isDefinition())
4647llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4648 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4649 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4650 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4653 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4657 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4661 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4670 QualType QTy(
ID->getTypeForDecl(), 0);
4671 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4672 if (It == TypeCache.end())
4675 llvm::DISubprogram *FD = DBuilder.createFunction(
4676 InterfaceType, getObjCMethodName(OMD), StringRef(),
4677 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4678 DBuilder.finalizeSubprogram(FD);
4685llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4690 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4691 !CGM.getCodeGenOpts().EmitCodeView))
4694 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4696 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4699 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4702 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4703 return getOrCreateMethodType(
Method, F);
4705 const auto *FTy = FnType->
getAs<FunctionType>();
4708 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4710 SmallVector<llvm::Metadata *, 16> Elts;
4713 QualType ResultTy = OMethod->getReturnType();
4716 if (ResultTy == CGM.getContext().getObjCInstanceType())
4717 ResultTy = CGM.getContext().getPointerType(
4718 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4720 Elts.push_back(getOrCreateType(ResultTy, F));
4722 QualType SelfDeclTy;
4723 if (
auto *SelfDecl = OMethod->getSelfDecl())
4724 SelfDeclTy = SelfDecl->getType();
4725 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4728 if (!SelfDeclTy.
isNull())
4730 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4732 Elts.push_back(DBuilder.createArtificialType(
4733 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4735 for (
const auto *PI : OMethod->parameters())
4736 Elts.push_back(getOrCreateType(PI->getType(), F));
4738 if (OMethod->isVariadic())
4739 Elts.push_back(DBuilder.createUnspecifiedParameter());
4741 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4742 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4748 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4749 if (FD->isVariadic()) {
4750 SmallVector<llvm::Metadata *, 16> EltTys;
4751 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4752 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4754 EltTys.push_back(getOrCreateType(ParamType, F));
4755 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4756 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4757 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4770 CC = SrcFnTy->getCallConv();
4772 for (
const VarDecl *VD : Args)
4773 ArgTypes.push_back(VD->
getType());
4774 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4780 llvm::Function *Fn,
bool CurFuncIsThunk) {
4782 StringRef LinkageName;
4784 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4787 bool HasDecl = (D !=
nullptr);
4789 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4790 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4791 llvm::DIFile *Unit = getOrCreateFile(Loc);
4792 llvm::DIScope *FDContext = Unit;
4793 llvm::DINodeArray TParamsArray;
4794 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4797 LinkageName = Fn->getName();
4798 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4800 auto FI = SPCache.find(FD->getCanonicalDecl());
4801 if (FI != SPCache.end()) {
4802 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4803 if (SP && SP->isDefinition()) {
4804 LexicalBlockStack.emplace_back(SP);
4805 RegionMap[D].reset(SP);
4809 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4810 TParamsArray, Flags);
4813 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4814 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4815 Name = getObjCMethodName(OMD);
4816 Flags |= llvm::DINode::FlagPrototyped;
4823 Name = Fn->getName();
4828 Flags |= llvm::DINode::FlagPrototyped;
4830 Name.consume_front(
"\01");
4834 "Unexpected DynamicInitKind !");
4838 Flags |= llvm::DINode::FlagArtificial;
4844 Flags |= llvm::DINode::FlagThunk;
4846 if (Fn->hasLocalLinkage())
4847 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4848 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4849 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4852 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4853 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4855 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4856 unsigned ScopeLine = getLineNumber(ScopeLoc);
4857 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4858 llvm::DISubprogram *
Decl =
nullptr;
4859 llvm::DINodeArray Annotations =
nullptr;
4862 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4863 : getFunctionDeclaration(D);
4864 Annotations = CollectBTFDeclTagAnnotations(D);
4872 llvm::DISubprogram *SP = DBuilder.createFunction(
4873 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4874 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4875 Annotations,
"", KeyInstructions);
4876 Fn->setSubprogram(SP);
4885 LexicalBlockStack.emplace_back(SP);
4888 RegionMap[D].reset(SP);
4892 QualType FnType, llvm::Function *Fn) {
4894 StringRef LinkageName;
4900 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4901 return GetName(D,
true);
4904 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4905 llvm::DIFile *Unit = getOrCreateFile(Loc);
4906 bool IsDeclForCallSite = Fn ?
true :
false;
4907 llvm::DIScope *FDContext =
4908 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4909 llvm::DINodeArray TParamsArray;
4912 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4913 TParamsArray, Flags);
4914 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4915 Name = getObjCMethodName(OMD);
4916 Flags |= llvm::DINode::FlagPrototyped;
4918 llvm_unreachable(
"not a function or ObjC method");
4920 Name.consume_front(
"\01");
4923 Flags |= llvm::DINode::FlagArtificial;
4928 unsigned LineNo = getLineNumber(Loc);
4929 unsigned ScopeLine = 0;
4930 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4931 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4932 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4934 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4935 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4937 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4938 llvm::DISubprogram *SP = DBuilder.createFunction(
4939 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4940 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4946 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
4947 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4948 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4951 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4952 DBuilder.createParameterVariable(
4953 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4954 llvm::DINode::FlagZero, ParamAnnotations);
4960 if (IsDeclForCallSite)
4961 Fn->setSubprogram(SP);
4969 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4972 if (
Func->getSubprogram())
4980 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4995 auto FI = SPCache.find(FD->getCanonicalDecl());
4996 llvm::DISubprogram *SP =
nullptr;
4997 if (FI != SPCache.end())
4998 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4999 if (!SP || !SP->isDefinition())
5000 SP = getFunctionStub(GD);
5001 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5002 LexicalBlockStack.emplace_back(SP);
5008 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5017 if (CurLoc.isInvalid() || LexicalBlockStack.empty())
5020 llvm::MDNode *
Scope = LexicalBlockStack.back();
5021 Builder.SetCurrentDebugLocation(
5022 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5023 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5027 llvm::MDNode *Back =
nullptr;
5028 if (!LexicalBlockStack.empty())
5029 Back = LexicalBlockStack.back().get();
5030 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5032 getColumnNumber(CurLoc)));
5035void CGDebugInfo::AppendAddressSpaceXDeref(
5037 std::optional<unsigned> DWARFAddressSpace =
5039 if (!DWARFAddressSpace)
5042 Expr.push_back(llvm::dwarf::DW_OP_constu);
5043 Expr.push_back(*DWARFAddressSpace);
5044 Expr.push_back(llvm::dwarf::DW_OP_swap);
5045 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5054 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5055 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5056 LexicalBlockStack.back(), CurInlinedAt));
5058 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5062 CreateLexicalBlock(Loc);
5067 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5072 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5075 LexicalBlockStack.pop_back();
5079 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5080 unsigned RCount = FnBeginRegionCount.back();
5081 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5084 while (LexicalBlockStack.size() != RCount) {
5087 LexicalBlockStack.pop_back();
5089 FnBeginRegionCount.pop_back();
5091 if (Fn && Fn->getSubprogram())
5092 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5095CGDebugInfo::BlockByRefType
5096CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5097 uint64_t *XOffset) {
5100 uint64_t FieldSize, FieldOffset;
5101 uint32_t FieldAlign;
5103 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5108 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5109 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5111 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5112 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5115 if (HasCopyAndDispose) {
5118 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5120 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5122 bool HasByrefExtendedLayout;
5125 HasByrefExtendedLayout) &&
5126 HasByrefExtendedLayout) {
5129 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5138 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5141 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5144 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5149 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5150 FieldSize = CGM.getContext().getTypeSize(FType);
5151 FieldAlign = CGM.getContext().toBits(Align);
5153 *XOffset = FieldOffset;
5154 llvm::DIType *FieldTy = DBuilder.createMemberType(
5155 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5156 llvm::DINode::FlagZero, WrappedTy);
5157 EltTys.push_back(FieldTy);
5158 FieldOffset += FieldSize;
5160 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5161 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5162 llvm::DINode::FlagZero,
nullptr, Elements),
5166llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5167 llvm::Value *Storage,
5168 std::optional<unsigned> ArgNo,
5170 const bool UsePointerValue) {
5171 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5172 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5173 if (VD->
hasAttr<NoDebugAttr>())
5178 llvm::DIFile *Unit =
nullptr;
5179 if (!VarIsArtificial)
5183 if (VD->
hasAttr<BlocksAttr>())
5184 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5186 Ty = getOrCreateType(VD->
getType(), Unit);
5196 if (!VarIsArtificial) {
5200 SmallVector<uint64_t, 13> Expr;
5201 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5208 Flags |= llvm::DINode::FlagArtificial;
5212 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5213 AppendAddressSpaceXDeref(AddressSpace, Expr);
5217 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5220 Flags |= llvm::DINode::FlagObjectPointer;
5221 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5222 if (PVD->isExplicitObjectParameter())
5223 Flags |= llvm::DINode::FlagObjectPointer;
5231 StringRef Name = VD->
getName();
5232 if (!Name.empty()) {
5238 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5240 offset = CGM.getContext().toCharUnitsFromBits(
5243 Expr.push_back(llvm::dwarf::DW_OP_deref);
5244 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5246 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5249 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5261 for (
const auto *Field : RD->
fields()) {
5262 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5263 StringRef FieldName =
Field->getName();
5271 auto *D = DBuilder.createAutoVariable(
5272 Scope, FieldName, Unit,
Line, FieldTy,
5273 CGM.getCodeGenOpts().OptimizationLevel != 0,
5274 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5277 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5278 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5281 Builder.GetInsertBlock());
5289 if (UsePointerValue) {
5290 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5291 "Debug info already contains DW_OP_deref.");
5292 Expr.push_back(llvm::dwarf::DW_OP_deref);
5296 llvm::DILocalVariable *D =
nullptr;
5298 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5299 D = DBuilder.createParameterVariable(
5300 Scope, Name, *ArgNo, Unit,
Line, Ty,
5301 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5310 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5316 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5317 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5318 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5319 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5321 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5327 if (Iter != CoroutineParameterMappings.end()) {
5328 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5329 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5330 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5332 if (Iter2 != ParamDbgMappings.end())
5333 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5339 D = RemapCoroArgToLocalVar();
5342 D = DBuilder.createAutoVariable(
5343 Scope, Name, Unit,
Line, Ty,
5344 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5347 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5348 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5349 Column, Scope, CurInlinedAt),
5350 Builder.GetInsertBlock());
5355llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5356 llvm::Value *Storage,
5357 std::optional<unsigned> ArgNo,
5359 const bool UsePointerValue) {
5360 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5361 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5362 if (BD->
hasAttr<NoDebugAttr>())
5369 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5370 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5378 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5380 SmallVector<uint64_t, 3> Expr;
5381 AppendAddressSpaceXDeref(AddressSpace, Expr);
5386 if (UsePointerValue) {
5387 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5388 "Debug info already contains DW_OP_deref.");
5389 Expr.push_back(llvm::dwarf::DW_OP_deref);
5394 StringRef Name = BD->
getName();
5397 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5398 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5399 llvm::DINode::FlagZero, Align);
5401 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5402 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5403 const unsigned fieldIndex = FD->getFieldIndex();
5404 const clang::CXXRecordDecl *parent =
5405 (
const CXXRecordDecl *)FD->getParent();
5406 const ASTRecordLayout &layout =
5407 CGM.getContext().getASTRecordLayout(parent);
5409 if (FD->isBitField()) {
5410 const CGRecordLayout &RL =
5411 CGM.getTypes().getCGRecordLayout(FD->getParent());
5416 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5422 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5423 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5424 Expr.push_back(Info.
Offset);
5427 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5428 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5429 }
else if (fieldOffset != 0) {
5430 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5431 "Unexpected non-bitfield with non-byte-aligned offset");
5432 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5434 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5437 }
else if (
const ArraySubscriptExpr *ASE =
5438 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5439 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5440 const uint64_t value = IL->getValue().getZExtValue();
5441 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5444 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5445 Expr.push_back(CGM.getContext()
5446 .toCharUnitsFromBits(value * typeSize)
5453 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5454 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5455 Column, Scope, CurInlinedAt),
5456 Builder.GetInsertBlock());
5461llvm::DILocalVariable *
5464 const bool UsePointerValue) {
5465 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5467 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5469 EmitDeclare(B, Storage, std::nullopt, Builder,
5476 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5480 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5481 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5483 if (D->
hasAttr<NoDebugAttr>())
5487 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5493 StringRef Name = D->
getName();
5499 CGM.getCodeGenOpts().OptimizationLevel != 0);
5502 DBuilder.insertLabel(L,
5503 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5504 Scope, CurInlinedAt),
5505 Builder.GetInsertBlock()->end());
5508llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5510 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5513 return DBuilder.createObjectPointerType(Ty,
true);
5518 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5519 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5520 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5522 if (Builder.GetInsertBlock() ==
nullptr)
5524 if (VD->
hasAttr<NoDebugAttr>())
5527 bool isByRef = VD->
hasAttr<BlocksAttr>();
5529 uint64_t XOffset = 0;
5530 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5533 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5535 Ty = getOrCreateType(VD->
getType(), Unit);
5539 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5541 Ty = CreateSelfType(VD->
getType(), Ty);
5544 const unsigned Line =
5548 const llvm::DataLayout &target = CGM.getDataLayout();
5555 addr.push_back(llvm::dwarf::DW_OP_deref);
5556 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5559 addr.push_back(llvm::dwarf::DW_OP_deref);
5560 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5563 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5565 addr.push_back(llvm::dwarf::DW_OP_deref);
5566 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5568 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5574 auto *D = DBuilder.createAutoVariable(
5576 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5579 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5580 LexicalBlockStack.back(), CurInlinedAt);
5581 auto *
Expr = DBuilder.createExpression(addr);
5583 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5585 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5588llvm::DILocalVariable *
5591 bool UsePointerValue) {
5592 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5593 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5597struct BlockLayoutChunk {
5598 uint64_t OffsetInBits;
5601bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5602 return l.OffsetInBits < r.OffsetInBits;
5606void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5608 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5609 SmallVectorImpl<llvm::Metadata *> &Fields) {
5613 if (CGM.getLangOpts().OpenCL) {
5614 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5615 BlockLayout.getElementOffsetInBits(0),
5617 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5618 BlockLayout.getElementOffsetInBits(1),
5622 BlockLayout.getElementOffsetInBits(0),
5624 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5625 BlockLayout.getElementOffsetInBits(1),
5629 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5630 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5631 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5632 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5633 BlockLayout.getElementOffsetInBits(3),
5635 Fields.push_back(createFieldType(
5640 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5647 llvm::AllocaInst *Alloca,
5649 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5655 llvm::DIFile *tunit = getOrCreateFile(loc);
5656 unsigned line = getLineNumber(loc);
5657 unsigned column = getColumnNumber(loc);
5662 const llvm::StructLayout *blockLayout =
5666 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5675 BlockLayoutChunk chunk;
5676 chunk.OffsetInBits =
5677 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5678 chunk.Capture =
nullptr;
5679 chunks.push_back(chunk);
5683 for (
const auto &capture :
blockDecl->captures()) {
5684 const VarDecl *variable = capture.getVariable();
5691 BlockLayoutChunk chunk;
5692 chunk.OffsetInBits =
5693 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5694 chunk.Capture = &capture;
5695 chunks.push_back(chunk);
5699 llvm::array_pod_sort(chunks.begin(), chunks.end());
5701 for (
const BlockLayoutChunk &Chunk : chunks) {
5702 uint64_t offsetInBits = Chunk.OffsetInBits;
5709 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5711 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5712 type = CGM.getContext().getCanonicalTagType(RDecl);
5714 llvm_unreachable(
"unexpected block declcontext");
5716 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5717 offsetInBits, tunit, tunit));
5722 StringRef name = variable->
getName();
5724 llvm::DIType *fieldType;
5726 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5731 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5732 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5733 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5734 PtrInfo.
Width, Align, offsetInBits,
5735 llvm::DINode::FlagZero, fieldType);
5739 offsetInBits, Align, tunit, tunit);
5741 fields.push_back(fieldType);
5745 llvm::raw_svector_ostream(typeName)
5746 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5748 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5750 llvm::DIType *
type =
5751 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5752 CGM.getContext().toBits(block.
BlockSize), 0,
5753 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5754 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5757 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5761 auto *debugVar = DBuilder.createParameterVariable(
5762 scope, Name, ArgNo, tunit, line,
type,
5763 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5766 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5767 llvm::DILocation::get(CGM.getLLVMContext(), line,
5768 column, scope, CurInlinedAt),
5769 Builder.GetInsertBlock());
5772llvm::DIDerivedType *
5773CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5778 if (MI != StaticDataMemberCache.end()) {
5779 assert(MI->second &&
"Static data member declaration should still exist");
5790llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5791 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5792 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5793 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5795 for (
const auto *Field : RD->
fields()) {
5796 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5797 StringRef FieldName = Field->getName();
5800 if (FieldName.empty()) {
5801 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5802 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5803 LineNo, LinkageName, Var, DContext);
5807 GVE = DBuilder.createGlobalVariableExpression(
5808 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5809 Var->hasLocalLinkage());
5810 Var->addDebugInfo(GVE);
5822 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5827 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5838 struct ReferencesAnonymous
5840 bool RefAnon =
false;
5841 bool VisitRecordType(RecordType *RT) {
5849 ReferencesAnonymous RT;
5862struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5863 bool Reconstitutable =
true;
5864 bool VisitVectorType(VectorType *FT) {
5865 Reconstitutable =
false;
5868 bool VisitAtomicType(AtomicType *FT) {
5869 Reconstitutable =
false;
5872 bool VisitType(
Type *
T) {
5876 Reconstitutable =
false;
5881 bool TraverseEnumType(EnumType *ET,
bool =
false) {
5884 if (
const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
5885 if (!ED->getIdentifier()) {
5886 Reconstitutable =
false;
5889 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5890 Reconstitutable =
false;
5896 bool VisitFunctionProtoType(FunctionProtoType *FT) {
5900 return Reconstitutable;
5902 bool VisitRecordType(RecordType *RT,
bool =
false) {
5904 Reconstitutable =
false;
5914 ReconstitutableType
T;
5916 return T.Reconstitutable;
5919bool CGDebugInfo::HasReconstitutableArgs(
5920 ArrayRef<TemplateArgument> Args)
const {
5921 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
5961 llvm_unreachable(
"Other, unresolved, template arguments should "
5962 "not be seen here");
5967std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5969 llvm::raw_string_ostream
OS(Name);
5970 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5973 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5974 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5976 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5977 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5979 std::optional<TemplateArgs> Args;
5981 bool IsOperatorOverload =
false;
5982 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5983 Args = GetTemplateArgs(RD);
5984 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5985 Args = GetTemplateArgs(FD);
5987 IsOperatorOverload |=
5990 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5991 Args = GetTemplateArgs(VD);
6015 bool Reconstitutable =
6016 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6018 PrintingPolicy PP = getPrintingPolicy();
6020 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6024 bool Mangled = TemplateNamesKind ==
6025 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6031 std::string EncodedOriginalName;
6032 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6037 printTemplateArgumentList(OS, Args->Args, PP);
6038 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6040 std::string CanonicalOriginalName;
6041 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6043 assert(EncodedOriginalName == CanonicalOriginalName);
6052 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6053 if (D->
hasAttr<NoDebugAttr>())
6056 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6057 return GetName(D,
true);
6063 if (Cached != DeclCache.end())
6064 return Var->addDebugInfo(
6068 llvm::DIFile *Unit =
nullptr;
6069 llvm::DIScope *DContext =
nullptr;
6071 StringRef DeclName, LinkageName;
6073 llvm::MDTuple *TemplateParameters =
nullptr;
6074 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6075 TemplateParameters, DContext);
6079 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6084 if (
T->isUnionType() && DeclName.empty()) {
6085 const auto *RD =
T->castAsRecordDecl();
6087 "unnamed non-anonymous struct or union?");
6088 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6093 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6094 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6095 if (D->
hasAttr<CUDASharedAttr>())
6098 else if (D->
hasAttr<CUDAConstantAttr>())
6102 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6104 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6105 GVE = DBuilder.createGlobalVariableExpression(
6106 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6107 Var->hasLocalLinkage(),
true,
6108 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6109 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6110 Align, Annotations);
6111 Var->addDebugInfo(GVE);
6117 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6118 if (VD->
hasAttr<NoDebugAttr>())
6120 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6121 return GetName(VD,
true);
6126 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6127 StringRef Name = VD->
getName();
6128 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6130 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6132 if (CGM.getCodeGenOpts().EmitCodeView) {
6143 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6144 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6145 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6155 auto *VarD = dyn_cast<VarDecl>(VD);
6156 if (VarD && VarD->isStaticDataMember()) {
6158 getDeclContextDescriptor(VarD);
6163 RetainedTypes.push_back(
6164 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6168 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6170 auto &GV = DeclCache[VD];
6174 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6175 llvm::MDTuple *TemplateParameters =
nullptr;
6179 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6180 TemplateParameters = parameterNodes.get();
6183 GV.reset(DBuilder.createGlobalVariableExpression(
6184 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6185 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6186 TemplateParameters, Align));
6191 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6192 if (D->
hasAttr<NoDebugAttr>())
6196 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6197 StringRef Name = D->
getName();
6198 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6200 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6201 llvm::DIGlobalVariableExpression *GVE =
6202 DBuilder.createGlobalVariableExpression(
6203 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6204 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6205 Var->addDebugInfo(GVE);
6212 if (CGM.getCodeGenOpts().getDebugInfo() <=
6213 llvm::codegenoptions::DebugLineTablesOnly)
6216 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6220 llvm::DIFile *Unit = DIL->getFile();
6221 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6226 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6227 llvm::Value *Var = Load->getPointerOperand();
6232 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6233 return DbgDeclare->getVariable()->getType() ==
Type;
6235 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6239 llvm::DILocalVariable *D =
6240 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6241 Type,
false, llvm::DINode::FlagArtificial);
6243 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6244 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6254 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6258 if (D->
hasAttr<NoDebugAttr>())
6261 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6276 if (!(DI = getDeclarationOrDefinition(
6277 AliaseeDecl.getCanonicalDecl().getDecl())))
6280 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6283 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6284 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6298 llvm::DIFile *
File = getOrCreateFile(Loc);
6299 llvm::DIGlobalVariableExpression *Debug =
6300 DBuilder.createGlobalVariableExpression(
6301 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6302 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6303 GV->addDebugInfo(Debug);
6306llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6307 if (!LexicalBlockStack.empty())
6308 return LexicalBlockStack.back();
6309 llvm::DIScope *Mod = getParentModuleOrNull(D);
6310 return getContextDescriptor(D, Mod ? Mod : TheCU);
6314 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6318 CGM.getCodeGenOpts().DebugExplicitImport) {
6322 DBuilder.createImportedModule(
6324 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6329 if (llvm::DINode *
Target =
6332 DBuilder.createImportedDeclaration(
6334 getOrCreateFile(Loc), getLineNumber(Loc));
6339 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6342 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6344 for (
const auto *USD : UD.
shadows()) {
6349 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6350 if (
const auto *AT = FD->getType()
6353 if (AT->getDeducedType().isNull())
6364 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6367 "We shouldn't be codegening an invalid UsingEnumDecl"
6368 " containing no decls");
6370 for (
const auto *USD : UD.
shadows())
6375 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6377 if (
Module *M = ID.getImportedModule()) {
6379 auto Loc = ID.getLocation();
6380 DBuilder.createImportedDeclaration(
6381 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6382 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6383 getLineNumber(Loc));
6387llvm::DIImportedEntity *
6389 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6391 auto &VH = NamespaceAliasCache[&NA];
6394 llvm::DIImportedEntity *R;
6396 if (
const auto *Underlying =
6399 R = DBuilder.createImportedDeclaration(
6402 getLineNumber(Loc), NA.
getName());
6404 R = DBuilder.createImportedDeclaration(
6407 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6413CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6417 auto I = NamespaceCache.find(NSDecl);
6418 if (I != NamespaceCache.end())
6421 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6423 llvm::DINamespace *NS =
6424 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6425 NamespaceCache[NSDecl].reset(NS);
6430 assert(TheCU &&
"no main compile unit");
6431 TheCU->setDWOId(Signature);
6437 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6438 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6440 ? CreateTypeDefinition(E.Type, E.Unit)
6442 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6446 for (
const auto &P : ObjCMethodCache) {
6447 if (P.second.empty())
6450 QualType QTy(P.first->getTypeForDecl(), 0);
6452 assert(It != TypeCache.end());
6454 llvm::DICompositeType *InterfaceDecl =
6457 auto CurElts = InterfaceDecl->getElements();
6461 for (
auto &SubprogramDirect : P.second)
6462 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6463 EltTys.push_back(SubprogramDirect.getPointer());
6465 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6466 DBuilder.replaceArrays(InterfaceDecl, Elements);
6469 for (
const auto &P : ReplaceMap) {
6472 assert(Ty->isForwardDecl());
6474 auto It = TypeCache.find(P.first);
6475 assert(It != TypeCache.end());
6478 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6482 for (
const auto &P : FwdDeclReplaceMap) {
6485 llvm::Metadata *Repl;
6487 auto It = DeclCache.find(P.first);
6491 if (It == DeclCache.end())
6496 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6497 Repl = GVE->getVariable();
6503 for (
auto &RT : RetainedTypes)
6504 if (
auto MD = TypeCache[RT])
6507 DBuilder.finalize();
6512 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6513 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6514 DBuilder.retainType(DieTy);
6518 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6519 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6520 DBuilder.retainType(DieTy);
6524 if (LexicalBlockStack.empty())
6525 return llvm::DebugLoc();
6527 llvm::MDNode *
Scope = LexicalBlockStack.back();
6528 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6529 getColumnNumber(Loc),
Scope);
6535 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6536 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6537 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6538 return llvm::DINode::FlagZero;
6543 bool SupportsDWARFv4Ext =
6544 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6545 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6546 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6548 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6549 return llvm::DINode::FlagZero;
6551 return llvm::DINode::FlagAllCallsDescribed;
6562 return DBuilder.createConstantValueExpression(
6563 Val.
getFloat().bitcastToAPInt().getZExtValue());
6568 llvm::APSInt
const &ValInt = Val.
getInt();
6569 std::optional<uint64_t> ValIntOpt;
6570 if (ValInt.isUnsigned())
6571 ValIntOpt = ValInt.tryZExtValue();
6572 else if (
auto tmp = ValInt.trySExtValue())
6575 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6578 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6583CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6585 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6586 CGF.CurLexicalScope =
this;
6588 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6593 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6606#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6608 Label = "__ubsan_check_" #Name; \
6612#undef SANITIZER_CHECK
6623#define SANITIZER(NAME, ID) \
6624 case SanitizerKind::SO_##ID: \
6625 Label = "__ubsan_check_" NAME; \
6627#include "clang/Basic/Sanitizers.def"
6629 llvm_unreachable(
"unexpected sanitizer kind");
6634 for (
unsigned int i = 0; i < Label.length(); i++)
6635 if (!std::isalpha(Label[i]))
6644 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6646 if (!DI || !CheckDebugLoc)
6647 return CheckDebugLoc;
6648 const auto &AnnotateDebugInfo =
6649 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6650 if (AnnotateDebugInfo.empty())
6651 return CheckDebugLoc;
6654 if (Ordinals.size() == 1)
6659 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6660 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label);
6662 return CheckDebugLoc;
6670 assert(!CGF->IsSanitizerScope);
6671 CGF->IsSanitizerScope =
true;
6675 assert(CGF->IsSanitizerScope);
6676 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to the current atom group, created using ApplyA...
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file.
void completeFunction()
Reset internal state.
void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl)
Emit information about global variable alias.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)
Emit call to llvm.dbg.label for an label.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
void EmitUsingShadowDecl(const UsingShadowDecl &USD)
Emit a shadow decl brought in by a using or using-enum.
void EmitUsingEnumDecl(const UsingEnumDecl &UD)
Emit C++ using-enum declaration.
void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)
Constructs the debug code for exiting a function.
void EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an include directive.
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about an external variable.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void removeObjCLifetime()
void removeAddressSpace()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isBitIntType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.