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);
350 if (CurLoc != NewLoc) {
352 CurLocFile =
nullptr;
361 if (CGM.getCodeGenOpts().DebugColumnInfo)
363 CurLocFile = getOrCreateFile(CurLoc);
369 if (LexicalBlockStack.empty())
373 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
376 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
377 LexicalBlockStack.pop_back();
378 LexicalBlockStack.emplace_back(
379 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
382 LexicalBlockStack.pop_back();
383 LexicalBlockStack.emplace_back(
384 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
388llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
389 llvm::DIScope *Mod = getParentModuleOrNull(D);
394llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
399 auto I = RegionMap.find(Context);
400 if (I != RegionMap.end()) {
401 llvm::Metadata *
V = I->second;
402 return dyn_cast_or_null<llvm::DIScope>(
V);
406 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
407 return getOrCreateNamespace(NSDecl);
409 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
410 if (!RDecl->isDependentType())
416PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
417 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
424 if (CGM.getCodeGenOpts().EmitCodeView) {
425 PP.MSVCFormatting =
true;
435 PP.PrintAsCanonical =
true;
436 PP.UsePreferredNames =
false;
437 PP.AlwaysIncludeTypeForTemplateArgument =
true;
446StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
447 bool *NameIsSimplified) {
448 return internString(GetName(FD,
false, NameIsSimplified));
451StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
452 SmallString<256> MethodName;
453 llvm::raw_svector_ostream
OS(MethodName);
456 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
457 OS << OID->getName();
458 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
459 OS << OID->getName();
460 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
461 if (OC->IsClassExtension()) {
462 OS << OC->getClassInterface()->getName();
464 OS << OC->getIdentifier()->getNameStart() <<
'('
465 << OC->getIdentifier()->getNameStart() <<
')';
467 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
468 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
472 return internString(
OS.str());
475StringRef CGDebugInfo::getSelectorName(Selector S) {
479StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
480 bool *NameIsSimplified) {
483 return internString(GetName(RD,
false, NameIsSimplified));
489 return II->getName();
494 if (CGM.getCodeGenOpts().EmitCodeView) {
497 "Typedef should not be in another decl context!");
498 assert(D->getDeclName().getAsIdentifierInfo() &&
499 "Typedef was not named!");
500 return D->getDeclName().getAsIdentifierInfo()->getName();
503 if (CGM.getLangOpts().CPlusPlus) {
506 ASTContext &Context = CGM.getContext();
510 Name = DD->getName();
511 else if (
const TypedefNameDecl *TND =
515 Name = TND->getName();
518 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
519 if (CXXRD->isLambda())
521 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
524 SmallString<256> UnnamedType(
"<unnamed-type-");
527 return internString(UnnamedType);
535std::optional<llvm::DIFile::ChecksumKind>
536CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
539 if (!CGM.getCodeGenOpts().EmitCodeView &&
540 CGM.getCodeGenOpts().DwarfVersion < 5)
543 SourceManager &SM = CGM.getContext().getSourceManager();
544 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
548 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
549 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
551 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
552 return llvm::DIFile::CSK_MD5;
554 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
555 return llvm::DIFile::CSK_SHA1;
557 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
558 return llvm::DIFile::CSK_SHA256;
562 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
565std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
567 if (!CGM.getCodeGenOpts().EmbedSource)
570 bool SourceInvalid =
false;
579llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
580 SourceManager &SM = CGM.getContext().getSourceManager();
583 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
589 FileName = TheCU->getFile()->getFilename();
590 CSInfo = TheCU->getFile()->getChecksum();
592 if (Loc == CurLoc && CurLocFile)
599 FileName = TheCU->getFile()->getFilename();
607 auto It = DIFileCache.find(
FileName.data());
608 if (It != DIFileCache.end()) {
610 if (llvm::Metadata *
V = It->second)
615 SmallString<64> Checksum;
617 std::optional<llvm::DIFile::ChecksumKind> CSKind =
618 computeChecksum(FID, Checksum);
620 CSInfo.emplace(*CSKind, Checksum);
625llvm::DIFile *CGDebugInfo::createFile(
627 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
628 std::optional<StringRef> Source) {
632 std::string CurDir =
remapDIPath(getCurrentDirname());
633 SmallString<128> DirBuf;
634 SmallString<128> FileBuf;
635 if (llvm::sys::path::is_absolute(RemappedFile)) {
638 auto FileIt = llvm::sys::path::begin(RemappedFile);
639 auto FileE = llvm::sys::path::end(RemappedFile);
640 auto CurDirIt = llvm::sys::path::begin(CurDir);
641 auto CurDirE = llvm::sys::path::end(CurDir);
642 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
643 llvm::sys::path::append(DirBuf, *CurDirIt);
644 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
650 for (; FileIt != FileE; ++FileIt)
651 llvm::sys::path::append(FileBuf, *FileIt);
656 if (!llvm::sys::path::is_absolute(
FileName))
660 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
661 DIFileCache[
FileName.data()].reset(F);
666 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
688 if (DebugLoc == CurLoc)
694StringRef CGDebugInfo::getCurrentDirname() {
702 assert(CGO.DwarfVersion <= 5);
704 llvm::dwarf::SourceLanguage LangTag;
707 LangTag = llvm::dwarf::DW_LANG_HLSL;
709 LangTag = llvm::dwarf::DW_LANG_HIP;
711 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
712 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
713 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
714 else if (LO.CPlusPlus14)
715 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
716 else if (LO.CPlusPlus11)
717 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
719 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
720 }
else if (LO.ObjC) {
721 LangTag = llvm::dwarf::DW_LANG_ObjC;
722 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
723 LangTag = llvm::dwarf::DW_LANG_OpenCL;
724 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
725 LangTag = llvm::dwarf::DW_LANG_C11;
727 LangTag = llvm::dwarf::DW_LANG_C99;
729 LangTag = llvm::dwarf::DW_LANG_C89;
735static llvm::DISourceLanguageName
744 llvm::dwarf::SourceLanguageName LangTag;
747 LangTag = llvm::dwarf::DW_LNAME_HLSL;
749 LangTag = llvm::dwarf::DW_LNAME_HIP;
750 }
else if (LO.ObjC) {
751 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
753 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
756 }
else if (LO.ObjC) {
757 LangTag = llvm::dwarf::DW_LNAME_ObjC;
758 }
else if (LO.OpenCL) {
759 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
761 LangTag = llvm::dwarf::DW_LNAME_C;
765 return llvm::DISourceLanguageName(LangTag, LangVersion);
768void CGDebugInfo::CreateCompileUnit() {
769 SmallString<64> Checksum;
770 std::optional<llvm::DIFile::ChecksumKind> CSKind;
771 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
781 SourceManager &SM = CGM.getContext().getSourceManager();
782 auto &CGO = CGM.getCodeGenOpts();
783 const LangOptions &LO = CGM.getLangOpts();
784 std::string MainFileName = CGO.MainFileName;
785 if (MainFileName.empty())
786 MainFileName =
"<stdin>";
792 std::string MainFileDir;
795 MainFileDir = std::string(MainFile->getDir().getName());
796 if (!llvm::sys::path::is_absolute(MainFileName)) {
797 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
798 llvm::sys::path::Style Style =
800 ? (CGM.getTarget().
getTriple().isOSWindows()
801 ? llvm::sys::path::Style::windows_backslash
802 : llvm::sys::path::Style::posix)
803 : llvm::sys::path::Style::native;
804 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
805 MainFileName = std::string(
806 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
813 if (MainFile->getName() == MainFileName &&
815 MainFile->getName().rsplit(
'.').second)
817 MainFileName = CGM.getModule().getName().str();
826 unsigned RuntimeVers = 0;
830 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
832 case llvm::codegenoptions::NoDebugInfo:
833 case llvm::codegenoptions::LocTrackingOnly:
834 EmissionKind = llvm::DICompileUnit::NoDebug;
836 case llvm::codegenoptions::DebugLineTablesOnly:
837 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
839 case llvm::codegenoptions::DebugDirectivesOnly:
840 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
842 case llvm::codegenoptions::DebugInfoConstructor:
843 case llvm::codegenoptions::LimitedDebugInfo:
844 case llvm::codegenoptions::FullDebugInfo:
845 case llvm::codegenoptions::UnusedTypeInfo:
846 EmissionKind = llvm::DICompileUnit::FullDebug;
851 auto &CGOpts = CGM.getCodeGenOpts();
857 CSInfo.emplace(*CSKind, Checksum);
858 llvm::DIFile *CUFile = DBuilder.createFile(
862 StringRef Sysroot, SDK;
863 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
864 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
865 if (CGM.getCodeGenOpts().DebugRecordSysroot)
866 Sysroot = FullSysroot;
867 auto B = llvm::sys::path::rbegin(FullSysroot);
868 auto E = llvm::sys::path::rend(FullSysroot);
870 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
875 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
876 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
877 CGOpts.DebugNameTable);
878 if (CGM.getTarget().getTriple().isNVPTX())
879 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
880 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
881 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
884 TheCU = DBuilder.createCompileUnit(
886 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
887 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
888 CGOpts.PrepareForThinLTO,
889 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
890 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
891 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
894llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
898#define BUILTIN_TYPE(Id, SingletonId)
899#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
900#include "clang/AST/BuiltinTypes.def"
901 case BuiltinType::Dependent:
902 llvm_unreachable(
"Unexpected builtin type");
903 case BuiltinType::NullPtr:
904 return DBuilder.createNullPtrType();
905 case BuiltinType::Void:
907 case BuiltinType::ObjCClass:
910 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
911 "objc_class", TheCU, TheCU->getFile(), 0);
913 case BuiltinType::ObjCId: {
924 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
925 "objc_class", TheCU, TheCU->getFile(), 0);
927 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
929 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
931 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
932 (uint64_t)0, 0, llvm::DINode::FlagZero,
933 nullptr, llvm::DINodeArray());
935 DBuilder.replaceArrays(
936 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
937 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
938 llvm::DINode::FlagZero, ISATy)));
941 case BuiltinType::ObjCSel: {
943 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
944 "objc_selector", TheCU,
945 TheCU->getFile(), 0);
949#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
950 case BuiltinType::Id: \
951 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
953#include "clang/Basic/OpenCLImageTypes.def"
954 case BuiltinType::OCLSampler:
955 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
956 case BuiltinType::OCLEvent:
957 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
958 case BuiltinType::OCLClkEvent:
959 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
960 case BuiltinType::OCLQueue:
961 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
962 case BuiltinType::OCLReserveID:
963 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
964#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
965 case BuiltinType::Id: \
966 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
967#include "clang/Basic/OpenCLExtensionTypes.def"
968#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
969 case BuiltinType::Id: \
970 return getOrCreateStructPtrType(#Name, SingletonId);
971#include "clang/Basic/HLSLIntangibleTypes.def"
972#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
973 case BuiltinType::Id: \
974 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
975#include "clang/Basic/HLSLPackedTypes.def"
977#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
978#include "clang/Basic/AArch64ACLETypes.def"
980 if (BT->
getKind() == BuiltinType::MFloat8) {
981 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
982 BTName = BT->
getName(CGM.getLangOpts());
985 return DBuilder.createBasicType(BTName, Size, Encoding);
987 ASTContext::BuiltinVectorTypeInfo Info =
989 BT->
getKind() == BuiltinType::SveCount
990 ? ASTContext::BuiltinVectorTypeInfo(
991 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
993 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1000 "Unsupported number of vectors for svcount_t");
1002 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1003 llvm::Metadata *BitStride =
nullptr;
1004 if (BT->
getKind() == BuiltinType::SveBool) {
1005 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1006 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1007 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1008 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1010 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1013 llvm::Metadata *LowerBound, *UpperBound;
1014 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1015 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1016 if (Info.
EC.isScalable()) {
1017 unsigned NumElemsPerVG = NumElems / 2;
1018 SmallVector<uint64_t, 9> Expr(
1019 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1020 46, 0, llvm::dwarf::DW_OP_mul,
1021 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1022 UpperBound = DBuilder.createExpression(Expr);
1024 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1025 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1027 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1028 nullptr, LowerBound, UpperBound,
nullptr);
1029 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1030 llvm::DIType *ElemTy =
1031 getOrCreateType(Info.
ElementType, TheCU->getFile());
1033 return DBuilder.createVectorType( 0, Align, ElemTy,
1034 SubscriptArray, BitStride);
1038#define PPC_VECTOR_TYPE(Name, Id, size) \
1039 case BuiltinType::Id:
1040#include "clang/Basic/PPCTypes.def"
1043#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1044#include "clang/Basic/RISCVVTypes.def"
1046 ASTContext::BuiltinVectorTypeInfo Info =
1047 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1049 unsigned ElementCount = Info.
EC.getKnownMinValue();
1050 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1052 bool Fractional =
false;
1055 unsigned FixedSize = ElementCount * SEW;
1056 if (Info.
ElementType == CGM.getContext().BoolTy) {
1059 }
else if (FixedSize < 64) {
1062 LMUL = 64 / FixedSize;
1064 LMUL = FixedSize / 64;
1068 SmallVector<uint64_t, 12> Expr(
1072 {llvm::dwarf::DW_OP_bregx,
1075 llvm::dwarf::DW_OP_constu,
1077 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1079 Expr.push_back(llvm::dwarf::DW_OP_div);
1081 Expr.push_back(llvm::dwarf::DW_OP_mul);
1084 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1086 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1089 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1090 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1091 auto *UpperBound = DBuilder.createExpression(Expr);
1092 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1093 nullptr, LowerBound, UpperBound,
nullptr);
1094 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1095 llvm::DIType *ElemTy =
1096 getOrCreateType(Info.
ElementType, TheCU->getFile());
1099 return DBuilder.createVectorType(0, Align, ElemTy,
1103#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1104 case BuiltinType::Id: { \
1107 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1108 MangledName, TheCU, TheCU->getFile(), 0); \
1109 return SingletonId; \
1111#include "clang/Basic/WebAssemblyReferenceTypes.def"
1112#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1113 case BuiltinType::Id: { \
1116 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1117 TheCU, TheCU->getFile(), 0); \
1118 return SingletonId; \
1120#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1121 case BuiltinType::Id: { \
1124 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1125 return SingletonId; \
1127#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1128 case BuiltinType::Id: { \
1131 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1132 return SingletonId; \
1134#include "clang/Basic/AMDGPUTypes.def"
1135#define SPIRV_TYPE(Name, Id, SingletonId) \
1136 case BuiltinType::Id: \
1137 return getOrCreateStructPtrType(Name, SingletonId);
1138#include "clang/Basic/SPIRVTypes.def"
1139 case BuiltinType::UChar:
1140 case BuiltinType::Char_U:
1141 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1143 case BuiltinType::Char_S:
1144 case BuiltinType::SChar:
1145 Encoding = llvm::dwarf::DW_ATE_signed_char;
1147 case BuiltinType::Char8:
1148 case BuiltinType::Char16:
1149 case BuiltinType::Char32:
1150 Encoding = llvm::dwarf::DW_ATE_UTF;
1152 case BuiltinType::UShort:
1153 case BuiltinType::UInt:
1154 case BuiltinType::UInt128:
1155 case BuiltinType::ULong:
1156 case BuiltinType::WChar_U:
1157 case BuiltinType::ULongLong:
1158 Encoding = llvm::dwarf::DW_ATE_unsigned;
1160 case BuiltinType::Short:
1161 case BuiltinType::Int:
1162 case BuiltinType::Int128:
1163 case BuiltinType::Long:
1164 case BuiltinType::WChar_S:
1165 case BuiltinType::LongLong:
1166 Encoding = llvm::dwarf::DW_ATE_signed;
1168 case BuiltinType::Bool:
1169 Encoding = llvm::dwarf::DW_ATE_boolean;
1171 case BuiltinType::Half:
1172 case BuiltinType::Float:
1173 case BuiltinType::LongDouble:
1174 case BuiltinType::Float16:
1175 case BuiltinType::BFloat16:
1176 case BuiltinType::Float128:
1177 case BuiltinType::Double:
1178 case BuiltinType::Ibm128:
1184 Encoding = llvm::dwarf::DW_ATE_float;
1186 case BuiltinType::ShortAccum:
1187 case BuiltinType::Accum:
1188 case BuiltinType::LongAccum:
1189 case BuiltinType::ShortFract:
1190 case BuiltinType::Fract:
1191 case BuiltinType::LongFract:
1192 case BuiltinType::SatShortFract:
1193 case BuiltinType::SatFract:
1194 case BuiltinType::SatLongFract:
1195 case BuiltinType::SatShortAccum:
1196 case BuiltinType::SatAccum:
1197 case BuiltinType::SatLongAccum:
1198 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1200 case BuiltinType::UShortAccum:
1201 case BuiltinType::UAccum:
1202 case BuiltinType::ULongAccum:
1203 case BuiltinType::UShortFract:
1204 case BuiltinType::UFract:
1205 case BuiltinType::ULongFract:
1206 case BuiltinType::SatUShortAccum:
1207 case BuiltinType::SatUAccum:
1208 case BuiltinType::SatULongAccum:
1209 case BuiltinType::SatUShortFract:
1210 case BuiltinType::SatUFract:
1211 case BuiltinType::SatULongFract:
1212 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1214 case BuiltinType::MetaInfo:
1215 llvm_unreachable(
"std::meta::info is consteval-only type");
1218 BTName = BT->
getName(CGM.getLangOpts());
1221 return DBuilder.createBasicType(BTName, Size, Encoding);
1224llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1225 SmallString<32> Name;
1226 llvm::raw_svector_ostream
OS(Name);
1227 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1230 ? llvm::dwarf::DW_ATE_unsigned
1231 : llvm::dwarf::DW_ATE_signed;
1232 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1233 Encoding, llvm::DINode::FlagZero, 0,
1237llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1239 return getOrCreateType(Ty->getUnderlyingType(), U);
1242llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1244 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1246 Encoding = llvm::dwarf::DW_ATE_lo_user;
1249 return DBuilder.createBasicType(
"complex", Size, Encoding);
1263 return llvm::dwarf::DW_TAG_const_type;
1267 return llvm::dwarf::DW_TAG_volatile_type;
1271 return llvm::dwarf::DW_TAG_restrict_type;
1273 return (llvm::dwarf::Tag)0;
1276llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1277 llvm::DIFile *Unit) {
1278 QualifierCollector Qc;
1292 bool AuthenticatesNullValues =
1295 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1296 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1297 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1298 ExtraDiscr, IsaPointer,
1299 AuthenticatesNullValues);
1301 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1302 return getOrCreateType(QualType(
T, 0), Unit);
1306 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1310 return DBuilder.createQualifiedType(Tag, FromTy);
1313llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1314 llvm::DIFile *Unit) {
1323 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1328 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1334 return DBuilder.createQualifiedType(Tag, FromTy);
1337llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1338 llvm::DIFile *Unit) {
1344 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1346 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1350llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1351 llvm::DIFile *Unit) {
1352 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1358 case llvm::dwarf::DW_LANG_C_plus_plus:
1359 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1360 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1361 case llvm::dwarf::DW_LANG_HIP:
1363 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1373 case llvm::dwarf::DW_LNAME_C_plus_plus:
1374 case llvm::dwarf::DW_LNAME_HIP:
1376 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1387 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1388 SourceLang.hasVersionedName())
1390 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1394 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1420 llvm::DICompileUnit *TheCU) {
1438 llvm::DICompileUnit *TheCU) {
1444 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1446 if (RD->isDynamicClass() &&
1452 llvm::raw_svector_ostream Out(Identifier);
1459 llvm::dwarf::Tag Tag;
1461 Tag = llvm::dwarf::DW_TAG_structure_type;
1463 Tag = llvm::dwarf::DW_TAG_union_type;
1468 Tag = llvm::dwarf::DW_TAG_class_type;
1473llvm::DICompositeType *
1474CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1475 llvm::DIScope *Ctx) {
1477 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1479 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1480 const unsigned Line =
1482 StringRef RDName = getClassName(RD);
1489 Size = CGM.getContext().getTypeSize(Ty);
1491 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1496 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1497 if (!CXXRD->hasDefinition() ||
1498 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1499 Flags |= llvm::DINode::FlagNonTrivial;
1502 SmallString<256> Identifier;
1504 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1506 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1509 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1510 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1511 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1512 CollectCXXTemplateParams(TSpecial, DefUnit));
1513 ReplaceMap.emplace_back(
1514 std::piecewise_construct, std::make_tuple(Ty),
1515 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1519llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1522 llvm::DIFile *Unit) {
1527 std::optional<unsigned> DWARFAddressSpace =
1528 CGM.getTarget().getDWARFAddressSpace(
1529 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1531 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1532 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1533 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1534 Size, Align, DWARFAddressSpace);
1536 SmallVector<llvm::Metadata *, 4> Annots;
1537 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1539 llvm::DINodeArray Annotations =
nullptr;
1540 if (Annots.size() > 0)
1541 Annotations = DBuilder.getOrCreateArray(Annots);
1542 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1543 Align, DWARFAddressSpace, StringRef(),
1548llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1549 llvm::DIType *&
Cache) {
1552 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1553 TheCU, TheCU->getFile(), 0);
1554 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1555 Cache = DBuilder.createPointerType(
Cache, Size);
1559uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1560 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1561 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1571 if (CGM.getLangOpts().OpenCL) {
1572 FType = CGM.getContext().IntTy;
1573 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1574 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1576 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1578 FType = CGM.getContext().IntTy;
1579 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1580 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1582 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1583 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1584 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1585 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1586 EltTys.push_back(DBuilder.createMemberType(
1587 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1588 FieldOffset, llvm::DINode::FlagZero, DescTy));
1589 FieldOffset += FieldSize;
1595llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1596 llvm::DIFile *Unit) {
1597 SmallVector<llvm::Metadata *, 8> EltTys;
1600 llvm::DINodeArray Elements;
1603 FType = CGM.getContext().UnsignedLongTy;
1604 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1605 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1607 Elements = DBuilder.getOrCreateArray(EltTys);
1610 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1613 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1614 FieldOffset, 0, Flags,
nullptr, Elements);
1619 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1621 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1624 Elements = DBuilder.getOrCreateArray(EltTys);
1630 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1631 Flags,
nullptr, Elements);
1633 return DBuilder.createPointerType(EltTy, Size);
1636static llvm::SmallVector<TemplateArgument>
1638 assert(Ty->isTypeAlias());
1647 ArrayRef SubstArgs = Ty->template_arguments();
1650 if (Param->isParameterPack()) {
1659 if (SubstArgs.empty()) {
1668 SpecArgs.push_back(SubstArgs.front());
1669 SubstArgs = SubstArgs.drop_front();
1674llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1675 llvm::DIFile *Unit) {
1676 assert(Ty->isTypeAlias());
1677 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1679 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1687 SmallString<128> NS;
1688 llvm::raw_svector_ostream
OS(NS);
1690 auto PP = getPrintingPolicy();
1693 SourceLocation Loc =
AliasDecl->getLocation();
1695 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1696 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1705 llvm::raw_string_ostream
OS(Name);
1707 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1708 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1709 !HasReconstitutableArgs(Args.Args))
1710 printTemplateArgumentList(OS, Args.Args, PP);
1712 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1713 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1714 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1718 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1720 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1737 return llvm::DINode::FlagZero;
1741 return llvm::DINode::FlagPrivate;
1743 return llvm::DINode::FlagProtected;
1745 return llvm::DINode::FlagPublic;
1747 return llvm::DINode::FlagZero;
1749 llvm_unreachable(
"unexpected access enumerator");
1752llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1753 llvm::DIFile *Unit) {
1754 llvm::DIType *Underlying =
1770 SmallVector<llvm::Metadata *, 4> Annots;
1771 llvm::DINodeArray Annotations;
1773 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1774 if (!Annots.empty())
1775 Annotations = DBuilder.getOrCreateArray(Annots);
1777 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1782 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1783 getOrCreateFile(Loc), getLineNumber(Loc),
1784 getDeclContextDescriptor(Ty->
getDecl()), Align,
1785 Flags, Annotations);
1793 if (
T.isSPIROrSPIRV())
1794 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1799 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1801 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1803 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1805 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1807 return llvm::dwarf::DW_CC_BORLAND_pascal;
1809 return llvm::dwarf::DW_CC_LLVM_Win64;
1811 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1815 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1817 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1819 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1821 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1823 return llvm::dwarf::DW_CC_LLVM_Swift;
1825 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1827 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1829 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1831 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1833 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1835 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1837 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1838#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1852 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1858 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1860 Flags |= llvm::DINode::FlagLValueReference;
1862 Flags |= llvm::DINode::FlagRValueReference;
1866llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1867 llvm::DIFile *Unit) {
1868 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1870 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1876 SmallVector<llvm::Metadata *, 16> EltTys;
1879 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1881 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1885 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1888 for (
const QualType &ParamType : FPT->param_types())
1889 EltTys.push_back(getOrCreateType(ParamType, Unit));
1890 if (FPT->isVariadic())
1891 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1894 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1895 llvm::DIType *F = DBuilder.createSubroutineType(
1896 EltTypeArray, Flags,
1901llvm::DIDerivedType *
1902CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1903 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1904 StringRef Name = BitFieldDecl->
getName();
1905 QualType Ty = BitFieldDecl->
getType();
1906 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1909 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1910 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1913 llvm::DIFile *
File = getOrCreateFile(Loc);
1914 unsigned Line = getLineNumber(Loc);
1916 const CGBitFieldInfo &BitFieldInfo =
1917 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1919 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1926 if (CGM.getDataLayout().isBigEndian())
1928 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1930 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1931 return DBuilder.createBitFieldMemberType(
1932 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1933 Flags, DebugType, Annotations);
1936llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1937 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1938 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1940 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1965 if (PreviousFieldsDI.empty())
1969 auto *PreviousMDEntry =
1970 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1971 auto *PreviousMDField =
1972 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1973 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1974 PreviousMDField->getSizeInBits() == 0)
1978 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1980 assert(PreviousBitfield->isBitField());
1982 if (!PreviousBitfield->isZeroLengthBitField())
1985 QualType Ty = PreviousBitfield->getType();
1986 SourceLocation Loc = PreviousBitfield->getLocation();
1987 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1988 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1989 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1991 llvm::DIFile *
File = getOrCreateFile(Loc);
1992 unsigned Line = getLineNumber(Loc);
1998 llvm::DINode::DIFlags Flags =
2000 llvm::DINodeArray Annotations =
2001 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2002 return DBuilder.createBitFieldMemberType(
2003 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2004 Flags, DebugType, Annotations);
2007llvm::DIType *CGDebugInfo::createFieldType(
2009 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2010 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2011 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2014 llvm::DIFile *file = getOrCreateFile(loc);
2015 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2018 auto Align = AlignInBits;
2019 if (!
type->isIncompleteArrayType()) {
2020 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2021 SizeInBits = TI.
Width;
2027 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2028 offsetInBits, flags, debugType, Annotations);
2032CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2033 llvm::DIFile *FileScope) {
2037 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2040 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2041 SP = DBuilder.createFunction(
2042 FileScope, FuncName, StringRef(),
2043 FileScope, 0, DIFnTy,
2045 llvm::DINode::FlagArtificial,
2046 llvm::DISubprogram::SPFlagDefinition,
2047 nullptr,
nullptr,
nullptr,
2048 nullptr, StringRef(),
2049 CGM.getCodeGenOpts().DebugKeyInstructions);
2056CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2058 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2060 assert(
Capture.capturesVariable());
2062 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2063 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2065 return CaptureDecl->
getName();
2068void CGDebugInfo::CollectRecordLambdaFields(
2069 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2070 llvm::DIType *RecordTy) {
2075 unsigned fieldno = 0;
2078 I != E; ++I, ++Field, ++fieldno) {
2079 const LambdaCapture &
Capture = *I;
2081 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2083 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2093 Loc =
Field->getLocation();
2094 }
else if (
Capture.capturesVariable()) {
2097 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2098 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2105 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2107 FieldIndexCache[*
Field] = elements.size();
2108 elements.push_back(createFieldType(
2110 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2116template <
typename T>
2117static llvm::Constant *
2128 return llvm::ConstantDataArray::get(Ctx, Vals);
2141 const QualType ElemQTy = ArrayTy->getElementType();
2148 switch (ElemBitWidth) {
2164llvm::DIDerivedType *
2165CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2166 const RecordDecl *RD) {
2170 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2171 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2173 unsigned LineNumber = getLineNumber(Var->
getLocation());
2174 StringRef VName = Var->
getName();
2178 llvm::Constant *
C =
nullptr;
2183 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2184 if (
Value->isFloat())
2185 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2186 if (
Value->isArray())
2192 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2193 ? llvm::dwarf::DW_TAG_variable
2194 : llvm::dwarf::DW_TAG_member;
2196 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2197 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2202void CGDebugInfo::CollectRecordNormalField(
2203 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2204 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2205 const RecordDecl *RD) {
2210 if (
name.empty() && !
type->isRecordType())
2213 llvm::DIType *FieldType;
2215 llvm::DIDerivedType *BitFieldType;
2216 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2217 if (llvm::DIType *Separator =
2218 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2219 elements.push_back(Separator);
2222 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2225 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2228 FieldIndexCache[field] = elements.size();
2229 elements.push_back(FieldType);
2232void CGDebugInfo::CollectRecordNestedType(
2233 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2234 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2241 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2242 elements.push_back(nestedType);
2245void CGDebugInfo::CollectRecordFields(
2246 const RecordDecl *record, llvm::DIFile *tunit,
2247 SmallVectorImpl<llvm::Metadata *> &elements,
2248 llvm::DICompositeType *RecordTy) {
2249 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2251 if (CXXDecl && CXXDecl->
isLambda())
2252 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2254 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2257 unsigned fieldNo = 0;
2261 for (
const auto *I : record->
decls())
2262 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2263 if (
V->hasAttr<NoDebugAttr>())
2268 if (CGM.getCodeGenOpts().EmitCodeView &&
2276 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2277 if (MI != StaticDataMemberCache.end()) {
2278 assert(MI->second &&
2279 "Static data member declaration should still exist");
2280 elements.push_back(MI->second);
2282 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2283 elements.push_back(Field);
2285 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2286 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2287 elements, RecordTy, record);
2291 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2294 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2299 if (!nestedType->isImplicit() &&
2300 nestedType->getDeclContext() == record)
2301 CollectRecordNestedType(nestedType, elements);
2307llvm::DISubroutineType *
2308CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2309 llvm::DIFile *Unit) {
2310 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2312 return cast_or_null<llvm::DISubroutineType>(
2313 getOrCreateType(QualType(
Func, 0), Unit));
2316 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2317 ThisType =
Method->getThisType();
2319 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2322llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2323 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2324 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2326 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2329llvm::DISubroutineType *
2330CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2331 const FunctionProtoType *
Func,
2332 llvm::DIFile *Unit,
bool SkipFirst) {
2333 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2348 getOrCreateType(CGM.getContext().getFunctionType(
2349 Func->getReturnType(),
Func->getParamTypes(), EPI),
2351 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2352 assert(Args.size() &&
"Invalid number of arguments!");
2354 SmallVector<llvm::Metadata *, 16> Elts;
2357 Elts.push_back(Args[0]);
2359 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2363 if (!HasExplicitObjectParameter) {
2364 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2367 DBuilder.createObjectPointerType(ThisPtrType,
true);
2368 Elts.push_back(ThisPtrType);
2372 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2373 Elts.push_back(Args[i]);
2376 if (HasExplicitObjectParameter) {
2377 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2378 "Expected at least return type and object parameter.");
2379 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2382 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2384 return DBuilder.createSubroutineType(
2385 EltTypeArray, OriginalFunc->getFlags(),
2392 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2400CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2403 const bool IsCtorOrDtor =
2406 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2413 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2416 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2419 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2422 return CGM.getMangledName(
Method);
2425bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2428 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2431llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2432 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2435 StringRef MethodName = getFunctionName(
Method);
2436 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2438 StringRef MethodLinkageName;
2445 MethodLinkageName = GetMethodLinkageName(
Method);
2448 llvm::DIFile *MethodDefUnit =
nullptr;
2449 unsigned MethodLine = 0;
2450 if (!
Method->isImplicit()) {
2451 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2452 MethodLine = getLineNumber(
Method->getLocation());
2456 llvm::DIType *ContainingType =
nullptr;
2457 unsigned VIndex = 0;
2458 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2459 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2460 int ThisAdjustment = 0;
2463 if (
Method->isPureVirtual())
2464 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2466 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2468 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2472 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2476 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2479 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2480 CGM.getContext().getLangOpts())
2484 MethodVFTableLocation ML =
2485 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2493 if (
Method->size_overridden_methods() == 0)
2494 Flags |= llvm::DINode::FlagIntroducedVirtual;
2499 ThisAdjustment = CGM.getCXXABI()
2500 .getVirtualFunctionPrologueThisAdjustment(GD)
2503 ContainingType = RecordTy;
2506 if (
Method->getCanonicalDecl()->isDeleted())
2507 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2509 if (
Method->isNoReturn())
2510 Flags |= llvm::DINode::FlagNoReturn;
2513 Flags |= llvm::DINode::FlagStaticMember;
2514 if (
Method->isImplicit())
2515 Flags |= llvm::DINode::FlagArtificial;
2517 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2518 if (CXXC->isExplicit())
2519 Flags |= llvm::DINode::FlagExplicit;
2520 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2521 if (CXXC->isExplicit())
2522 Flags |= llvm::DINode::FlagExplicit;
2524 if (
Method->hasPrototype())
2525 Flags |= llvm::DINode::FlagPrototyped;
2527 Flags |= llvm::DINode::FlagLValueReference;
2529 Flags |= llvm::DINode::FlagRValueReference;
2530 if (!
Method->isExternallyVisible())
2531 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2532 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2533 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2538 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2539 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2540 if (
const auto *Def =
2541 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2542 Def && !Def->isDelegatingConstructor()) {
2548 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2549 llvm::DISubprogram *SP = DBuilder.createMethod(
2550 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2551 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2552 TParamsArray.get(),
nullptr,
2553 CGM.getCodeGenOpts().DebugKeyInstructions);
2555 SPCache[
Method->getCanonicalDecl()].reset(SP);
2560void CGDebugInfo::CollectCXXMemberFunctions(
2561 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2562 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2567 for (
const auto *I : RD->
decls()) {
2568 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2582 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2591 auto MI = SPCache.find(
Method->getCanonicalDecl());
2592 EltTys.push_back(MI == SPCache.end()
2593 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2594 :
static_cast<llvm::Metadata *
>(MI->second));
2598void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2599 SmallVectorImpl<llvm::Metadata *> &EltTys,
2600 llvm::DIType *RecordTy) {
2601 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2602 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2603 llvm::DINode::FlagZero);
2607 if (CGM.getCodeGenOpts().EmitCodeView) {
2608 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2609 llvm::DINode::FlagIndirectVirtualBase);
2613void CGDebugInfo::CollectCXXBasesAux(
2614 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2615 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2617 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2618 llvm::DINode::DIFlags StartingFlags) {
2619 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2620 for (
const auto &BI : Bases) {
2623 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2625 if (!SeenTypes.insert(Base).second)
2627 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2628 llvm::DINode::DIFlags BFlags = StartingFlags;
2632 if (BI.isVirtual()) {
2633 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2636 BaseOffset = 0 - CGM.getItaniumVTableContext()
2637 .getVirtualBaseOffsetOffset(RD, Base)
2643 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2644 VBPtrOffset = CGM.getContext()
2645 .getASTRecordLayout(RD)
2649 BFlags |= llvm::DINode::FlagVirtual;
2656 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2657 VBPtrOffset, BFlags);
2658 EltTys.push_back(DTy);
2663CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2664 llvm::DIFile *Unit) {
2666 return llvm::DINodeArray();
2667 TemplateArgs &Args = *OArgs;
2668 SmallVector<llvm::Metadata *, 16> TemplateParams;
2669 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2670 const TemplateArgument &TA = Args.Args[i];
2674 Name = Args.TList->getParam(i)->getName();
2678 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2679 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2680 TheCU, Name, TTy, defaultParameter));
2685 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2686 TheCU, Name, TTy, defaultParameter,
2687 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2692 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2693 llvm::Constant *
V =
nullptr;
2696 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2697 !D->
hasAttr<CUDADeviceAttr>()) {
2700 if (
const auto *VD = dyn_cast<VarDecl>(D))
2701 V = CGM.GetAddrOfGlobalVar(VD);
2704 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2705 MD && MD->isImplicitObjectMemberFunction())
2706 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2707 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2708 V = CGM.GetAddrOfFunction(FD);
2711 else if (
const auto *MPT =
2712 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2716 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2718 CGM.getContext().toCharUnitsFromBits((
int64_t)fieldOffset);
2719 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2720 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2721 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2722 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2724 V = ConstantEmitter(CGM).emitAbstract(
2725 SourceLocation(), TPO->getValue(), TPO->getType());
2727 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2729 assert(
V &&
"Failed to find template parameter pointer");
2730 V =
V->stripPointerCasts();
2732 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2733 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2737 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2738 llvm::Constant *
V =
nullptr;
2741 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2747 if (MPT->isMemberDataPointer())
2748 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2750 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2751 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2752 TheCU, Name, TTy, defaultParameter,
V));
2756 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2757 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2759 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2760 TheCU, Name, TTy, defaultParameter,
V));
2763 std::string QualName;
2764 llvm::raw_string_ostream
OS(QualName);
2766 OS, getPrintingPolicy());
2767 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2768 TheCU, Name,
nullptr, QualName, defaultParameter));
2772 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2773 TheCU, Name,
nullptr,
2780 T = CGM.getContext().getLValueReferenceType(
T);
2781 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2782 assert(
V &&
"Expression in template argument isn't constant");
2783 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2784 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2785 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2791 "These argument types shouldn't exist in concrete types");
2794 return DBuilder.getOrCreateArray(TemplateParams);
2797std::optional<CGDebugInfo::TemplateArgs>
2798CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2806 return std::nullopt;
2808std::optional<CGDebugInfo::TemplateArgs>
2809CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2813 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2815 return std::nullopt;
2816 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2817 const TemplateParameterList *TList =
T->getTemplateParameters();
2818 auto TA = TS->getTemplateArgs().asArray();
2819 return {{TList, TA}};
2821std::optional<CGDebugInfo::TemplateArgs>
2822CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2823 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2827 TemplateParameterList *TPList =
2828 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2829 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2830 return {{TPList, TAList.
asArray()}};
2832 return std::nullopt;
2836CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2837 llvm::DIFile *Unit) {
2838 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2841llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2842 llvm::DIFile *Unit) {
2843 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2846llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2847 llvm::DIFile *Unit) {
2848 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2851void CGDebugInfo::CollectBTFDeclTagAnnotations(
2852 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2854 llvm::Metadata *Ops[2] = {
2855 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2856 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2857 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2861llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2862 if (!D->
hasAttr<BTFDeclTagAttr>())
2865 SmallVector<llvm::Metadata *, 4> Annotations;
2866 CollectBTFDeclTagAnnotations(D, Annotations);
2867 return DBuilder.getOrCreateArray(Annotations);
2870void CGDebugInfo::CollectBTFTypeTagAnnotations(
2871 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2872 const BTFTagAttributedType *BTFAttrTy;
2874 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2876 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2879 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2881 llvm::Metadata *Ops[2] = {
2882 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2883 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2884 Annotations.insert(Annotations.begin(),
2885 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2887 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2891llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2893 return VTablePtrType;
2895 ASTContext &Context = CGM.getContext();
2898 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2899 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2900 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2902 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2903 std::optional<unsigned> DWARFAddressSpace =
2904 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2906 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2907 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2908 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2909 return VTablePtrType;
2912StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2924 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2926 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2936 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2937 VTable->isDeclarationForLinker())
2941 StringRef SymbolName =
"__clang_vtable";
2943 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2952 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2954 llvm::DIFile *Unit = getOrCreateFile(Loc);
2955 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2957 llvm::DINode::FlagArtificial;
2958 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2959 ? llvm::dwarf::DW_TAG_variable
2960 : llvm::dwarf::DW_TAG_member;
2961 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2962 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2966 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2970 llvm::DIGlobalVariableExpression *GVE =
2971 DBuilder.createGlobalVariableExpression(
2972 TheCU, SymbolName, VTable->getName(), Unit, 0,
2973 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2974 true,
nullptr, DT,
nullptr,
2976 VTable->addDebugInfo(GVE);
2979StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2981 llvm::Function *InitFn) {
2986 return InitFn->getName();
2996 llvm::raw_svector_ostream OS(QualifiedGV);
2998 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3000 std::swap(Quals, GVName);
3004 llvm::raw_svector_ostream OS(InitName);
3006 OS << Quals <<
"::";
3011 llvm_unreachable(
"not an initializer");
3013 OS <<
"`dynamic initializer for '";
3016 OS <<
"`dynamic atexit destructor for '";
3023 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3024 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3025 getPrintingPolicy());
3030 return internString(
OS.str());
3033void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3034 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3043 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3050 llvm::DIType *VPtrTy =
nullptr;
3051 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3052 CGM.getTarget().getCXXABI().isMicrosoft();
3053 if (NeedVTableShape) {
3055 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3056 const VTableLayout &VFTLayout =
3057 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3058 unsigned VSlotCount =
3060 unsigned VTableWidth = PtrWidth * VSlotCount;
3061 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3062 std::optional<unsigned> DWARFAddressSpace =
3063 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3066 llvm::DIType *VTableType = DBuilder.createPointerType(
3067 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3068 EltTys.push_back(VTableType);
3071 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3079 VPtrTy = getOrCreateVTablePtrType(Unit);
3081 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3082 llvm::DIType *VPtrMember =
3083 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3084 llvm::DINode::FlagArtificial, VPtrTy);
3085 EltTys.push_back(VPtrMember);
3088std::pair<llvm::DIType *, unsigned>
3093 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3100 auto I = FieldIndexCache.find(Field);
3101 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3102 return {
T, I->second};
3112 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3113 assert(!D.
isNull() &&
"null type");
3114 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3115 assert(
T &&
"could not create debug info for type");
3124 if (CGM.getCodeGenOpts().getDebugInfo() <=
3125 llvm::codegenoptions::DebugLineTablesOnly)
3129 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3131 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3133 CI->setMetadata(
"heapallocsite", node);
3137 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3139 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3141 auto I = TypeCache.find(TyPtr);
3144 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3145 assert(!Res->isForwardDecl());
3146 TypeCache[TyPtr].reset(Res);
3150 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3151 !CGM.getLangOpts().CPlusPlus)
3157 if (RD->
hasAttr<DLLImportAttr>())
3160 if (MD->hasAttr<DLLImportAttr>())
3173 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3183 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3184 Explicit = TD->isExplicitInstantiationOrSpecialization();
3188 if (CXXDecl->
fields().empty())
3198 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3199 if (CXXRD->isDynamicClass() &&
3200 CGM.getVTableLinkage(CXXRD) ==
3201 llvm::GlobalValue::AvailableExternallyLinkage &&
3212 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3214 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3216 auto I = TypeCache.find(TyPtr);
3223 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3224 assert(!Res->isForwardDecl());
3225 TypeCache[TyPtr].reset(Res);
3232 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3233 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3260 bool HasNonDeletedCtor =
false;
3262 if (Ctor->isCopyOrMoveConstructor())
3269 if (CtorDef->isDelegatingConstructor())
3273 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3276 if (!Ctor->isDeleted())
3277 HasNonDeletedCtor =
true;
3279 return HasNonDeletedCtor;
3295 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3298 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3299 RD->
hasAttr<StandaloneDebugAttr>())
3302 if (!LangOpts.CPlusPlus)
3308 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3324 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3325 Spec = SD->getSpecializationKind();
3334 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3345 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3346 llvm::DIType *
T = getTypeOrNull(Ty);
3347 if (
T &&
T->isForwardDecl())
3351llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3353 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3357 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3361 auto [Def, Pref] = CreateTypeDefinition(Ty);
3363 return Pref ? Pref : Def;
3366llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3367 llvm::DIFile *Unit) {
3371 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3375 return getOrCreateType(PNA->getTypedefType(), Unit);
3402 const auto *RT = QT->
getAs<RecordType>();
3406 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3407 if (!CRD || !CRD->hasDefinition())
3412 assert(CRD->isStandardLayout());
3418std::pair<llvm::DIType *, llvm::DIType *>
3419CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3423 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3431 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3435 return {FwdDecl,
nullptr};
3437 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3438 CollectContainingType(CXXDecl, FwdDecl);
3441 LexicalBlockStack.emplace_back(&*FwdDecl);
3442 RegionMap[RD].reset(FwdDecl);
3445 SmallVector<llvm::Metadata *, 16> EltTys;
3452 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3454 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3455 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3459 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3460 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3461 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3463 LexicalBlockStack.pop_back();
3464 RegionMap.erase(RD);
3466 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3467 DBuilder.replaceArrays(FwdDecl, Elements);
3469 if (FwdDecl->isTemporary())
3471 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3473 RegionMap[RD].reset(FwdDecl);
3475 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3490 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3491 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3492 return {FwdDecl, PrefDI};
3494 return {FwdDecl,
nullptr};
3497llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3498 llvm::DIFile *Unit) {
3500 return getOrCreateType(Ty->getBaseType(), Unit);
3503llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3504 llvm::DIFile *Unit) {
3506 SourceLocation Loc = Ty->getDecl()->getLocation();
3509 return DBuilder.createTypedef(
3510 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3511 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3512 getDeclContextDescriptor(Ty->getDecl()));
3539llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3540 llvm::DIFile *Unit) {
3545 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3546 TheCU->getSourceLanguage().getUnversionedName());
3551 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3552 !
ID->getImplementation())
3553 return DBuilder.createForwardDecl(
3554 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3555 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3558 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3559 unsigned Line = getLineNumber(
ID->getLocation());
3563 ObjCInterfaceDecl *Def =
ID->getDefinition();
3565 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3566 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3567 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3568 DefUnit,
Line, RuntimeLang);
3569 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3573 return CreateTypeDefinition(Ty, Unit);
3576llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3577 bool CreateSkeletonCU) {
3582 auto ModRef = ModuleCache.find(M);
3583 if (ModRef != ModuleCache.end())
3587 SmallString<128> ConfigMacros;
3589 llvm::raw_svector_ostream
OS(ConfigMacros);
3590 const auto &PPOpts = CGM.getPreprocessorOpts();
3593 for (
auto &M : PPOpts.Macros) {
3596 const std::string &
Macro = M.first;
3597 bool Undef = M.second;
3598 OS <<
"\"-" << (Undef ?
'U' :
'D');
3599 for (
char c :
Macro)
3614 bool IsRootModule = M ? !M->
Parent :
true;
3618 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3619 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3620 "clang module without ASTFile must be specified by -fmodule-name");
3623 auto RemapPath = [
this](StringRef Path) -> std::string {
3625 StringRef Relative(Remapped);
3626 StringRef CompDir = TheCU->getDirectory();
3627 if (CompDir.empty())
3630 if (Relative.consume_front(CompDir))
3631 Relative.consume_front(llvm::sys::path::get_separator());
3633 return Relative.str();
3636 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3643 Signature = ModSig.truncatedValue();
3647 llvm::DIBuilder DIB(CGM.getModule());
3649 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3650 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3651 PCM = getCurrentDirname();
3655 llvm::sys::path::append(PCM, Mod.
getASTFile());
3656 DIB.createCompileUnit(
3657 TheCU->getSourceLanguage(),
3660 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3661 llvm::DICompileUnit::FullDebug, Signature);
3665 llvm::DIModule *Parent =
3667 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3669 StringRef IncludePath = Mod.
getPath();
3670 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3671 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3672 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3675 llvm::DIModule *DIMod =
3676 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3677 RemapPath(IncludePath));
3678 ModuleCache[M].reset(DIMod);
3682llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3683 llvm::DIFile *Unit) {
3685 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3686 unsigned Line = getLineNumber(
ID->getLocation());
3688 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3694 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3695 if (
ID->getImplementation())
3696 Flags |= llvm::DINode::FlagObjcClassComplete;
3698 llvm::DINodeArray Annotations;
3699 const auto *RuntimeName =
ID->getAttr<ObjCRuntimeNameAttr>();
3700 if (RuntimeName && RuntimeName->getMetadataName() !=
ID->getName()) {
3701 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
3702 llvm::Metadata *Ops[2] = {
3703 llvm::MDString::get(Ctx,
"objc_runtime_name"),
3704 llvm::MDString::get(Ctx, RuntimeName->getMetadataName())};
3705 Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)});
3708 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3709 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3710 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3711 nullptr, llvm::DINodeArray(), RuntimeLang,
nullptr,
3715 QualType QTy(Ty, 0);
3716 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3719 LexicalBlockStack.emplace_back(RealDecl);
3720 RegionMap[Ty->
getDecl()].reset(RealDecl);
3723 SmallVector<llvm::Metadata *, 16> EltTys;
3725 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3727 llvm::DIType *SClassTy =
3728 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3732 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3733 llvm::DINode::FlagZero);
3734 EltTys.push_back(InhTag);
3738 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3739 SourceLocation Loc = PD->getLocation();
3740 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3741 unsigned PLine = getLineNumber(Loc);
3742 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3743 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3744 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3745 PD->getName(), PUnit, PLine,
3747 : getSelectorName(PD->getGetterName()),
3749 : getSelectorName(PD->getSetterName()),
3750 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3751 EltTys.push_back(PropertyNode);
3756 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3760 llvm::DenseSet<IsClassAndIdent> PropertySet;
3762 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3763 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3765 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3766 for (
auto *PD : ClassExt->properties()) {
3767 PropertySet.insert(GetIsClassAndIdent(PD));
3770 for (
const auto *PD :
ID->properties()) {
3773 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3779 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3780 unsigned FieldNo = 0;
3781 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3782 Field =
Field->getNextIvar(), ++FieldNo) {
3783 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3787 StringRef FieldName =
Field->getName();
3790 if (FieldName.empty())
3794 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3795 unsigned FieldLine = getLineNumber(
Field->getLocation());
3796 QualType FType =
Field->getType();
3803 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3804 : CGM.getContext().getTypeSize(FType);
3809 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3813 if (
Field->isBitField()) {
3815 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3816 FieldOffset %= CGM.getContext().getCharWidth();
3824 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3826 Flags = llvm::DINode::FlagProtected;
3828 Flags = llvm::DINode::FlagPrivate;
3830 Flags = llvm::DINode::FlagPublic;
3832 if (
Field->isBitField())
3833 Flags |= llvm::DINode::FlagBitField;
3835 llvm::MDNode *PropertyNode =
nullptr;
3836 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3837 llvm::DIFile *PUnit =
nullptr;
3839 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3840 if (ObjCPropertyImplDecl *PImpD =
3841 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3842 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3843 SynthesizedProperty = PD;
3844 SourceLocation Loc = PD->getLocation();
3845 PUnit = getOrCreateFile(Loc);
3846 PLine = getLineNumber(Loc);
3847 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3848 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3849 PropertyNode = DBuilder.createObjCProperty(
3850 PD->getName(), PUnit, PLine,
3853 : getSelectorName(PD->getGetterName()),
3856 : getSelectorName(PD->getSetterName()),
3857 PD->getPropertyAttributes(),
3858 getOrCreateType(PD->getType(), PUnit));
3862 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3863 FieldSize, FieldAlign, FieldOffset,
3864 Flags, FieldTy, PropertyNode);
3865 EltTys.push_back(IvarTy);
3867 if (SynthesizedProperty) {
3868 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3869 EltTys.push_back(DBuilder.createProperty(
3870 SynthesizedProperty->
getName(), PUnit, PLine,
3871 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3875 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3876 DBuilder.replaceArrays(RealDecl, Elements);
3878 LexicalBlockStack.pop_back();
3882llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3883 llvm::DIFile *Unit) {
3891 auto &Ctx = CGM.getContext();
3896 QualType CharVecTy =
3898 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3901 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3904 llvm::Metadata *Subscript;
3905 QualType QTy(Ty, 0);
3906 auto SizeExpr = SizeExprCache.find(QTy);
3907 if (SizeExpr != SizeExprCache.end())
3908 Subscript = DBuilder.getOrCreateSubrange(
3909 SizeExpr->getSecond() ,
nullptr ,
3910 nullptr ,
nullptr );
3913 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3914 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3915 Subscript = DBuilder.getOrCreateSubrange(
3916 CountNode ,
nullptr ,
nullptr ,
3919 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3924 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3927llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3928 llvm::DIFile *Unit) {
3932 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3937 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3938 auto *ColumnCountNode =
3939 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3940 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3941 auto *RowCountNode =
3942 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3943 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3944 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3945 ColumnCountNode ,
nullptr ,
nullptr ,
3947 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3948 RowCountNode ,
nullptr ,
nullptr ,
3950 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3951 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3954llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3959 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3974 Size = CGM.getContext().getTypeSize(Ty);
3981 SmallVector<llvm::Metadata *, 8> Subscripts;
3982 QualType EltTy(Ty, 0);
3983 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3992 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3993 Count = CAT->getZExtSize();
3994 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3995 if (Expr *Size = VAT->getSizeExpr()) {
3997 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3998 Count =
Result.Val.getInt().getExtValue();
4002 auto SizeNode = SizeExprCache.find(EltTy);
4003 if (SizeNode != SizeExprCache.end())
4004 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4005 SizeNode->getSecond() ,
nullptr ,
4006 nullptr ,
nullptr ));
4009 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4010 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4011 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4012 CountNode ,
nullptr ,
nullptr ,
4018 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4020 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4024llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4025 llvm::DIFile *Unit) {
4026 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4030llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4031 llvm::DIFile *Unit) {
4032 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4034 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4035 CGM.getCodeGenOpts().DwarfVersion < 4)
4036 Tag = llvm::dwarf::DW_TAG_reference_type;
4038 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4041llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4043 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4047 Size = CGM.getContext().getTypeSize(Ty);
4050 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4053 Flags |= llvm::DINode::FlagSingleInheritance;
4056 Flags |= llvm::DINode::FlagMultipleInheritance;
4059 Flags |= llvm::DINode::FlagVirtualInheritance;
4069 llvm::DIType *ClassType = getOrCreateType(
T, U);
4071 return DBuilder.createMemberPointerType(
4075 const FunctionProtoType *FPT =
4077 return DBuilder.createMemberPointerType(
4078 getOrCreateInstanceMethodType(
4081 ClassType, Size, 0, Flags);
4084llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4086 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4089llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4093llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4095 return getOrCreateType(Ty->getWrappedType(), U);
4098llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4105 const EnumType *Ty) {
4117llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4120 bool isImportedFromModule =
4121 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4125 if (isImportedFromModule || !ED->getDefinition()) {
4132 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4133 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4134 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4135 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4137 unsigned Line = getLineNumber(ED->getLocation());
4138 StringRef EDName = ED->getName();
4139 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4140 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4141 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4143 ReplaceMap.emplace_back(
4144 std::piecewise_construct, std::make_tuple(Ty),
4145 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4149 return CreateTypeDefinition(Ty);
4152llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4155 SmallVector<llvm::Metadata *, 16> Enumerators;
4156 ED = ED->getDefinition();
4157 assert(ED &&
"An enumeration definition is required");
4158 for (
const auto *
Enum : ED->enumerators()) {
4159 Enumerators.push_back(
4160 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4163 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4164 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4165 EnumKind = Attr->getExtensibility();
4168 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4170 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4171 unsigned Line = getLineNumber(ED->getLocation());
4172 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4173 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4174 return DBuilder.createEnumerationType(
4175 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4176 0, Identifier, ED->isScoped(), EnumKind);
4181 StringRef Name, StringRef
Value) {
4182 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4183 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4189 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4190 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4191 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4196 llvm::DISubprogram *SynthSubprogram) {
4197 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4198 SynthSubprogram, ParentLocation);
4203 StringRef SynthFuncName,
4204 llvm::DIFile *SynthFile) {
4205 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4210 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4216 FuncName += Category;
4218 FuncName += FailureMsg;
4221 TrapLocation->getFile());
4231 Quals += InnerQuals;
4233 switch (
T->getTypeClass()) {
4235 return C.getQualifiedType(
T.getTypePtr(), Quals);
4238 case Type::InjectedClassName:
4239 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4241 case Type::TemplateSpecialization: {
4243 if (Spec->isTypeAlias())
4244 return C.getQualifiedType(
T.getTypePtr(), Quals);
4245 T = Spec->desugar();
4248 case Type::TypeOfExpr:
4254 case Type::Decltype:
4257 case Type::UnaryTransform:
4260 case Type::Attributed:
4263 case Type::BTFTagAttributed:
4266 case Type::CountAttributed:
4275 case Type::MacroQualified:
4278 case Type::SubstTemplateTypeParm:
4282 case Type::DeducedTemplateSpecialization: {
4284 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4288 case Type::PackIndexing: {
4292 case Type::Adjusted:
4299 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4304llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4307 if (It != TypeCache.end()) {
4309 if (llvm::Metadata *
V = It->second)
4322 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4329 RetainedTypes.push_back(
4330 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4333llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4337 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4339 llvm::raw_string_ostream OS(Name);
4340 Ty.
print(OS, getPrintingPolicy());
4347 if (
auto *
T = getTypeOrNull(Ty))
4350 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4351 void *TyPtr = Ty.getAsOpaquePtr();
4354 TypeCache[TyPtr].reset(Res);
4359llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4367 auto Info = Reader->getSourceDescriptor(Idx);
4369 return getOrCreateModuleRef(*Info,
true);
4370 }
else if (ClangModuleMap) {
4383 auto Info = ASTSourceDescriptor(*M);
4384 return getOrCreateModuleRef(Info,
false);
4387 return getOrCreateModuleRef(PCHDescriptor,
false);
4394llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4397 return CreateQualifiedType(Ty, Unit);
4401#define TYPE(Class, Base)
4402#define ABSTRACT_TYPE(Class, Base)
4403#define NON_CANONICAL_TYPE(Class, Base)
4404#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4405#include "clang/AST/TypeNodes.inc"
4406 llvm_unreachable(
"Dependent types cannot show up in debug information");
4408 case Type::ExtVector:
4411 case Type::ConstantMatrix:
4413 case Type::ObjCObjectPointer:
4415 case Type::ObjCObject:
4417 case Type::ObjCTypeParam:
4419 case Type::ObjCInterface:
4427 case Type::BlockPointer:
4435 case Type::FunctionProto:
4436 case Type::FunctionNoProto:
4438 case Type::ConstantArray:
4439 case Type::VariableArray:
4440 case Type::IncompleteArray:
4441 case Type::ArrayParameter:
4444 case Type::LValueReference:
4446 case Type::RValueReference:
4449 case Type::MemberPointer:
4457 case Type::OverflowBehavior:
4462 case Type::TemplateSpecialization:
4464 case Type::HLSLAttributedResource:
4466 case Type::HLSLInlineSpirv:
4468 case Type::PredefinedSugar:
4470 case Type::CountAttributed:
4471 case Type::LateParsedAttr:
4473 case Type::Attributed:
4474 case Type::BTFTagAttributed:
4475 case Type::Adjusted:
4477 case Type::DeducedTemplateSpecialization:
4480 case Type::MacroQualified:
4481 case Type::SubstTemplateTypeParm:
4482 case Type::TypeOfExpr:
4484 case Type::Decltype:
4485 case Type::PackIndexing:
4486 case Type::UnaryTransform:
4490 llvm_unreachable(
"type should have been unwrapped!");
4493llvm::DICompositeType *
4494CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4495 QualType QTy(Ty, 0);
4497 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4502 if (
T && !
T->isForwardDecl())
4506 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4511 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4514 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4519llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4521 bool NameIsSimplified =
false;
4524 StringRef RDName = getClassName(RD, &NameIsSimplified);
4526 llvm::DIFile *DefUnit =
nullptr;
4529 DefUnit = getOrCreateFile(Loc);
4530 Line = getLineNumber(Loc);
4533 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4537 auto *
T = cast_or_null<llvm::DICompositeType>(
4538 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4546 return getOrCreateRecordFwdDecl(Ty, RDContext);
4559 auto Flags = llvm::DINode::FlagZero;
4560 if (NameIsSimplified)
4561 Flags |= llvm::DINode::FlagNameIsSimplified;
4562 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4564 Flags |= llvm::DINode::FlagTypePassByReference;
4566 Flags |= llvm::DINode::FlagTypePassByValue;
4569 if (!CXXRD->isTrivial())
4570 Flags |= llvm::DINode::FlagNonTrivial;
4573 if (CXXRD->isAnonymousStructOrUnion())
4574 Flags |= llvm::DINode::FlagExportSymbols;
4577 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4580 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4581 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4583 Flags, Identifier, Annotations);
4587 switch (RealDecl->getTag()) {
4589 llvm_unreachable(
"invalid composite type tag");
4591 case llvm::dwarf::DW_TAG_array_type:
4592 case llvm::dwarf::DW_TAG_enumeration_type:
4597 if (Identifier.empty())
4601 case llvm::dwarf::DW_TAG_structure_type:
4602 case llvm::dwarf::DW_TAG_union_type:
4603 case llvm::dwarf::DW_TAG_class_type:
4606 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4610 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4611 CXXRecordDecl *TemplateDecl =
4612 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4613 RegionMap[TemplateDecl].reset(RealDecl);
4615 RegionMap[RD].reset(RealDecl);
4617 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4619 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4620 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4621 CollectCXXTemplateParams(TSpecial, DefUnit));
4625void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4626 llvm::DICompositeType *RealDecl) {
4628 llvm::DIType *ContainingType =
nullptr;
4629 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4633 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4640 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4641 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4643 ContainingType = RealDecl;
4645 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4648llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4649 StringRef Name, uint64_t *Offset) {
4650 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4651 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4654 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4655 *Offset, llvm::DINode::FlagZero, FieldTy);
4656 *Offset += FieldSize;
4660void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4662 StringRef &LinkageName,
4663 llvm::DIScope *&FDContext,
4664 llvm::DINodeArray &TParamsArray,
4665 llvm::DINode::DIFlags &Flags) {
4667 bool NameIsSimplified =
false;
4668 Name = getFunctionName(FD, &NameIsSimplified);
4669 if (NameIsSimplified)
4670 Flags |= llvm::DINode::FlagNameIsSimplified;
4671 Name = getFunctionName(FD);
4674 LinkageName = CGM.getMangledName(GD);
4676 Flags |= llvm::DINode::FlagPrototyped;
4680 if (LinkageName == Name ||
4681 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4682 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4683 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4684 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4685 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4686 LinkageName = StringRef();
4690 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4691 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4692 CGM.getCodeGenOpts().EmitCodeView)) {
4693 if (
const NamespaceDecl *NSDecl =
4695 FDContext = getOrCreateNamespace(NSDecl);
4696 else if (
const RecordDecl *RDecl =
4698 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4699 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4702 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4705 Flags |= llvm::DINode::FlagNoReturn;
4707 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4711void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4712 unsigned &LineNo, QualType &
T,
4713 StringRef &Name, StringRef &LinkageName,
4714 llvm::MDTuple *&TemplateParameters,
4715 llvm::DIScope *&VDContext) {
4724 llvm::APInt ConstVal(32, 1);
4725 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4727 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4734 LinkageName = CGM.getMangledName(VD);
4735 if (LinkageName == Name)
4736 LinkageName = StringRef();
4739 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4740 TemplateParameters = parameterNodes.get();
4742 TemplateParameters =
nullptr;
4748 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4749 VDContext = LexicalBlockStack.back();
4768 DC = CGM.getContext().getTranslationUnitDecl();
4770 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4771 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4774llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4776 llvm::DINodeArray TParamsArray;
4777 StringRef Name, LinkageName;
4778 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4779 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4781 llvm::DIFile *Unit = getOrCreateFile(Loc);
4782 llvm::DIScope *DContext = Unit;
4783 unsigned Line = getLineNumber(Loc);
4784 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4789 SmallVector<QualType, 16> ArgTypes;
4790 for (
const ParmVarDecl *Parm : FD->
parameters())
4791 ArgTypes.push_back(Parm->getType());
4794 QualType FnType = CGM.getContext().getFunctionType(
4795 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4797 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4798 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4799 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4803 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4804 return DBuilder.createFunction(
4805 DContext, Name, LinkageName, Unit,
Line,
4806 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4807 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4809 CGM.getCodeGenOpts().DebugKeyInstructions);
4812 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4813 DContext, Name, LinkageName, Unit,
Line,
4814 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4815 TParamsArray.get(), getFunctionDeclaration(FD));
4817 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4818 std::make_tuple(CanonDecl),
4819 std::make_tuple(SP));
4823llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4824 return getFunctionFwdDeclOrStub(GD,
false);
4827llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4828 return getFunctionFwdDeclOrStub(GD,
true);
4831llvm::DIGlobalVariable *
4832CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4834 StringRef Name, LinkageName;
4836 llvm::DIFile *Unit = getOrCreateFile(Loc);
4837 llvm::DIScope *DContext = Unit;
4838 unsigned Line = getLineNumber(Loc);
4839 llvm::MDTuple *TemplateParameters =
nullptr;
4841 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4844 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4845 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4847 FwdDeclReplaceMap.emplace_back(
4848 std::piecewise_construct,
4850 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4854llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4859 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4860 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4861 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4865 if (I != DeclCache.end()) {
4867 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4868 return GVE->getVariable();
4876 if (IE != ImportedDeclCache.end()) {
4877 auto N = IE->second;
4878 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4880 return dyn_cast_or_null<llvm::DINode>(N);
4885 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4886 return getFunctionForwardDeclaration(FD);
4887 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4888 return getGlobalVariableForwardDeclaration(VD);
4893llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4894 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4897 const auto *FD = dyn_cast<FunctionDecl>(D);
4902 auto *S = getDeclContextDescriptor(D);
4905 if (MI == SPCache.end()) {
4907 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4911 if (MI != SPCache.end()) {
4912 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4913 if (SP && !SP->isDefinition())
4917 for (
auto *NextFD : FD->
redecls()) {
4918 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4919 if (MI != SPCache.end()) {
4920 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4921 if (SP && !SP->isDefinition())
4928llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4929 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4930 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4931 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4934 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4938 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4942 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4951 QualType QTy(
ID->getTypeForDecl(), 0);
4952 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4953 if (It == TypeCache.end())
4956 llvm::DISubprogram *FD = DBuilder.createFunction(
4957 InterfaceType, getObjCMethodName(OMD), StringRef(),
4958 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4959 DBuilder.finalizeSubprogram(FD);
4966llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4971 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4972 !CGM.getCodeGenOpts().EmitCodeView))
4975 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4977 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4980 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4983 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4984 return getOrCreateMethodType(
Method, F);
4986 const auto *FTy = FnType->
getAs<FunctionType>();
4989 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4991 SmallVector<llvm::Metadata *, 16> Elts;
4994 QualType ResultTy = OMethod->getReturnType();
4997 if (ResultTy == CGM.getContext().getObjCInstanceType())
4998 ResultTy = CGM.getContext().getPointerType(
4999 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5001 Elts.push_back(getOrCreateType(ResultTy, F));
5003 QualType SelfDeclTy;
5004 if (
auto *SelfDecl = OMethod->getSelfDecl())
5005 SelfDeclTy = SelfDecl->getType();
5006 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5009 if (!SelfDeclTy.
isNull())
5011 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5013 Elts.push_back(DBuilder.createArtificialType(
5014 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5016 for (
const auto *PI : OMethod->parameters())
5017 Elts.push_back(getOrCreateType(PI->getType(), F));
5019 if (OMethod->isVariadic())
5020 Elts.push_back(DBuilder.createUnspecifiedParameter());
5022 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5023 return DBuilder.createSubroutineType(
5024 EltTypeArray, llvm::DINode::FlagZero,
5025 getDwarfCC(CC, CGM.getTarget().getTriple()));
5030 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5031 if (FD->isVariadic()) {
5032 SmallVector<llvm::Metadata *, 16> EltTys;
5033 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5034 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5036 EltTys.push_back(getOrCreateType(ParamType, F));
5037 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5038 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5039 return DBuilder.createSubroutineType(
5040 EltTypeArray, llvm::DINode::FlagZero,
5041 getDwarfCC(CC, CGM.getTarget().getTriple()));
5053 CC = SrcFnTy->getCallConv();
5055 for (
const VarDecl *VD : Args)
5056 ArgTypes.push_back(VD->
getType());
5057 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5063 llvm::Function *Fn,
bool CurFuncIsThunk) {
5065 StringRef LinkageName;
5067 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5070 bool HasDecl = (D !=
nullptr);
5072 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5073 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5074 llvm::DIFile *Unit = getOrCreateFile(Loc);
5075 llvm::DIScope *FDContext = Unit;
5076 llvm::DINodeArray TParamsArray;
5077 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5080 LinkageName = Fn->getName();
5081 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5083 auto FI = SPCache.find(FD->getCanonicalDecl());
5084 if (FI != SPCache.end()) {
5085 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5086 if (SP && SP->isDefinition()) {
5087 LexicalBlockStack.emplace_back(SP);
5088 RegionMap[D].reset(SP);
5092 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5093 TParamsArray, Flags);
5096 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5097 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5098 Name = getObjCMethodName(OMD);
5099 Flags |= llvm::DINode::FlagPrototyped;
5105 if (Name != Fn->getName())
5106 LinkageName = Fn->getName();
5108 Name = Fn->getName();
5113 Flags |= llvm::DINode::FlagPrototyped;
5115 Name.consume_front(
"\01");
5119 "Unexpected DynamicInitKind !");
5123 Flags |= llvm::DINode::FlagArtificial;
5129 Flags |= llvm::DINode::FlagThunk;
5131 if (Fn->hasLocalLinkage())
5132 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5133 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5134 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5137 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5138 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5140 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5141 unsigned ScopeLine = getLineNumber(ScopeLoc);
5142 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5143 llvm::DISubprogram *
Decl =
nullptr;
5144 llvm::DINodeArray Annotations =
nullptr;
5147 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5148 : getFunctionDeclaration(D);
5149 Annotations = CollectBTFDeclTagAnnotations(D);
5157 llvm::DISubprogram *SP = DBuilder.createFunction(
5158 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5159 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5160 Annotations,
"", KeyInstructions);
5161 Fn->setSubprogram(SP);
5170 LexicalBlockStack.emplace_back(SP);
5173 RegionMap[D].reset(SP);
5177 QualType FnType, llvm::Function *Fn) {
5179 StringRef LinkageName;
5185 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5186 return GetName(D,
true);
5189 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5190 llvm::DIFile *Unit = getOrCreateFile(Loc);
5191 bool IsDeclForCallSite = Fn ?
true :
false;
5192 llvm::DIScope *FDContext =
5193 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5194 llvm::DINodeArray TParamsArray;
5197 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5198 TParamsArray, Flags);
5199 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5200 Name = getObjCMethodName(OMD);
5201 Flags |= llvm::DINode::FlagPrototyped;
5203 llvm_unreachable(
"not a function or ObjC method");
5205 Name.consume_front(
"\01");
5208 Flags |= llvm::DINode::FlagArtificial;
5213 unsigned LineNo = getLineNumber(Loc);
5214 unsigned ScopeLine = 0;
5215 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5216 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5217 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5219 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5220 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5222 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5223 llvm::DISubprogram *SP = DBuilder.createFunction(
5224 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5225 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5231 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5232 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5233 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5236 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5237 DBuilder.createParameterVariable(
5238 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5239 llvm::DINode::FlagZero, ParamAnnotations);
5245 if (IsDeclForCallSite)
5246 Fn->setSubprogram(SP);
5250 llvm::CallBase *CI) {
5251 if (!shouldGenerateVirtualCallSite())
5257 assert(CI &&
"Invalid Call Instruction.");
5258 if (!CI->isIndirectCall())
5262 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5263 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5271 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5274 if (
Func->getSubprogram())
5278 if (!
Func->isDeclaration())
5300 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5301 Func->setSubprogram(SP);
5312 auto FI = SPCache.find(FD->getCanonicalDecl());
5313 llvm::DISubprogram *SP =
nullptr;
5314 if (FI != SPCache.end())
5315 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5316 if (!SP || !SP->isDefinition())
5317 SP = getFunctionStub(GD);
5318 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5319 LexicalBlockStack.emplace_back(SP);
5325 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5334 if (CurLoc.isInvalid() || LexicalBlockStack.empty())
5337 llvm::MDNode *
Scope = LexicalBlockStack.back();
5338 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5339 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5343 llvm::MDNode *Back =
nullptr;
5344 if (!LexicalBlockStack.empty())
5345 Back = LexicalBlockStack.back().get();
5348 unsigned Line = getLineNumber(CurLoc);
5349 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5350 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5354void CGDebugInfo::AppendAddressSpaceXDeref(
5356 std::optional<unsigned> DWARFAddressSpace =
5358 if (!DWARFAddressSpace)
5361 Expr.push_back(llvm::dwarf::DW_OP_constu);
5362 Expr.push_back(*DWARFAddressSpace);
5363 Expr.push_back(llvm::dwarf::DW_OP_swap);
5364 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5373 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5374 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5375 LexicalBlockStack.back(), CurInlinedAt));
5377 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5381 CreateLexicalBlock(Loc);
5386 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5391 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5394 LexicalBlockStack.pop_back();
5398 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5399 unsigned RCount = FnBeginRegionCount.back();
5400 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5403 while (LexicalBlockStack.size() != RCount) {
5406 LexicalBlockStack.pop_back();
5408 FnBeginRegionCount.pop_back();
5410 if (Fn && Fn->getSubprogram())
5411 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5414CGDebugInfo::BlockByRefType
5415CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5416 uint64_t *XOffset) {
5419 uint64_t FieldSize, FieldOffset;
5420 uint32_t FieldAlign;
5422 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5427 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5428 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5430 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5431 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5434 if (HasCopyAndDispose) {
5437 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5439 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5441 bool HasByrefExtendedLayout;
5444 HasByrefExtendedLayout) &&
5445 HasByrefExtendedLayout) {
5448 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5457 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5460 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5463 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5468 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5469 FieldSize = CGM.getContext().getTypeSize(FType);
5470 FieldAlign = CGM.getContext().toBits(Align);
5472 *XOffset = FieldOffset;
5473 llvm::DIType *FieldTy = DBuilder.createMemberType(
5474 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5475 llvm::DINode::FlagZero, WrappedTy);
5476 EltTys.push_back(FieldTy);
5477 FieldOffset += FieldSize;
5479 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5480 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5481 llvm::DINode::FlagZero,
nullptr, Elements),
5485llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5486 llvm::Value *Storage,
5487 std::optional<unsigned> ArgNo,
5489 const bool UsePointerValue) {
5490 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5491 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5492 if (VD->
hasAttr<NoDebugAttr>())
5497 llvm::DIFile *Unit =
nullptr;
5498 if (!VarIsArtificial)
5502 if (VD->
hasAttr<BlocksAttr>())
5503 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5505 Ty = getOrCreateType(VD->
getType(), Unit);
5515 if (!VarIsArtificial) {
5519 SmallVector<uint64_t, 13> Expr;
5520 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5527 Flags |= llvm::DINode::FlagArtificial;
5531 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5532 AppendAddressSpaceXDeref(AddressSpace, Expr);
5536 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5539 Flags |= llvm::DINode::FlagObjectPointer;
5540 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5541 if (PVD->isExplicitObjectParameter())
5542 Flags |= llvm::DINode::FlagObjectPointer;
5550 StringRef Name = VD->
getName();
5551 if (!Name.empty()) {
5557 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5559 offset = CGM.getContext().toCharUnitsFromBits(
5562 Expr.push_back(llvm::dwarf::DW_OP_deref);
5563 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5565 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5568 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5580 for (
const auto *Field : RD->
fields()) {
5581 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5582 StringRef FieldName =
Field->getName();
5590 auto *D = DBuilder.createAutoVariable(
5591 Scope, FieldName, Unit,
Line, FieldTy,
5592 CGM.getCodeGenOpts().OptimizationLevel != 0,
5593 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5596 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5597 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5600 Builder.GetInsertBlock());
5608 if (UsePointerValue) {
5609 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5610 "Debug info already contains DW_OP_deref.");
5611 Expr.push_back(llvm::dwarf::DW_OP_deref);
5615 llvm::DILocalVariable *D =
nullptr;
5617 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5618 D = DBuilder.createParameterVariable(
5619 Scope, Name, *ArgNo, Unit,
Line, Ty,
5620 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5629 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5635 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5636 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5637 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5638 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5640 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5646 if (Iter != CoroutineParameterMappings.end()) {
5647 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5648 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5649 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5651 if (Iter2 != ParamDbgMappings.end())
5652 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5658 D = RemapCoroArgToLocalVar();
5661 D = DBuilder.createAutoVariable(
5662 Scope, Name, Unit,
Line, Ty,
5663 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5666 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5667 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5668 Column, Scope, CurInlinedAt),
5669 Builder.GetInsertBlock());
5674llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5675 llvm::Value *Storage,
5676 std::optional<unsigned> ArgNo,
5678 const bool UsePointerValue) {
5679 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5680 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5681 if (BD->
hasAttr<NoDebugAttr>())
5688 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5689 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5697 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5699 SmallVector<uint64_t, 3> Expr;
5700 AppendAddressSpaceXDeref(AddressSpace, Expr);
5705 if (UsePointerValue) {
5706 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5707 "Debug info already contains DW_OP_deref.");
5708 Expr.push_back(llvm::dwarf::DW_OP_deref);
5713 StringRef Name = BD->
getName();
5716 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5717 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5718 llvm::DINode::FlagZero, Align);
5720 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5721 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5722 const unsigned fieldIndex = FD->getFieldIndex();
5723 const clang::CXXRecordDecl *parent =
5724 (
const CXXRecordDecl *)FD->getParent();
5725 const ASTRecordLayout &layout =
5726 CGM.getContext().getASTRecordLayout(parent);
5728 if (FD->isBitField()) {
5729 const CGRecordLayout &RL =
5730 CGM.getTypes().getCGRecordLayout(FD->getParent());
5735 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5741 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5742 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5743 Expr.push_back(Info.
Offset);
5746 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5747 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5748 }
else if (fieldOffset != 0) {
5749 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5750 "Unexpected non-bitfield with non-byte-aligned offset");
5751 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5753 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5756 }
else if (
const ArraySubscriptExpr *ASE =
5757 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5758 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5759 const uint64_t value = IL->getValue().getZExtValue();
5760 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5763 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5764 Expr.push_back(CGM.getContext()
5765 .toCharUnitsFromBits(value * typeSize)
5772 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5773 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5774 Column, Scope, CurInlinedAt),
5775 Builder.GetInsertBlock());
5780llvm::DILocalVariable *
5783 const bool UsePointerValue) {
5784 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5786 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5788 EmitDeclare(B, Storage, std::nullopt, Builder,
5795 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5799 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5800 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5802 if (D->
hasAttr<NoDebugAttr>())
5806 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5812 StringRef Name = D->
getName();
5818 CGM.getCodeGenOpts().OptimizationLevel != 0);
5821 DBuilder.insertLabel(L,
5822 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5823 Scope, CurInlinedAt),
5824 Builder.GetInsertBlock()->end());
5827llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5829 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5832 return DBuilder.createObjectPointerType(Ty,
true);
5837 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5838 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5839 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5841 if (Builder.GetInsertBlock() ==
nullptr)
5843 if (VD->
hasAttr<NoDebugAttr>())
5846 bool isByRef = VD->
hasAttr<BlocksAttr>();
5848 uint64_t XOffset = 0;
5849 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5852 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5854 Ty = getOrCreateType(VD->
getType(), Unit);
5858 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5860 Ty = CreateSelfType(VD->
getType(), Ty);
5863 const unsigned Line =
5867 const llvm::DataLayout &target = CGM.getDataLayout();
5874 addr.push_back(llvm::dwarf::DW_OP_deref);
5875 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5878 addr.push_back(llvm::dwarf::DW_OP_deref);
5879 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5882 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5884 addr.push_back(llvm::dwarf::DW_OP_deref);
5885 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5887 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5893 auto *D = DBuilder.createAutoVariable(
5895 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5898 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5899 LexicalBlockStack.back(), CurInlinedAt);
5900 auto *
Expr = DBuilder.createExpression(addr);
5902 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5904 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5907llvm::DILocalVariable *
5910 bool UsePointerValue) {
5911 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5912 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5916struct BlockLayoutChunk {
5917 uint64_t OffsetInBits;
5920bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5921 return l.OffsetInBits < r.OffsetInBits;
5925void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5927 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5928 SmallVectorImpl<llvm::Metadata *> &Fields) {
5932 if (CGM.getLangOpts().OpenCL) {
5933 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5934 BlockLayout.getElementOffsetInBits(0),
5936 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5937 BlockLayout.getElementOffsetInBits(1),
5941 BlockLayout.getElementOffsetInBits(0),
5943 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5944 BlockLayout.getElementOffsetInBits(1),
5948 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5949 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5950 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5951 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5952 BlockLayout.getElementOffsetInBits(3),
5954 Fields.push_back(createFieldType(
5959 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5966 llvm::AllocaInst *Alloca,
5968 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5974 llvm::DIFile *tunit = getOrCreateFile(loc);
5975 unsigned line = getLineNumber(loc);
5976 unsigned column = getColumnNumber(loc);
5981 const llvm::StructLayout *blockLayout =
5985 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5994 BlockLayoutChunk chunk;
5995 chunk.OffsetInBits =
5996 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5997 chunk.Capture =
nullptr;
5998 chunks.push_back(chunk);
6002 for (
const auto &capture :
blockDecl->captures()) {
6003 const VarDecl *variable = capture.getVariable();
6010 BlockLayoutChunk chunk;
6011 chunk.OffsetInBits =
6012 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6013 chunk.Capture = &capture;
6014 chunks.push_back(chunk);
6018 llvm::array_pod_sort(chunks.begin(), chunks.end());
6020 for (
const BlockLayoutChunk &Chunk : chunks) {
6021 uint64_t offsetInBits = Chunk.OffsetInBits;
6028 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6030 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6031 type = CGM.getContext().getCanonicalTagType(RDecl);
6033 llvm_unreachable(
"unexpected block declcontext");
6035 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6036 offsetInBits, tunit, tunit));
6041 StringRef name = variable->
getName();
6043 llvm::DIType *fieldType;
6045 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6050 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6051 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6052 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6053 PtrInfo.
Width, Align, offsetInBits,
6054 llvm::DINode::FlagZero, fieldType);
6058 offsetInBits, Align, tunit, tunit);
6060 fields.push_back(fieldType);
6064 llvm::raw_svector_ostream(typeName)
6065 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6067 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6069 llvm::DIType *
type =
6070 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6071 CGM.getContext().toBits(block.
BlockSize), 0,
6072 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6073 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6076 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6080 auto *debugVar = DBuilder.createParameterVariable(
6081 scope, Name, ArgNo, tunit, line,
type,
6082 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6085 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6086 llvm::DILocation::get(CGM.getLLVMContext(), line,
6087 column, scope, CurInlinedAt),
6088 Builder.GetInsertBlock());
6091llvm::DIDerivedType *
6092CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6097 if (MI != StaticDataMemberCache.end()) {
6098 assert(MI->second &&
"Static data member declaration should still exist");
6109llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6110 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6111 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6112 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6114 for (
const auto *Field : RD->
fields()) {
6115 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6116 StringRef FieldName = Field->getName();
6119 if (FieldName.empty()) {
6120 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6121 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6122 LineNo, LinkageName, Var, DContext);
6126 GVE = DBuilder.createGlobalVariableExpression(
6127 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6128 Var->hasLocalLinkage());
6129 Var->addDebugInfo(GVE);
6141 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6146 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6157 struct ReferencesAnonymous
6159 bool RefAnon =
false;
6160 bool VisitRecordType(RecordType *RT) {
6168 ReferencesAnonymous RT;
6181struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6182 bool Reconstitutable =
true;
6183 bool VisitVectorType(VectorType *FT) {
6184 Reconstitutable =
false;
6187 bool VisitAtomicType(AtomicType *FT) {
6188 Reconstitutable =
false;
6191 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6194 const EnumDecl *ED = ET->getDecl();
6196 Reconstitutable =
false;
6200 Reconstitutable =
false;
6205 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6209 return Reconstitutable;
6211 bool VisitRecordType(RecordType *RT,
bool =
false) {
6213 Reconstitutable =
false;
6223 ReconstitutableType
T;
6225 return T.Reconstitutable;
6228bool CGDebugInfo::HasReconstitutableArgs(
6229 ArrayRef<TemplateArgument> Args)
const {
6230 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6270 llvm_unreachable(
"Other, unresolved, template arguments should "
6271 "not be seen here");
6276std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6277 bool *NameIsSimplified)
const {
6279 llvm::raw_string_ostream
OS(Name);
6280 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6283 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6284 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6286 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6287 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6289 std::optional<TemplateArgs> Args;
6291 bool IsOperatorOverload =
false;
6292 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6293 Args = GetTemplateArgs(RD);
6294 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6295 Args = GetTemplateArgs(FD);
6297 IsOperatorOverload |=
6300 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6301 Args = GetTemplateArgs(VD);
6325 bool Reconstitutable =
6326 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6328 PrintingPolicy PP = getPrintingPolicy();
6330 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6335 if (NameIsSimplified)
6336 *NameIsSimplified =
true;
6337 bool Mangled = TemplateNamesKind ==
6338 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6344 std::string EncodedOriginalName;
6345 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6350 printTemplateArgumentList(OS, Args->Args, PP);
6351 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6353 std::string CanonicalOriginalName;
6354 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6356 assert(EncodedOriginalName == CanonicalOriginalName);
6365 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6366 if (D->
hasAttr<NoDebugAttr>())
6369 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6370 return GetName(D,
true);
6376 if (Cached != DeclCache.end())
6377 return Var->addDebugInfo(
6381 llvm::DIFile *Unit =
nullptr;
6382 llvm::DIScope *DContext =
nullptr;
6384 StringRef DeclName, LinkageName;
6386 llvm::MDTuple *TemplateParameters =
nullptr;
6387 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6388 TemplateParameters, DContext);
6392 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6397 if (
T->isUnionType() && DeclName.empty()) {
6398 const auto *RD =
T->castAsRecordDecl();
6400 "unnamed non-anonymous struct or union?");
6401 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6406 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6407 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6408 if (D->
hasAttr<CUDASharedAttr>())
6411 else if (D->
hasAttr<CUDAConstantAttr>())
6415 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6417 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6418 GVE = DBuilder.createGlobalVariableExpression(
6419 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6420 Var->hasLocalLinkage(),
true,
6421 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6422 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6423 Align, Annotations);
6424 Var->addDebugInfo(GVE);
6430 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6431 if (VD->
hasAttr<NoDebugAttr>())
6433 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6434 return GetName(VD,
true);
6439 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6440 StringRef Name = VD->
getName();
6441 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6443 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6445 if (CGM.getCodeGenOpts().EmitCodeView) {
6456 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6457 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6458 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6468 auto *VarD = dyn_cast<VarDecl>(VD);
6469 if (VarD && VarD->isStaticDataMember()) {
6471 getDeclContextDescriptor(VarD);
6476 RetainedTypes.push_back(
6477 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6481 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6483 auto &GV = DeclCache[VD];
6487 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6488 llvm::MDTuple *TemplateParameters =
nullptr;
6492 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6493 TemplateParameters = parameterNodes.get();
6496 GV.reset(DBuilder.createGlobalVariableExpression(
6497 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6498 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6499 TemplateParameters, Align));
6504 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6505 if (D->
hasAttr<NoDebugAttr>())
6509 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6510 StringRef Name = D->
getName();
6511 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6513 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6514 llvm::DIGlobalVariableExpression *GVE =
6515 DBuilder.createGlobalVariableExpression(
6516 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6517 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6518 Var->addDebugInfo(GVE);
6525 if (CGM.getCodeGenOpts().getDebugInfo() <=
6526 llvm::codegenoptions::DebugLineTablesOnly)
6529 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6533 llvm::DIFile *Unit = DIL->getFile();
6534 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6539 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6540 llvm::Value *Var = Load->getPointerOperand();
6545 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6546 return DbgDeclare->getVariable()->getType() ==
Type;
6548 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6552 llvm::DILocalVariable *D =
6553 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6554 Type,
false, llvm::DINode::FlagArtificial);
6556 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6557 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6567 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6571 if (D->
hasAttr<NoDebugAttr>())
6574 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6589 if (!(DI = getDeclarationOrDefinition(
6590 AliaseeDecl.getCanonicalDecl().getDecl())))
6593 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6596 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6597 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6611 llvm::DIFile *
File = getOrCreateFile(Loc);
6612 llvm::DIGlobalVariableExpression *Debug =
6613 DBuilder.createGlobalVariableExpression(
6614 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6615 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6616 GV->addDebugInfo(Debug);
6619llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6620 if (!LexicalBlockStack.empty())
6621 return LexicalBlockStack.back();
6622 llvm::DIScope *Mod = getParentModuleOrNull(D);
6623 return getContextDescriptor(D, Mod ? Mod : TheCU);
6627 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6631 CGM.getCodeGenOpts().DebugExplicitImport) {
6635 DBuilder.createImportedModule(
6637 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6642 if (llvm::DINode *
Target =
6645 DBuilder.createImportedDeclaration(
6647 getOrCreateFile(Loc), getLineNumber(Loc));
6652 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6655 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6657 for (
const auto *USD : UD.
shadows()) {
6662 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6663 if (
const auto *AT = FD->getType()
6666 if (AT->getDeducedType().isNull())
6677 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6680 "We shouldn't be codegening an invalid UsingEnumDecl"
6681 " containing no decls");
6683 for (
const auto *USD : UD.
shadows())
6688 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6690 if (
Module *M = ID.getImportedModule()) {
6692 auto Loc = ID.getLocation();
6693 DBuilder.createImportedDeclaration(
6694 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6695 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6696 getLineNumber(Loc));
6700llvm::DIImportedEntity *
6702 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6704 auto &VH = NamespaceAliasCache[&NA];
6707 llvm::DIImportedEntity *R;
6709 if (
const auto *Underlying =
6712 R = DBuilder.createImportedDeclaration(
6715 getLineNumber(Loc), NA.
getName());
6717 R = DBuilder.createImportedDeclaration(
6720 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6726CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6730 auto I = NamespaceCache.find(NSDecl);
6731 if (I != NamespaceCache.end())
6734 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6736 llvm::DINamespace *NS =
6737 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6738 NamespaceCache[NSDecl].reset(NS);
6743 assert(TheCU &&
"no main compile unit");
6744 TheCU->setDWOId(Signature);
6750 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6751 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6753 ? CreateTypeDefinition(E.Type, E.Unit)
6755 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6759 for (
const auto &P : ObjCMethodCache) {
6760 if (P.second.empty())
6763 QualType QTy(P.first->getTypeForDecl(), 0);
6765 assert(It != TypeCache.end());
6767 llvm::DICompositeType *InterfaceDecl =
6770 auto CurElts = InterfaceDecl->getElements();
6774 for (
auto &SubprogramDirect : P.second)
6775 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6776 EltTys.push_back(SubprogramDirect.getPointer());
6778 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6779 DBuilder.replaceArrays(InterfaceDecl, Elements);
6782 for (
const auto &P : ReplaceMap) {
6785 assert(Ty->isForwardDecl());
6787 auto It = TypeCache.find(P.first);
6788 assert(It != TypeCache.end());
6791 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6795 for (
const auto &P : FwdDeclReplaceMap) {
6798 llvm::Metadata *Repl;
6800 auto It = DeclCache.find(P.first);
6804 if (It == DeclCache.end())
6809 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6810 Repl = GVE->getVariable();
6816 for (
auto &RT : RetainedTypes)
6817 if (
auto MD = TypeCache[RT])
6820 DBuilder.finalize();
6825 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6826 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6827 DBuilder.retainType(DieTy);
6831 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6832 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6833 DBuilder.retainType(DieTy);
6837 if (LexicalBlockStack.empty())
6838 return llvm::DebugLoc();
6840 llvm::MDNode *
Scope = LexicalBlockStack.back();
6841 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6842 getColumnNumber(Loc),
Scope);
6848 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6849 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6850 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6851 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6852 return llvm::DINode::FlagZero;
6857 bool SupportsDWARFv4Ext =
6858 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6859 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6860 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6862 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6863 return llvm::DINode::FlagZero;
6865 return llvm::DINode::FlagAllCallsDescribed;
6876 return DBuilder.createConstantValueExpression(
6877 Val.
getFloat().bitcastToAPInt().getZExtValue());
6882 llvm::APSInt
const &ValInt = Val.
getInt();
6883 std::optional<uint64_t> ValIntOpt;
6884 if (ValInt.isUnsigned())
6885 ValIntOpt = ValInt.tryZExtValue();
6886 else if (
auto tmp = ValInt.trySExtValue())
6889 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6892 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6897CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6899 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6900 CGF.CurLexicalScope =
this;
6902 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6907 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6920#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6922 Label = "__ubsan_check_" #Name; \
6926#undef SANITIZER_CHECK
6937#define SANITIZER(NAME, ID) \
6938 case SanitizerKind::SO_##ID: \
6939 Label = "__ubsan_check_" NAME; \
6941#include "clang/Basic/Sanitizers.def"
6943 llvm_unreachable(
"unexpected sanitizer kind");
6948 for (
unsigned int i = 0; i < Label.length(); i++)
6949 if (!std::isalpha(Label[i]))
6958 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6960 if (!DI || !CheckDebugLoc)
6961 return CheckDebugLoc;
6962 const auto &AnnotateDebugInfo =
6963 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6964 if (AnnotateDebugInfo.empty())
6965 return CheckDebugLoc;
6968 if (Ordinals.size() == 1)
6973 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6977 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6978 "ubsan_interface.h",
6980 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6983 return CheckDebugLoc;
6991 assert(!CGF->IsSanitizerScope);
6992 CGF->IsSanitizerScope =
true;
6996 assert(CGF->IsSanitizerScope);
6997 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static unsigned getDwarfCC(CallingConv CC, const llvm::Triple &T)
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 void completeStandardLayoutUnionType(CGDebugInfo &DebugInfo, QualType QT)
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 llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static void completeStandardLayoutUnionMembers(CGDebugInfo &DebugInfo, const CXXRecordDecl *RD)
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 bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a base class of a C++ class.
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).
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
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.
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
capture_const_iterator captures_end() const
method_range methods() const
bool defaultedDefaultConstructorIsConstexpr() const
Determine whether a defaulted default constructor for this class would be constexpr.
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.
This is an opaque type for sizes expressed in character units.
bool isPositive() const
Test whether the quantity is greater than zero.
bool isZero() const
Test whether the quantity equals zero.
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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...
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 completeUnusedClass(const CXXRecordDecl &D)
void setInlinedAt(llvm::DILocation *InlinedAt)
Update the current inline scope.
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.
std::pair< llvm::DIType *, unsigned > getOrCreatePreserveAccessInfo(QualType Ty, const FieldDecl *Field)
Return the complete record type and field index for preserve-access intrinsics.
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...
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
llvm::DILocation * getInlinedAt() const
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc ParentLocation, llvm::DISubprogram *SynthSubprogram)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
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...
bool isInvalidDecl() const
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...
Represents a member of a struct/union/class.
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.
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
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.
unsigned getLine() const
Return the presumed line number 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
RecordDecl * getDefinitionOrSelf() const
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
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.
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
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.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
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,...
Top level wrappers for InstallAPI frontend operations.
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...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
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 PrettyEnums
Whether to print enumerators with a matching enumerator name or via cast.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
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.