41#include "llvm/ADT/DenseSet.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DerivedTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/Metadata.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/MD5.h"
53#include "llvm/Support/Path.h"
54#include "llvm/Support/SHA1.h"
55#include "llvm/Support/SHA256.h"
56#include "llvm/Support/TimeProfiler.h"
71 if (TI.isAlignRequired())
99 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
103 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
127 if (!llvm::isa<ParmVarDecl>(VD))
137 if (!Method->isImplicit() || !Method->isPropertyAccessor())
148 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
149 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
150 DBuilder(CGM.getModule()) {
155 assert(LexicalBlockStack.empty() &&
156 "Region stack mismatch, stack not empty!");
159void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
160 uint64_t Group, uint8_t Rank) {
161 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
165 Rank = std::min<uint8_t>(Rank, 7);
167 const llvm::DebugLoc &DL = I->getDebugLoc();
172 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
173 Group = DL->getAtomGroup();
174 Rank = DL->getAtomRank();
179 KeyInstructionsInfo.HighestEmittedAtom =
180 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
183 llvm::DILocation *NewDL = llvm::DILocation::get(
184 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
185 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
186 I->setDebugLoc(NewDL);
190 llvm::Value *Backup) {
192 KeyInstructionsInfo.CurrentAtom);
198 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
201 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
202 if (!SP || !SP->getKeyInstructionsEnabled())
205 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
207 llvm::Instruction *BackupI =
208 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
213 addInstSourceAtomMetadata(BackupI, Group, 2);
219 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
220 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
223 addInstSourceAtomMetadata(BackupI, Group, Rank++);
229 KeyInstructionsInfo.NextAtom = 1;
230 KeyInstructionsInfo.HighestEmittedAtom = 0;
231 KeyInstructionsInfo.CurrentAtom = 0;
237 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
238 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
246 DI->KeyInstructionsInfo.NextAtom =
247 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
248 DI->KeyInstructionsInfo.NextAtom);
250 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
256 init(TemporaryLocation);
263 init(TemporaryLocation, DefaultToEmpty);
267 bool DefaultToEmpty) {
274 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
276 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
279 if (TemporaryLocation.
isValid()) {
280 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
284 if (DefaultToEmpty) {
285 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
290 assert(!DI->LexicalBlockStack.empty());
291 CGF->Builder.SetCurrentDebugLocation(
292 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
293 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
303 if (!CGF.getDebugInfo()) {
307 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
311 if (Loc->getAtomGroup())
312 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
313 Loc->getColumn(), Loc->getScope(),
314 Loc->getInlinedAt(), Loc.isImplicitCode());
315 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
323 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
329 if (!CGF.getDebugInfo()) {
333 auto &DI = *CGF.getDebugInfo();
334 SavedLocation = DI.getLocation();
335 assert((DI.getInlinedAt() ==
336 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
337 "CGDebugInfo and IRBuilder are out of sync");
339 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
345 auto &DI = *CGF->getDebugInfo();
346 DI.EmitInlineFunctionEnd(CGF->Builder);
347 DI.EmitLocation(CGF->Builder, SavedLocation);
357 if (CurLoc != NewLoc) {
359 CurLocFile =
nullptr;
368 if (CGM.getCodeGenOpts().DebugColumnInfo)
370 CurLocFile = getOrCreateFile(CurLoc);
376 if (LexicalBlockStack.empty())
380 if (!CurLocFile ||
Scope->getFile() == CurLocFile)
383 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
384 LexicalBlockStack.pop_back();
385 LexicalBlockStack.emplace_back(
386 DBuilder.createLexicalBlockFile(LBF->getScope(), CurLocFile));
389 LexicalBlockStack.pop_back();
390 LexicalBlockStack.emplace_back(
391 DBuilder.createLexicalBlockFile(
Scope, CurLocFile));
395llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
396 llvm::DIScope *Mod = getParentModuleOrNull(D);
401llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
406 auto I = RegionMap.find(Context);
407 if (I != RegionMap.end()) {
408 llvm::Metadata *
V = I->second;
409 return dyn_cast_or_null<llvm::DIScope>(
V);
413 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
414 return getOrCreateNamespace(NSDecl);
416 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
417 if (!RDecl->isDependentType())
423PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
424 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
431 if (CGM.getCodeGenOpts().EmitCodeView) {
453StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
454 bool *NameIsSimplified) {
455 return internString(GetName(FD,
false, NameIsSimplified));
458StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
459 SmallString<256> MethodName;
460 llvm::raw_svector_ostream
OS(MethodName);
463 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
464 OS << OID->getName();
465 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
466 OS << OID->getName();
467 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
468 if (OC->IsClassExtension()) {
469 OS << OC->getClassInterface()->getName();
471 OS << OC->getIdentifier()->getNameStart() <<
'('
472 << OC->getIdentifier()->getNameStart() <<
')';
474 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
475 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
479 return internString(
OS.str());
482StringRef CGDebugInfo::getSelectorName(Selector S) {
486StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
487 bool *NameIsSimplified) {
490 return internString(GetName(RD,
false, NameIsSimplified));
496 return II->getName();
501 if (CGM.getCodeGenOpts().EmitCodeView) {
504 "Typedef should not be in another decl context!");
505 assert(D->getDeclName().getAsIdentifierInfo() &&
506 "Typedef was not named!");
507 return D->getDeclName().getAsIdentifierInfo()->getName();
510 if (CGM.getLangOpts().CPlusPlus) {
513 ASTContext &Context = CGM.getContext();
517 Name = DD->getName();
518 else if (
const TypedefNameDecl *TND =
522 Name = TND->getName();
525 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
526 if (CXXRD->isLambda())
528 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
531 SmallString<256> UnnamedType(
"<unnamed-type-");
534 return internString(UnnamedType);
542std::optional<llvm::DIFile::ChecksumKind>
543CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
546 if (!CGM.getCodeGenOpts().EmitCodeView &&
547 CGM.getCodeGenOpts().DwarfVersion < 5)
550 SourceManager &SM = CGM.getContext().getSourceManager();
551 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
555 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
556 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
558 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
559 return llvm::DIFile::CSK_MD5;
561 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
562 return llvm::DIFile::CSK_SHA1;
564 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
565 return llvm::DIFile::CSK_SHA256;
569 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
572std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
574 if (!CGM.getCodeGenOpts().EmbedSource)
577 bool SourceInvalid =
false;
586llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
587 SourceManager &SM = CGM.getContext().getSourceManager();
590 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
596 FileName = TheCU->getFile()->getFilename();
597 CSInfo = TheCU->getFile()->getChecksum();
600 if (Loc == CurLoc && CurLocFile)
607 FileName = TheCU->getFile()->getFilename();
615 auto It = DIFileCache.find(
FileName.data());
616 if (It != DIFileCache.end()) {
618 if (llvm::Metadata *
V = It->second)
623 SmallString<64> Checksum;
625 std::optional<llvm::DIFile::ChecksumKind> CSKind =
626 computeChecksum(FID, Checksum);
628 CSInfo.emplace(*CSKind, Checksum);
634llvm::DIFile *CGDebugInfo::createFile(
636 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
637 std::optional<StringRef> Source) {
641 std::string CurDir =
remapDIPath(getCurrentDirname());
642 SmallString<128> DirBuf;
643 SmallString<128> FileBuf;
644 if (llvm::sys::path::is_absolute(RemappedFile)) {
647 auto FileIt = llvm::sys::path::begin(RemappedFile);
648 auto FileE = llvm::sys::path::end(RemappedFile);
649 auto CurDirIt = llvm::sys::path::begin(CurDir);
650 auto CurDirE = llvm::sys::path::end(CurDir);
651 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
652 llvm::sys::path::append(DirBuf, *CurDirIt);
653 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
659 for (; FileIt != FileE; ++FileIt)
660 llvm::sys::path::append(FileBuf, *FileIt);
665 if (!llvm::sys::path::is_absolute(
FileName))
669 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
670 DIFileCache[
FileName.data()].reset(F);
675 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
683 if (DebugLoc == CurLoc)
698 if (DebugLoc == CurLoc)
704StringRef CGDebugInfo::getCurrentDirname() {
712 assert(CGO.DwarfVersion <= 5);
714 llvm::dwarf::SourceLanguage LangTag;
717 LangTag = llvm::dwarf::DW_LANG_HLSL;
719 LangTag = llvm::dwarf::DW_LANG_HIP;
721 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
722 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
723 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
724 else if (LO.CPlusPlus14)
725 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
726 else if (LO.CPlusPlus11)
727 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
729 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
730 }
else if (LO.ObjC) {
731 LangTag = llvm::dwarf::DW_LANG_ObjC;
732 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
733 LangTag = llvm::dwarf::DW_LANG_OpenCL;
734 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
735 LangTag = llvm::dwarf::DW_LANG_C11;
737 LangTag = llvm::dwarf::DW_LANG_C99;
739 LangTag = llvm::dwarf::DW_LANG_C89;
745static llvm::DISourceLanguageName
754 llvm::dwarf::SourceLanguageName LangTag;
757 LangTag = llvm::dwarf::DW_LNAME_HLSL;
759 LangTag = llvm::dwarf::DW_LNAME_HIP;
760 }
else if (LO.ObjC) {
761 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
763 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
766 }
else if (LO.ObjC) {
767 LangTag = llvm::dwarf::DW_LNAME_ObjC;
768 }
else if (LO.OpenCL) {
769 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
771 LangTag = llvm::dwarf::DW_LNAME_C;
775 return llvm::DISourceLanguageName(LangTag, LangVersion);
778void CGDebugInfo::CreateCompileUnit() {
779 SmallString<64> Checksum;
780 std::optional<llvm::DIFile::ChecksumKind> CSKind;
781 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
791 SourceManager &SM = CGM.getContext().getSourceManager();
792 auto &CGO = CGM.getCodeGenOpts();
793 const LangOptions &LO = CGM.getLangOpts();
794 std::string MainFileName = CGO.MainFileName;
795 if (MainFileName.empty())
796 MainFileName =
"<stdin>";
802 std::string MainFileDir;
805 MainFileDir = std::string(MainFile->getDir().getName());
806 if (!llvm::sys::path::is_absolute(MainFileName)) {
807 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
808 llvm::sys::path::Style Style =
810 ? (CGM.getTarget().
getTriple().isOSWindows()
811 ? llvm::sys::path::Style::windows_backslash
812 : llvm::sys::path::Style::posix)
813 : llvm::sys::path::Style::native;
814 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
815 MainFileName = std::string(
816 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
823 if (MainFile->getName() == MainFileName &&
825 MainFile->getName().rsplit(
'.').second)
827 MainFileName = CGM.getModule().getName().str();
836 unsigned RuntimeVers = 0;
840 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
842 case llvm::codegenoptions::NoDebugInfo:
843 case llvm::codegenoptions::LocTrackingOnly:
844 EmissionKind = llvm::DICompileUnit::NoDebug;
846 case llvm::codegenoptions::DebugLineTablesOnly:
847 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
849 case llvm::codegenoptions::DebugDirectivesOnly:
850 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
852 case llvm::codegenoptions::DebugInfoConstructor:
853 case llvm::codegenoptions::LimitedDebugInfo:
854 case llvm::codegenoptions::FullDebugInfo:
855 case llvm::codegenoptions::UnusedTypeInfo:
856 EmissionKind = llvm::DICompileUnit::FullDebug;
861 auto &CGOpts = CGM.getCodeGenOpts();
867 CSInfo.emplace(*CSKind, Checksum);
868 llvm::DIFile *CUFile = DBuilder.createFile(
872 StringRef Sysroot, SDK;
873 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
874 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
875 if (CGM.getCodeGenOpts().DebugRecordSysroot)
876 Sysroot = FullSysroot;
877 auto B = llvm::sys::path::rbegin(FullSysroot);
878 auto E = llvm::sys::path::rend(FullSysroot);
880 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
885 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
886 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
887 CGOpts.DebugNameTable);
888 if (CGM.getTarget().getTriple().isNVPTX())
889 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
890 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
891 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
894 TheCU = DBuilder.createCompileUnit(
896 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
897 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
898 CGOpts.PrepareForThinLTO,
899 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
900 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
901 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
904llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
908#define BUILTIN_TYPE(Id, SingletonId)
909#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
910#include "clang/AST/BuiltinTypes.def"
911 case BuiltinType::Dependent:
912 llvm_unreachable(
"Unexpected builtin type");
913 case BuiltinType::NullPtr:
914 return DBuilder.createNullPtrType();
915 case BuiltinType::Void:
917 case BuiltinType::ObjCClass:
920 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
921 "objc_class", TheCU, TheCU->getFile(), 0);
923 case BuiltinType::ObjCId: {
934 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
935 "objc_class", TheCU, TheCU->getFile(), 0);
937 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
939 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
941 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
942 (uint64_t)0, 0, llvm::DINode::FlagZero,
943 nullptr, llvm::DINodeArray());
945 DBuilder.replaceArrays(
946 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
947 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
948 llvm::DINode::FlagZero, ISATy)));
951 case BuiltinType::ObjCSel: {
953 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
954 "objc_selector", TheCU,
955 TheCU->getFile(), 0);
959#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
960 case BuiltinType::Id: \
961 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
963#include "clang/Basic/OpenCLImageTypes.def"
964 case BuiltinType::OCLSampler:
965 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
966 case BuiltinType::OCLEvent:
967 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
968 case BuiltinType::OCLClkEvent:
969 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
970 case BuiltinType::OCLQueue:
971 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
972 case BuiltinType::OCLReserveID:
973 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
974#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
975 case BuiltinType::Id: \
976 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
977#include "clang/Basic/OpenCLExtensionTypes.def"
978#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
979 case BuiltinType::Id: \
980 return getOrCreateStructPtrType(#Name, SingletonId);
981#include "clang/Basic/HLSLIntangibleTypes.def"
983#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
984#include "clang/Basic/AArch64ACLETypes.def"
986 if (BT->
getKind() == BuiltinType::MFloat8) {
987 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
988 BTName = BT->
getName(CGM.getLangOpts());
991 return DBuilder.createBasicType(BTName, Size, Encoding);
993 ASTContext::BuiltinVectorTypeInfo Info =
995 BT->
getKind() == BuiltinType::SveCount
996 ? ASTContext::BuiltinVectorTypeInfo(
997 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
999 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1006 "Unsupported number of vectors for svcount_t");
1008 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1009 llvm::Metadata *BitStride =
nullptr;
1010 if (BT->
getKind() == BuiltinType::SveBool) {
1011 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1012 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1013 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1014 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1016 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1019 llvm::Metadata *LowerBound, *UpperBound;
1020 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1021 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1022 if (Info.
EC.isScalable()) {
1023 unsigned NumElemsPerVG = NumElems / 2;
1024 SmallVector<uint64_t, 9> Expr(
1025 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1026 46, 0, llvm::dwarf::DW_OP_mul,
1027 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1028 UpperBound = DBuilder.createExpression(Expr);
1030 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1031 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1033 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1034 nullptr, LowerBound, UpperBound,
nullptr);
1035 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1036 llvm::DIType *ElemTy =
1037 getOrCreateType(Info.
ElementType, TheCU->getFile());
1039 return DBuilder.createVectorType( 0, Align, ElemTy,
1040 SubscriptArray, BitStride);
1044#define PPC_VECTOR_TYPE(Name, Id, size) \
1045 case BuiltinType::Id:
1046#include "clang/Basic/PPCTypes.def"
1049#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1050#include "clang/Basic/RISCVVTypes.def"
1052 ASTContext::BuiltinVectorTypeInfo Info =
1053 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1055 unsigned ElementCount = Info.
EC.getKnownMinValue();
1056 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1058 bool Fractional =
false;
1061 unsigned FixedSize = ElementCount * SEW;
1062 if (Info.
ElementType == CGM.getContext().BoolTy) {
1065 }
else if (FixedSize < 64) {
1068 LMUL = 64 / FixedSize;
1070 LMUL = FixedSize / 64;
1074 SmallVector<uint64_t, 12> Expr(
1078 {llvm::dwarf::DW_OP_bregx,
1081 llvm::dwarf::DW_OP_constu,
1083 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1085 Expr.push_back(llvm::dwarf::DW_OP_div);
1087 Expr.push_back(llvm::dwarf::DW_OP_mul);
1090 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1092 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1095 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1096 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1097 auto *UpperBound = DBuilder.createExpression(Expr);
1098 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1099 nullptr, LowerBound, UpperBound,
nullptr);
1100 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1101 llvm::DIType *ElemTy =
1102 getOrCreateType(Info.
ElementType, TheCU->getFile());
1105 return DBuilder.createVectorType(0, Align, ElemTy,
1109#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1110 case BuiltinType::Id: { \
1113 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1114 MangledName, TheCU, TheCU->getFile(), 0); \
1115 return SingletonId; \
1117#include "clang/Basic/WebAssemblyReferenceTypes.def"
1118#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1119 case BuiltinType::Id: { \
1122 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1123 TheCU, TheCU->getFile(), 0); \
1124 return SingletonId; \
1126#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1127 case BuiltinType::Id: { \
1130 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1131 return SingletonId; \
1133#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1134 case BuiltinType::Id: { \
1137 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1138 return SingletonId; \
1140#include "clang/Basic/AMDGPUTypes.def"
1141#define SPIRV_TYPE(Name, Id, SingletonId) \
1142 case BuiltinType::Id: \
1143 return getOrCreateStructPtrType(Name, SingletonId);
1144#include "clang/Basic/SPIRVTypes.def"
1145 case BuiltinType::UChar:
1146 case BuiltinType::Char_U:
1147 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1149 case BuiltinType::Char_S:
1150 case BuiltinType::SChar:
1151 Encoding = llvm::dwarf::DW_ATE_signed_char;
1153 case BuiltinType::Char8:
1154 case BuiltinType::Char16:
1155 case BuiltinType::Char32:
1156 Encoding = llvm::dwarf::DW_ATE_UTF;
1158 case BuiltinType::UShort:
1159 case BuiltinType::UInt:
1160 case BuiltinType::UInt128:
1161 case BuiltinType::ULong:
1162 case BuiltinType::WChar_U:
1163 case BuiltinType::ULongLong:
1164 Encoding = llvm::dwarf::DW_ATE_unsigned;
1166 case BuiltinType::Short:
1167 case BuiltinType::Int:
1168 case BuiltinType::Int128:
1169 case BuiltinType::Long:
1170 case BuiltinType::WChar_S:
1171 case BuiltinType::LongLong:
1172 Encoding = llvm::dwarf::DW_ATE_signed;
1174 case BuiltinType::Bool:
1175 Encoding = llvm::dwarf::DW_ATE_boolean;
1177 case BuiltinType::Half:
1178 case BuiltinType::Float:
1179 case BuiltinType::LongDouble:
1180 case BuiltinType::Float16:
1181 case BuiltinType::BFloat16:
1182 case BuiltinType::Float128:
1183 case BuiltinType::Double:
1184 case BuiltinType::Ibm128:
1190 Encoding = llvm::dwarf::DW_ATE_float;
1192 case BuiltinType::ShortAccum:
1193 case BuiltinType::Accum:
1194 case BuiltinType::LongAccum:
1195 case BuiltinType::ShortFract:
1196 case BuiltinType::Fract:
1197 case BuiltinType::LongFract:
1198 case BuiltinType::SatShortFract:
1199 case BuiltinType::SatFract:
1200 case BuiltinType::SatLongFract:
1201 case BuiltinType::SatShortAccum:
1202 case BuiltinType::SatAccum:
1203 case BuiltinType::SatLongAccum:
1204 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1206 case BuiltinType::UShortAccum:
1207 case BuiltinType::UAccum:
1208 case BuiltinType::ULongAccum:
1209 case BuiltinType::UShortFract:
1210 case BuiltinType::UFract:
1211 case BuiltinType::ULongFract:
1212 case BuiltinType::SatUShortAccum:
1213 case BuiltinType::SatUAccum:
1214 case BuiltinType::SatULongAccum:
1215 case BuiltinType::SatUShortFract:
1216 case BuiltinType::SatUFract:
1217 case BuiltinType::SatULongFract:
1218 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1222 BTName = BT->
getName(CGM.getLangOpts());
1225 return DBuilder.createBasicType(BTName, Size, Encoding);
1228llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1229 SmallString<32> Name;
1230 llvm::raw_svector_ostream
OS(Name);
1231 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1234 ? llvm::dwarf::DW_ATE_unsigned
1235 : llvm::dwarf::DW_ATE_signed;
1236 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1237 Encoding, llvm::DINode::FlagZero, 0,
1241llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1243 return getOrCreateType(Ty->getUnderlyingType(), U);
1246llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1248 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1250 Encoding = llvm::dwarf::DW_ATE_lo_user;
1253 return DBuilder.createBasicType(
"complex", Size, Encoding);
1267 return llvm::dwarf::DW_TAG_const_type;
1271 return llvm::dwarf::DW_TAG_volatile_type;
1275 return llvm::dwarf::DW_TAG_restrict_type;
1277 return (llvm::dwarf::Tag)0;
1280llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1281 llvm::DIFile *Unit) {
1282 QualifierCollector Qc;
1296 bool AuthenticatesNullValues =
1299 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1300 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1301 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1302 ExtraDiscr, IsaPointer,
1303 AuthenticatesNullValues);
1305 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1306 return getOrCreateType(QualType(
T, 0), Unit);
1310 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1314 return DBuilder.createQualifiedType(Tag, FromTy);
1317llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1318 llvm::DIFile *Unit) {
1327 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1332 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1338 return DBuilder.createQualifiedType(Tag, FromTy);
1341llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1342 llvm::DIFile *Unit) {
1348 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1350 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1354llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1355 llvm::DIFile *Unit) {
1356 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1362 case llvm::dwarf::DW_LANG_C_plus_plus:
1363 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1364 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1365 case llvm::dwarf::DW_LANG_HIP:
1367 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1377 case llvm::dwarf::DW_LNAME_C_plus_plus:
1378 case llvm::dwarf::DW_LNAME_HIP:
1380 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1391 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1392 SourceLang.hasVersionedName())
1394 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1398 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1424 llvm::DICompileUnit *TheCU) {
1442 llvm::DICompileUnit *TheCU) {
1448 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1450 if (RD->isDynamicClass() &&
1456 llvm::raw_svector_ostream Out(Identifier);
1463 llvm::dwarf::Tag Tag;
1465 Tag = llvm::dwarf::DW_TAG_structure_type;
1467 Tag = llvm::dwarf::DW_TAG_union_type;
1472 Tag = llvm::dwarf::DW_TAG_class_type;
1477llvm::DICompositeType *
1478CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1479 llvm::DIScope *Ctx) {
1481 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1483 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1484 const unsigned Line =
1486 StringRef RDName = getClassName(RD);
1493 Size = CGM.getContext().getTypeSize(Ty);
1495 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1500 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1501 if (!CXXRD->hasDefinition() ||
1502 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1503 Flags |= llvm::DINode::FlagNonTrivial;
1506 SmallString<256> Identifier;
1508 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1510 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1513 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1514 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1515 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1516 CollectCXXTemplateParams(TSpecial, DefUnit));
1517 ReplaceMap.emplace_back(
1518 std::piecewise_construct, std::make_tuple(Ty),
1519 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1523llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1526 llvm::DIFile *Unit) {
1531 std::optional<unsigned> DWARFAddressSpace =
1532 CGM.getTarget().getDWARFAddressSpace(
1533 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1535 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1536 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1537 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1538 Size, Align, DWARFAddressSpace);
1540 SmallVector<llvm::Metadata *, 4> Annots;
1541 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1543 llvm::DINodeArray Annotations =
nullptr;
1544 if (Annots.size() > 0)
1545 Annotations = DBuilder.getOrCreateArray(Annots);
1546 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1547 Align, DWARFAddressSpace, StringRef(),
1552llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1553 llvm::DIType *&
Cache) {
1556 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1557 TheCU, TheCU->getFile(), 0);
1558 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1559 Cache = DBuilder.createPointerType(
Cache, Size);
1563uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1564 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1565 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1575 if (CGM.getLangOpts().OpenCL) {
1576 FType = CGM.getContext().IntTy;
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1578 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1580 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1581 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1582 FType = CGM.getContext().IntTy;
1583 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1584 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1586 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1587 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1588 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1589 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1590 EltTys.push_back(DBuilder.createMemberType(
1591 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1592 FieldOffset, llvm::DINode::FlagZero, DescTy));
1593 FieldOffset += FieldSize;
1599llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1600 llvm::DIFile *Unit) {
1601 SmallVector<llvm::Metadata *, 8> EltTys;
1604 llvm::DINodeArray Elements;
1607 FType = CGM.getContext().UnsignedLongTy;
1608 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1609 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1611 Elements = DBuilder.getOrCreateArray(EltTys);
1614 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1617 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1618 FieldOffset, 0, Flags,
nullptr, Elements);
1623 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1625 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1628 Elements = DBuilder.getOrCreateArray(EltTys);
1634 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1635 Flags,
nullptr, Elements);
1637 return DBuilder.createPointerType(EltTy, Size);
1640static llvm::SmallVector<TemplateArgument>
1642 assert(Ty->isTypeAlias());
1651 ArrayRef SubstArgs = Ty->template_arguments();
1654 if (Param->isParameterPack()) {
1663 if (SubstArgs.empty()) {
1672 SpecArgs.push_back(SubstArgs.front());
1673 SubstArgs = SubstArgs.drop_front();
1678llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1679 llvm::DIFile *Unit) {
1680 assert(Ty->isTypeAlias());
1681 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1683 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1691 SmallString<128> NS;
1692 llvm::raw_svector_ostream
OS(NS);
1694 auto PP = getPrintingPolicy();
1697 SourceLocation Loc =
AliasDecl->getLocation();
1699 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1700 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1709 llvm::raw_string_ostream
OS(Name);
1711 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1712 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1713 !HasReconstitutableArgs(Args.Args))
1714 printTemplateArgumentList(OS, Args.Args, PP);
1716 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1717 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1718 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1722 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1724 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1741 return llvm::DINode::FlagZero;
1745 return llvm::DINode::FlagPrivate;
1747 return llvm::DINode::FlagProtected;
1749 return llvm::DINode::FlagPublic;
1751 return llvm::DINode::FlagZero;
1753 llvm_unreachable(
"unexpected access enumerator");
1756llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1757 llvm::DIFile *Unit) {
1758 llvm::DIType *Underlying =
1774 SmallVector<llvm::Metadata *, 4> Annots;
1775 llvm::DINodeArray Annotations;
1777 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1778 if (!Annots.empty())
1779 Annotations = DBuilder.getOrCreateArray(Annots);
1781 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1786 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1787 getOrCreateFile(Loc), getLineNumber(Loc),
1788 getDeclContextDescriptor(Ty->
getDecl()), Align,
1789 Flags, Annotations);
1797 if (
T.isSPIROrSPIRV())
1798 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1803 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1805 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1807 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1809 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1811 return llvm::dwarf::DW_CC_BORLAND_pascal;
1813 return llvm::dwarf::DW_CC_LLVM_Win64;
1815 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1819 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1821 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1823 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1825 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1827 return llvm::dwarf::DW_CC_LLVM_Swift;
1829 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1831 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1833 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1835 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1837 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1839 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1841 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1842#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1856 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1862 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1864 Flags |= llvm::DINode::FlagLValueReference;
1866 Flags |= llvm::DINode::FlagRValueReference;
1870llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1871 llvm::DIFile *Unit) {
1872 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1874 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1880 SmallVector<llvm::Metadata *, 16> EltTys;
1883 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1885 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1889 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1892 for (
const QualType &ParamType : FPT->param_types())
1893 EltTys.push_back(getOrCreateType(ParamType, Unit));
1894 if (FPT->isVariadic())
1895 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1898 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1899 llvm::DIType *F = DBuilder.createSubroutineType(
1900 EltTypeArray, Flags,
1905llvm::DIDerivedType *
1906CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1907 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1908 StringRef Name = BitFieldDecl->
getName();
1909 QualType Ty = BitFieldDecl->
getType();
1910 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1913 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1914 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1917 llvm::DIFile *
File = getOrCreateFile(Loc);
1918 unsigned Line = getLineNumber(Loc);
1920 const CGBitFieldInfo &BitFieldInfo =
1921 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1923 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1930 if (CGM.getDataLayout().isBigEndian())
1932 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1934 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1935 return DBuilder.createBitFieldMemberType(
1936 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1937 Flags, DebugType, Annotations);
1940llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1941 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1942 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1944 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1969 if (PreviousFieldsDI.empty())
1973 auto *PreviousMDEntry =
1974 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1975 auto *PreviousMDField =
1976 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1977 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1978 PreviousMDField->getSizeInBits() == 0)
1982 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1984 assert(PreviousBitfield->isBitField());
1986 if (!PreviousBitfield->isZeroLengthBitField())
1989 QualType Ty = PreviousBitfield->getType();
1990 SourceLocation Loc = PreviousBitfield->getLocation();
1991 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1992 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1993 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1995 llvm::DIFile *
File = getOrCreateFile(Loc);
1996 unsigned Line = getLineNumber(Loc);
2002 llvm::DINode::DIFlags Flags =
2004 llvm::DINodeArray Annotations =
2005 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2006 return DBuilder.createBitFieldMemberType(
2007 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2008 Flags, DebugType, Annotations);
2011llvm::DIType *CGDebugInfo::createFieldType(
2013 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2014 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2015 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2018 llvm::DIFile *file = getOrCreateFile(loc);
2019 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2022 auto Align = AlignInBits;
2023 if (!
type->isIncompleteArrayType()) {
2024 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2025 SizeInBits = TI.
Width;
2031 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2032 offsetInBits, flags, debugType, Annotations);
2036CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2037 llvm::DIFile *FileScope) {
2041 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2044 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2045 SP = DBuilder.createFunction(
2046 FileScope, FuncName, StringRef(),
2047 FileScope, 0, DIFnTy,
2049 llvm::DINode::FlagArtificial,
2050 llvm::DISubprogram::SPFlagDefinition,
2051 nullptr,
nullptr,
nullptr,
2052 nullptr, StringRef(),
2053 CGM.getCodeGenOpts().DebugKeyInstructions);
2060CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2062 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2064 assert(
Capture.capturesVariable());
2066 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2067 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2069 return CaptureDecl->
getName();
2072void CGDebugInfo::CollectRecordLambdaFields(
2073 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2074 llvm::DIType *RecordTy) {
2079 unsigned fieldno = 0;
2082 I != E; ++I, ++Field, ++fieldno) {
2083 const LambdaCapture &
Capture = *I;
2085 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2087 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2097 Loc =
Field->getLocation();
2098 }
else if (
Capture.capturesVariable()) {
2101 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2102 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2109 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2111 elements.push_back(createFieldType(
2113 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2119template <
typename T>
2120static llvm::Constant *
2131 return llvm::ConstantDataArray::get(Ctx, Vals);
2144 const QualType ElemQTy = ArrayTy->getElementType();
2151 switch (ElemBitWidth) {
2167llvm::DIDerivedType *
2168CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2169 const RecordDecl *RD) {
2173 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2174 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2176 unsigned LineNumber = getLineNumber(Var->
getLocation());
2177 StringRef VName = Var->
getName();
2181 llvm::Constant *
C =
nullptr;
2186 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2187 if (
Value->isFloat())
2188 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2189 if (
Value->isArray())
2195 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2196 ? llvm::dwarf::DW_TAG_variable
2197 : llvm::dwarf::DW_TAG_member;
2199 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2200 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2205void CGDebugInfo::CollectRecordNormalField(
2206 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2207 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2208 const RecordDecl *RD) {
2213 if (
name.empty() && !
type->isRecordType())
2216 llvm::DIType *FieldType;
2218 llvm::DIDerivedType *BitFieldType;
2219 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2220 if (llvm::DIType *Separator =
2221 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2222 elements.push_back(Separator);
2225 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2228 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2231 elements.push_back(FieldType);
2234void CGDebugInfo::CollectRecordNestedType(
2235 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2236 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2243 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2244 elements.push_back(nestedType);
2247void CGDebugInfo::CollectRecordFields(
2248 const RecordDecl *record, llvm::DIFile *tunit,
2249 SmallVectorImpl<llvm::Metadata *> &elements,
2250 llvm::DICompositeType *RecordTy) {
2251 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2253 if (CXXDecl && CXXDecl->
isLambda())
2254 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2256 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2259 unsigned fieldNo = 0;
2263 for (
const auto *I : record->
decls())
2264 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2265 if (
V->hasAttr<NoDebugAttr>())
2270 if (CGM.getCodeGenOpts().EmitCodeView &&
2278 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2279 if (MI != StaticDataMemberCache.end()) {
2280 assert(MI->second &&
2281 "Static data member declaration should still exist");
2282 elements.push_back(MI->second);
2284 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2285 elements.push_back(Field);
2287 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2288 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2289 elements, RecordTy, record);
2293 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2296 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2301 if (!nestedType->isImplicit() &&
2302 nestedType->getDeclContext() == record)
2303 CollectRecordNestedType(nestedType, elements);
2309llvm::DISubroutineType *
2310CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2311 llvm::DIFile *Unit) {
2312 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2314 return cast_or_null<llvm::DISubroutineType>(
2315 getOrCreateType(QualType(
Func, 0), Unit));
2318 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2319 ThisType =
Method->getThisType();
2321 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2324llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2325 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2326 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2328 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2331llvm::DISubroutineType *
2332CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2333 const FunctionProtoType *
Func,
2334 llvm::DIFile *Unit,
bool SkipFirst) {
2335 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2350 getOrCreateType(CGM.getContext().getFunctionType(
2351 Func->getReturnType(),
Func->getParamTypes(), EPI),
2353 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2354 assert(Args.size() &&
"Invalid number of arguments!");
2356 SmallVector<llvm::Metadata *, 16> Elts;
2359 Elts.push_back(Args[0]);
2361 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2365 if (!HasExplicitObjectParameter) {
2366 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2369 DBuilder.createObjectPointerType(ThisPtrType,
true);
2370 Elts.push_back(ThisPtrType);
2374 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2375 Elts.push_back(Args[i]);
2378 if (HasExplicitObjectParameter) {
2379 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2380 "Expected at least return type and object parameter.");
2381 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2384 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2386 return DBuilder.createSubroutineType(
2387 EltTypeArray, OriginalFunc->getFlags(),
2394 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2402CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2405 const bool IsCtorOrDtor =
2408 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2415 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2418 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2421 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2424 return CGM.getMangledName(
Method);
2427bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2430 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2433llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2434 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2437 StringRef MethodName = getFunctionName(
Method);
2438 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2440 StringRef MethodLinkageName;
2447 MethodLinkageName = GetMethodLinkageName(
Method);
2450 llvm::DIFile *MethodDefUnit =
nullptr;
2451 unsigned MethodLine = 0;
2452 if (!
Method->isImplicit()) {
2453 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2454 MethodLine = getLineNumber(
Method->getLocation());
2458 llvm::DIType *ContainingType =
nullptr;
2459 unsigned VIndex = 0;
2460 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2461 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2462 int ThisAdjustment = 0;
2465 if (
Method->isPureVirtual())
2466 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2468 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2470 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2474 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2478 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2481 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2482 CGM.getContext().getLangOpts())
2486 MethodVFTableLocation ML =
2487 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2495 if (
Method->size_overridden_methods() == 0)
2496 Flags |= llvm::DINode::FlagIntroducedVirtual;
2501 ThisAdjustment = CGM.getCXXABI()
2502 .getVirtualFunctionPrologueThisAdjustment(GD)
2505 ContainingType = RecordTy;
2508 if (
Method->getCanonicalDecl()->isDeleted())
2509 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2511 if (
Method->isNoReturn())
2512 Flags |= llvm::DINode::FlagNoReturn;
2515 Flags |= llvm::DINode::FlagStaticMember;
2516 if (
Method->isImplicit())
2517 Flags |= llvm::DINode::FlagArtificial;
2519 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2520 if (CXXC->isExplicit())
2521 Flags |= llvm::DINode::FlagExplicit;
2522 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2523 if (CXXC->isExplicit())
2524 Flags |= llvm::DINode::FlagExplicit;
2526 if (
Method->hasPrototype())
2527 Flags |= llvm::DINode::FlagPrototyped;
2529 Flags |= llvm::DINode::FlagLValueReference;
2531 Flags |= llvm::DINode::FlagRValueReference;
2532 if (!
Method->isExternallyVisible())
2533 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2534 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2535 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2539 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2540 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2543 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2544 llvm::DISubprogram *SP = DBuilder.createMethod(
2545 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2546 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2547 TParamsArray.get(),
nullptr,
2548 CGM.getCodeGenOpts().DebugKeyInstructions);
2550 SPCache[
Method->getCanonicalDecl()].reset(SP);
2555void CGDebugInfo::CollectCXXMemberFunctions(
2556 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2557 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2562 for (
const auto *I : RD->
decls()) {
2563 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2577 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2586 auto MI = SPCache.find(
Method->getCanonicalDecl());
2587 EltTys.push_back(MI == SPCache.end()
2588 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2589 :
static_cast<llvm::Metadata *
>(MI->second));
2593void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2594 SmallVectorImpl<llvm::Metadata *> &EltTys,
2595 llvm::DIType *RecordTy) {
2596 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2597 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2598 llvm::DINode::FlagZero);
2602 if (CGM.getCodeGenOpts().EmitCodeView) {
2603 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2604 llvm::DINode::FlagIndirectVirtualBase);
2608void CGDebugInfo::CollectCXXBasesAux(
2609 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2610 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2612 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2613 llvm::DINode::DIFlags StartingFlags) {
2614 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2615 for (
const auto &BI : Bases) {
2618 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2620 if (!SeenTypes.insert(Base).second)
2622 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2623 llvm::DINode::DIFlags BFlags = StartingFlags;
2627 if (BI.isVirtual()) {
2628 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2631 BaseOffset = 0 - CGM.getItaniumVTableContext()
2632 .getVirtualBaseOffsetOffset(RD, Base)
2638 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2639 VBPtrOffset = CGM.getContext()
2640 .getASTRecordLayout(RD)
2644 BFlags |= llvm::DINode::FlagVirtual;
2651 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2652 VBPtrOffset, BFlags);
2653 EltTys.push_back(DTy);
2658CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2659 llvm::DIFile *Unit) {
2661 return llvm::DINodeArray();
2662 TemplateArgs &Args = *OArgs;
2663 SmallVector<llvm::Metadata *, 16> TemplateParams;
2664 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2665 const TemplateArgument &TA = Args.Args[i];
2669 Name = Args.TList->getParam(i)->getName();
2673 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2674 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2675 TheCU, Name, TTy, defaultParameter));
2680 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2681 TheCU, Name, TTy, defaultParameter,
2682 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2687 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2688 llvm::Constant *
V =
nullptr;
2691 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2692 !D->
hasAttr<CUDADeviceAttr>()) {
2695 if (
const auto *VD = dyn_cast<VarDecl>(D))
2696 V = CGM.GetAddrOfGlobalVar(VD);
2699 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2700 MD && MD->isImplicitObjectMemberFunction())
2701 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2702 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2703 V = CGM.GetAddrOfFunction(FD);
2706 else if (
const auto *MPT =
2707 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2711 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2713 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2714 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2715 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2716 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2717 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2719 V = ConstantEmitter(CGM).emitAbstract(
2720 SourceLocation(), TPO->getValue(), TPO->getType());
2722 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2724 assert(
V &&
"Failed to find template parameter pointer");
2725 V =
V->stripPointerCasts();
2727 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2728 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2732 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2733 llvm::Constant *
V =
nullptr;
2736 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2742 if (MPT->isMemberDataPointer())
2743 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2745 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2746 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2747 TheCU, Name, TTy, defaultParameter,
V));
2751 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2752 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2754 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2755 TheCU, Name, TTy, defaultParameter,
V));
2758 std::string QualName;
2759 llvm::raw_string_ostream
OS(QualName);
2761 OS, getPrintingPolicy());
2762 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2763 TheCU, Name,
nullptr, QualName, defaultParameter));
2767 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2768 TheCU, Name,
nullptr,
2775 T = CGM.getContext().getLValueReferenceType(
T);
2776 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2777 assert(
V &&
"Expression in template argument isn't constant");
2778 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2779 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2780 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2786 "These argument types shouldn't exist in concrete types");
2789 return DBuilder.getOrCreateArray(TemplateParams);
2792std::optional<CGDebugInfo::TemplateArgs>
2793CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2801 return std::nullopt;
2803std::optional<CGDebugInfo::TemplateArgs>
2804CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2808 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2810 return std::nullopt;
2811 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2812 const TemplateParameterList *TList =
T->getTemplateParameters();
2813 auto TA = TS->getTemplateArgs().asArray();
2814 return {{TList, TA}};
2816std::optional<CGDebugInfo::TemplateArgs>
2817CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2818 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2822 TemplateParameterList *TPList =
2823 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2824 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2825 return {{TPList, TAList.
asArray()}};
2827 return std::nullopt;
2831CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2832 llvm::DIFile *Unit) {
2833 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2836llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2837 llvm::DIFile *Unit) {
2838 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2841llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2842 llvm::DIFile *Unit) {
2843 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2846void CGDebugInfo::CollectBTFDeclTagAnnotations(
2847 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2849 llvm::Metadata *Ops[2] = {
2850 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2851 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2852 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2856llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2857 if (!D->
hasAttr<BTFDeclTagAttr>())
2860 SmallVector<llvm::Metadata *, 4> Annotations;
2861 CollectBTFDeclTagAnnotations(D, Annotations);
2862 return DBuilder.getOrCreateArray(Annotations);
2865void CGDebugInfo::CollectBTFTypeTagAnnotations(
2866 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2867 const BTFTagAttributedType *BTFAttrTy;
2869 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2871 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2874 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2876 llvm::Metadata *Ops[2] = {
2877 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2878 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2879 Annotations.insert(Annotations.begin(),
2880 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2882 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2886llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2888 return VTablePtrType;
2890 ASTContext &Context = CGM.getContext();
2893 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2894 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2895 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2897 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2898 std::optional<unsigned> DWARFAddressSpace =
2899 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2901 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2902 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2903 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2904 return VTablePtrType;
2907StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2919 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2921 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2931 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2932 VTable->isDeclarationForLinker())
2936 StringRef SymbolName =
"__clang_vtable";
2938 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2947 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2949 llvm::DIFile *Unit = getOrCreateFile(Loc);
2950 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2952 llvm::DINode::FlagArtificial;
2953 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2954 ? llvm::dwarf::DW_TAG_variable
2955 : llvm::dwarf::DW_TAG_member;
2956 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2957 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2961 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2965 llvm::DIGlobalVariableExpression *GVE =
2966 DBuilder.createGlobalVariableExpression(
2967 TheCU, SymbolName, VTable->getName(), Unit, 0,
2968 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2969 true,
nullptr, DT,
nullptr,
2971 VTable->addDebugInfo(GVE);
2974StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2976 llvm::Function *InitFn) {
2981 return InitFn->getName();
2991 llvm::raw_svector_ostream OS(QualifiedGV);
2993 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2995 std::swap(Quals, GVName);
2999 llvm::raw_svector_ostream OS(InitName);
3001 OS << Quals <<
"::";
3006 llvm_unreachable(
"not an initializer");
3008 OS <<
"`dynamic initializer for '";
3011 OS <<
"`dynamic atexit destructor for '";
3018 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3019 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3020 getPrintingPolicy());
3025 return internString(
OS.str());
3028void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3029 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3038 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3045 llvm::DIType *VPtrTy =
nullptr;
3046 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3047 CGM.getTarget().getCXXABI().isMicrosoft();
3048 if (NeedVTableShape) {
3050 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3051 const VTableLayout &VFTLayout =
3052 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3053 unsigned VSlotCount =
3055 unsigned VTableWidth = PtrWidth * VSlotCount;
3056 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3057 std::optional<unsigned> DWARFAddressSpace =
3058 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3061 llvm::DIType *VTableType = DBuilder.createPointerType(
3062 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3063 EltTys.push_back(VTableType);
3066 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3074 VPtrTy = getOrCreateVTablePtrType(Unit);
3076 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3077 llvm::DIType *VPtrMember =
3078 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3079 llvm::DINode::FlagArtificial, VPtrTy);
3080 EltTys.push_back(VPtrMember);
3085 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3086 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
3097 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3098 assert(!D.
isNull() &&
"null type");
3099 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3100 assert(
T &&
"could not create debug info for type");
3109 if (CGM.getCodeGenOpts().getDebugInfo() <=
3110 llvm::codegenoptions::DebugLineTablesOnly)
3114 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3116 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3118 CI->setMetadata(
"heapallocsite", node);
3122 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3124 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3126 auto I = TypeCache.find(TyPtr);
3129 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3130 assert(!Res->isForwardDecl());
3131 TypeCache[TyPtr].reset(Res);
3135 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3136 !CGM.getLangOpts().CPlusPlus)
3142 if (RD->
hasAttr<DLLImportAttr>())
3145 if (MD->hasAttr<DLLImportAttr>())
3158 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3168 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3169 Explicit = TD->isExplicitInstantiationOrSpecialization();
3173 if (CXXDecl->
fields().empty())
3183 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3184 if (CXXRD->isDynamicClass() &&
3185 CGM.getVTableLinkage(CXXRD) ==
3186 llvm::GlobalValue::AvailableExternallyLinkage &&
3197 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3199 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3201 auto I = TypeCache.find(TyPtr);
3208 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3209 assert(!Res->isForwardDecl());
3210 TypeCache[TyPtr].reset(Res);
3217 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3218 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3241 if (Ctor->isCopyOrMoveConstructor())
3243 if (!Ctor->isDeleted())
3262 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3265 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3266 RD->
hasAttr<StandaloneDebugAttr>())
3269 if (!LangOpts.CPlusPlus)
3275 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3291 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3292 Spec = SD->getSpecializationKind();
3301 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3312 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3313 llvm::DIType *
T = getTypeOrNull(Ty);
3314 if (
T &&
T->isForwardDecl())
3318llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3320 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3324 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3328 auto [Def, Pref] = CreateTypeDefinition(Ty);
3330 return Pref ? Pref : Def;
3333llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3334 llvm::DIFile *Unit) {
3338 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3342 return getOrCreateType(PNA->getTypedefType(), Unit);
3345std::pair<llvm::DIType *, llvm::DIType *>
3346CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3350 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3358 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3362 return {FwdDecl,
nullptr};
3364 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3365 CollectContainingType(CXXDecl, FwdDecl);
3368 LexicalBlockStack.emplace_back(&*FwdDecl);
3369 RegionMap[RD].reset(FwdDecl);
3372 SmallVector<llvm::Metadata *, 16> EltTys;
3379 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3381 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3382 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3386 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3387 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3388 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3390 LexicalBlockStack.pop_back();
3391 RegionMap.erase(RD);
3393 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3394 DBuilder.replaceArrays(FwdDecl, Elements);
3396 if (FwdDecl->isTemporary())
3398 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3400 RegionMap[RD].reset(FwdDecl);
3402 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3403 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3404 return {FwdDecl, PrefDI};
3406 return {FwdDecl,
nullptr};
3409llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3410 llvm::DIFile *Unit) {
3412 return getOrCreateType(Ty->getBaseType(), Unit);
3415llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3416 llvm::DIFile *Unit) {
3418 SourceLocation Loc = Ty->getDecl()->getLocation();
3421 return DBuilder.createTypedef(
3422 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3423 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3424 getDeclContextDescriptor(Ty->getDecl()));
3451llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3452 llvm::DIFile *Unit) {
3457 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3458 TheCU->getSourceLanguage().getUnversionedName());
3463 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3464 !
ID->getImplementation())
3465 return DBuilder.createForwardDecl(
3466 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3467 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3470 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3471 unsigned Line = getLineNumber(
ID->getLocation());
3475 ObjCInterfaceDecl *Def =
ID->getDefinition();
3477 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3478 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3479 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3480 DefUnit,
Line, RuntimeLang);
3481 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3485 return CreateTypeDefinition(Ty, Unit);
3488llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3489 bool CreateSkeletonCU) {
3494 auto ModRef = ModuleCache.find(M);
3495 if (ModRef != ModuleCache.end())
3499 SmallString<128> ConfigMacros;
3501 llvm::raw_svector_ostream
OS(ConfigMacros);
3502 const auto &PPOpts = CGM.getPreprocessorOpts();
3505 for (
auto &M : PPOpts.Macros) {
3508 const std::string &
Macro = M.first;
3509 bool Undef = M.second;
3510 OS <<
"\"-" << (Undef ?
'U' :
'D');
3511 for (
char c :
Macro)
3526 bool IsRootModule = M ? !M->
Parent :
true;
3530 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3531 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3532 "clang module without ASTFile must be specified by -fmodule-name");
3535 auto RemapPath = [
this](StringRef Path) -> std::string {
3537 StringRef Relative(Remapped);
3538 StringRef CompDir = TheCU->getDirectory();
3539 if (CompDir.empty())
3542 if (Relative.consume_front(CompDir))
3543 Relative.consume_front(llvm::sys::path::get_separator());
3545 return Relative.str();
3548 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3555 Signature = ModSig.truncatedValue();
3559 llvm::DIBuilder DIB(CGM.getModule());
3561 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3562 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3563 PCM = getCurrentDirname();
3567 llvm::sys::path::append(PCM, Mod.
getASTFile());
3568 DIB.createCompileUnit(
3569 TheCU->getSourceLanguage(),
3572 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3573 llvm::DICompileUnit::FullDebug, Signature);
3577 llvm::DIModule *Parent =
3579 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3581 StringRef IncludePath = Mod.
getPath();
3582 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3583 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3584 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3587 llvm::DIModule *DIMod =
3588 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3589 RemapPath(IncludePath));
3590 ModuleCache[M].reset(DIMod);
3594llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3595 llvm::DIFile *Unit) {
3597 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3598 unsigned Line = getLineNumber(
ID->getLocation());
3600 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3606 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3607 if (
ID->getImplementation())
3608 Flags |= llvm::DINode::FlagObjcClassComplete;
3610 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3611 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3612 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3613 nullptr, llvm::DINodeArray(), RuntimeLang);
3615 QualType QTy(Ty, 0);
3616 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3619 LexicalBlockStack.emplace_back(RealDecl);
3620 RegionMap[Ty->
getDecl()].reset(RealDecl);
3623 SmallVector<llvm::Metadata *, 16> EltTys;
3625 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3627 llvm::DIType *SClassTy =
3628 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3632 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3633 llvm::DINode::FlagZero);
3634 EltTys.push_back(InhTag);
3638 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3639 SourceLocation Loc = PD->getLocation();
3640 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3641 unsigned PLine = getLineNumber(Loc);
3642 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3643 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3644 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3645 PD->getName(), PUnit, PLine,
3647 : getSelectorName(PD->getGetterName()),
3649 : getSelectorName(PD->getSetterName()),
3650 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3651 EltTys.push_back(PropertyNode);
3656 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3660 llvm::DenseSet<IsClassAndIdent> PropertySet;
3662 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3663 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3665 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3666 for (
auto *PD : ClassExt->properties()) {
3667 PropertySet.insert(GetIsClassAndIdent(PD));
3670 for (
const auto *PD :
ID->properties()) {
3673 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3679 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3680 unsigned FieldNo = 0;
3681 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3682 Field =
Field->getNextIvar(), ++FieldNo) {
3683 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3687 StringRef FieldName =
Field->getName();
3690 if (FieldName.empty())
3694 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3695 unsigned FieldLine = getLineNumber(
Field->getLocation());
3696 QualType FType =
Field->getType();
3703 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3704 : CGM.getContext().getTypeSize(FType);
3709 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3713 if (
Field->isBitField()) {
3715 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3716 FieldOffset %= CGM.getContext().getCharWidth();
3724 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3726 Flags = llvm::DINode::FlagProtected;
3728 Flags = llvm::DINode::FlagPrivate;
3730 Flags = llvm::DINode::FlagPublic;
3732 if (
Field->isBitField())
3733 Flags |= llvm::DINode::FlagBitField;
3735 llvm::MDNode *PropertyNode =
nullptr;
3736 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3737 if (ObjCPropertyImplDecl *PImpD =
3738 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3739 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3740 SourceLocation Loc = PD->getLocation();
3741 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3742 unsigned PLine = getLineNumber(Loc);
3743 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3744 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3745 PropertyNode = DBuilder.createObjCProperty(
3746 PD->getName(), PUnit, PLine,
3749 : getSelectorName(PD->getGetterName()),
3752 : getSelectorName(PD->getSetterName()),
3753 PD->getPropertyAttributes(),
3754 getOrCreateType(PD->getType(), PUnit));
3758 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3759 FieldSize, FieldAlign, FieldOffset, Flags,
3760 FieldTy, PropertyNode);
3761 EltTys.push_back(FieldTy);
3764 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3765 DBuilder.replaceArrays(RealDecl, Elements);
3767 LexicalBlockStack.pop_back();
3771llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3772 llvm::DIFile *Unit) {
3780 auto &Ctx = CGM.getContext();
3785 QualType CharVecTy =
3787 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3790 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3793 llvm::Metadata *Subscript;
3794 QualType QTy(Ty, 0);
3795 auto SizeExpr = SizeExprCache.find(QTy);
3796 if (SizeExpr != SizeExprCache.end())
3797 Subscript = DBuilder.getOrCreateSubrange(
3798 SizeExpr->getSecond() ,
nullptr ,
3799 nullptr ,
nullptr );
3802 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3803 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3804 Subscript = DBuilder.getOrCreateSubrange(
3805 CountNode ,
nullptr ,
nullptr ,
3808 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3813 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3816llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3817 llvm::DIFile *Unit) {
3821 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3826 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3827 auto *ColumnCountNode =
3828 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3829 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3830 auto *RowCountNode =
3831 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3832 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3833 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3834 ColumnCountNode ,
nullptr ,
nullptr ,
3836 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3837 RowCountNode ,
nullptr ,
nullptr ,
3839 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3840 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3843llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3848 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3863 Size = CGM.getContext().getTypeSize(Ty);
3870 SmallVector<llvm::Metadata *, 8> Subscripts;
3871 QualType EltTy(Ty, 0);
3872 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3881 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3882 Count = CAT->getZExtSize();
3883 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3884 if (Expr *Size = VAT->getSizeExpr()) {
3886 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3887 Count =
Result.Val.getInt().getExtValue();
3891 auto SizeNode = SizeExprCache.find(EltTy);
3892 if (SizeNode != SizeExprCache.end())
3893 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3894 SizeNode->getSecond() ,
nullptr ,
3895 nullptr ,
nullptr ));
3898 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3899 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3900 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3901 CountNode ,
nullptr ,
nullptr ,
3907 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3909 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3913llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3914 llvm::DIFile *Unit) {
3915 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3919llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3920 llvm::DIFile *Unit) {
3921 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3923 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3924 CGM.getCodeGenOpts().DwarfVersion < 4)
3925 Tag = llvm::dwarf::DW_TAG_reference_type;
3927 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3930llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3932 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3936 Size = CGM.getContext().getTypeSize(Ty);
3939 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3942 Flags |= llvm::DINode::FlagSingleInheritance;
3945 Flags |= llvm::DINode::FlagMultipleInheritance;
3948 Flags |= llvm::DINode::FlagVirtualInheritance;
3958 llvm::DIType *ClassType = getOrCreateType(
T, U);
3960 return DBuilder.createMemberPointerType(
3964 const FunctionProtoType *FPT =
3966 return DBuilder.createMemberPointerType(
3967 getOrCreateInstanceMethodType(
3970 ClassType, Size, 0, Flags);
3973llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3975 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3978llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3982llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3984 return getOrCreateType(Ty->getWrappedType(), U);
3987llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3994 const EnumType *Ty) {
4006llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4009 bool isImportedFromModule =
4010 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4014 if (isImportedFromModule || !ED->getDefinition()) {
4021 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4022 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4023 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4024 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4026 unsigned Line = getLineNumber(ED->getLocation());
4027 StringRef EDName = ED->getName();
4028 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4029 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4030 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4032 ReplaceMap.emplace_back(
4033 std::piecewise_construct, std::make_tuple(Ty),
4034 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4038 return CreateTypeDefinition(Ty);
4041llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4044 SmallVector<llvm::Metadata *, 16> Enumerators;
4045 ED = ED->getDefinition();
4046 assert(ED &&
"An enumeration definition is required");
4047 for (
const auto *
Enum : ED->enumerators()) {
4048 Enumerators.push_back(
4049 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4052 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4053 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4054 EnumKind = Attr->getExtensibility();
4057 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4059 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4060 unsigned Line = getLineNumber(ED->getLocation());
4061 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4062 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4063 return DBuilder.createEnumerationType(
4064 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4065 0, Identifier, ED->isScoped(), EnumKind);
4070 StringRef Name, StringRef
Value) {
4071 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4072 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4078 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4079 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4080 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4085 llvm::DISubprogram *SynthSubprogram) {
4086 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4087 SynthSubprogram, ParentLocation);
4092 StringRef SynthFuncName,
4093 llvm::DIFile *SynthFile) {
4094 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4099 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4105 FuncName += Category;
4107 FuncName += FailureMsg;
4110 TrapLocation->getFile());
4120 Quals += InnerQuals;
4122 switch (
T->getTypeClass()) {
4124 return C.getQualifiedType(
T.getTypePtr(), Quals);
4127 case Type::InjectedClassName:
4128 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4130 case Type::TemplateSpecialization: {
4132 if (Spec->isTypeAlias())
4133 return C.getQualifiedType(
T.getTypePtr(), Quals);
4134 T = Spec->desugar();
4137 case Type::TypeOfExpr:
4143 case Type::Decltype:
4146 case Type::UnaryTransform:
4149 case Type::Attributed:
4152 case Type::BTFTagAttributed:
4155 case Type::CountAttributed:
4164 case Type::MacroQualified:
4167 case Type::SubstTemplateTypeParm:
4171 case Type::DeducedTemplateSpecialization: {
4173 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4177 case Type::PackIndexing: {
4181 case Type::Adjusted:
4188 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4193llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4196 if (It != TypeCache.end()) {
4198 if (llvm::Metadata *
V = It->second)
4211 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4218 RetainedTypes.push_back(
4219 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4222llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4226 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4228 llvm::raw_string_ostream OS(Name);
4229 Ty.
print(OS, getPrintingPolicy());
4236 if (
auto *
T = getTypeOrNull(Ty))
4239 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4240 void *TyPtr = Ty.getAsOpaquePtr();
4243 TypeCache[TyPtr].reset(Res);
4248llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4256 auto Info = Reader->getSourceDescriptor(Idx);
4258 return getOrCreateModuleRef(*Info,
true);
4259 }
else if (ClangModuleMap) {
4272 auto Info = ASTSourceDescriptor(*M);
4273 return getOrCreateModuleRef(Info,
false);
4276 return getOrCreateModuleRef(PCHDescriptor,
false);
4283llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4286 return CreateQualifiedType(Ty, Unit);
4290#define TYPE(Class, Base)
4291#define ABSTRACT_TYPE(Class, Base)
4292#define NON_CANONICAL_TYPE(Class, Base)
4293#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4294#include "clang/AST/TypeNodes.inc"
4295 llvm_unreachable(
"Dependent types cannot show up in debug information");
4297 case Type::ExtVector:
4300 case Type::ConstantMatrix:
4302 case Type::ObjCObjectPointer:
4304 case Type::ObjCObject:
4306 case Type::ObjCTypeParam:
4308 case Type::ObjCInterface:
4316 case Type::BlockPointer:
4324 case Type::FunctionProto:
4325 case Type::FunctionNoProto:
4327 case Type::ConstantArray:
4328 case Type::VariableArray:
4329 case Type::IncompleteArray:
4330 case Type::ArrayParameter:
4333 case Type::LValueReference:
4335 case Type::RValueReference:
4338 case Type::MemberPointer:
4346 case Type::OverflowBehavior:
4351 case Type::TemplateSpecialization:
4353 case Type::HLSLAttributedResource:
4355 case Type::HLSLInlineSpirv:
4357 case Type::PredefinedSugar:
4359 case Type::CountAttributed:
4360 case Type::LateParsedAttr:
4362 case Type::Attributed:
4363 case Type::BTFTagAttributed:
4364 case Type::Adjusted:
4366 case Type::DeducedTemplateSpecialization:
4369 case Type::MacroQualified:
4370 case Type::SubstTemplateTypeParm:
4371 case Type::TypeOfExpr:
4373 case Type::Decltype:
4374 case Type::PackIndexing:
4375 case Type::UnaryTransform:
4379 llvm_unreachable(
"type should have been unwrapped!");
4382llvm::DICompositeType *
4383CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4384 QualType QTy(Ty, 0);
4386 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4391 if (
T && !
T->isForwardDecl())
4395 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4400 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4403 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4408llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4410 bool NameIsSimplified =
false;
4413 StringRef RDName = getClassName(RD, &NameIsSimplified);
4415 llvm::DIFile *DefUnit =
nullptr;
4418 DefUnit = getOrCreateFile(Loc);
4419 Line = getLineNumber(Loc);
4422 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4426 auto *
T = cast_or_null<llvm::DICompositeType>(
4427 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4435 return getOrCreateRecordFwdDecl(Ty, RDContext);
4448 auto Flags = llvm::DINode::FlagZero;
4449 if (NameIsSimplified)
4450 Flags |= llvm::DINode::FlagNameIsSimplified;
4451 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4453 Flags |= llvm::DINode::FlagTypePassByReference;
4455 Flags |= llvm::DINode::FlagTypePassByValue;
4458 if (!CXXRD->isTrivial())
4459 Flags |= llvm::DINode::FlagNonTrivial;
4462 if (CXXRD->isAnonymousStructOrUnion())
4463 Flags |= llvm::DINode::FlagExportSymbols;
4466 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4469 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4470 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4472 Flags, Identifier, Annotations);
4476 switch (RealDecl->getTag()) {
4478 llvm_unreachable(
"invalid composite type tag");
4480 case llvm::dwarf::DW_TAG_array_type:
4481 case llvm::dwarf::DW_TAG_enumeration_type:
4486 if (Identifier.empty())
4490 case llvm::dwarf::DW_TAG_structure_type:
4491 case llvm::dwarf::DW_TAG_union_type:
4492 case llvm::dwarf::DW_TAG_class_type:
4495 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4499 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4500 CXXRecordDecl *TemplateDecl =
4501 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4502 RegionMap[TemplateDecl].reset(RealDecl);
4504 RegionMap[RD].reset(RealDecl);
4506 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4508 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4509 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4510 CollectCXXTemplateParams(TSpecial, DefUnit));
4514void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4515 llvm::DICompositeType *RealDecl) {
4517 llvm::DIType *ContainingType =
nullptr;
4518 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4522 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4529 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4530 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4532 ContainingType = RealDecl;
4534 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4537llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4538 StringRef Name, uint64_t *Offset) {
4539 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4540 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4543 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4544 *Offset, llvm::DINode::FlagZero, FieldTy);
4545 *Offset += FieldSize;
4549void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4551 StringRef &LinkageName,
4552 llvm::DIScope *&FDContext,
4553 llvm::DINodeArray &TParamsArray,
4554 llvm::DINode::DIFlags &Flags) {
4556 bool NameIsSimplified =
false;
4557 Name = getFunctionName(FD, &NameIsSimplified);
4558 if (NameIsSimplified)
4559 Flags |= llvm::DINode::FlagNameIsSimplified;
4560 Name = getFunctionName(FD);
4563 LinkageName = CGM.getMangledName(GD);
4565 Flags |= llvm::DINode::FlagPrototyped;
4569 if (LinkageName == Name ||
4570 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4571 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4572 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4573 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4574 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4575 LinkageName = StringRef();
4579 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4580 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4581 CGM.getCodeGenOpts().EmitCodeView)) {
4582 if (
const NamespaceDecl *NSDecl =
4584 FDContext = getOrCreateNamespace(NSDecl);
4585 else if (
const RecordDecl *RDecl =
4587 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4588 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4591 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4594 Flags |= llvm::DINode::FlagNoReturn;
4596 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4600void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4601 unsigned &LineNo, QualType &
T,
4602 StringRef &Name, StringRef &LinkageName,
4603 llvm::MDTuple *&TemplateParameters,
4604 llvm::DIScope *&VDContext) {
4613 llvm::APInt ConstVal(32, 1);
4614 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4616 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4623 LinkageName = CGM.getMangledName(VD);
4624 if (LinkageName == Name)
4625 LinkageName = StringRef();
4628 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4629 TemplateParameters = parameterNodes.get();
4631 TemplateParameters =
nullptr;
4637 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4638 VDContext = LexicalBlockStack.back();
4657 DC = CGM.getContext().getTranslationUnitDecl();
4659 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4660 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4663llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4665 llvm::DINodeArray TParamsArray;
4666 StringRef Name, LinkageName;
4667 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4668 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4670 llvm::DIFile *Unit = getOrCreateFile(Loc);
4671 llvm::DIScope *DContext = Unit;
4672 unsigned Line = getLineNumber(Loc);
4673 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4678 SmallVector<QualType, 16> ArgTypes;
4679 for (
const ParmVarDecl *Parm : FD->
parameters())
4680 ArgTypes.push_back(Parm->getType());
4683 QualType FnType = CGM.getContext().getFunctionType(
4684 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4686 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4687 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4688 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4692 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4693 return DBuilder.createFunction(
4694 DContext, Name, LinkageName, Unit,
Line,
4695 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4696 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4698 CGM.getCodeGenOpts().DebugKeyInstructions);
4701 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4702 DContext, Name, LinkageName, Unit,
Line,
4703 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4704 TParamsArray.get(), getFunctionDeclaration(FD));
4706 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4707 std::make_tuple(CanonDecl),
4708 std::make_tuple(SP));
4712llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4713 return getFunctionFwdDeclOrStub(GD,
false);
4716llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4717 return getFunctionFwdDeclOrStub(GD,
true);
4720llvm::DIGlobalVariable *
4721CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4723 StringRef Name, LinkageName;
4725 llvm::DIFile *Unit = getOrCreateFile(Loc);
4726 llvm::DIScope *DContext = Unit;
4727 unsigned Line = getLineNumber(Loc);
4728 llvm::MDTuple *TemplateParameters =
nullptr;
4730 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4733 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4734 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4736 FwdDeclReplaceMap.emplace_back(
4737 std::piecewise_construct,
4739 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4743llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4748 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4749 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4750 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4754 if (I != DeclCache.end()) {
4756 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4757 return GVE->getVariable();
4765 if (IE != ImportedDeclCache.end()) {
4766 auto N = IE->second;
4767 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4769 return dyn_cast_or_null<llvm::DINode>(N);
4774 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4775 return getFunctionForwardDeclaration(FD);
4776 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4777 return getGlobalVariableForwardDeclaration(VD);
4782llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4783 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4786 const auto *FD = dyn_cast<FunctionDecl>(D);
4791 auto *S = getDeclContextDescriptor(D);
4794 if (MI == SPCache.end()) {
4796 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4800 if (MI != SPCache.end()) {
4801 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4802 if (SP && !SP->isDefinition())
4806 for (
auto *NextFD : FD->
redecls()) {
4807 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4808 if (MI != SPCache.end()) {
4809 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4810 if (SP && !SP->isDefinition())
4817llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4818 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4819 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4820 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4823 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4827 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4831 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4840 QualType QTy(
ID->getTypeForDecl(), 0);
4841 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4842 if (It == TypeCache.end())
4845 llvm::DISubprogram *FD = DBuilder.createFunction(
4846 InterfaceType, getObjCMethodName(OMD), StringRef(),
4847 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4848 DBuilder.finalizeSubprogram(FD);
4855llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4860 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4861 !CGM.getCodeGenOpts().EmitCodeView))
4864 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4866 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4869 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4872 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4873 return getOrCreateMethodType(
Method, F);
4875 const auto *FTy = FnType->
getAs<FunctionType>();
4878 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4880 SmallVector<llvm::Metadata *, 16> Elts;
4883 QualType ResultTy = OMethod->getReturnType();
4886 if (ResultTy == CGM.getContext().getObjCInstanceType())
4887 ResultTy = CGM.getContext().getPointerType(
4888 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4890 Elts.push_back(getOrCreateType(ResultTy, F));
4892 QualType SelfDeclTy;
4893 if (
auto *SelfDecl = OMethod->getSelfDecl())
4894 SelfDeclTy = SelfDecl->getType();
4895 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4898 if (!SelfDeclTy.
isNull())
4900 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4902 Elts.push_back(DBuilder.createArtificialType(
4903 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4905 for (
const auto *PI : OMethod->parameters())
4906 Elts.push_back(getOrCreateType(PI->getType(), F));
4908 if (OMethod->isVariadic())
4909 Elts.push_back(DBuilder.createUnspecifiedParameter());
4911 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4912 return DBuilder.createSubroutineType(
4913 EltTypeArray, llvm::DINode::FlagZero,
4914 getDwarfCC(CC, CGM.getTarget().getTriple()));
4919 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4920 if (FD->isVariadic()) {
4921 SmallVector<llvm::Metadata *, 16> EltTys;
4922 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4923 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4925 EltTys.push_back(getOrCreateType(ParamType, F));
4926 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4927 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4928 return DBuilder.createSubroutineType(
4929 EltTypeArray, llvm::DINode::FlagZero,
4930 getDwarfCC(CC, CGM.getTarget().getTriple()));
4942 CC = SrcFnTy->getCallConv();
4944 for (
const VarDecl *VD : Args)
4945 ArgTypes.push_back(VD->
getType());
4946 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4952 llvm::Function *Fn,
bool CurFuncIsThunk) {
4954 StringRef LinkageName;
4956 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4959 bool HasDecl = (D !=
nullptr);
4961 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4962 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4963 llvm::DIFile *Unit = getOrCreateFile(Loc);
4964 llvm::DIScope *FDContext = Unit;
4965 llvm::DINodeArray TParamsArray;
4966 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4969 LinkageName = Fn->getName();
4970 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4972 auto FI = SPCache.find(FD->getCanonicalDecl());
4973 if (FI != SPCache.end()) {
4974 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4975 if (SP && SP->isDefinition()) {
4976 LexicalBlockStack.emplace_back(SP);
4977 RegionMap[D].reset(SP);
4981 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4982 TParamsArray, Flags);
4985 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4986 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4987 Name = getObjCMethodName(OMD);
4988 Flags |= llvm::DINode::FlagPrototyped;
4994 if (Name != Fn->getName())
4995 LinkageName = Fn->getName();
4997 Name = Fn->getName();
5002 Flags |= llvm::DINode::FlagPrototyped;
5004 Name.consume_front(
"\01");
5008 "Unexpected DynamicInitKind !");
5012 Flags |= llvm::DINode::FlagArtificial;
5018 Flags |= llvm::DINode::FlagThunk;
5020 if (Fn->hasLocalLinkage())
5021 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5022 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5023 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5026 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5027 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5029 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5030 unsigned ScopeLine = getLineNumber(ScopeLoc);
5031 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5032 llvm::DISubprogram *
Decl =
nullptr;
5033 llvm::DINodeArray Annotations =
nullptr;
5036 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5037 : getFunctionDeclaration(D);
5038 Annotations = CollectBTFDeclTagAnnotations(D);
5046 llvm::DISubprogram *SP = DBuilder.createFunction(
5047 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5048 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5049 Annotations,
"", KeyInstructions);
5050 Fn->setSubprogram(SP);
5059 LexicalBlockStack.emplace_back(SP);
5062 RegionMap[D].reset(SP);
5066 QualType FnType, llvm::Function *Fn) {
5068 StringRef LinkageName;
5074 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5075 return GetName(D,
true);
5078 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5079 llvm::DIFile *Unit = getOrCreateFile(Loc);
5080 bool IsDeclForCallSite = Fn ?
true :
false;
5081 llvm::DIScope *FDContext =
5082 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5083 llvm::DINodeArray TParamsArray;
5086 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5087 TParamsArray, Flags);
5088 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5089 Name = getObjCMethodName(OMD);
5090 Flags |= llvm::DINode::FlagPrototyped;
5092 llvm_unreachable(
"not a function or ObjC method");
5094 Name.consume_front(
"\01");
5097 Flags |= llvm::DINode::FlagArtificial;
5102 unsigned LineNo = getLineNumber(Loc);
5103 unsigned ScopeLine = 0;
5104 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5105 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5106 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5108 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5109 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5111 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5112 llvm::DISubprogram *SP = DBuilder.createFunction(
5113 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5114 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5120 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5121 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5122 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5125 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5126 DBuilder.createParameterVariable(
5127 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5128 llvm::DINode::FlagZero, ParamAnnotations);
5134 if (IsDeclForCallSite)
5135 Fn->setSubprogram(SP);
5139 llvm::CallBase *CI) {
5140 if (!shouldGenerateVirtualCallSite())
5146 assert(CI &&
"Invalid Call Instruction.");
5147 if (!CI->isIndirectCall())
5151 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5152 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5160 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5163 if (
Func->getSubprogram())
5167 if (!
Func->isDeclaration())
5191 auto FI = SPCache.find(FD->getCanonicalDecl());
5192 llvm::DISubprogram *SP =
nullptr;
5193 if (FI != SPCache.end())
5194 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5195 if (!SP || !SP->isDefinition())
5196 SP = getFunctionStub(GD);
5197 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5198 LexicalBlockStack.emplace_back(SP);
5204 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5213 if (CurLoc.isInvalid() ||
5214 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5215 LexicalBlockStack.empty())
5218 llvm::MDNode *
Scope = LexicalBlockStack.back();
5219 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5220 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5224 llvm::MDNode *Back =
nullptr;
5225 if (!LexicalBlockStack.empty())
5226 Back = LexicalBlockStack.back().get();
5227 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5229 getColumnNumber(CurLoc)));
5232void CGDebugInfo::AppendAddressSpaceXDeref(
5234 std::optional<unsigned> DWARFAddressSpace =
5236 if (!DWARFAddressSpace)
5239 Expr.push_back(llvm::dwarf::DW_OP_constu);
5240 Expr.push_back(*DWARFAddressSpace);
5241 Expr.push_back(llvm::dwarf::DW_OP_swap);
5242 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5251 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5252 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5253 LexicalBlockStack.back(), CurInlinedAt));
5255 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5259 CreateLexicalBlock(Loc);
5264 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5269 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5272 LexicalBlockStack.pop_back();
5276 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5277 unsigned RCount = FnBeginRegionCount.back();
5278 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5281 while (LexicalBlockStack.size() != RCount) {
5284 LexicalBlockStack.pop_back();
5286 FnBeginRegionCount.pop_back();
5288 if (Fn && Fn->getSubprogram())
5289 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5292CGDebugInfo::BlockByRefType
5293CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5294 uint64_t *XOffset) {
5297 uint64_t FieldSize, FieldOffset;
5298 uint32_t FieldAlign;
5300 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5305 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5306 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5308 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5309 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5312 if (HasCopyAndDispose) {
5315 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5317 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5319 bool HasByrefExtendedLayout;
5322 HasByrefExtendedLayout) &&
5323 HasByrefExtendedLayout) {
5326 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5335 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5338 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5341 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5346 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5347 FieldSize = CGM.getContext().getTypeSize(FType);
5348 FieldAlign = CGM.getContext().toBits(Align);
5350 *XOffset = FieldOffset;
5351 llvm::DIType *FieldTy = DBuilder.createMemberType(
5352 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5353 llvm::DINode::FlagZero, WrappedTy);
5354 EltTys.push_back(FieldTy);
5355 FieldOffset += FieldSize;
5357 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5358 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5359 llvm::DINode::FlagZero,
nullptr, Elements),
5363llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5364 llvm::Value *Storage,
5365 std::optional<unsigned> ArgNo,
5367 const bool UsePointerValue) {
5368 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5369 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5370 if (VD->
hasAttr<NoDebugAttr>())
5375 llvm::DIFile *Unit =
nullptr;
5376 if (!VarIsArtificial)
5380 if (VD->
hasAttr<BlocksAttr>())
5381 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5383 Ty = getOrCreateType(VD->
getType(), Unit);
5393 if (!VarIsArtificial) {
5397 SmallVector<uint64_t, 13> Expr;
5398 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5405 Flags |= llvm::DINode::FlagArtificial;
5409 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5410 AppendAddressSpaceXDeref(AddressSpace, Expr);
5414 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5417 Flags |= llvm::DINode::FlagObjectPointer;
5418 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5419 if (PVD->isExplicitObjectParameter())
5420 Flags |= llvm::DINode::FlagObjectPointer;
5428 StringRef Name = VD->
getName();
5429 if (!Name.empty()) {
5435 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5437 offset = CGM.getContext().toCharUnitsFromBits(
5440 Expr.push_back(llvm::dwarf::DW_OP_deref);
5441 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5443 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5446 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5458 for (
const auto *Field : RD->
fields()) {
5459 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5460 StringRef FieldName =
Field->getName();
5468 auto *D = DBuilder.createAutoVariable(
5469 Scope, FieldName, Unit,
Line, FieldTy,
5470 CGM.getCodeGenOpts().OptimizationLevel != 0,
5471 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5474 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5475 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5478 Builder.GetInsertBlock());
5486 if (UsePointerValue) {
5487 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5488 "Debug info already contains DW_OP_deref.");
5489 Expr.push_back(llvm::dwarf::DW_OP_deref);
5493 llvm::DILocalVariable *D =
nullptr;
5495 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5496 D = DBuilder.createParameterVariable(
5497 Scope, Name, *ArgNo, Unit,
Line, Ty,
5498 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5507 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5513 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5514 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5515 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5516 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5518 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5524 if (Iter != CoroutineParameterMappings.end()) {
5525 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5526 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5527 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5529 if (Iter2 != ParamDbgMappings.end())
5530 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5536 D = RemapCoroArgToLocalVar();
5539 D = DBuilder.createAutoVariable(
5540 Scope, Name, Unit,
Line, Ty,
5541 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5544 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5545 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5546 Column, Scope, CurInlinedAt),
5547 Builder.GetInsertBlock());
5552llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5553 llvm::Value *Storage,
5554 std::optional<unsigned> ArgNo,
5556 const bool UsePointerValue) {
5557 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5558 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5559 if (BD->
hasAttr<NoDebugAttr>())
5566 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5567 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5575 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5577 SmallVector<uint64_t, 3> Expr;
5578 AppendAddressSpaceXDeref(AddressSpace, Expr);
5583 if (UsePointerValue) {
5584 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5585 "Debug info already contains DW_OP_deref.");
5586 Expr.push_back(llvm::dwarf::DW_OP_deref);
5591 StringRef Name = BD->
getName();
5594 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5595 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5596 llvm::DINode::FlagZero, Align);
5598 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5599 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5600 const unsigned fieldIndex = FD->getFieldIndex();
5601 const clang::CXXRecordDecl *parent =
5602 (
const CXXRecordDecl *)FD->getParent();
5603 const ASTRecordLayout &layout =
5604 CGM.getContext().getASTRecordLayout(parent);
5606 if (FD->isBitField()) {
5607 const CGRecordLayout &RL =
5608 CGM.getTypes().getCGRecordLayout(FD->getParent());
5613 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5619 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5620 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5621 Expr.push_back(Info.
Offset);
5624 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5625 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5626 }
else if (fieldOffset != 0) {
5627 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5628 "Unexpected non-bitfield with non-byte-aligned offset");
5629 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5631 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5634 }
else if (
const ArraySubscriptExpr *ASE =
5635 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5636 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5637 const uint64_t value = IL->getValue().getZExtValue();
5638 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5641 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5642 Expr.push_back(CGM.getContext()
5643 .toCharUnitsFromBits(value * typeSize)
5650 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5651 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5652 Column, Scope, CurInlinedAt),
5653 Builder.GetInsertBlock());
5658llvm::DILocalVariable *
5661 const bool UsePointerValue) {
5662 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5664 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5666 EmitDeclare(B, Storage, std::nullopt, Builder,
5673 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5677 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5678 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5680 if (D->
hasAttr<NoDebugAttr>())
5684 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5690 StringRef Name = D->
getName();
5696 CGM.getCodeGenOpts().OptimizationLevel != 0);
5699 DBuilder.insertLabel(L,
5700 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5701 Scope, CurInlinedAt),
5702 Builder.GetInsertBlock()->end());
5705llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5707 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5710 return DBuilder.createObjectPointerType(Ty,
true);
5715 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5716 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5717 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5719 if (Builder.GetInsertBlock() ==
nullptr)
5721 if (VD->
hasAttr<NoDebugAttr>())
5724 bool isByRef = VD->
hasAttr<BlocksAttr>();
5726 uint64_t XOffset = 0;
5727 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5730 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5732 Ty = getOrCreateType(VD->
getType(), Unit);
5736 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5738 Ty = CreateSelfType(VD->
getType(), Ty);
5741 const unsigned Line =
5745 const llvm::DataLayout &target = CGM.getDataLayout();
5752 addr.push_back(llvm::dwarf::DW_OP_deref);
5753 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5756 addr.push_back(llvm::dwarf::DW_OP_deref);
5757 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5760 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5762 addr.push_back(llvm::dwarf::DW_OP_deref);
5763 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5765 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5771 auto *D = DBuilder.createAutoVariable(
5773 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5776 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5777 LexicalBlockStack.back(), CurInlinedAt);
5778 auto *
Expr = DBuilder.createExpression(addr);
5780 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5782 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5785llvm::DILocalVariable *
5788 bool UsePointerValue) {
5789 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5790 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5794struct BlockLayoutChunk {
5795 uint64_t OffsetInBits;
5798bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5799 return l.OffsetInBits < r.OffsetInBits;
5803void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5805 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5806 SmallVectorImpl<llvm::Metadata *> &Fields) {
5810 if (CGM.getLangOpts().OpenCL) {
5811 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5812 BlockLayout.getElementOffsetInBits(0),
5814 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5815 BlockLayout.getElementOffsetInBits(1),
5819 BlockLayout.getElementOffsetInBits(0),
5821 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5822 BlockLayout.getElementOffsetInBits(1),
5826 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5827 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5828 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5829 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5830 BlockLayout.getElementOffsetInBits(3),
5832 Fields.push_back(createFieldType(
5837 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5844 llvm::AllocaInst *Alloca,
5846 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5852 llvm::DIFile *tunit = getOrCreateFile(loc);
5853 unsigned line = getLineNumber(loc);
5854 unsigned column = getColumnNumber(loc);
5859 const llvm::StructLayout *blockLayout =
5863 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5872 BlockLayoutChunk chunk;
5873 chunk.OffsetInBits =
5874 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5875 chunk.Capture =
nullptr;
5876 chunks.push_back(chunk);
5880 for (
const auto &capture :
blockDecl->captures()) {
5881 const VarDecl *variable = capture.getVariable();
5888 BlockLayoutChunk chunk;
5889 chunk.OffsetInBits =
5890 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5891 chunk.Capture = &capture;
5892 chunks.push_back(chunk);
5896 llvm::array_pod_sort(chunks.begin(), chunks.end());
5898 for (
const BlockLayoutChunk &Chunk : chunks) {
5899 uint64_t offsetInBits = Chunk.OffsetInBits;
5906 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5908 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5909 type = CGM.getContext().getCanonicalTagType(RDecl);
5911 llvm_unreachable(
"unexpected block declcontext");
5913 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5914 offsetInBits, tunit, tunit));
5919 StringRef name = variable->
getName();
5921 llvm::DIType *fieldType;
5923 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5928 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5929 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5930 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5931 PtrInfo.
Width, Align, offsetInBits,
5932 llvm::DINode::FlagZero, fieldType);
5936 offsetInBits, Align, tunit, tunit);
5938 fields.push_back(fieldType);
5942 llvm::raw_svector_ostream(typeName)
5943 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5945 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5947 llvm::DIType *
type =
5948 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5949 CGM.getContext().toBits(block.
BlockSize), 0,
5950 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5951 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5954 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5958 auto *debugVar = DBuilder.createParameterVariable(
5959 scope, Name, ArgNo, tunit, line,
type,
5960 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5963 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5964 llvm::DILocation::get(CGM.getLLVMContext(), line,
5965 column, scope, CurInlinedAt),
5966 Builder.GetInsertBlock());
5969llvm::DIDerivedType *
5970CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5975 if (MI != StaticDataMemberCache.end()) {
5976 assert(MI->second &&
"Static data member declaration should still exist");
5987llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5988 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5989 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5990 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5992 for (
const auto *Field : RD->
fields()) {
5993 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5994 StringRef FieldName = Field->getName();
5997 if (FieldName.empty()) {
5998 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5999 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6000 LineNo, LinkageName, Var, DContext);
6004 GVE = DBuilder.createGlobalVariableExpression(
6005 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6006 Var->hasLocalLinkage());
6007 Var->addDebugInfo(GVE);
6019 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6024 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6035 struct ReferencesAnonymous
6037 bool RefAnon =
false;
6038 bool VisitRecordType(RecordType *RT) {
6046 ReferencesAnonymous RT;
6059struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6060 bool Reconstitutable =
true;
6061 bool VisitVectorType(VectorType *FT) {
6062 Reconstitutable =
false;
6065 bool VisitAtomicType(AtomicType *FT) {
6066 Reconstitutable =
false;
6069 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6072 const EnumDecl *ED = ET->getDecl();
6074 Reconstitutable =
false;
6078 Reconstitutable =
false;
6083 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6087 return Reconstitutable;
6089 bool VisitRecordType(RecordType *RT,
bool =
false) {
6091 Reconstitutable =
false;
6101 ReconstitutableType
T;
6103 return T.Reconstitutable;
6106bool CGDebugInfo::HasReconstitutableArgs(
6107 ArrayRef<TemplateArgument> Args)
const {
6108 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6148 llvm_unreachable(
"Other, unresolved, template arguments should "
6149 "not be seen here");
6154std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6155 bool *NameIsSimplified)
const {
6157 llvm::raw_string_ostream
OS(Name);
6158 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6161 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6162 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6164 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6165 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6167 std::optional<TemplateArgs> Args;
6169 bool IsOperatorOverload =
false;
6170 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6171 Args = GetTemplateArgs(RD);
6172 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6173 Args = GetTemplateArgs(FD);
6175 IsOperatorOverload |=
6178 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6179 Args = GetTemplateArgs(VD);
6203 bool Reconstitutable =
6204 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6206 PrintingPolicy PP = getPrintingPolicy();
6208 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6213 if (NameIsSimplified)
6214 *NameIsSimplified =
true;
6215 bool Mangled = TemplateNamesKind ==
6216 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6222 std::string EncodedOriginalName;
6223 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6228 printTemplateArgumentList(OS, Args->Args, PP);
6229 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6231 std::string CanonicalOriginalName;
6232 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6234 assert(EncodedOriginalName == CanonicalOriginalName);
6243 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6244 if (D->
hasAttr<NoDebugAttr>())
6247 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6248 return GetName(D,
true);
6254 if (Cached != DeclCache.end())
6255 return Var->addDebugInfo(
6259 llvm::DIFile *Unit =
nullptr;
6260 llvm::DIScope *DContext =
nullptr;
6262 StringRef DeclName, LinkageName;
6264 llvm::MDTuple *TemplateParameters =
nullptr;
6265 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6266 TemplateParameters, DContext);
6270 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6275 if (
T->isUnionType() && DeclName.empty()) {
6276 const auto *RD =
T->castAsRecordDecl();
6278 "unnamed non-anonymous struct or union?");
6279 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6284 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6285 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6286 if (D->
hasAttr<CUDASharedAttr>())
6289 else if (D->
hasAttr<CUDAConstantAttr>())
6293 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6295 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6296 GVE = DBuilder.createGlobalVariableExpression(
6297 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6298 Var->hasLocalLinkage(),
true,
6299 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6300 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6301 Align, Annotations);
6302 Var->addDebugInfo(GVE);
6308 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6309 if (VD->
hasAttr<NoDebugAttr>())
6311 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6312 return GetName(VD,
true);
6317 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6318 StringRef Name = VD->
getName();
6319 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6321 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6323 if (CGM.getCodeGenOpts().EmitCodeView) {
6334 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6335 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6336 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6346 auto *VarD = dyn_cast<VarDecl>(VD);
6347 if (VarD && VarD->isStaticDataMember()) {
6349 getDeclContextDescriptor(VarD);
6354 RetainedTypes.push_back(
6355 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6359 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6361 auto &GV = DeclCache[VD];
6365 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6366 llvm::MDTuple *TemplateParameters =
nullptr;
6370 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6371 TemplateParameters = parameterNodes.get();
6374 GV.reset(DBuilder.createGlobalVariableExpression(
6375 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6376 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6377 TemplateParameters, Align));
6382 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6383 if (D->
hasAttr<NoDebugAttr>())
6387 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6388 StringRef Name = D->
getName();
6389 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6391 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6392 llvm::DIGlobalVariableExpression *GVE =
6393 DBuilder.createGlobalVariableExpression(
6394 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6395 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6396 Var->addDebugInfo(GVE);
6403 if (CGM.getCodeGenOpts().getDebugInfo() <=
6404 llvm::codegenoptions::DebugLineTablesOnly)
6407 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6411 llvm::DIFile *Unit = DIL->getFile();
6412 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6417 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6418 llvm::Value *Var = Load->getPointerOperand();
6423 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6424 return DbgDeclare->getVariable()->getType() ==
Type;
6426 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6430 llvm::DILocalVariable *D =
6431 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6432 Type,
false, llvm::DINode::FlagArtificial);
6434 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6435 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6445 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6449 if (D->
hasAttr<NoDebugAttr>())
6452 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6467 if (!(DI = getDeclarationOrDefinition(
6468 AliaseeDecl.getCanonicalDecl().getDecl())))
6471 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6474 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6475 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6489 llvm::DIFile *
File = getOrCreateFile(Loc);
6490 llvm::DIGlobalVariableExpression *Debug =
6491 DBuilder.createGlobalVariableExpression(
6492 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6493 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6494 GV->addDebugInfo(Debug);
6497llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6498 if (!LexicalBlockStack.empty())
6499 return LexicalBlockStack.back();
6500 llvm::DIScope *Mod = getParentModuleOrNull(D);
6501 return getContextDescriptor(D, Mod ? Mod : TheCU);
6505 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6509 CGM.getCodeGenOpts().DebugExplicitImport) {
6513 DBuilder.createImportedModule(
6515 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6520 if (llvm::DINode *
Target =
6523 DBuilder.createImportedDeclaration(
6525 getOrCreateFile(Loc), getLineNumber(Loc));
6530 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6533 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6535 for (
const auto *USD : UD.
shadows()) {
6540 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6541 if (
const auto *AT = FD->getType()
6544 if (AT->getDeducedType().isNull())
6555 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6558 "We shouldn't be codegening an invalid UsingEnumDecl"
6559 " containing no decls");
6561 for (
const auto *USD : UD.
shadows())
6566 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6568 if (
Module *M = ID.getImportedModule()) {
6570 auto Loc = ID.getLocation();
6571 DBuilder.createImportedDeclaration(
6572 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6573 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6574 getLineNumber(Loc));
6578llvm::DIImportedEntity *
6580 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6582 auto &VH = NamespaceAliasCache[&NA];
6585 llvm::DIImportedEntity *R;
6587 if (
const auto *Underlying =
6590 R = DBuilder.createImportedDeclaration(
6593 getLineNumber(Loc), NA.
getName());
6595 R = DBuilder.createImportedDeclaration(
6598 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6604CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6608 auto I = NamespaceCache.find(NSDecl);
6609 if (I != NamespaceCache.end())
6612 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6614 llvm::DINamespace *NS =
6615 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6616 NamespaceCache[NSDecl].reset(NS);
6621 assert(TheCU &&
"no main compile unit");
6622 TheCU->setDWOId(Signature);
6628 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6629 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6631 ? CreateTypeDefinition(E.Type, E.Unit)
6633 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6637 for (
const auto &P : ObjCMethodCache) {
6638 if (P.second.empty())
6641 QualType QTy(P.first->getTypeForDecl(), 0);
6643 assert(It != TypeCache.end());
6645 llvm::DICompositeType *InterfaceDecl =
6648 auto CurElts = InterfaceDecl->getElements();
6652 for (
auto &SubprogramDirect : P.second)
6653 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6654 EltTys.push_back(SubprogramDirect.getPointer());
6656 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6657 DBuilder.replaceArrays(InterfaceDecl, Elements);
6660 for (
const auto &P : ReplaceMap) {
6663 assert(Ty->isForwardDecl());
6665 auto It = TypeCache.find(P.first);
6666 assert(It != TypeCache.end());
6669 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6673 for (
const auto &P : FwdDeclReplaceMap) {
6676 llvm::Metadata *Repl;
6678 auto It = DeclCache.find(P.first);
6682 if (It == DeclCache.end())
6687 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6688 Repl = GVE->getVariable();
6694 for (
auto &RT : RetainedTypes)
6695 if (
auto MD = TypeCache[RT])
6698 DBuilder.finalize();
6703 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6704 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6705 DBuilder.retainType(DieTy);
6709 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6710 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6711 DBuilder.retainType(DieTy);
6715 if (LexicalBlockStack.empty())
6716 return llvm::DebugLoc();
6718 llvm::MDNode *
Scope = LexicalBlockStack.back();
6719 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6720 getColumnNumber(Loc),
Scope);
6726 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6727 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6728 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6729 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6730 return llvm::DINode::FlagZero;
6735 bool SupportsDWARFv4Ext =
6736 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6737 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6738 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6740 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6741 return llvm::DINode::FlagZero;
6743 return llvm::DINode::FlagAllCallsDescribed;
6754 return DBuilder.createConstantValueExpression(
6755 Val.
getFloat().bitcastToAPInt().getZExtValue());
6760 llvm::APSInt
const &ValInt = Val.
getInt();
6761 std::optional<uint64_t> ValIntOpt;
6762 if (ValInt.isUnsigned())
6763 ValIntOpt = ValInt.tryZExtValue();
6764 else if (
auto tmp = ValInt.trySExtValue())
6767 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6770 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6775CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6777 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6778 CGF.CurLexicalScope =
this;
6780 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6785 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6798#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6800 Label = "__ubsan_check_" #Name; \
6804#undef SANITIZER_CHECK
6815#define SANITIZER(NAME, ID) \
6816 case SanitizerKind::SO_##ID: \
6817 Label = "__ubsan_check_" NAME; \
6819#include "clang/Basic/Sanitizers.def"
6821 llvm_unreachable(
"unexpected sanitizer kind");
6826 for (
unsigned int i = 0; i < Label.length(); i++)
6827 if (!std::isalpha(Label[i]))
6836 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6838 if (!DI || !CheckDebugLoc)
6839 return CheckDebugLoc;
6840 const auto &AnnotateDebugInfo =
6841 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6842 if (AnnotateDebugInfo.empty())
6843 return CheckDebugLoc;
6846 if (Ordinals.size() == 1)
6851 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6855 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6856 "ubsan_interface.h",
6858 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6861 return CheckDebugLoc;
6869 assert(!CGF->IsSanitizerScope);
6870 CGF->IsSanitizerScope =
true;
6874 assert(CGF->IsSanitizerScope);
6875 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 llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static 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 C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
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.
void completeClassData(const RecordDecl *RD)
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a define directive or a macro undefined by a undef directive...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
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 * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
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 * 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.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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,...
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned PrettyEnums
Whether to print enumerators with a matching enumerator name or via cast.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.