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"
76 if (TI.isAlignRequired())
103 auto const *RefExpr =
104 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
108 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
132 if (!llvm::isa<ParmVarDecl>(VD))
142 if (!Method->isImplicit() || !Method->isPropertyAccessor())
153 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
154 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
155 DBuilder(CGM.getModule()) {
160 assert(LexicalBlockStack.empty() &&
161 "Region stack mismatch, stack not empty!");
164void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
165 uint64_t Group, uint8_t Rank) {
166 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
170 Rank = std::min<uint8_t>(Rank, 7);
172 const llvm::DebugLoc &DL = I->getDebugLoc();
177 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
178 Group = DL->getAtomGroup();
179 Rank = DL->getAtomRank();
184 KeyInstructionsInfo.HighestEmittedAtom =
185 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
188 llvm::DILocation *NewDL = llvm::DILocation::get(
189 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
190 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
191 I->setDebugLoc(NewDL);
195 llvm::Value *Backup) {
197 KeyInstructionsInfo.CurrentAtom);
203 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
206 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
207 if (!SP || !SP->getKeyInstructionsEnabled())
210 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
212 llvm::Instruction *BackupI =
213 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
218 addInstSourceAtomMetadata(BackupI, Group, 2);
224 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
225 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
228 addInstSourceAtomMetadata(BackupI, Group, Rank++);
234 KeyInstructionsInfo.NextAtom = 1;
235 KeyInstructionsInfo.HighestEmittedAtom = 0;
236 KeyInstructionsInfo.CurrentAtom = 0;
242 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
243 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
251 DI->KeyInstructionsInfo.NextAtom =
252 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
253 DI->KeyInstructionsInfo.NextAtom);
255 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
261 init(TemporaryLocation);
268 init(TemporaryLocation, DefaultToEmpty);
272 bool DefaultToEmpty) {
279 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
281 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
284 if (TemporaryLocation.
isValid()) {
285 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
289 if (DefaultToEmpty) {
290 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
295 assert(!DI->LexicalBlockStack.empty());
296 CGF->Builder.SetCurrentDebugLocation(
297 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
298 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
308 if (!CGF.getDebugInfo()) {
312 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
316 if (Loc->getAtomGroup())
317 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
318 Loc->getColumn(), Loc->getScope(),
319 Loc->getInlinedAt(), Loc.isImplicitCode());
320 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
328 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
334 if (!CGF.getDebugInfo()) {
338 auto &DI = *CGF.getDebugInfo();
339 SavedLocation = DI.getLocation();
340 assert((DI.getInlinedAt() ==
341 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
342 "CGDebugInfo and IRBuilder are out of sync");
344 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
350 auto &DI = *CGF->getDebugInfo();
351 DI.EmitInlineFunctionEnd(CGF->Builder);
352 DI.EmitLocation(CGF->Builder, SavedLocation);
362 if (CurLoc != NewLoc) {
364 CurLocFile =
nullptr;
373 if (CGM.getCodeGenOpts().DebugColumnInfo)
375 CurLocFile = getOrCreateFile(CurLoc);
381 if (LexicalBlockStack.empty())
385 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
388 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
389 LexicalBlockStack.pop_back();
390 LexicalBlockStack.emplace_back(
391 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
394 LexicalBlockStack.pop_back();
395 LexicalBlockStack.emplace_back(
396 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
400llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
401 llvm::DIScope *Mod = getParentModuleOrNull(D);
406llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
411 auto I = RegionMap.find(Context);
412 if (I != RegionMap.end()) {
413 llvm::Metadata *
V = I->second;
414 return dyn_cast_or_null<llvm::DIScope>(
V);
418 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
419 return getOrCreateNamespace(NSDecl);
421 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
422 if (!RDecl->isDependentType())
428PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
429 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
436 if (CGM.getCodeGenOpts().EmitCodeView) {
437 PP.MSVCFormatting =
true;
447 PP.PrintAsCanonical =
true;
448 PP.UsePreferredNames =
false;
449 PP.AlwaysIncludeTypeForTemplateArgument =
true;
458StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
459 bool *NameIsSimplified) {
460 return internString(GetName(FD,
false, NameIsSimplified));
463StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
464 SmallString<256> MethodName;
465 llvm::raw_svector_ostream
OS(MethodName);
468 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
469 OS << OID->getName();
470 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
471 OS << OID->getName();
472 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
473 if (OC->IsClassExtension()) {
474 OS << OC->getClassInterface()->getName();
476 OS << OC->getIdentifier()->getNameStart() <<
'('
477 << OC->getIdentifier()->getNameStart() <<
')';
479 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
480 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
484 return internString(
OS.str());
487StringRef CGDebugInfo::getSelectorName(Selector S) {
491StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
492 bool *NameIsSimplified) {
495 return internString(GetName(RD,
false, NameIsSimplified));
501 return II->getName();
506 if (CGM.getCodeGenOpts().EmitCodeView) {
509 "Typedef should not be in another decl context!");
510 assert(D->getDeclName().getAsIdentifierInfo() &&
511 "Typedef was not named!");
512 return D->getDeclName().getAsIdentifierInfo()->getName();
515 if (CGM.getLangOpts().CPlusPlus) {
518 ASTContext &Context = CGM.getContext();
522 Name = DD->getName();
523 else if (
const TypedefNameDecl *TND =
527 Name = TND->getName();
530 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
531 if (CXXRD->isLambda())
533 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
536 SmallString<256> UnnamedType(
"<unnamed-type-");
539 return internString(UnnamedType);
547std::optional<llvm::DIFile::ChecksumKind>
548CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
551 if (!CGM.getCodeGenOpts().EmitCodeView &&
552 CGM.getCodeGenOpts().DwarfVersion < 5)
555 SourceManager &SM = CGM.getContext().getSourceManager();
556 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
560 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
561 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
563 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
564 return llvm::DIFile::CSK_MD5;
566 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
567 return llvm::DIFile::CSK_SHA1;
569 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
570 return llvm::DIFile::CSK_SHA256;
574 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
577std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
579 if (!CGM.getCodeGenOpts().EmbedSource)
582 bool SourceInvalid =
false;
591llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
592 SourceManager &SM = CGM.getContext().getSourceManager();
595 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
601 FileName = TheCU->getFile()->getFilename();
602 CSInfo = TheCU->getFile()->getChecksum();
605 if (Loc == CurLoc && CurLocFile)
612 FileName = TheCU->getFile()->getFilename();
620 auto It = DIFileCache.find(
FileName.data());
621 if (It != DIFileCache.end()) {
623 if (llvm::Metadata *
V = It->second)
628 SmallString<64> Checksum;
630 std::optional<llvm::DIFile::ChecksumKind> CSKind =
631 computeChecksum(FID, Checksum);
633 CSInfo.emplace(*CSKind, Checksum);
639llvm::DIFile *CGDebugInfo::createFile(
641 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
642 std::optional<StringRef> Source) {
646 std::string CurDir =
remapDIPath(getCurrentDirname());
647 SmallString<128> DirBuf;
648 SmallString<128> FileBuf;
649 if (llvm::sys::path::is_absolute(RemappedFile)) {
652 auto FileIt = llvm::sys::path::begin(RemappedFile);
653 auto FileE = llvm::sys::path::end(RemappedFile);
654 auto CurDirIt = llvm::sys::path::begin(CurDir);
655 auto CurDirE = llvm::sys::path::end(CurDir);
656 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
657 llvm::sys::path::append(DirBuf, *CurDirIt);
658 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
664 for (; FileIt != FileE; ++FileIt)
665 llvm::sys::path::append(FileBuf, *FileIt);
670 if (!llvm::sys::path::is_absolute(
FileName))
674 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
675 DIFileCache[
FileName.data()].reset(F);
680 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
688 if (DebugLoc == CurLoc)
703 if (DebugLoc == CurLoc)
709StringRef CGDebugInfo::getCurrentDirname() {
717 assert(CGO.DwarfVersion <= 5);
719 llvm::dwarf::SourceLanguage LangTag;
722 LangTag = llvm::dwarf::DW_LANG_HLSL;
724 LangTag = llvm::dwarf::DW_LANG_HIP;
726 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
727 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
728 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
729 else if (LO.CPlusPlus14)
730 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
731 else if (LO.CPlusPlus11)
732 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
734 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
735 }
else if (LO.ObjC) {
736 LangTag = llvm::dwarf::DW_LANG_ObjC;
737 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
738 LangTag = llvm::dwarf::DW_LANG_OpenCL;
739 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
740 LangTag = llvm::dwarf::DW_LANG_C11;
742 LangTag = llvm::dwarf::DW_LANG_C99;
744 LangTag = llvm::dwarf::DW_LANG_C89;
750static llvm::DISourceLanguageName
759 llvm::dwarf::SourceLanguageName LangTag;
762 LangTag = llvm::dwarf::DW_LNAME_HLSL;
764 LangTag = llvm::dwarf::DW_LNAME_HIP;
765 }
else if (LO.ObjC) {
766 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
768 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
771 }
else if (LO.ObjC) {
772 LangTag = llvm::dwarf::DW_LNAME_ObjC;
773 }
else if (LO.OpenCL) {
774 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
776 LangTag = llvm::dwarf::DW_LNAME_C;
780 return llvm::DISourceLanguageName(LangTag, LangVersion);
783void CGDebugInfo::CreateCompileUnit() {
784 SmallString<64> Checksum;
785 std::optional<llvm::DIFile::ChecksumKind> CSKind;
786 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
796 SourceManager &SM = CGM.getContext().getSourceManager();
797 auto &CGO = CGM.getCodeGenOpts();
798 const LangOptions &LO = CGM.getLangOpts();
799 std::string MainFileName = CGO.MainFileName;
800 if (MainFileName.empty())
801 MainFileName =
"<stdin>";
807 std::string MainFileDir;
810 MainFileDir = std::string(MainFile->getDir().getName());
811 if (!llvm::sys::path::is_absolute(MainFileName)) {
812 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
813 llvm::sys::path::Style Style =
815 ? (CGM.getTarget().
getTriple().isOSWindows()
816 ? llvm::sys::path::Style::windows_backslash
817 : llvm::sys::path::Style::posix)
818 : llvm::sys::path::Style::native;
819 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
820 MainFileName = std::string(
821 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
828 if (MainFile->getName() == MainFileName &&
830 MainFile->getName().rsplit(
'.').second)
832 MainFileName = CGM.getModule().getName().str();
841 unsigned RuntimeVers = 0;
845 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
847 case llvm::codegenoptions::NoDebugInfo:
848 case llvm::codegenoptions::LocTrackingOnly:
849 EmissionKind = llvm::DICompileUnit::NoDebug;
851 case llvm::codegenoptions::DebugLineTablesOnly:
852 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
854 case llvm::codegenoptions::DebugDirectivesOnly:
855 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
857 case llvm::codegenoptions::DebugInfoConstructor:
858 case llvm::codegenoptions::LimitedDebugInfo:
859 case llvm::codegenoptions::FullDebugInfo:
860 case llvm::codegenoptions::UnusedTypeInfo:
861 EmissionKind = llvm::DICompileUnit::FullDebug;
866 auto &CGOpts = CGM.getCodeGenOpts();
872 CSInfo.emplace(*CSKind, Checksum);
873 llvm::DIFile *CUFile = DBuilder.createFile(
877 StringRef Sysroot, SDK;
878 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
879 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
880 if (CGM.getCodeGenOpts().DebugRecordSysroot)
881 Sysroot = FullSysroot;
882 auto B = llvm::sys::path::rbegin(FullSysroot);
883 auto E = llvm::sys::path::rend(FullSysroot);
885 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
890 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
891 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
892 CGOpts.DebugNameTable);
893 if (CGM.getTarget().getTriple().isNVPTX())
894 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
895 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
896 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
899 TheCU = DBuilder.createCompileUnit(
901 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
902 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
903 CGOpts.PrepareForThinLTO,
904 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
905 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
906 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
909llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
913#define BUILTIN_TYPE(Id, SingletonId)
914#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
915#include "clang/AST/BuiltinTypes.def"
916 case BuiltinType::Dependent:
917 llvm_unreachable(
"Unexpected builtin type");
918 case BuiltinType::NullPtr:
919 return DBuilder.createNullPtrType();
920 case BuiltinType::Void:
922 case BuiltinType::ObjCClass:
925 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
926 "objc_class", TheCU, TheCU->getFile(), 0);
928 case BuiltinType::ObjCId: {
939 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
940 "objc_class", TheCU, TheCU->getFile(), 0);
942 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
944 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
946 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
947 (uint64_t)0, 0, llvm::DINode::FlagZero,
948 nullptr, llvm::DINodeArray());
950 DBuilder.replaceArrays(
951 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
952 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
953 llvm::DINode::FlagZero, ISATy)));
956 case BuiltinType::ObjCSel: {
958 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
959 "objc_selector", TheCU,
960 TheCU->getFile(), 0);
964#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
965 case BuiltinType::Id: \
966 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
968#include "clang/Basic/OpenCLImageTypes.def"
969 case BuiltinType::OCLSampler:
970 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
971 case BuiltinType::OCLEvent:
972 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
973 case BuiltinType::OCLClkEvent:
974 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
975 case BuiltinType::OCLQueue:
976 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
977 case BuiltinType::OCLReserveID:
978 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
979#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
980 case BuiltinType::Id: \
981 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
982#include "clang/Basic/OpenCLExtensionTypes.def"
983#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
984 case BuiltinType::Id: \
985 return getOrCreateStructPtrType(#Name, SingletonId);
986#include "clang/Basic/HLSLIntangibleTypes.def"
987#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
988 case BuiltinType::Id: \
989 return DBuilder.createBasicType(#Name, 32, llvm::dwarf::DW_ATE_unsigned);
990#include "clang/Basic/HLSLPackedTypes.def"
992#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
993#include "clang/Basic/AArch64ACLETypes.def"
995 if (BT->
getKind() == BuiltinType::MFloat8) {
996 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
997 BTName = BT->
getName(CGM.getLangOpts());
1000 return DBuilder.createBasicType(BTName, Size, Encoding);
1002 ASTContext::BuiltinVectorTypeInfo Info =
1004 BT->
getKind() == BuiltinType::SveCount
1005 ? ASTContext::BuiltinVectorTypeInfo(
1006 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1008 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1015 "Unsupported number of vectors for svcount_t");
1017 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1018 llvm::Metadata *BitStride =
nullptr;
1019 if (BT->
getKind() == BuiltinType::SveBool) {
1020 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1021 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1022 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1023 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1025 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1028 llvm::Metadata *LowerBound, *UpperBound;
1029 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1030 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1031 if (Info.
EC.isScalable()) {
1032 unsigned NumElemsPerVG = NumElems / 2;
1033 SmallVector<uint64_t, 9> Expr(
1034 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1035 46, 0, llvm::dwarf::DW_OP_mul,
1036 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1037 UpperBound = DBuilder.createExpression(Expr);
1039 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1040 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1042 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1043 nullptr, LowerBound, UpperBound,
nullptr);
1044 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1045 llvm::DIType *ElemTy =
1046 getOrCreateType(Info.
ElementType, TheCU->getFile());
1048 return DBuilder.createVectorType( 0, Align, ElemTy,
1049 SubscriptArray, BitStride);
1053#define PPC_VECTOR_TYPE(Name, Id, size) \
1054 case BuiltinType::Id:
1055#include "clang/Basic/PPCTypes.def"
1058#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1059#include "clang/Basic/RISCVVTypes.def"
1061 ASTContext::BuiltinVectorTypeInfo Info =
1062 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1064 unsigned ElementCount = Info.
EC.getKnownMinValue();
1065 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1067 bool Fractional =
false;
1070 unsigned FixedSize = ElementCount * SEW;
1071 if (Info.
ElementType == CGM.getContext().BoolTy) {
1074 }
else if (FixedSize < 64) {
1077 LMUL = 64 / FixedSize;
1079 LMUL = FixedSize / 64;
1083 SmallVector<uint64_t, 12> Expr(
1087 {llvm::dwarf::DW_OP_bregx,
1090 llvm::dwarf::DW_OP_constu,
1092 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1094 Expr.push_back(llvm::dwarf::DW_OP_div);
1096 Expr.push_back(llvm::dwarf::DW_OP_mul);
1099 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1101 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1104 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1105 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1106 auto *UpperBound = DBuilder.createExpression(Expr);
1107 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1108 nullptr, LowerBound, UpperBound,
nullptr);
1109 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1110 llvm::DIType *ElemTy =
1111 getOrCreateType(Info.
ElementType, TheCU->getFile());
1114 return DBuilder.createVectorType(0, Align, ElemTy,
1118#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1119 case BuiltinType::Id: { \
1122 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1123 MangledName, TheCU, TheCU->getFile(), 0); \
1124 return SingletonId; \
1126#include "clang/Basic/WebAssemblyReferenceTypes.def"
1127#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1128 case BuiltinType::Id: { \
1131 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1132 TheCU, TheCU->getFile(), 0); \
1133 return SingletonId; \
1135#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1136 case BuiltinType::Id: { \
1139 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1140 return SingletonId; \
1142#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1143 case BuiltinType::Id: { \
1146 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1147 return SingletonId; \
1149#include "clang/Basic/AMDGPUTypes.def"
1150#define SPIRV_TYPE(Name, Id, SingletonId) \
1151 case BuiltinType::Id: \
1152 return getOrCreateStructPtrType(Name, SingletonId);
1153#include "clang/Basic/SPIRVTypes.def"
1154 case BuiltinType::UChar:
1155 case BuiltinType::Char_U:
1156 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1158 case BuiltinType::Char_S:
1159 case BuiltinType::SChar:
1160 Encoding = llvm::dwarf::DW_ATE_signed_char;
1162 case BuiltinType::Char8:
1163 case BuiltinType::Char16:
1164 case BuiltinType::Char32:
1165 Encoding = llvm::dwarf::DW_ATE_UTF;
1167 case BuiltinType::UShort:
1168 case BuiltinType::UInt:
1169 case BuiltinType::UInt128:
1170 case BuiltinType::ULong:
1171 case BuiltinType::WChar_U:
1172 case BuiltinType::ULongLong:
1173 Encoding = llvm::dwarf::DW_ATE_unsigned;
1175 case BuiltinType::Short:
1176 case BuiltinType::Int:
1177 case BuiltinType::Int128:
1178 case BuiltinType::Long:
1179 case BuiltinType::WChar_S:
1180 case BuiltinType::LongLong:
1181 Encoding = llvm::dwarf::DW_ATE_signed;
1183 case BuiltinType::Bool:
1184 Encoding = llvm::dwarf::DW_ATE_boolean;
1186 case BuiltinType::Half:
1187 case BuiltinType::Float:
1188 case BuiltinType::LongDouble:
1189 case BuiltinType::Float16:
1190 case BuiltinType::BFloat16:
1191 case BuiltinType::Float128:
1192 case BuiltinType::Double:
1193 case BuiltinType::Ibm128:
1199 Encoding = llvm::dwarf::DW_ATE_float;
1201 case BuiltinType::ShortAccum:
1202 case BuiltinType::Accum:
1203 case BuiltinType::LongAccum:
1204 case BuiltinType::ShortFract:
1205 case BuiltinType::Fract:
1206 case BuiltinType::LongFract:
1207 case BuiltinType::SatShortFract:
1208 case BuiltinType::SatFract:
1209 case BuiltinType::SatLongFract:
1210 case BuiltinType::SatShortAccum:
1211 case BuiltinType::SatAccum:
1212 case BuiltinType::SatLongAccum:
1213 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1215 case BuiltinType::UShortAccum:
1216 case BuiltinType::UAccum:
1217 case BuiltinType::ULongAccum:
1218 case BuiltinType::UShortFract:
1219 case BuiltinType::UFract:
1220 case BuiltinType::ULongFract:
1221 case BuiltinType::SatUShortAccum:
1222 case BuiltinType::SatUAccum:
1223 case BuiltinType::SatULongAccum:
1224 case BuiltinType::SatUShortFract:
1225 case BuiltinType::SatUFract:
1226 case BuiltinType::SatULongFract:
1227 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1229 case BuiltinType::MetaInfo:
1230 llvm_unreachable(
"std::meta::info is consteval-only type");
1233 BTName = BT->
getName(CGM.getLangOpts());
1236 return DBuilder.createBasicType(BTName, Size, Encoding);
1239llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1240 SmallString<32> Name;
1241 llvm::raw_svector_ostream
OS(Name);
1242 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1245 ? llvm::dwarf::DW_ATE_unsigned
1246 : llvm::dwarf::DW_ATE_signed;
1247 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1248 Encoding, llvm::DINode::FlagZero, 0,
1252llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1254 return getOrCreateType(Ty->getUnderlyingType(), U);
1257llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1259 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1261 Encoding = llvm::dwarf::DW_ATE_lo_user;
1264 return DBuilder.createBasicType(
"complex", Size, Encoding);
1278 return llvm::dwarf::DW_TAG_const_type;
1282 return llvm::dwarf::DW_TAG_volatile_type;
1286 return llvm::dwarf::DW_TAG_restrict_type;
1288 return (llvm::dwarf::Tag)0;
1291llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1292 llvm::DIFile *Unit) {
1293 QualifierCollector Qc;
1307 bool AuthenticatesNullValues =
1310 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1311 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1312 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1313 ExtraDiscr, IsaPointer,
1314 AuthenticatesNullValues);
1316 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1317 return getOrCreateType(QualType(
T, 0), Unit);
1321 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1325 return DBuilder.createQualifiedType(Tag, FromTy);
1328llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1329 llvm::DIFile *Unit) {
1338 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1343 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1349 return DBuilder.createQualifiedType(Tag, FromTy);
1352llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1353 llvm::DIFile *Unit) {
1359 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1361 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1365llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1366 llvm::DIFile *Unit) {
1367 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1373 case llvm::dwarf::DW_LANG_C_plus_plus:
1374 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1375 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1376 case llvm::dwarf::DW_LANG_HIP:
1378 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1388 case llvm::dwarf::DW_LNAME_C_plus_plus:
1389 case llvm::dwarf::DW_LNAME_HIP:
1391 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1402 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1403 SourceLang.hasVersionedName())
1405 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1409 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1435 llvm::DICompileUnit *TheCU) {
1453 llvm::DICompileUnit *TheCU) {
1459 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1461 if (RD->isDynamicClass() &&
1467 llvm::raw_svector_ostream Out(Identifier);
1474 llvm::dwarf::Tag Tag;
1476 Tag = llvm::dwarf::DW_TAG_structure_type;
1478 Tag = llvm::dwarf::DW_TAG_union_type;
1483 Tag = llvm::dwarf::DW_TAG_class_type;
1488llvm::DICompositeType *
1489CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1490 llvm::DIScope *Ctx) {
1492 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1494 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1495 const unsigned Line =
1497 StringRef RDName = getClassName(RD);
1504 Size = CGM.getContext().getTypeSize(Ty);
1506 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1511 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1512 if (!CXXRD->hasDefinition() ||
1513 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1514 Flags |= llvm::DINode::FlagNonTrivial;
1517 SmallString<256> Identifier;
1519 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1521 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1524 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1525 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1526 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1527 CollectCXXTemplateParams(TSpecial, DefUnit));
1528 ReplaceMap.emplace_back(
1529 std::piecewise_construct, std::make_tuple(Ty),
1530 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1534llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1537 llvm::DIFile *Unit) {
1542 std::optional<unsigned> DWARFAddressSpace =
1543 CGM.getTarget().getDWARFAddressSpace(
1544 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1546 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1547 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1548 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1549 Size, Align, DWARFAddressSpace);
1551 SmallVector<llvm::Metadata *, 4> Annots;
1552 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1554 llvm::DINodeArray Annotations =
nullptr;
1555 if (Annots.size() > 0)
1556 Annotations = DBuilder.getOrCreateArray(Annots);
1557 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1558 Align, DWARFAddressSpace, StringRef(),
1563llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1564 llvm::DIType *&
Cache) {
1567 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1568 TheCU, TheCU->getFile(), 0);
1569 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1570 Cache = DBuilder.createPointerType(
Cache, Size);
1574uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1575 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1576 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1586 if (CGM.getLangOpts().OpenCL) {
1587 FType = CGM.getContext().IntTy;
1588 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1589 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1591 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1592 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1593 FType = CGM.getContext().IntTy;
1594 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1595 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1597 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1598 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1599 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1600 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1601 EltTys.push_back(DBuilder.createMemberType(
1602 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1603 FieldOffset, llvm::DINode::FlagZero, DescTy));
1604 FieldOffset += FieldSize;
1610llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1611 llvm::DIFile *Unit) {
1612 SmallVector<llvm::Metadata *, 8> EltTys;
1615 llvm::DINodeArray Elements;
1618 FType = CGM.getContext().UnsignedLongTy;
1619 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1620 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1622 Elements = DBuilder.getOrCreateArray(EltTys);
1625 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1628 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1629 FieldOffset, 0, Flags,
nullptr, Elements);
1634 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1636 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1639 Elements = DBuilder.getOrCreateArray(EltTys);
1645 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1646 Flags,
nullptr, Elements);
1648 return DBuilder.createPointerType(EltTy, Size);
1651static llvm::SmallVector<TemplateArgument>
1653 assert(Ty->isTypeAlias());
1662 ArrayRef SubstArgs = Ty->template_arguments();
1665 if (Param->isParameterPack()) {
1674 if (SubstArgs.empty()) {
1683 SpecArgs.push_back(SubstArgs.front());
1684 SubstArgs = SubstArgs.drop_front();
1689llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1690 llvm::DIFile *Unit) {
1691 assert(Ty->isTypeAlias());
1692 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1694 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1702 SmallString<128> NS;
1703 llvm::raw_svector_ostream
OS(NS);
1705 auto PP = getPrintingPolicy();
1708 SourceLocation Loc =
AliasDecl->getLocation();
1710 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1711 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1720 llvm::raw_string_ostream
OS(Name);
1722 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1723 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1724 !HasReconstitutableArgs(Args.Args))
1725 printTemplateArgumentList(OS, Args.Args, PP);
1727 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1728 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1729 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1733 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1735 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1752 return llvm::DINode::FlagZero;
1756 return llvm::DINode::FlagPrivate;
1758 return llvm::DINode::FlagProtected;
1760 return llvm::DINode::FlagPublic;
1762 return llvm::DINode::FlagZero;
1764 llvm_unreachable(
"unexpected access enumerator");
1767llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1768 llvm::DIFile *Unit) {
1769 llvm::DIType *Underlying =
1785 SmallVector<llvm::Metadata *, 4> Annots;
1786 llvm::DINodeArray Annotations;
1788 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1789 if (!Annots.empty())
1790 Annotations = DBuilder.getOrCreateArray(Annots);
1792 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1797 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1798 getOrCreateFile(Loc), getLineNumber(Loc),
1799 getDeclContextDescriptor(Ty->
getDecl()), Align,
1800 Flags, Annotations);
1808 if (
T.isSPIROrSPIRV())
1809 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1814 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1816 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1818 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1820 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1822 return llvm::dwarf::DW_CC_BORLAND_pascal;
1824 return llvm::dwarf::DW_CC_LLVM_Win64;
1826 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1830 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1832 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1834 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1836 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1838 return llvm::dwarf::DW_CC_LLVM_Swift;
1840 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1842 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1844 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1846 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1848 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1850 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1852 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1853#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1867 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1873 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1875 Flags |= llvm::DINode::FlagLValueReference;
1877 Flags |= llvm::DINode::FlagRValueReference;
1881llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1882 llvm::DIFile *Unit) {
1883 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1885 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1891 SmallVector<llvm::Metadata *, 16> EltTys;
1894 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1896 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1900 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1903 for (
const QualType &ParamType : FPT->param_types())
1904 EltTys.push_back(getOrCreateType(ParamType, Unit));
1905 if (FPT->isVariadic())
1906 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1909 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1910 llvm::DIType *F = DBuilder.createSubroutineType(
1911 EltTypeArray, Flags,
1916llvm::DIDerivedType *
1917CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1918 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1919 StringRef Name = BitFieldDecl->
getName();
1920 QualType Ty = BitFieldDecl->
getType();
1921 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1924 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1925 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1928 llvm::DIFile *
File = getOrCreateFile(Loc);
1929 unsigned Line = getLineNumber(Loc);
1931 const CGBitFieldInfo &BitFieldInfo =
1932 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1934 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1941 if (CGM.getDataLayout().isBigEndian())
1943 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1945 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1946 return DBuilder.createBitFieldMemberType(
1947 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1948 Flags, DebugType, Annotations);
1951llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1952 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1953 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1955 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1980 if (PreviousFieldsDI.empty())
1984 auto *PreviousMDEntry =
1985 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1986 auto *PreviousMDField =
1987 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1988 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1989 PreviousMDField->getSizeInBits() == 0)
1993 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1995 assert(PreviousBitfield->isBitField());
1997 if (!PreviousBitfield->isZeroLengthBitField())
2000 QualType Ty = PreviousBitfield->getType();
2001 SourceLocation Loc = PreviousBitfield->getLocation();
2002 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2003 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
2004 llvm::DIScope *RecordTy = BitFieldDI->getScope();
2006 llvm::DIFile *
File = getOrCreateFile(Loc);
2007 unsigned Line = getLineNumber(Loc);
2013 llvm::DINode::DIFlags Flags =
2015 llvm::DINodeArray Annotations =
2016 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2017 return DBuilder.createBitFieldMemberType(
2018 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2019 Flags, DebugType, Annotations);
2022llvm::DIType *CGDebugInfo::createFieldType(
2024 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2025 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2026 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2029 llvm::DIFile *file = getOrCreateFile(loc);
2030 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2033 auto Align = AlignInBits;
2034 if (!
type->isIncompleteArrayType()) {
2035 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2036 SizeInBits = TI.
Width;
2042 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2043 offsetInBits, flags, debugType, Annotations);
2047CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2048 llvm::DIFile *FileScope) {
2052 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2055 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2056 SP = DBuilder.createFunction(
2057 FileScope, FuncName, StringRef(),
2058 FileScope, 0, DIFnTy,
2060 llvm::DINode::FlagArtificial,
2061 llvm::DISubprogram::SPFlagDefinition,
2062 nullptr,
nullptr,
nullptr,
2063 nullptr, StringRef(),
2064 CGM.getCodeGenOpts().DebugKeyInstructions);
2071CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2073 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2075 assert(
Capture.capturesVariable());
2077 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2078 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2080 return CaptureDecl->
getName();
2083void CGDebugInfo::CollectRecordLambdaFields(
2084 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2085 llvm::DIType *RecordTy) {
2090 unsigned fieldno = 0;
2093 I != E; ++I, ++Field, ++fieldno) {
2094 const LambdaCapture &
Capture = *I;
2096 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2098 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2108 Loc =
Field->getLocation();
2109 }
else if (
Capture.capturesVariable()) {
2112 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2113 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2120 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2122 FieldIndexCache[*
Field] = elements.size();
2123 elements.push_back(createFieldType(
2125 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2131template <
typename T>
2132static llvm::Constant *
2143 return llvm::ConstantDataArray::get(Ctx, Vals);
2156 const QualType ElemQTy = ArrayTy->getElementType();
2163 switch (ElemBitWidth) {
2179llvm::DIDerivedType *
2180CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2181 const RecordDecl *RD) {
2185 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2186 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2188 unsigned LineNumber = getLineNumber(Var->
getLocation());
2189 StringRef VName = Var->
getName();
2193 llvm::Constant *
C =
nullptr;
2198 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2199 if (
Value->isFloat())
2200 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2201 if (
Value->isArray())
2207 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2208 ? llvm::dwarf::DW_TAG_variable
2209 : llvm::dwarf::DW_TAG_member;
2211 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2212 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2217void CGDebugInfo::CollectRecordNormalField(
2218 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2219 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2220 const RecordDecl *RD) {
2225 if (
name.empty() && !
type->isRecordType())
2228 llvm::DIType *FieldType;
2230 llvm::DIDerivedType *BitFieldType;
2231 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2232 if (llvm::DIType *Separator =
2233 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2234 elements.push_back(Separator);
2237 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2240 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2243 FieldIndexCache[field] = elements.size();
2244 elements.push_back(FieldType);
2247void CGDebugInfo::CollectRecordNestedType(
2248 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2249 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2256 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2257 elements.push_back(nestedType);
2260void CGDebugInfo::CollectRecordFields(
2261 const RecordDecl *record, llvm::DIFile *tunit,
2262 SmallVectorImpl<llvm::Metadata *> &elements,
2263 llvm::DICompositeType *RecordTy) {
2264 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2266 if (CXXDecl && CXXDecl->
isLambda())
2267 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2269 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2272 unsigned fieldNo = 0;
2276 for (
const auto *I : record->
decls())
2277 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2278 if (
V->hasAttr<NoDebugAttr>())
2283 if (CGM.getCodeGenOpts().EmitCodeView &&
2291 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2292 if (MI != StaticDataMemberCache.end()) {
2293 assert(MI->second &&
2294 "Static data member declaration should still exist");
2295 elements.push_back(MI->second);
2297 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2298 elements.push_back(Field);
2300 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2301 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2302 elements, RecordTy, record);
2306 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2309 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2314 if (!nestedType->isImplicit() &&
2315 nestedType->getDeclContext() == record)
2316 CollectRecordNestedType(nestedType, elements);
2322llvm::DISubroutineType *
2323CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2324 llvm::DIFile *Unit) {
2325 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2327 return cast_or_null<llvm::DISubroutineType>(
2328 getOrCreateType(QualType(
Func, 0), Unit));
2331 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2332 ThisType =
Method->getThisType();
2334 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2337llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2338 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2339 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2341 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2344llvm::DISubroutineType *
2345CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2346 const FunctionProtoType *
Func,
2347 llvm::DIFile *Unit,
bool SkipFirst) {
2348 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2363 getOrCreateType(CGM.getContext().getFunctionType(
2364 Func->getReturnType(),
Func->getParamTypes(), EPI),
2366 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2367 assert(Args.size() &&
"Invalid number of arguments!");
2369 SmallVector<llvm::Metadata *, 16> Elts;
2372 Elts.push_back(Args[0]);
2374 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2378 if (!HasExplicitObjectParameter) {
2379 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2382 DBuilder.createObjectPointerType(ThisPtrType,
true);
2383 Elts.push_back(ThisPtrType);
2387 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2388 Elts.push_back(Args[i]);
2391 if (HasExplicitObjectParameter) {
2392 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2393 "Expected at least return type and object parameter.");
2394 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2397 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2399 return DBuilder.createSubroutineType(
2400 EltTypeArray, OriginalFunc->getFlags(),
2407 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2415CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2418 const bool IsCtorOrDtor =
2421 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2428 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2431 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2434 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2437 return CGM.getMangledName(
Method);
2440bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2443 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2446llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2447 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2450 StringRef MethodName = getFunctionName(
Method);
2451 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2453 StringRef MethodLinkageName;
2460 MethodLinkageName = GetMethodLinkageName(
Method);
2463 llvm::DIFile *MethodDefUnit =
nullptr;
2464 unsigned MethodLine = 0;
2465 if (!
Method->isImplicit()) {
2466 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2467 MethodLine = getLineNumber(
Method->getLocation());
2471 llvm::DIType *ContainingType =
nullptr;
2472 unsigned VIndex = 0;
2473 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2474 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2475 int ThisAdjustment = 0;
2478 if (
Method->isPureVirtual())
2479 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2481 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2483 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2487 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2491 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2494 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2495 CGM.getContext().getLangOpts())
2499 MethodVFTableLocation ML =
2500 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2508 if (
Method->size_overridden_methods() == 0)
2509 Flags |= llvm::DINode::FlagIntroducedVirtual;
2514 ThisAdjustment = CGM.getCXXABI()
2515 .getVirtualFunctionPrologueThisAdjustment(GD)
2518 ContainingType = RecordTy;
2521 if (
Method->getCanonicalDecl()->isDeleted())
2522 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2524 if (
Method->isNoReturn())
2525 Flags |= llvm::DINode::FlagNoReturn;
2528 Flags |= llvm::DINode::FlagStaticMember;
2529 if (
Method->isImplicit())
2530 Flags |= llvm::DINode::FlagArtificial;
2532 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2533 if (CXXC->isExplicit())
2534 Flags |= llvm::DINode::FlagExplicit;
2535 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2536 if (CXXC->isExplicit())
2537 Flags |= llvm::DINode::FlagExplicit;
2539 if (
Method->hasPrototype())
2540 Flags |= llvm::DINode::FlagPrototyped;
2542 Flags |= llvm::DINode::FlagLValueReference;
2544 Flags |= llvm::DINode::FlagRValueReference;
2545 if (!
Method->isExternallyVisible())
2546 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2547 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2548 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2553 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2554 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2555 if (
const auto *Def =
2556 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2557 Def && !Def->isDelegatingConstructor()) {
2563 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2564 llvm::DISubprogram *SP = DBuilder.createMethod(
2565 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2566 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2567 TParamsArray.get(),
nullptr,
2568 CGM.getCodeGenOpts().DebugKeyInstructions);
2570 SPCache[
Method->getCanonicalDecl()].reset(SP);
2575void CGDebugInfo::CollectCXXMemberFunctions(
2576 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2577 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2582 for (
const auto *I : RD->
decls()) {
2583 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2597 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2606 auto MI = SPCache.find(
Method->getCanonicalDecl());
2607 EltTys.push_back(MI == SPCache.end()
2608 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2609 :
static_cast<llvm::Metadata *
>(MI->second));
2613void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2614 SmallVectorImpl<llvm::Metadata *> &EltTys,
2615 llvm::DIType *RecordTy) {
2616 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2617 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2618 llvm::DINode::FlagZero);
2622 if (CGM.getCodeGenOpts().EmitCodeView) {
2623 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2624 llvm::DINode::FlagIndirectVirtualBase);
2628void CGDebugInfo::CollectCXXBasesAux(
2629 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2630 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2632 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2633 llvm::DINode::DIFlags StartingFlags) {
2634 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2635 for (
const auto &BI : Bases) {
2638 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2640 if (!SeenTypes.insert(Base).second)
2642 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2643 llvm::DINode::DIFlags BFlags = StartingFlags;
2647 if (BI.isVirtual()) {
2648 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2651 BaseOffset = 0 - CGM.getItaniumVTableContext()
2652 .getVirtualBaseOffsetOffset(RD, Base)
2658 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2659 VBPtrOffset = CGM.getContext()
2660 .getASTRecordLayout(RD)
2664 BFlags |= llvm::DINode::FlagVirtual;
2671 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2672 VBPtrOffset, BFlags);
2673 EltTys.push_back(DTy);
2678CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2679 llvm::DIFile *Unit) {
2681 return llvm::DINodeArray();
2682 TemplateArgs &Args = *OArgs;
2683 SmallVector<llvm::Metadata *, 16> TemplateParams;
2684 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2685 const TemplateArgument &TA = Args.Args[i];
2689 Name = Args.TList->getParam(i)->getName();
2693 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2694 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2695 TheCU, Name, TTy, defaultParameter));
2700 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2701 TheCU, Name, TTy, defaultParameter,
2702 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2707 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2708 llvm::Constant *
V =
nullptr;
2711 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2712 !D->
hasAttr<CUDADeviceAttr>()) {
2715 if (
const auto *VD = dyn_cast<VarDecl>(D))
2716 V = CGM.GetAddrOfGlobalVar(VD);
2719 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2720 MD && MD->isImplicitObjectMemberFunction())
2721 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2722 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2723 V = CGM.GetAddrOfFunction(FD);
2726 else if (
const auto *MPT =
2727 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2731 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2733 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2734 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2735 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2736 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2737 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2739 V = ConstantEmitter(CGM).emitAbstract(
2740 SourceLocation(), TPO->getValue(), TPO->getType());
2742 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2744 assert(
V &&
"Failed to find template parameter pointer");
2745 V =
V->stripPointerCasts();
2747 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2748 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2752 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2753 llvm::Constant *
V =
nullptr;
2756 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2762 if (MPT->isMemberDataPointer())
2763 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2765 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2766 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2767 TheCU, Name, TTy, defaultParameter,
V));
2771 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2772 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2774 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2775 TheCU, Name, TTy, defaultParameter,
V));
2778 std::string QualName;
2779 llvm::raw_string_ostream
OS(QualName);
2781 OS, getPrintingPolicy());
2782 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2783 TheCU, Name,
nullptr, QualName, defaultParameter));
2787 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2788 TheCU, Name,
nullptr,
2795 T = CGM.getContext().getLValueReferenceType(
T);
2796 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2797 assert(
V &&
"Expression in template argument isn't constant");
2798 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2799 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2800 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2806 "These argument types shouldn't exist in concrete types");
2809 return DBuilder.getOrCreateArray(TemplateParams);
2812std::optional<CGDebugInfo::TemplateArgs>
2813CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2821 return std::nullopt;
2823std::optional<CGDebugInfo::TemplateArgs>
2824CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2828 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2830 return std::nullopt;
2831 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2832 const TemplateParameterList *TList =
T->getTemplateParameters();
2833 auto TA = TS->getTemplateArgs().asArray();
2834 return {{TList, TA}};
2836std::optional<CGDebugInfo::TemplateArgs>
2837CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2838 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2842 TemplateParameterList *TPList =
2843 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2844 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2845 return {{TPList, TAList.
asArray()}};
2847 return std::nullopt;
2851CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2852 llvm::DIFile *Unit) {
2853 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2856llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2857 llvm::DIFile *Unit) {
2858 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2861llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2862 llvm::DIFile *Unit) {
2863 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2866void CGDebugInfo::CollectBTFDeclTagAnnotations(
2867 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2869 llvm::Metadata *Ops[2] = {
2870 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2871 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2872 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2876llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2877 if (!D->
hasAttr<BTFDeclTagAttr>())
2880 SmallVector<llvm::Metadata *, 4> Annotations;
2881 CollectBTFDeclTagAnnotations(D, Annotations);
2882 return DBuilder.getOrCreateArray(Annotations);
2885void CGDebugInfo::CollectBTFTypeTagAnnotations(
2886 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2887 const BTFTagAttributedType *BTFAttrTy;
2889 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2891 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2894 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2896 llvm::Metadata *Ops[2] = {
2897 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2898 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2899 Annotations.insert(Annotations.begin(),
2900 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2902 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2906llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2908 return VTablePtrType;
2910 ASTContext &Context = CGM.getContext();
2913 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2914 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2915 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2917 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2918 std::optional<unsigned> DWARFAddressSpace =
2919 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2921 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2922 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2923 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2924 return VTablePtrType;
2927StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2939 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2941 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2951 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2952 VTable->isDeclarationForLinker())
2956 StringRef SymbolName =
"__clang_vtable";
2958 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2967 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2969 llvm::DIFile *Unit = getOrCreateFile(Loc);
2970 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2972 llvm::DINode::FlagArtificial;
2973 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2974 ? llvm::dwarf::DW_TAG_variable
2975 : llvm::dwarf::DW_TAG_member;
2976 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2977 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2981 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2985 llvm::DIGlobalVariableExpression *GVE =
2986 DBuilder.createGlobalVariableExpression(
2987 TheCU, SymbolName, VTable->getName(), Unit, 0,
2988 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2989 true,
nullptr, DT,
nullptr,
2991 VTable->addDebugInfo(GVE);
2994StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2996 llvm::Function *InitFn) {
3001 return InitFn->getName();
3011 llvm::raw_svector_ostream OS(QualifiedGV);
3013 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3015 std::swap(Quals, GVName);
3019 llvm::raw_svector_ostream OS(InitName);
3021 OS << Quals <<
"::";
3026 llvm_unreachable(
"not an initializer");
3028 OS <<
"`dynamic initializer for '";
3031 OS <<
"`dynamic atexit destructor for '";
3038 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3039 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3040 getPrintingPolicy());
3045 return internString(
OS.str());
3048void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3049 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3058 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3065 llvm::DIType *VPtrTy =
nullptr;
3066 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3067 CGM.getTarget().getCXXABI().isMicrosoft();
3068 if (NeedVTableShape) {
3070 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3071 const VTableLayout &VFTLayout =
3072 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3073 unsigned VSlotCount =
3075 unsigned VTableWidth = PtrWidth * VSlotCount;
3076 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3077 std::optional<unsigned> DWARFAddressSpace =
3078 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3081 llvm::DIType *VTableType = DBuilder.createPointerType(
3082 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3083 EltTys.push_back(VTableType);
3086 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3094 VPtrTy = getOrCreateVTablePtrType(Unit);
3096 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3097 llvm::DIType *VPtrMember =
3098 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3099 llvm::DINode::FlagArtificial, VPtrTy);
3100 EltTys.push_back(VPtrMember);
3103std::pair<llvm::DIType *, unsigned>
3108 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3115 auto I = FieldIndexCache.find(Field);
3116 assert(I != FieldIndexCache.end() &&
"Missing field debug information");
3117 return {
T, I->second};
3127 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3128 assert(!D.
isNull() &&
"null type");
3129 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3130 assert(
T &&
"could not create debug info for type");
3139 if (CGM.getCodeGenOpts().getDebugInfo() <=
3140 llvm::codegenoptions::DebugLineTablesOnly)
3144 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3146 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3148 CI->setMetadata(
"heapallocsite", node);
3152 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3154 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3156 auto I = TypeCache.find(TyPtr);
3159 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3160 assert(!Res->isForwardDecl());
3161 TypeCache[TyPtr].reset(Res);
3165 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3166 !CGM.getLangOpts().CPlusPlus)
3172 if (RD->
hasAttr<DLLImportAttr>())
3175 if (MD->hasAttr<DLLImportAttr>())
3188 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3198 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3199 Explicit = TD->isExplicitInstantiationOrSpecialization();
3203 if (CXXDecl->
fields().empty())
3213 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3214 if (CXXRD->isDynamicClass() &&
3215 CGM.getVTableLinkage(CXXRD) ==
3216 llvm::GlobalValue::AvailableExternallyLinkage &&
3227 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3229 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3231 auto I = TypeCache.find(TyPtr);
3238 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3239 assert(!Res->isForwardDecl());
3240 TypeCache[TyPtr].reset(Res);
3247 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3248 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3275 bool HasNonDeletedCtor =
false;
3277 if (Ctor->isCopyOrMoveConstructor())
3284 if (CtorDef->isDelegatingConstructor())
3288 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3291 if (!Ctor->isDeleted())
3292 HasNonDeletedCtor =
true;
3294 return HasNonDeletedCtor;
3310 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3313 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3314 RD->
hasAttr<StandaloneDebugAttr>())
3317 if (!LangOpts.CPlusPlus)
3323 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3339 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3340 Spec = SD->getSpecializationKind();
3349 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3360 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3361 llvm::DIType *
T = getTypeOrNull(Ty);
3362 if (
T &&
T->isForwardDecl())
3366llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3368 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3372 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3376 auto [Def, Pref] = CreateTypeDefinition(Ty);
3378 return Pref ? Pref : Def;
3381llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3382 llvm::DIFile *Unit) {
3386 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3390 return getOrCreateType(PNA->getTypedefType(), Unit);
3417 const auto *RT = QT->
getAs<RecordType>();
3421 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3422 if (!CRD || !CRD->hasDefinition())
3427 assert(CRD->isStandardLayout());
3433std::pair<llvm::DIType *, llvm::DIType *>
3434CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3438 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3446 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3450 return {FwdDecl,
nullptr};
3452 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3453 CollectContainingType(CXXDecl, FwdDecl);
3456 LexicalBlockStack.emplace_back(&*FwdDecl);
3457 RegionMap[RD].reset(FwdDecl);
3460 SmallVector<llvm::Metadata *, 16> EltTys;
3467 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3469 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3470 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3474 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3475 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3476 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3478 LexicalBlockStack.pop_back();
3479 RegionMap.erase(RD);
3481 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3482 DBuilder.replaceArrays(FwdDecl, Elements);
3484 if (FwdDecl->isTemporary())
3486 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3488 RegionMap[RD].reset(FwdDecl);
3490 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3505 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3506 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3507 return {FwdDecl, PrefDI};
3509 return {FwdDecl,
nullptr};
3512llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3513 llvm::DIFile *Unit) {
3515 return getOrCreateType(Ty->getBaseType(), Unit);
3518llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3519 llvm::DIFile *Unit) {
3521 SourceLocation Loc = Ty->getDecl()->getLocation();
3524 return DBuilder.createTypedef(
3525 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3526 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3527 getDeclContextDescriptor(Ty->getDecl()));
3554llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3555 llvm::DIFile *Unit) {
3560 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3561 TheCU->getSourceLanguage().getUnversionedName());
3566 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3567 !
ID->getImplementation())
3568 return DBuilder.createForwardDecl(
3569 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3570 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3573 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3574 unsigned Line = getLineNumber(
ID->getLocation());
3578 ObjCInterfaceDecl *Def =
ID->getDefinition();
3580 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3581 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3582 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3583 DefUnit,
Line, RuntimeLang);
3584 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3588 return CreateTypeDefinition(Ty, Unit);
3591llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3592 bool CreateSkeletonCU) {
3597 auto ModRef = ModuleCache.find(M);
3598 if (ModRef != ModuleCache.end())
3602 SmallString<128> ConfigMacros;
3604 llvm::raw_svector_ostream
OS(ConfigMacros);
3605 const auto &PPOpts = CGM.getPreprocessorOpts();
3608 for (
auto &M : PPOpts.Macros) {
3611 const std::string &
Macro = M.first;
3612 bool Undef = M.second;
3613 OS <<
"\"-" << (Undef ?
'U' :
'D');
3614 for (
char c :
Macro)
3629 bool IsRootModule = M ? !M->
Parent :
true;
3633 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3634 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3635 "clang module without ASTFile must be specified by -fmodule-name");
3638 auto RemapPath = [
this](StringRef Path) -> std::string {
3640 StringRef Relative(Remapped);
3641 StringRef CompDir = TheCU->getDirectory();
3642 if (CompDir.empty())
3645 if (Relative.consume_front(CompDir))
3646 Relative.consume_front(llvm::sys::path::get_separator());
3648 return Relative.str();
3651 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3658 Signature = ModSig.truncatedValue();
3662 llvm::DIBuilder DIB(CGM.getModule());
3664 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3665 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3666 PCM = getCurrentDirname();
3670 llvm::sys::path::append(PCM, Mod.
getASTFile());
3671 DIB.createCompileUnit(
3672 TheCU->getSourceLanguage(),
3675 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3676 llvm::DICompileUnit::FullDebug, Signature);
3680 llvm::DIModule *Parent =
3682 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3684 StringRef IncludePath = Mod.
getPath();
3685 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3686 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3687 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3690 llvm::DIModule *DIMod =
3691 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3692 RemapPath(IncludePath));
3693 ModuleCache[M].reset(DIMod);
3697llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3698 llvm::DIFile *Unit) {
3700 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3701 unsigned Line = getLineNumber(
ID->getLocation());
3703 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3709 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3710 if (
ID->getImplementation())
3711 Flags |= llvm::DINode::FlagObjcClassComplete;
3713 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3714 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3715 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3716 nullptr, llvm::DINodeArray(), RuntimeLang);
3718 QualType QTy(Ty, 0);
3719 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3722 LexicalBlockStack.emplace_back(RealDecl);
3723 RegionMap[Ty->
getDecl()].reset(RealDecl);
3726 SmallVector<llvm::Metadata *, 16> EltTys;
3728 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3730 llvm::DIType *SClassTy =
3731 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3735 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3736 llvm::DINode::FlagZero);
3737 EltTys.push_back(InhTag);
3741 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3742 SourceLocation Loc = PD->getLocation();
3743 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3744 unsigned PLine = getLineNumber(Loc);
3745 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3746 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3747 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3748 PD->getName(), PUnit, PLine,
3750 : getSelectorName(PD->getGetterName()),
3752 : getSelectorName(PD->getSetterName()),
3753 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3754 EltTys.push_back(PropertyNode);
3759 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3763 llvm::DenseSet<IsClassAndIdent> PropertySet;
3765 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3766 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3768 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3769 for (
auto *PD : ClassExt->properties()) {
3770 PropertySet.insert(GetIsClassAndIdent(PD));
3773 for (
const auto *PD :
ID->properties()) {
3776 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3782 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3783 unsigned FieldNo = 0;
3784 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3785 Field =
Field->getNextIvar(), ++FieldNo) {
3786 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3790 StringRef FieldName =
Field->getName();
3793 if (FieldName.empty())
3797 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3798 unsigned FieldLine = getLineNumber(
Field->getLocation());
3799 QualType FType =
Field->getType();
3806 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3807 : CGM.getContext().getTypeSize(FType);
3812 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3816 if (
Field->isBitField()) {
3818 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3819 FieldOffset %= CGM.getContext().getCharWidth();
3827 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3829 Flags = llvm::DINode::FlagProtected;
3831 Flags = llvm::DINode::FlagPrivate;
3833 Flags = llvm::DINode::FlagPublic;
3835 if (
Field->isBitField())
3836 Flags |= llvm::DINode::FlagBitField;
3838 llvm::MDNode *PropertyNode =
nullptr;
3839 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3840 llvm::DIFile *PUnit =
nullptr;
3842 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3843 if (ObjCPropertyImplDecl *PImpD =
3844 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3845 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3846 SynthesizedProperty = PD;
3847 SourceLocation Loc = PD->getLocation();
3848 PUnit = getOrCreateFile(Loc);
3849 PLine = getLineNumber(Loc);
3850 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3851 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3852 PropertyNode = DBuilder.createObjCProperty(
3853 PD->getName(), PUnit, PLine,
3856 : getSelectorName(PD->getGetterName()),
3859 : getSelectorName(PD->getSetterName()),
3860 PD->getPropertyAttributes(),
3861 getOrCreateType(PD->getType(), PUnit));
3865 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3866 FieldSize, FieldAlign, FieldOffset,
3867 Flags, FieldTy, PropertyNode);
3868 EltTys.push_back(IvarTy);
3870 if (SynthesizedProperty) {
3871 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3872 EltTys.push_back(DBuilder.createProperty(
3873 SynthesizedProperty->
getName(), PUnit, PLine,
3874 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3878 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3879 DBuilder.replaceArrays(RealDecl, Elements);
3881 LexicalBlockStack.pop_back();
3885llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3886 llvm::DIFile *Unit) {
3894 auto &Ctx = CGM.getContext();
3899 QualType CharVecTy =
3901 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3904 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3907 llvm::Metadata *Subscript;
3908 QualType QTy(Ty, 0);
3909 auto SizeExpr = SizeExprCache.find(QTy);
3910 if (SizeExpr != SizeExprCache.end())
3911 Subscript = DBuilder.getOrCreateSubrange(
3912 SizeExpr->getSecond() ,
nullptr ,
3913 nullptr ,
nullptr );
3916 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3917 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3918 Subscript = DBuilder.getOrCreateSubrange(
3919 CountNode ,
nullptr ,
nullptr ,
3922 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3927 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3930llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3931 llvm::DIFile *Unit) {
3935 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3940 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3941 auto *ColumnCountNode =
3942 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3943 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3944 auto *RowCountNode =
3945 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3946 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3947 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3948 ColumnCountNode ,
nullptr ,
nullptr ,
3950 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3951 RowCountNode ,
nullptr ,
nullptr ,
3953 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3954 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3957llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3962 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3977 Size = CGM.getContext().getTypeSize(Ty);
3984 SmallVector<llvm::Metadata *, 8> Subscripts;
3985 QualType EltTy(Ty, 0);
3986 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3995 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3996 Count = CAT->getZExtSize();
3997 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3998 if (Expr *Size = VAT->getSizeExpr()) {
4000 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
4001 Count =
Result.Val.getInt().getExtValue();
4005 auto SizeNode = SizeExprCache.find(EltTy);
4006 if (SizeNode != SizeExprCache.end())
4007 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4008 SizeNode->getSecond() ,
nullptr ,
4009 nullptr ,
nullptr ));
4012 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
4013 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
4014 Subscripts.push_back(DBuilder.getOrCreateSubrange(
4015 CountNode ,
nullptr ,
nullptr ,
4021 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4023 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4027llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4028 llvm::DIFile *Unit) {
4029 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4033llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4034 llvm::DIFile *Unit) {
4035 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4037 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4038 CGM.getCodeGenOpts().DwarfVersion < 4)
4039 Tag = llvm::dwarf::DW_TAG_reference_type;
4041 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4044llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4046 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4050 Size = CGM.getContext().getTypeSize(Ty);
4053 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4056 Flags |= llvm::DINode::FlagSingleInheritance;
4059 Flags |= llvm::DINode::FlagMultipleInheritance;
4062 Flags |= llvm::DINode::FlagVirtualInheritance;
4072 llvm::DIType *ClassType = getOrCreateType(
T, U);
4074 return DBuilder.createMemberPointerType(
4078 const FunctionProtoType *FPT =
4080 return DBuilder.createMemberPointerType(
4081 getOrCreateInstanceMethodType(
4084 ClassType, Size, 0, Flags);
4087llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4089 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4092llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4096llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4098 return getOrCreateType(Ty->getWrappedType(), U);
4101llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4108 const EnumType *Ty) {
4120llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4123 bool isImportedFromModule =
4124 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4128 if (isImportedFromModule || !ED->getDefinition()) {
4135 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4136 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4137 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4138 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4140 unsigned Line = getLineNumber(ED->getLocation());
4141 StringRef EDName = ED->getName();
4142 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4143 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4144 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4146 ReplaceMap.emplace_back(
4147 std::piecewise_construct, std::make_tuple(Ty),
4148 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4152 return CreateTypeDefinition(Ty);
4155llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4158 SmallVector<llvm::Metadata *, 16> Enumerators;
4159 ED = ED->getDefinition();
4160 assert(ED &&
"An enumeration definition is required");
4161 for (
const auto *
Enum : ED->enumerators()) {
4162 Enumerators.push_back(
4163 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4166 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4167 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4168 EnumKind = Attr->getExtensibility();
4171 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4173 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4174 unsigned Line = getLineNumber(ED->getLocation());
4175 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4176 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4177 return DBuilder.createEnumerationType(
4178 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4179 0, Identifier, ED->isScoped(), EnumKind);
4184 StringRef Name, StringRef
Value) {
4185 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4186 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4192 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4193 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4194 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4199 llvm::DISubprogram *SynthSubprogram) {
4200 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4201 SynthSubprogram, ParentLocation);
4206 StringRef SynthFuncName,
4207 llvm::DIFile *SynthFile) {
4208 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4213 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4219 FuncName += Category;
4221 FuncName += FailureMsg;
4224 TrapLocation->getFile());
4234 Quals += InnerQuals;
4236 switch (
T->getTypeClass()) {
4238 return C.getQualifiedType(
T.getTypePtr(), Quals);
4241 case Type::InjectedClassName:
4242 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4244 case Type::TemplateSpecialization: {
4246 if (Spec->isTypeAlias())
4247 return C.getQualifiedType(
T.getTypePtr(), Quals);
4248 T = Spec->desugar();
4251 case Type::TypeOfExpr:
4257 case Type::Decltype:
4260 case Type::UnaryTransform:
4263 case Type::Attributed:
4266 case Type::BTFTagAttributed:
4269 case Type::CountAttributed:
4278 case Type::MacroQualified:
4281 case Type::SubstTemplateTypeParm:
4285 case Type::DeducedTemplateSpecialization: {
4287 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4291 case Type::PackIndexing: {
4295 case Type::Adjusted:
4302 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4307llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4310 if (It != TypeCache.end()) {
4312 if (llvm::Metadata *
V = It->second)
4325 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4332 RetainedTypes.push_back(
4333 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4336llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4340 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4342 llvm::raw_string_ostream OS(Name);
4343 Ty.
print(OS, getPrintingPolicy());
4350 if (
auto *
T = getTypeOrNull(Ty))
4353 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4354 void *TyPtr = Ty.getAsOpaquePtr();
4357 TypeCache[TyPtr].reset(Res);
4362llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4370 auto Info = Reader->getSourceDescriptor(Idx);
4372 return getOrCreateModuleRef(*Info,
true);
4373 }
else if (ClangModuleMap) {
4386 auto Info = ASTSourceDescriptor(*M);
4387 return getOrCreateModuleRef(Info,
false);
4390 return getOrCreateModuleRef(PCHDescriptor,
false);
4397llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4400 return CreateQualifiedType(Ty, Unit);
4404#define TYPE(Class, Base)
4405#define ABSTRACT_TYPE(Class, Base)
4406#define NON_CANONICAL_TYPE(Class, Base)
4407#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4408#include "clang/AST/TypeNodes.inc"
4409 llvm_unreachable(
"Dependent types cannot show up in debug information");
4411 case Type::ExtVector:
4414 case Type::ConstantMatrix:
4416 case Type::ObjCObjectPointer:
4418 case Type::ObjCObject:
4420 case Type::ObjCTypeParam:
4422 case Type::ObjCInterface:
4430 case Type::BlockPointer:
4438 case Type::FunctionProto:
4439 case Type::FunctionNoProto:
4441 case Type::ConstantArray:
4442 case Type::VariableArray:
4443 case Type::IncompleteArray:
4444 case Type::ArrayParameter:
4447 case Type::LValueReference:
4449 case Type::RValueReference:
4452 case Type::MemberPointer:
4460 case Type::OverflowBehavior:
4465 case Type::TemplateSpecialization:
4467 case Type::HLSLAttributedResource:
4469 case Type::HLSLInlineSpirv:
4471 case Type::PredefinedSugar:
4473 case Type::CountAttributed:
4474 case Type::LateParsedAttr:
4476 case Type::Attributed:
4477 case Type::BTFTagAttributed:
4478 case Type::Adjusted:
4480 case Type::DeducedTemplateSpecialization:
4483 case Type::MacroQualified:
4484 case Type::SubstTemplateTypeParm:
4485 case Type::TypeOfExpr:
4487 case Type::Decltype:
4488 case Type::PackIndexing:
4489 case Type::UnaryTransform:
4493 llvm_unreachable(
"type should have been unwrapped!");
4496llvm::DICompositeType *
4497CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4498 QualType QTy(Ty, 0);
4500 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4505 if (
T && !
T->isForwardDecl())
4509 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4514 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4517 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4522llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4524 bool NameIsSimplified =
false;
4527 StringRef RDName = getClassName(RD, &NameIsSimplified);
4529 llvm::DIFile *DefUnit =
nullptr;
4532 DefUnit = getOrCreateFile(Loc);
4533 Line = getLineNumber(Loc);
4536 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4540 auto *
T = cast_or_null<llvm::DICompositeType>(
4541 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4549 return getOrCreateRecordFwdDecl(Ty, RDContext);
4562 auto Flags = llvm::DINode::FlagZero;
4563 if (NameIsSimplified)
4564 Flags |= llvm::DINode::FlagNameIsSimplified;
4565 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4567 Flags |= llvm::DINode::FlagTypePassByReference;
4569 Flags |= llvm::DINode::FlagTypePassByValue;
4572 if (!CXXRD->isTrivial())
4573 Flags |= llvm::DINode::FlagNonTrivial;
4576 if (CXXRD->isAnonymousStructOrUnion())
4577 Flags |= llvm::DINode::FlagExportSymbols;
4580 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4583 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4584 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4586 Flags, Identifier, Annotations);
4590 switch (RealDecl->getTag()) {
4592 llvm_unreachable(
"invalid composite type tag");
4594 case llvm::dwarf::DW_TAG_array_type:
4595 case llvm::dwarf::DW_TAG_enumeration_type:
4600 if (Identifier.empty())
4604 case llvm::dwarf::DW_TAG_structure_type:
4605 case llvm::dwarf::DW_TAG_union_type:
4606 case llvm::dwarf::DW_TAG_class_type:
4609 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4613 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4614 CXXRecordDecl *TemplateDecl =
4615 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4616 RegionMap[TemplateDecl].reset(RealDecl);
4618 RegionMap[RD].reset(RealDecl);
4620 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4622 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4623 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4624 CollectCXXTemplateParams(TSpecial, DefUnit));
4628void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4629 llvm::DICompositeType *RealDecl) {
4631 llvm::DIType *ContainingType =
nullptr;
4632 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4636 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4643 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4644 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4646 ContainingType = RealDecl;
4648 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4651llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4652 StringRef Name, uint64_t *Offset) {
4653 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4654 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4657 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4658 *Offset, llvm::DINode::FlagZero, FieldTy);
4659 *Offset += FieldSize;
4663void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4665 StringRef &LinkageName,
4666 llvm::DIScope *&FDContext,
4667 llvm::DINodeArray &TParamsArray,
4668 llvm::DINode::DIFlags &Flags) {
4670 bool NameIsSimplified =
false;
4671 Name = getFunctionName(FD, &NameIsSimplified);
4672 if (NameIsSimplified)
4673 Flags |= llvm::DINode::FlagNameIsSimplified;
4674 Name = getFunctionName(FD);
4677 LinkageName = CGM.getMangledName(GD);
4679 Flags |= llvm::DINode::FlagPrototyped;
4683 if (LinkageName == Name ||
4684 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4685 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4686 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4687 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4688 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4689 LinkageName = StringRef();
4693 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4694 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4695 CGM.getCodeGenOpts().EmitCodeView)) {
4696 if (
const NamespaceDecl *NSDecl =
4698 FDContext = getOrCreateNamespace(NSDecl);
4699 else if (
const RecordDecl *RDecl =
4701 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4702 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4705 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4708 Flags |= llvm::DINode::FlagNoReturn;
4710 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4714void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4715 unsigned &LineNo, QualType &
T,
4716 StringRef &Name, StringRef &LinkageName,
4717 llvm::MDTuple *&TemplateParameters,
4718 llvm::DIScope *&VDContext) {
4727 llvm::APInt ConstVal(32, 1);
4728 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4730 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4737 LinkageName = CGM.getMangledName(VD);
4738 if (LinkageName == Name)
4739 LinkageName = StringRef();
4742 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4743 TemplateParameters = parameterNodes.get();
4745 TemplateParameters =
nullptr;
4751 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4752 VDContext = LexicalBlockStack.back();
4771 DC = CGM.getContext().getTranslationUnitDecl();
4773 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4774 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4777llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4779 llvm::DINodeArray TParamsArray;
4780 StringRef Name, LinkageName;
4781 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4782 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4784 llvm::DIFile *Unit = getOrCreateFile(Loc);
4785 llvm::DIScope *DContext = Unit;
4786 unsigned Line = getLineNumber(Loc);
4787 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4792 SmallVector<QualType, 16> ArgTypes;
4793 for (
const ParmVarDecl *Parm : FD->
parameters())
4794 ArgTypes.push_back(Parm->getType());
4797 QualType FnType = CGM.getContext().getFunctionType(
4798 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4800 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4801 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4802 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4806 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4807 return DBuilder.createFunction(
4808 DContext, Name, LinkageName, Unit,
Line,
4809 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4810 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4812 CGM.getCodeGenOpts().DebugKeyInstructions);
4815 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4816 DContext, Name, LinkageName, Unit,
Line,
4817 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4818 TParamsArray.get(), getFunctionDeclaration(FD));
4820 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4821 std::make_tuple(CanonDecl),
4822 std::make_tuple(SP));
4826llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4827 return getFunctionFwdDeclOrStub(GD,
false);
4830llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4831 return getFunctionFwdDeclOrStub(GD,
true);
4834llvm::DIGlobalVariable *
4835CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4837 StringRef Name, LinkageName;
4839 llvm::DIFile *Unit = getOrCreateFile(Loc);
4840 llvm::DIScope *DContext = Unit;
4841 unsigned Line = getLineNumber(Loc);
4842 llvm::MDTuple *TemplateParameters =
nullptr;
4844 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4847 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4848 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4850 FwdDeclReplaceMap.emplace_back(
4851 std::piecewise_construct,
4853 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4857llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4862 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4863 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4864 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4868 if (I != DeclCache.end()) {
4870 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4871 return GVE->getVariable();
4879 if (IE != ImportedDeclCache.end()) {
4880 auto N = IE->second;
4881 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4883 return dyn_cast_or_null<llvm::DINode>(N);
4888 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4889 return getFunctionForwardDeclaration(FD);
4890 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4891 return getGlobalVariableForwardDeclaration(VD);
4896llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4897 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4900 const auto *FD = dyn_cast<FunctionDecl>(D);
4905 auto *S = getDeclContextDescriptor(D);
4908 if (MI == SPCache.end()) {
4910 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4914 if (MI != SPCache.end()) {
4915 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4916 if (SP && !SP->isDefinition())
4920 for (
auto *NextFD : FD->
redecls()) {
4921 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4922 if (MI != SPCache.end()) {
4923 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4924 if (SP && !SP->isDefinition())
4931llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4932 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4933 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4934 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4937 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4941 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4945 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4954 QualType QTy(
ID->getTypeForDecl(), 0);
4955 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4956 if (It == TypeCache.end())
4959 llvm::DISubprogram *FD = DBuilder.createFunction(
4960 InterfaceType, getObjCMethodName(OMD), StringRef(),
4961 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4962 DBuilder.finalizeSubprogram(FD);
4969llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4974 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4975 !CGM.getCodeGenOpts().EmitCodeView))
4978 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4980 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4983 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4986 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4987 return getOrCreateMethodType(
Method, F);
4989 const auto *FTy = FnType->
getAs<FunctionType>();
4992 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4994 SmallVector<llvm::Metadata *, 16> Elts;
4997 QualType ResultTy = OMethod->getReturnType();
5000 if (ResultTy == CGM.getContext().getObjCInstanceType())
5001 ResultTy = CGM.getContext().getPointerType(
5002 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
5004 Elts.push_back(getOrCreateType(ResultTy, F));
5006 QualType SelfDeclTy;
5007 if (
auto *SelfDecl = OMethod->getSelfDecl())
5008 SelfDeclTy = SelfDecl->getType();
5009 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5012 if (!SelfDeclTy.
isNull())
5014 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
5016 Elts.push_back(DBuilder.createArtificialType(
5017 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
5019 for (
const auto *PI : OMethod->parameters())
5020 Elts.push_back(getOrCreateType(PI->getType(), F));
5022 if (OMethod->isVariadic())
5023 Elts.push_back(DBuilder.createUnspecifiedParameter());
5025 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5026 return DBuilder.createSubroutineType(
5027 EltTypeArray, llvm::DINode::FlagZero,
5028 getDwarfCC(CC, CGM.getTarget().getTriple()));
5033 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5034 if (FD->isVariadic()) {
5035 SmallVector<llvm::Metadata *, 16> EltTys;
5036 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5037 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5039 EltTys.push_back(getOrCreateType(ParamType, F));
5040 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5041 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5042 return DBuilder.createSubroutineType(
5043 EltTypeArray, llvm::DINode::FlagZero,
5044 getDwarfCC(CC, CGM.getTarget().getTriple()));
5056 CC = SrcFnTy->getCallConv();
5058 for (
const VarDecl *VD : Args)
5059 ArgTypes.push_back(VD->
getType());
5060 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5066 llvm::Function *Fn,
bool CurFuncIsThunk) {
5068 StringRef LinkageName;
5070 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5073 bool HasDecl = (D !=
nullptr);
5075 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5076 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5077 llvm::DIFile *Unit = getOrCreateFile(Loc);
5078 llvm::DIScope *FDContext = Unit;
5079 llvm::DINodeArray TParamsArray;
5080 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5083 LinkageName = Fn->getName();
5084 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5086 auto FI = SPCache.find(FD->getCanonicalDecl());
5087 if (FI != SPCache.end()) {
5088 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5089 if (SP && SP->isDefinition()) {
5090 LexicalBlockStack.emplace_back(SP);
5091 RegionMap[D].reset(SP);
5095 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5096 TParamsArray, Flags);
5099 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5100 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5101 Name = getObjCMethodName(OMD);
5102 Flags |= llvm::DINode::FlagPrototyped;
5108 if (Name != Fn->getName())
5109 LinkageName = Fn->getName();
5111 Name = Fn->getName();
5116 Flags |= llvm::DINode::FlagPrototyped;
5118 Name.consume_front(
"\01");
5122 "Unexpected DynamicInitKind !");
5126 Flags |= llvm::DINode::FlagArtificial;
5132 Flags |= llvm::DINode::FlagThunk;
5134 if (Fn->hasLocalLinkage())
5135 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5136 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5137 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5140 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5141 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5143 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5144 unsigned ScopeLine = getLineNumber(ScopeLoc);
5145 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5146 llvm::DISubprogram *
Decl =
nullptr;
5147 llvm::DINodeArray Annotations =
nullptr;
5150 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5151 : getFunctionDeclaration(D);
5152 Annotations = CollectBTFDeclTagAnnotations(D);
5160 llvm::DISubprogram *SP = DBuilder.createFunction(
5161 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5162 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5163 Annotations,
"", KeyInstructions);
5164 Fn->setSubprogram(SP);
5173 LexicalBlockStack.emplace_back(SP);
5176 RegionMap[D].reset(SP);
5180 QualType FnType, llvm::Function *Fn) {
5182 StringRef LinkageName;
5188 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5189 return GetName(D,
true);
5192 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5193 llvm::DIFile *Unit = getOrCreateFile(Loc);
5194 bool IsDeclForCallSite = Fn ?
true :
false;
5195 llvm::DIScope *FDContext =
5196 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5197 llvm::DINodeArray TParamsArray;
5200 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5201 TParamsArray, Flags);
5202 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5203 Name = getObjCMethodName(OMD);
5204 Flags |= llvm::DINode::FlagPrototyped;
5206 llvm_unreachable(
"not a function or ObjC method");
5208 Name.consume_front(
"\01");
5211 Flags |= llvm::DINode::FlagArtificial;
5216 unsigned LineNo = getLineNumber(Loc);
5217 unsigned ScopeLine = 0;
5218 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5219 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5220 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5222 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5223 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5225 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5226 llvm::DISubprogram *SP = DBuilder.createFunction(
5227 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5228 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5234 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5235 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5236 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5239 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5240 DBuilder.createParameterVariable(
5241 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5242 llvm::DINode::FlagZero, ParamAnnotations);
5248 if (IsDeclForCallSite)
5249 Fn->setSubprogram(SP);
5253 llvm::CallBase *CI) {
5254 if (!shouldGenerateVirtualCallSite())
5260 assert(CI &&
"Invalid Call Instruction.");
5261 if (!CI->isIndirectCall())
5265 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5266 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5274 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5277 if (
Func->getSubprogram())
5281 if (!
Func->isDeclaration())
5303 if (
auto *SP = getFunctionDeclaration(CalleeDecl))
5304 Func->setSubprogram(SP);
5315 auto FI = SPCache.find(FD->getCanonicalDecl());
5316 llvm::DISubprogram *SP =
nullptr;
5317 if (FI != SPCache.end())
5318 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5319 if (!SP || !SP->isDefinition())
5320 SP = getFunctionStub(GD);
5321 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5322 LexicalBlockStack.emplace_back(SP);
5328 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5337 if (CurLoc.isInvalid() ||
5338 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5339 LexicalBlockStack.empty())
5342 llvm::MDNode *
Scope = LexicalBlockStack.back();
5343 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5344 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5348 llvm::MDNode *Back =
nullptr;
5349 if (!LexicalBlockStack.empty())
5350 Back = LexicalBlockStack.back().get();
5353 unsigned Line = getLineNumber(CurLoc);
5354 unsigned Column =
Line ? getColumnNumber(CurLoc) : 0;
5355 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5359void CGDebugInfo::AppendAddressSpaceXDeref(
5361 std::optional<unsigned> DWARFAddressSpace =
5363 if (!DWARFAddressSpace)
5366 Expr.push_back(llvm::dwarf::DW_OP_constu);
5367 Expr.push_back(*DWARFAddressSpace);
5368 Expr.push_back(llvm::dwarf::DW_OP_swap);
5369 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5378 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5379 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5380 LexicalBlockStack.back(), CurInlinedAt));
5382 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5386 CreateLexicalBlock(Loc);
5391 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5396 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5399 LexicalBlockStack.pop_back();
5403 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5404 unsigned RCount = FnBeginRegionCount.back();
5405 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5408 while (LexicalBlockStack.size() != RCount) {
5411 LexicalBlockStack.pop_back();
5413 FnBeginRegionCount.pop_back();
5415 if (Fn && Fn->getSubprogram())
5416 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5419CGDebugInfo::BlockByRefType
5420CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5421 uint64_t *XOffset) {
5424 uint64_t FieldSize, FieldOffset;
5425 uint32_t FieldAlign;
5427 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5432 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5433 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5435 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5436 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5439 if (HasCopyAndDispose) {
5442 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5444 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5446 bool HasByrefExtendedLayout;
5449 HasByrefExtendedLayout) &&
5450 HasByrefExtendedLayout) {
5453 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5462 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5465 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5468 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5473 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5474 FieldSize = CGM.getContext().getTypeSize(FType);
5475 FieldAlign = CGM.getContext().toBits(Align);
5477 *XOffset = FieldOffset;
5478 llvm::DIType *FieldTy = DBuilder.createMemberType(
5479 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5480 llvm::DINode::FlagZero, WrappedTy);
5481 EltTys.push_back(FieldTy);
5482 FieldOffset += FieldSize;
5484 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5485 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5486 llvm::DINode::FlagZero,
nullptr, Elements),
5490llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5491 llvm::Value *Storage,
5492 std::optional<unsigned> ArgNo,
5494 const bool UsePointerValue) {
5495 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5496 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5497 if (VD->
hasAttr<NoDebugAttr>())
5502 llvm::DIFile *Unit =
nullptr;
5503 if (!VarIsArtificial)
5507 if (VD->
hasAttr<BlocksAttr>())
5508 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5510 Ty = getOrCreateType(VD->
getType(), Unit);
5520 if (!VarIsArtificial) {
5524 SmallVector<uint64_t, 13> Expr;
5525 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5532 Flags |= llvm::DINode::FlagArtificial;
5536 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5537 AppendAddressSpaceXDeref(AddressSpace, Expr);
5541 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5544 Flags |= llvm::DINode::FlagObjectPointer;
5545 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5546 if (PVD->isExplicitObjectParameter())
5547 Flags |= llvm::DINode::FlagObjectPointer;
5555 StringRef Name = VD->
getName();
5556 if (!Name.empty()) {
5562 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5564 offset = CGM.getContext().toCharUnitsFromBits(
5567 Expr.push_back(llvm::dwarf::DW_OP_deref);
5568 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5570 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5573 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5585 for (
const auto *Field : RD->
fields()) {
5586 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5587 StringRef FieldName =
Field->getName();
5595 auto *D = DBuilder.createAutoVariable(
5596 Scope, FieldName, Unit,
Line, FieldTy,
5597 CGM.getCodeGenOpts().OptimizationLevel != 0,
5598 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5601 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5602 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5605 Builder.GetInsertBlock());
5613 if (UsePointerValue) {
5614 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5615 "Debug info already contains DW_OP_deref.");
5616 Expr.push_back(llvm::dwarf::DW_OP_deref);
5620 llvm::DILocalVariable *D =
nullptr;
5622 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5623 D = DBuilder.createParameterVariable(
5624 Scope, Name, *ArgNo, Unit,
Line, Ty,
5625 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5634 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5640 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5641 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5642 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5643 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5645 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5651 if (Iter != CoroutineParameterMappings.end()) {
5652 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5653 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5654 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5656 if (Iter2 != ParamDbgMappings.end())
5657 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5663 D = RemapCoroArgToLocalVar();
5666 D = DBuilder.createAutoVariable(
5667 Scope, Name, Unit,
Line, Ty,
5668 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5671 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5672 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5673 Column, Scope, CurInlinedAt),
5674 Builder.GetInsertBlock());
5679llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5680 llvm::Value *Storage,
5681 std::optional<unsigned> ArgNo,
5683 const bool UsePointerValue) {
5684 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5685 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5686 if (BD->
hasAttr<NoDebugAttr>())
5693 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5694 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5702 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5704 SmallVector<uint64_t, 3> Expr;
5705 AppendAddressSpaceXDeref(AddressSpace, Expr);
5710 if (UsePointerValue) {
5711 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5712 "Debug info already contains DW_OP_deref.");
5713 Expr.push_back(llvm::dwarf::DW_OP_deref);
5718 StringRef Name = BD->
getName();
5721 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5722 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5723 llvm::DINode::FlagZero, Align);
5725 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5726 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5727 const unsigned fieldIndex = FD->getFieldIndex();
5728 const clang::CXXRecordDecl *parent =
5729 (
const CXXRecordDecl *)FD->getParent();
5730 const ASTRecordLayout &layout =
5731 CGM.getContext().getASTRecordLayout(parent);
5733 if (FD->isBitField()) {
5734 const CGRecordLayout &RL =
5735 CGM.getTypes().getCGRecordLayout(FD->getParent());
5740 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5746 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5747 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5748 Expr.push_back(Info.
Offset);
5751 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5752 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5753 }
else if (fieldOffset != 0) {
5754 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5755 "Unexpected non-bitfield with non-byte-aligned offset");
5756 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5758 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5761 }
else if (
const ArraySubscriptExpr *ASE =
5762 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5763 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5764 const uint64_t value = IL->getValue().getZExtValue();
5765 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5768 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5769 Expr.push_back(CGM.getContext()
5770 .toCharUnitsFromBits(value * typeSize)
5777 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5778 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5779 Column, Scope, CurInlinedAt),
5780 Builder.GetInsertBlock());
5785llvm::DILocalVariable *
5788 const bool UsePointerValue) {
5789 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5791 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5793 EmitDeclare(B, Storage, std::nullopt, Builder,
5800 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5804 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5805 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5807 if (D->
hasAttr<NoDebugAttr>())
5811 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5817 StringRef Name = D->
getName();
5823 CGM.getCodeGenOpts().OptimizationLevel != 0);
5826 DBuilder.insertLabel(L,
5827 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5828 Scope, CurInlinedAt),
5829 Builder.GetInsertBlock()->end());
5832llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5834 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5837 return DBuilder.createObjectPointerType(Ty,
true);
5842 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5843 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5844 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5846 if (Builder.GetInsertBlock() ==
nullptr)
5848 if (VD->
hasAttr<NoDebugAttr>())
5851 bool isByRef = VD->
hasAttr<BlocksAttr>();
5853 uint64_t XOffset = 0;
5854 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5857 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5859 Ty = getOrCreateType(VD->
getType(), Unit);
5863 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5865 Ty = CreateSelfType(VD->
getType(), Ty);
5868 const unsigned Line =
5872 const llvm::DataLayout &target = CGM.getDataLayout();
5879 addr.push_back(llvm::dwarf::DW_OP_deref);
5880 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5883 addr.push_back(llvm::dwarf::DW_OP_deref);
5884 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5887 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5889 addr.push_back(llvm::dwarf::DW_OP_deref);
5890 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5892 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5898 auto *D = DBuilder.createAutoVariable(
5900 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5903 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5904 LexicalBlockStack.back(), CurInlinedAt);
5905 auto *
Expr = DBuilder.createExpression(addr);
5907 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5909 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5912llvm::DILocalVariable *
5915 bool UsePointerValue) {
5916 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5917 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5921struct BlockLayoutChunk {
5922 uint64_t OffsetInBits;
5925bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5926 return l.OffsetInBits < r.OffsetInBits;
5930void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5932 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5933 SmallVectorImpl<llvm::Metadata *> &Fields) {
5937 if (CGM.getLangOpts().OpenCL) {
5938 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5939 BlockLayout.getElementOffsetInBits(0),
5941 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5942 BlockLayout.getElementOffsetInBits(1),
5946 BlockLayout.getElementOffsetInBits(0),
5948 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5949 BlockLayout.getElementOffsetInBits(1),
5953 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5954 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5955 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5956 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5957 BlockLayout.getElementOffsetInBits(3),
5959 Fields.push_back(createFieldType(
5964 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5971 llvm::AllocaInst *Alloca,
5973 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5979 llvm::DIFile *tunit = getOrCreateFile(loc);
5980 unsigned line = getLineNumber(loc);
5981 unsigned column = getColumnNumber(loc);
5986 const llvm::StructLayout *blockLayout =
5990 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5999 BlockLayoutChunk chunk;
6000 chunk.OffsetInBits =
6001 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
6002 chunk.Capture =
nullptr;
6003 chunks.push_back(chunk);
6007 for (
const auto &capture :
blockDecl->captures()) {
6008 const VarDecl *variable = capture.getVariable();
6015 BlockLayoutChunk chunk;
6016 chunk.OffsetInBits =
6017 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
6018 chunk.Capture = &capture;
6019 chunks.push_back(chunk);
6023 llvm::array_pod_sort(chunks.begin(), chunks.end());
6025 for (
const BlockLayoutChunk &Chunk : chunks) {
6026 uint64_t offsetInBits = Chunk.OffsetInBits;
6033 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
6035 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6036 type = CGM.getContext().getCanonicalTagType(RDecl);
6038 llvm_unreachable(
"unexpected block declcontext");
6040 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6041 offsetInBits, tunit, tunit));
6046 StringRef name = variable->
getName();
6048 llvm::DIType *fieldType;
6050 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6055 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6056 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6057 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6058 PtrInfo.
Width, Align, offsetInBits,
6059 llvm::DINode::FlagZero, fieldType);
6063 offsetInBits, Align, tunit, tunit);
6065 fields.push_back(fieldType);
6069 llvm::raw_svector_ostream(typeName)
6070 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6072 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6074 llvm::DIType *
type =
6075 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6076 CGM.getContext().toBits(block.
BlockSize), 0,
6077 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6078 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6081 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6085 auto *debugVar = DBuilder.createParameterVariable(
6086 scope, Name, ArgNo, tunit, line,
type,
6087 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6090 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6091 llvm::DILocation::get(CGM.getLLVMContext(), line,
6092 column, scope, CurInlinedAt),
6093 Builder.GetInsertBlock());
6096llvm::DIDerivedType *
6097CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6102 if (MI != StaticDataMemberCache.end()) {
6103 assert(MI->second &&
"Static data member declaration should still exist");
6114llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6115 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6116 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6117 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6119 for (
const auto *Field : RD->
fields()) {
6120 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6121 StringRef FieldName = Field->getName();
6124 if (FieldName.empty()) {
6125 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6126 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6127 LineNo, LinkageName, Var, DContext);
6131 GVE = DBuilder.createGlobalVariableExpression(
6132 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6133 Var->hasLocalLinkage());
6134 Var->addDebugInfo(GVE);
6146 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6151 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6162 struct ReferencesAnonymous
6164 bool RefAnon =
false;
6165 bool VisitRecordType(RecordType *RT) {
6173 ReferencesAnonymous RT;
6186struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6187 bool Reconstitutable =
true;
6188 bool VisitVectorType(VectorType *FT) {
6189 Reconstitutable =
false;
6192 bool VisitAtomicType(AtomicType *FT) {
6193 Reconstitutable =
false;
6196 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6199 const EnumDecl *ED = ET->getDecl();
6201 Reconstitutable =
false;
6205 Reconstitutable =
false;
6210 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6214 return Reconstitutable;
6216 bool VisitRecordType(RecordType *RT,
bool =
false) {
6218 Reconstitutable =
false;
6228 ReconstitutableType
T;
6230 return T.Reconstitutable;
6233bool CGDebugInfo::HasReconstitutableArgs(
6234 ArrayRef<TemplateArgument> Args)
const {
6235 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6275 llvm_unreachable(
"Other, unresolved, template arguments should "
6276 "not be seen here");
6281std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6282 bool *NameIsSimplified)
const {
6284 llvm::raw_string_ostream
OS(Name);
6285 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6288 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6289 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6291 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6292 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6294 std::optional<TemplateArgs> Args;
6296 bool IsOperatorOverload =
false;
6297 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6298 Args = GetTemplateArgs(RD);
6299 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6300 Args = GetTemplateArgs(FD);
6302 IsOperatorOverload |=
6305 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6306 Args = GetTemplateArgs(VD);
6330 bool Reconstitutable =
6331 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6333 PrintingPolicy PP = getPrintingPolicy();
6335 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6340 if (NameIsSimplified)
6341 *NameIsSimplified =
true;
6342 bool Mangled = TemplateNamesKind ==
6343 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6349 std::string EncodedOriginalName;
6350 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6355 printTemplateArgumentList(OS, Args->Args, PP);
6356 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6358 std::string CanonicalOriginalName;
6359 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6361 assert(EncodedOriginalName == CanonicalOriginalName);
6370 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6371 if (D->
hasAttr<NoDebugAttr>())
6374 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6375 return GetName(D,
true);
6381 if (Cached != DeclCache.end())
6382 return Var->addDebugInfo(
6386 llvm::DIFile *Unit =
nullptr;
6387 llvm::DIScope *DContext =
nullptr;
6389 StringRef DeclName, LinkageName;
6391 llvm::MDTuple *TemplateParameters =
nullptr;
6392 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6393 TemplateParameters, DContext);
6397 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6402 if (
T->isUnionType() && DeclName.empty()) {
6403 const auto *RD =
T->castAsRecordDecl();
6405 "unnamed non-anonymous struct or union?");
6406 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6411 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6412 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6413 if (D->
hasAttr<CUDASharedAttr>())
6416 else if (D->
hasAttr<CUDAConstantAttr>())
6420 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6422 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6423 GVE = DBuilder.createGlobalVariableExpression(
6424 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6425 Var->hasLocalLinkage(),
true,
6426 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6427 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6428 Align, Annotations);
6429 Var->addDebugInfo(GVE);
6435 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6436 if (VD->
hasAttr<NoDebugAttr>())
6438 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6439 return GetName(VD,
true);
6444 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6445 StringRef Name = VD->
getName();
6446 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6448 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6450 if (CGM.getCodeGenOpts().EmitCodeView) {
6461 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6462 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6463 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6473 auto *VarD = dyn_cast<VarDecl>(VD);
6474 if (VarD && VarD->isStaticDataMember()) {
6476 getDeclContextDescriptor(VarD);
6481 RetainedTypes.push_back(
6482 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6486 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6488 auto &GV = DeclCache[VD];
6492 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6493 llvm::MDTuple *TemplateParameters =
nullptr;
6497 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6498 TemplateParameters = parameterNodes.get();
6501 GV.reset(DBuilder.createGlobalVariableExpression(
6502 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6503 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6504 TemplateParameters, Align));
6509 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6510 if (D->
hasAttr<NoDebugAttr>())
6514 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6515 StringRef Name = D->
getName();
6516 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6518 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6519 llvm::DIGlobalVariableExpression *GVE =
6520 DBuilder.createGlobalVariableExpression(
6521 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6522 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6523 Var->addDebugInfo(GVE);
6530 if (CGM.getCodeGenOpts().getDebugInfo() <=
6531 llvm::codegenoptions::DebugLineTablesOnly)
6534 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6538 llvm::DIFile *Unit = DIL->getFile();
6539 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6544 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6545 llvm::Value *Var = Load->getPointerOperand();
6550 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6551 return DbgDeclare->getVariable()->getType() ==
Type;
6553 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6557 llvm::DILocalVariable *D =
6558 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6559 Type,
false, llvm::DINode::FlagArtificial);
6561 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6562 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6572 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6576 if (D->
hasAttr<NoDebugAttr>())
6579 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6594 if (!(DI = getDeclarationOrDefinition(
6595 AliaseeDecl.getCanonicalDecl().getDecl())))
6598 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6601 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6602 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6616 llvm::DIFile *
File = getOrCreateFile(Loc);
6617 llvm::DIGlobalVariableExpression *Debug =
6618 DBuilder.createGlobalVariableExpression(
6619 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6620 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6621 GV->addDebugInfo(Debug);
6624llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6625 if (!LexicalBlockStack.empty())
6626 return LexicalBlockStack.back();
6627 llvm::DIScope *Mod = getParentModuleOrNull(D);
6628 return getContextDescriptor(D, Mod ? Mod : TheCU);
6632 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6636 CGM.getCodeGenOpts().DebugExplicitImport) {
6640 DBuilder.createImportedModule(
6642 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6647 if (llvm::DINode *
Target =
6650 DBuilder.createImportedDeclaration(
6652 getOrCreateFile(Loc), getLineNumber(Loc));
6657 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6660 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6662 for (
const auto *USD : UD.
shadows()) {
6667 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6668 if (
const auto *AT = FD->getType()
6671 if (AT->getDeducedType().isNull())
6682 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6685 "We shouldn't be codegening an invalid UsingEnumDecl"
6686 " containing no decls");
6688 for (
const auto *USD : UD.
shadows())
6693 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6695 if (
Module *M = ID.getImportedModule()) {
6697 auto Loc = ID.getLocation();
6698 DBuilder.createImportedDeclaration(
6699 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6700 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6701 getLineNumber(Loc));
6705llvm::DIImportedEntity *
6707 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6709 auto &VH = NamespaceAliasCache[&NA];
6712 llvm::DIImportedEntity *R;
6714 if (
const auto *Underlying =
6717 R = DBuilder.createImportedDeclaration(
6720 getLineNumber(Loc), NA.
getName());
6722 R = DBuilder.createImportedDeclaration(
6725 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6731CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6735 auto I = NamespaceCache.find(NSDecl);
6736 if (I != NamespaceCache.end())
6739 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6741 llvm::DINamespace *NS =
6742 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6743 NamespaceCache[NSDecl].reset(NS);
6748 assert(TheCU &&
"no main compile unit");
6749 TheCU->setDWOId(Signature);
6755 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6756 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6758 ? CreateTypeDefinition(E.Type, E.Unit)
6760 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6764 for (
const auto &P : ObjCMethodCache) {
6765 if (P.second.empty())
6768 QualType QTy(P.first->getTypeForDecl(), 0);
6770 assert(It != TypeCache.end());
6772 llvm::DICompositeType *InterfaceDecl =
6775 auto CurElts = InterfaceDecl->getElements();
6779 for (
auto &SubprogramDirect : P.second)
6780 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6781 EltTys.push_back(SubprogramDirect.getPointer());
6783 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6784 DBuilder.replaceArrays(InterfaceDecl, Elements);
6787 for (
const auto &P : ReplaceMap) {
6790 assert(Ty->isForwardDecl());
6792 auto It = TypeCache.find(P.first);
6793 assert(It != TypeCache.end());
6796 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6800 for (
const auto &P : FwdDeclReplaceMap) {
6803 llvm::Metadata *Repl;
6805 auto It = DeclCache.find(P.first);
6809 if (It == DeclCache.end())
6814 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6815 Repl = GVE->getVariable();
6821 for (
auto &RT : RetainedTypes)
6822 if (
auto MD = TypeCache[RT])
6825 DBuilder.finalize();
6830 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6831 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6832 DBuilder.retainType(DieTy);
6836 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6837 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6838 DBuilder.retainType(DieTy);
6842 if (LexicalBlockStack.empty())
6843 return llvm::DebugLoc();
6845 llvm::MDNode *
Scope = LexicalBlockStack.back();
6846 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6847 getColumnNumber(Loc),
Scope);
6853 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6854 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6855 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6856 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6857 return llvm::DINode::FlagZero;
6862 bool SupportsDWARFv4Ext =
6863 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6864 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6865 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6867 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6868 return llvm::DINode::FlagZero;
6870 return llvm::DINode::FlagAllCallsDescribed;
6881 return DBuilder.createConstantValueExpression(
6882 Val.
getFloat().bitcastToAPInt().getZExtValue());
6887 llvm::APSInt
const &ValInt = Val.
getInt();
6888 std::optional<uint64_t> ValIntOpt;
6889 if (ValInt.isUnsigned())
6890 ValIntOpt = ValInt.tryZExtValue();
6891 else if (
auto tmp = ValInt.trySExtValue())
6894 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6897 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6902CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6904 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6905 CGF.CurLexicalScope =
this;
6907 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6912 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6925#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6927 Label = "__ubsan_check_" #Name; \
6931#undef SANITIZER_CHECK
6942#define SANITIZER(NAME, ID) \
6943 case SanitizerKind::SO_##ID: \
6944 Label = "__ubsan_check_" NAME; \
6946#include "clang/Basic/Sanitizers.def"
6948 llvm_unreachable(
"unexpected sanitizer kind");
6953 for (
unsigned int i = 0; i < Label.length(); i++)
6954 if (!std::isalpha(Label[i]))
6963 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6965 if (!DI || !CheckDebugLoc)
6966 return CheckDebugLoc;
6967 const auto &AnnotateDebugInfo =
6968 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6969 if (AnnotateDebugInfo.empty())
6970 return CheckDebugLoc;
6973 if (Ordinals.size() == 1)
6978 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6982 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6983 "ubsan_interface.h",
6985 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6988 return CheckDebugLoc;
6996 assert(!CGF->IsSanitizerScope);
6997 CGF->IsSanitizerScope =
true;
7001 assert(CGF->IsSanitizerScope);
7002 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 SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static 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.
SourceLocation getFileLoc(SourceLocation Loc, unsigned MaxDepth=std::numeric_limits< unsigned >::max()) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
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,...
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.