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;
578 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
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)
603 PresumedLoc PLoc =
SM.getPresumedLoc(Loc);
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);
676 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
677 if (llvm::sys::path::replace_path_prefix(P, From, To))
679 return P.str().str();
687 if (DebugLoc == CurLoc)
689 return SM.getPresumedLoc(DebugLoc).getLine();
702 if (DebugLoc == CurLoc)
708StringRef CGDebugInfo::getCurrentDirname() {
716 assert(CGO.DwarfVersion <= 5);
718 llvm::dwarf::SourceLanguage LangTag;
721 LangTag = llvm::dwarf::DW_LANG_HLSL;
723 LangTag = llvm::dwarf::DW_LANG_HIP;
725 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
726 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
727 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
728 else if (LO.CPlusPlus14)
729 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
730 else if (LO.CPlusPlus11)
731 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
733 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
734 }
else if (LO.ObjC) {
735 LangTag = llvm::dwarf::DW_LANG_ObjC;
736 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
737 LangTag = llvm::dwarf::DW_LANG_OpenCL;
738 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
739 LangTag = llvm::dwarf::DW_LANG_C11;
741 LangTag = llvm::dwarf::DW_LANG_C99;
743 LangTag = llvm::dwarf::DW_LANG_C89;
749static llvm::DISourceLanguageName
758 llvm::dwarf::SourceLanguageName LangTag;
761 LangTag = llvm::dwarf::DW_LNAME_HLSL;
763 LangTag = llvm::dwarf::DW_LNAME_HIP;
764 }
else if (LO.ObjC) {
765 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
767 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
770 }
else if (LO.ObjC) {
771 LangTag = llvm::dwarf::DW_LNAME_ObjC;
772 }
else if (LO.OpenCL) {
773 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
775 LangTag = llvm::dwarf::DW_LNAME_C;
779 return llvm::DISourceLanguageName(LangTag, LangVersion);
782void CGDebugInfo::CreateCompileUnit() {
783 SmallString<64> Checksum;
784 std::optional<llvm::DIFile::ChecksumKind> CSKind;
785 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
795 SourceManager &
SM = CGM.getContext().getSourceManager();
796 auto &CGO = CGM.getCodeGenOpts();
797 const LangOptions &LO = CGM.getLangOpts();
798 std::string MainFileName = CGO.MainFileName;
799 if (MainFileName.empty())
800 MainFileName =
"<stdin>";
806 std::string MainFileDir;
808 SM.getFileEntryRefForID(
SM.getMainFileID())) {
809 MainFileDir = std::string(MainFile->getDir().getName());
810 if (!llvm::sys::path::is_absolute(MainFileName)) {
811 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
812 llvm::sys::path::Style Style =
814 ? (CGM.getTarget().
getTriple().isOSWindows()
815 ? llvm::sys::path::Style::windows_backslash
816 : llvm::sys::path::Style::posix)
817 : llvm::sys::path::Style::native;
818 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
819 MainFileName = std::string(
820 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
827 if (MainFile->getName() == MainFileName &&
829 MainFile->getName().rsplit(
'.').second)
831 MainFileName = CGM.getModule().getName().str();
833 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
840 unsigned RuntimeVers = 0;
844 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
846 case llvm::codegenoptions::NoDebugInfo:
847 case llvm::codegenoptions::LocTrackingOnly:
848 EmissionKind = llvm::DICompileUnit::NoDebug;
850 case llvm::codegenoptions::DebugLineTablesOnly:
851 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
853 case llvm::codegenoptions::DebugDirectivesOnly:
854 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
856 case llvm::codegenoptions::DebugInfoConstructor:
857 case llvm::codegenoptions::LimitedDebugInfo:
858 case llvm::codegenoptions::FullDebugInfo:
859 case llvm::codegenoptions::UnusedTypeInfo:
860 EmissionKind = llvm::DICompileUnit::FullDebug;
865 auto &CGOpts = CGM.getCodeGenOpts();
871 CSInfo.emplace(*CSKind, Checksum);
872 llvm::DIFile *CUFile = DBuilder.createFile(
874 getSource(
SM,
SM.getMainFileID()));
876 StringRef Sysroot, SDK;
877 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
878 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
879 if (CGM.getCodeGenOpts().DebugRecordSysroot)
880 Sysroot = FullSysroot;
881 auto B = llvm::sys::path::rbegin(FullSysroot);
882 auto E = llvm::sys::path::rend(FullSysroot);
884 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
889 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
890 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
891 CGOpts.DebugNameTable);
892 if (CGM.getTarget().getTriple().isNVPTX())
893 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
894 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
895 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
898 TheCU = DBuilder.createCompileUnit(
900 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
901 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
902 CGOpts.PrepareForThinLTO,
903 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
904 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
905 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
908llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
912#define BUILTIN_TYPE(Id, SingletonId)
913#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
914#include "clang/AST/BuiltinTypes.def"
915 case BuiltinType::Dependent:
916 llvm_unreachable(
"Unexpected builtin type");
917 case BuiltinType::NullPtr:
918 return DBuilder.createNullPtrType();
919 case BuiltinType::Void:
921 case BuiltinType::ObjCClass:
924 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
925 "objc_class", TheCU, TheCU->getFile(), 0);
927 case BuiltinType::ObjCId: {
938 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
939 "objc_class", TheCU, TheCU->getFile(), 0);
941 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
943 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
945 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
946 (uint64_t)0, 0, llvm::DINode::FlagZero,
947 nullptr, llvm::DINodeArray());
949 DBuilder.replaceArrays(
950 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
951 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
952 llvm::DINode::FlagZero, ISATy)));
955 case BuiltinType::ObjCSel: {
957 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
958 "objc_selector", TheCU,
959 TheCU->getFile(), 0);
963#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
964 case BuiltinType::Id: \
965 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
967#include "clang/Basic/OpenCLImageTypes.def"
968 case BuiltinType::OCLSampler:
969 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
970 case BuiltinType::OCLEvent:
971 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
972 case BuiltinType::OCLClkEvent:
973 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
974 case BuiltinType::OCLQueue:
975 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
976 case BuiltinType::OCLReserveID:
977 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
978#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
979 case BuiltinType::Id: \
980 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
981#include "clang/Basic/OpenCLExtensionTypes.def"
982#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
983 case BuiltinType::Id: \
984 return getOrCreateStructPtrType(#Name, SingletonId);
985#include "clang/Basic/HLSLIntangibleTypes.def"
987#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
988#include "clang/Basic/AArch64ACLETypes.def"
990 if (BT->
getKind() == BuiltinType::MFloat8) {
991 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
992 BTName = BT->
getName(CGM.getLangOpts());
995 return DBuilder.createBasicType(BTName, Size, Encoding);
997 ASTContext::BuiltinVectorTypeInfo Info =
999 BT->
getKind() == BuiltinType::SveCount
1000 ? ASTContext::BuiltinVectorTypeInfo(
1001 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
1003 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1010 "Unsupported number of vectors for svcount_t");
1012 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1013 llvm::Metadata *BitStride =
nullptr;
1014 if (BT->
getKind() == BuiltinType::SveBool) {
1015 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1016 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1017 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1018 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1020 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1023 llvm::Metadata *LowerBound, *UpperBound;
1024 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1025 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1026 if (Info.
EC.isScalable()) {
1027 unsigned NumElemsPerVG = NumElems / 2;
1028 SmallVector<uint64_t, 9> Expr(
1029 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1030 46, 0, llvm::dwarf::DW_OP_mul,
1031 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1032 UpperBound = DBuilder.createExpression(Expr);
1034 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1035 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1037 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1038 nullptr, LowerBound, UpperBound,
nullptr);
1039 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1040 llvm::DIType *ElemTy =
1041 getOrCreateType(Info.
ElementType, TheCU->getFile());
1043 return DBuilder.createVectorType( 0, Align, ElemTy,
1044 SubscriptArray, BitStride);
1048#define PPC_VECTOR_TYPE(Name, Id, size) \
1049 case BuiltinType::Id:
1050#include "clang/Basic/PPCTypes.def"
1053#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1054#include "clang/Basic/RISCVVTypes.def"
1056 ASTContext::BuiltinVectorTypeInfo Info =
1057 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1059 unsigned ElementCount = Info.
EC.getKnownMinValue();
1060 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1062 bool Fractional =
false;
1065 unsigned FixedSize = ElementCount * SEW;
1066 if (Info.
ElementType == CGM.getContext().BoolTy) {
1069 }
else if (FixedSize < 64) {
1072 LMUL = 64 / FixedSize;
1074 LMUL = FixedSize / 64;
1078 SmallVector<uint64_t, 12> Expr(
1082 {llvm::dwarf::DW_OP_bregx,
1085 llvm::dwarf::DW_OP_constu,
1087 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1089 Expr.push_back(llvm::dwarf::DW_OP_div);
1091 Expr.push_back(llvm::dwarf::DW_OP_mul);
1094 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1096 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1099 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1100 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1101 auto *UpperBound = DBuilder.createExpression(Expr);
1102 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1103 nullptr, LowerBound, UpperBound,
nullptr);
1104 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1105 llvm::DIType *ElemTy =
1106 getOrCreateType(Info.
ElementType, TheCU->getFile());
1109 return DBuilder.createVectorType(0, Align, ElemTy,
1113#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1114 case BuiltinType::Id: { \
1117 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1118 MangledName, TheCU, TheCU->getFile(), 0); \
1119 return SingletonId; \
1121#include "clang/Basic/WebAssemblyReferenceTypes.def"
1122#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1123 case BuiltinType::Id: { \
1126 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1127 TheCU, TheCU->getFile(), 0); \
1128 return SingletonId; \
1130#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1131 case BuiltinType::Id: { \
1134 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1135 return SingletonId; \
1137#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1138 case BuiltinType::Id: { \
1141 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1142 return SingletonId; \
1144#include "clang/Basic/AMDGPUTypes.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);
1799 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1801 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1803 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1805 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1807 return llvm::dwarf::DW_CC_BORLAND_pascal;
1809 return llvm::dwarf::DW_CC_LLVM_Win64;
1811 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1815 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1817 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1819 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1821 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1823 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1825 return llvm::dwarf::DW_CC_LLVM_Swift;
1827 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1829 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1831 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1833 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1835 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1837 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1839 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1840#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1854 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1860 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1862 Flags |= llvm::DINode::FlagLValueReference;
1864 Flags |= llvm::DINode::FlagRValueReference;
1868llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1869 llvm::DIFile *Unit) {
1870 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1872 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1878 SmallVector<llvm::Metadata *, 16> EltTys;
1881 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1883 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1887 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1890 for (
const QualType &ParamType : FPT->param_types())
1891 EltTys.push_back(getOrCreateType(ParamType, Unit));
1892 if (FPT->isVariadic())
1893 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1896 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1897 llvm::DIType *F = DBuilder.createSubroutineType(
1902llvm::DIDerivedType *
1903CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1904 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1905 StringRef Name = BitFieldDecl->
getName();
1906 QualType Ty = BitFieldDecl->
getType();
1907 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1910 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1911 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1914 llvm::DIFile *
File = getOrCreateFile(Loc);
1915 unsigned Line = getLineNumber(Loc);
1917 const CGBitFieldInfo &BitFieldInfo =
1918 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1920 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1927 if (CGM.getDataLayout().isBigEndian())
1929 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1931 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1932 return DBuilder.createBitFieldMemberType(
1933 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1934 Flags, DebugType, Annotations);
1937llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1938 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1939 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1941 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1966 if (PreviousFieldsDI.empty())
1970 auto *PreviousMDEntry =
1971 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1972 auto *PreviousMDField =
1973 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1974 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1975 PreviousMDField->getSizeInBits() == 0)
1979 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1981 assert(PreviousBitfield->isBitField());
1983 if (!PreviousBitfield->isZeroLengthBitField())
1986 QualType Ty = PreviousBitfield->getType();
1987 SourceLocation Loc = PreviousBitfield->getLocation();
1988 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1989 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1990 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1992 llvm::DIFile *
File = getOrCreateFile(Loc);
1993 unsigned Line = getLineNumber(Loc);
1999 llvm::DINode::DIFlags Flags =
2001 llvm::DINodeArray Annotations =
2002 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2003 return DBuilder.createBitFieldMemberType(
2004 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2005 Flags, DebugType, Annotations);
2008llvm::DIType *CGDebugInfo::createFieldType(
2010 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2011 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2012 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2015 llvm::DIFile *file = getOrCreateFile(loc);
2016 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2019 auto Align = AlignInBits;
2020 if (!
type->isIncompleteArrayType()) {
2021 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2022 SizeInBits = TI.
Width;
2028 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2029 offsetInBits, flags, debugType, Annotations);
2033CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2034 llvm::DIFile *FileScope) {
2038 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2041 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2042 SP = DBuilder.createFunction(
2043 FileScope, FuncName, StringRef(),
2044 FileScope, 0, DIFnTy,
2046 llvm::DINode::FlagArtificial,
2047 llvm::DISubprogram::SPFlagDefinition,
2048 nullptr,
nullptr,
nullptr,
2049 nullptr, StringRef(),
2050 CGM.getCodeGenOpts().DebugKeyInstructions);
2057CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2059 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2061 assert(
Capture.capturesVariable());
2063 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2064 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2066 return CaptureDecl->
getName();
2069void CGDebugInfo::CollectRecordLambdaFields(
2070 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2071 llvm::DIType *RecordTy) {
2076 unsigned fieldno = 0;
2079 I != E; ++I, ++Field, ++fieldno) {
2080 const LambdaCapture &
Capture = *I;
2082 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2084 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2094 Loc =
Field->getLocation();
2095 }
else if (
Capture.capturesVariable()) {
2098 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2099 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2106 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2108 elements.push_back(createFieldType(
2110 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2116template <
typename T>
2117static llvm::Constant *
2128 return llvm::ConstantDataArray::get(Ctx, Vals);
2141 const QualType ElemQTy = ArrayTy->getElementType();
2148 switch (ElemBitWidth) {
2164llvm::DIDerivedType *
2165CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2166 const RecordDecl *RD) {
2170 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2171 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2173 unsigned LineNumber = getLineNumber(Var->
getLocation());
2174 StringRef VName = Var->
getName();
2178 llvm::Constant *
C =
nullptr;
2183 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2184 if (
Value->isFloat())
2185 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2186 if (
Value->isArray())
2192 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2193 ? llvm::dwarf::DW_TAG_variable
2194 : llvm::dwarf::DW_TAG_member;
2196 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2197 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2202void CGDebugInfo::CollectRecordNormalField(
2203 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2204 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2205 const RecordDecl *RD) {
2210 if (
name.empty() && !
type->isRecordType())
2213 llvm::DIType *FieldType;
2215 llvm::DIDerivedType *BitFieldType;
2216 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2217 if (llvm::DIType *Separator =
2218 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2219 elements.push_back(Separator);
2222 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2225 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2228 elements.push_back(FieldType);
2231void CGDebugInfo::CollectRecordNestedType(
2232 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2233 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2240 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2241 elements.push_back(nestedType);
2244void CGDebugInfo::CollectRecordFields(
2245 const RecordDecl *record, llvm::DIFile *tunit,
2246 SmallVectorImpl<llvm::Metadata *> &elements,
2247 llvm::DICompositeType *RecordTy) {
2248 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2250 if (CXXDecl && CXXDecl->
isLambda())
2251 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2253 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2256 unsigned fieldNo = 0;
2260 for (
const auto *I : record->
decls())
2261 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2262 if (
V->hasAttr<NoDebugAttr>())
2267 if (CGM.getCodeGenOpts().EmitCodeView &&
2275 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2276 if (MI != StaticDataMemberCache.end()) {
2277 assert(MI->second &&
2278 "Static data member declaration should still exist");
2279 elements.push_back(MI->second);
2281 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2282 elements.push_back(Field);
2284 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2285 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2286 elements, RecordTy, record);
2290 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2293 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2298 if (!nestedType->isImplicit() &&
2299 nestedType->getDeclContext() == record)
2300 CollectRecordNestedType(nestedType, elements);
2306llvm::DISubroutineType *
2307CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2308 llvm::DIFile *Unit) {
2309 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2311 return cast_or_null<llvm::DISubroutineType>(
2312 getOrCreateType(QualType(
Func, 0), Unit));
2315 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2316 ThisType =
Method->getThisType();
2318 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2321llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2322 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2323 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2325 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2328llvm::DISubroutineType *
2329CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2330 const FunctionProtoType *
Func,
2331 llvm::DIFile *Unit,
bool SkipFirst) {
2332 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2347 getOrCreateType(CGM.getContext().getFunctionType(
2348 Func->getReturnType(),
Func->getParamTypes(), EPI),
2350 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2351 assert(Args.size() &&
"Invalid number of arguments!");
2353 SmallVector<llvm::Metadata *, 16> Elts;
2356 Elts.push_back(Args[0]);
2358 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2362 if (!HasExplicitObjectParameter) {
2363 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2366 DBuilder.createObjectPointerType(ThisPtrType,
true);
2367 Elts.push_back(ThisPtrType);
2371 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2372 Elts.push_back(Args[i]);
2375 if (HasExplicitObjectParameter) {
2376 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2377 "Expected at least return type and object parameter.");
2378 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2381 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2383 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2390 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2398CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2401 const bool IsCtorOrDtor =
2404 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2411 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2414 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2417 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2420 return CGM.getMangledName(
Method);
2423bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2426 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2429llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2430 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2433 StringRef MethodName = getFunctionName(
Method);
2434 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2436 StringRef MethodLinkageName;
2443 MethodLinkageName = GetMethodLinkageName(
Method);
2446 llvm::DIFile *MethodDefUnit =
nullptr;
2447 unsigned MethodLine = 0;
2448 if (!
Method->isImplicit()) {
2449 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2450 MethodLine = getLineNumber(
Method->getLocation());
2454 llvm::DIType *ContainingType =
nullptr;
2455 unsigned VIndex = 0;
2456 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2457 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2458 int ThisAdjustment = 0;
2461 if (
Method->isPureVirtual())
2462 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2464 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2466 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2470 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2474 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2477 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2478 CGM.getContext().getLangOpts())
2482 MethodVFTableLocation ML =
2483 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2491 if (
Method->size_overridden_methods() == 0)
2492 Flags |= llvm::DINode::FlagIntroducedVirtual;
2497 ThisAdjustment = CGM.getCXXABI()
2498 .getVirtualFunctionPrologueThisAdjustment(GD)
2501 ContainingType = RecordTy;
2504 if (
Method->getCanonicalDecl()->isDeleted())
2505 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2507 if (
Method->isNoReturn())
2508 Flags |= llvm::DINode::FlagNoReturn;
2511 Flags |= llvm::DINode::FlagStaticMember;
2512 if (
Method->isImplicit())
2513 Flags |= llvm::DINode::FlagArtificial;
2515 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2516 if (CXXC->isExplicit())
2517 Flags |= llvm::DINode::FlagExplicit;
2518 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2519 if (CXXC->isExplicit())
2520 Flags |= llvm::DINode::FlagExplicit;
2522 if (
Method->hasPrototype())
2523 Flags |= llvm::DINode::FlagPrototyped;
2525 Flags |= llvm::DINode::FlagLValueReference;
2527 Flags |= llvm::DINode::FlagRValueReference;
2528 if (!
Method->isExternallyVisible())
2529 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2530 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2531 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2535 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2536 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2539 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2540 llvm::DISubprogram *SP = DBuilder.createMethod(
2541 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2542 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2543 TParamsArray.get(),
nullptr,
2544 CGM.getCodeGenOpts().DebugKeyInstructions);
2546 SPCache[
Method->getCanonicalDecl()].reset(SP);
2551void CGDebugInfo::CollectCXXMemberFunctions(
2552 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2553 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2558 for (
const auto *I : RD->
decls()) {
2559 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2573 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2582 auto MI = SPCache.find(
Method->getCanonicalDecl());
2583 EltTys.push_back(MI == SPCache.end()
2584 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2585 :
static_cast<llvm::Metadata *
>(MI->second));
2589void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2590 SmallVectorImpl<llvm::Metadata *> &EltTys,
2591 llvm::DIType *RecordTy) {
2592 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2593 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2594 llvm::DINode::FlagZero);
2598 if (CGM.getCodeGenOpts().EmitCodeView) {
2599 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2600 llvm::DINode::FlagIndirectVirtualBase);
2604void CGDebugInfo::CollectCXXBasesAux(
2605 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2606 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2608 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2609 llvm::DINode::DIFlags StartingFlags) {
2610 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2611 for (
const auto &BI : Bases) {
2614 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2616 if (!SeenTypes.insert(Base).second)
2618 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2619 llvm::DINode::DIFlags BFlags = StartingFlags;
2623 if (BI.isVirtual()) {
2624 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2627 BaseOffset = 0 - CGM.getItaniumVTableContext()
2628 .getVirtualBaseOffsetOffset(RD, Base)
2634 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2635 VBPtrOffset = CGM.getContext()
2636 .getASTRecordLayout(RD)
2640 BFlags |= llvm::DINode::FlagVirtual;
2647 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2648 VBPtrOffset, BFlags);
2649 EltTys.push_back(DTy);
2654CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2655 llvm::DIFile *Unit) {
2657 return llvm::DINodeArray();
2658 TemplateArgs &Args = *OArgs;
2659 SmallVector<llvm::Metadata *, 16> TemplateParams;
2660 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2661 const TemplateArgument &TA = Args.Args[i];
2665 Name = Args.TList->getParam(i)->getName();
2669 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2670 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2671 TheCU, Name, TTy, defaultParameter));
2676 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2677 TheCU, Name, TTy, defaultParameter,
2678 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2683 llvm::DIType *TTy = getOrCreateType(T, Unit);
2684 llvm::Constant *
V =
nullptr;
2687 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2688 !D->
hasAttr<CUDADeviceAttr>()) {
2691 if (
const auto *VD = dyn_cast<VarDecl>(D))
2692 V = CGM.GetAddrOfGlobalVar(VD);
2695 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2696 MD && MD->isImplicitObjectMemberFunction())
2697 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2698 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2699 V = CGM.GetAddrOfFunction(FD);
2702 else if (
const auto *MPT =
2703 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2707 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2709 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2710 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2711 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2712 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2713 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2715 V = ConstantEmitter(CGM).emitAbstract(
2716 SourceLocation(), TPO->getValue(), TPO->getType());
2718 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2720 assert(
V &&
"Failed to find template parameter pointer");
2721 V =
V->stripPointerCasts();
2723 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2724 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2728 llvm::DIType *TTy = getOrCreateType(T, Unit);
2729 llvm::Constant *
V =
nullptr;
2732 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2738 if (MPT->isMemberDataPointer())
2739 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2741 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2742 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2743 TheCU, Name, TTy, defaultParameter,
V));
2747 llvm::DIType *TTy = getOrCreateType(T, Unit);
2748 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2750 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2751 TheCU, Name, TTy, defaultParameter,
V));
2754 std::string QualName;
2755 llvm::raw_string_ostream
OS(QualName);
2757 OS, getPrintingPolicy());
2758 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2759 TheCU, Name,
nullptr, QualName, defaultParameter));
2763 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2764 TheCU, Name,
nullptr,
2771 T = CGM.getContext().getLValueReferenceType(T);
2772 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2773 assert(
V &&
"Expression in template argument isn't constant");
2774 llvm::DIType *TTy = getOrCreateType(T, Unit);
2775 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2776 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2782 "These argument types shouldn't exist in concrete types");
2785 return DBuilder.getOrCreateArray(TemplateParams);
2788std::optional<CGDebugInfo::TemplateArgs>
2789CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2797 return std::nullopt;
2799std::optional<CGDebugInfo::TemplateArgs>
2800CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2804 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2806 return std::nullopt;
2807 VarTemplateDecl *T = TS->getSpecializedTemplate();
2809 auto TA = TS->getTemplateArgs().asArray();
2810 return {{TList, TA}};
2812std::optional<CGDebugInfo::TemplateArgs>
2813CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2814 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2818 TemplateParameterList *TPList =
2819 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2820 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2821 return {{TPList, TAList.
asArray()}};
2823 return std::nullopt;
2827CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2828 llvm::DIFile *Unit) {
2829 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2832llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2833 llvm::DIFile *Unit) {
2834 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2837llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2838 llvm::DIFile *Unit) {
2839 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2842void CGDebugInfo::CollectBTFDeclTagAnnotations(
2843 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2845 llvm::Metadata *Ops[2] = {
2846 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2847 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2848 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2852llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2853 if (!D->
hasAttr<BTFDeclTagAttr>())
2856 SmallVector<llvm::Metadata *, 4> Annotations;
2857 CollectBTFDeclTagAnnotations(D, Annotations);
2858 return DBuilder.getOrCreateArray(Annotations);
2861void CGDebugInfo::CollectBTFTypeTagAnnotations(
2862 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2863 const BTFTagAttributedType *BTFAttrTy;
2865 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2867 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2870 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2872 llvm::Metadata *Ops[2] = {
2873 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2874 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2875 Annotations.insert(Annotations.begin(),
2876 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2878 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2882llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2884 return VTablePtrType;
2886 ASTContext &Context = CGM.getContext();
2889 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2890 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2891 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2893 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2894 std::optional<unsigned> DWARFAddressSpace =
2895 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2897 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2898 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2899 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2900 return VTablePtrType;
2903StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2915 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2917 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2927 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2928 VTable->isDeclarationForLinker())
2932 StringRef SymbolName =
"__clang_vtable";
2934 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2943 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2945 llvm::DIFile *Unit = getOrCreateFile(Loc);
2946 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2948 llvm::DINode::FlagArtificial;
2949 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2950 ? llvm::dwarf::DW_TAG_variable
2951 : llvm::dwarf::DW_TAG_member;
2952 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2953 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2957 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2961 llvm::DIGlobalVariableExpression *GVE =
2962 DBuilder.createGlobalVariableExpression(
2963 TheCU, SymbolName, VTable->getName(), Unit, 0,
2964 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2965 true,
nullptr, DT,
nullptr,
2967 VTable->addDebugInfo(GVE);
2970StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2972 llvm::Function *InitFn) {
2977 return InitFn->getName();
2987 llvm::raw_svector_ostream OS(QualifiedGV);
2989 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2991 std::swap(Quals, GVName);
2995 llvm::raw_svector_ostream OS(InitName);
2997 OS << Quals <<
"::";
3002 llvm_unreachable(
"not an initializer");
3004 OS <<
"`dynamic initializer for '";
3007 OS <<
"`dynamic atexit destructor for '";
3014 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3015 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3016 getPrintingPolicy());
3021 return internString(
OS.str());
3024void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3025 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3034 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3041 llvm::DIType *VPtrTy =
nullptr;
3042 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3043 CGM.getTarget().getCXXABI().isMicrosoft();
3044 if (NeedVTableShape) {
3046 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3047 const VTableLayout &VFTLayout =
3048 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3049 unsigned VSlotCount =
3051 unsigned VTableWidth = PtrWidth * VSlotCount;
3052 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3053 std::optional<unsigned> DWARFAddressSpace =
3054 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3057 llvm::DIType *VTableType = DBuilder.createPointerType(
3058 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3059 EltTys.push_back(VTableType);
3062 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3070 VPtrTy = getOrCreateVTablePtrType(Unit);
3072 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3073 llvm::DIType *VPtrMember =
3074 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3075 llvm::DINode::FlagArtificial, VPtrTy);
3076 EltTys.push_back(VPtrMember);
3081 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3082 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3093 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3094 assert(!D.
isNull() &&
"null type");
3095 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3096 assert(T &&
"could not create debug info for type");
3105 if (CGM.getCodeGenOpts().getDebugInfo() <=
3106 llvm::codegenoptions::DebugLineTablesOnly)
3110 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3112 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3114 CI->setMetadata(
"heapallocsite", node);
3118 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3120 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3122 auto I = TypeCache.find(TyPtr);
3125 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3126 assert(!Res->isForwardDecl());
3127 TypeCache[TyPtr].reset(Res);
3131 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3132 !CGM.getLangOpts().CPlusPlus)
3138 if (RD->
hasAttr<DLLImportAttr>())
3141 if (MD->hasAttr<DLLImportAttr>())
3154 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3164 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3165 Explicit = TD->isExplicitInstantiationOrSpecialization();
3169 if (CXXDecl->
fields().empty())
3179 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3180 if (CXXRD->isDynamicClass() &&
3181 CGM.getVTableLinkage(CXXRD) ==
3182 llvm::GlobalValue::AvailableExternallyLinkage &&
3193 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3195 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3197 auto I = TypeCache.find(TyPtr);
3204 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3205 assert(!Res->isForwardDecl());
3206 TypeCache[TyPtr].reset(Res);
3213 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3214 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3237 if (Ctor->isCopyOrMoveConstructor())
3239 if (!Ctor->isDeleted())
3258 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3261 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3262 RD->
hasAttr<StandaloneDebugAttr>())
3265 if (!LangOpts.CPlusPlus)
3271 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3287 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3288 Spec = SD->getSpecializationKind();
3297 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3308 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3309 llvm::DIType *T = getTypeOrNull(Ty);
3310 if (T && T->isForwardDecl())
3314llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3316 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3320 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3324 auto [Def, Pref] = CreateTypeDefinition(Ty);
3326 return Pref ? Pref : Def;
3329llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3330 llvm::DIFile *Unit) {
3334 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3338 return getOrCreateType(PNA->getTypedefType(), Unit);
3341std::pair<llvm::DIType *, llvm::DIType *>
3342CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3346 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3354 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3358 return {FwdDecl,
nullptr};
3360 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3361 CollectContainingType(CXXDecl, FwdDecl);
3364 LexicalBlockStack.emplace_back(&*FwdDecl);
3365 RegionMap[RD].reset(FwdDecl);
3368 SmallVector<llvm::Metadata *, 16> EltTys;
3375 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3377 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3378 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3382 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3383 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3384 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3386 LexicalBlockStack.pop_back();
3387 RegionMap.erase(RD);
3389 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3390 DBuilder.replaceArrays(FwdDecl, Elements);
3392 if (FwdDecl->isTemporary())
3394 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3396 RegionMap[RD].reset(FwdDecl);
3398 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3399 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3400 return {FwdDecl, PrefDI};
3402 return {FwdDecl,
nullptr};
3405llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3406 llvm::DIFile *Unit) {
3408 return getOrCreateType(Ty->getBaseType(), Unit);
3411llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3412 llvm::DIFile *Unit) {
3414 SourceLocation Loc = Ty->getDecl()->getLocation();
3417 return DBuilder.createTypedef(
3418 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3419 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3420 getDeclContextDescriptor(Ty->getDecl()));
3447llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3448 llvm::DIFile *Unit) {
3453 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3454 TheCU->getSourceLanguage().getUnversionedName());
3459 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3460 !
ID->getImplementation())
3461 return DBuilder.createForwardDecl(
3462 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3463 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3466 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3467 unsigned Line = getLineNumber(
ID->getLocation());
3471 ObjCInterfaceDecl *Def =
ID->getDefinition();
3473 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3474 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3475 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3476 DefUnit,
Line, RuntimeLang);
3477 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3481 return CreateTypeDefinition(Ty, Unit);
3484llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3485 bool CreateSkeletonCU) {
3490 auto ModRef = ModuleCache.find(M);
3491 if (ModRef != ModuleCache.end())
3495 SmallString<128> ConfigMacros;
3497 llvm::raw_svector_ostream
OS(ConfigMacros);
3498 const auto &PPOpts = CGM.getPreprocessorOpts();
3501 for (
auto &M : PPOpts.Macros) {
3504 const std::string &
Macro = M.first;
3505 bool Undef = M.second;
3506 OS <<
"\"-" << (Undef ?
'U' :
'D');
3507 for (
char c :
Macro)
3522 bool IsRootModule = M ? !M->
Parent :
true;
3526 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3527 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3528 "clang module without ASTFile must be specified by -fmodule-name");
3531 auto RemapPath = [
this](StringRef Path) -> std::string {
3533 StringRef Relative(Remapped);
3534 StringRef CompDir = TheCU->getDirectory();
3535 if (CompDir.empty())
3538 if (Relative.consume_front(CompDir))
3539 Relative.consume_front(llvm::sys::path::get_separator());
3541 return Relative.str();
3544 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3551 Signature = ModSig.truncatedValue();
3555 llvm::DIBuilder DIB(CGM.getModule());
3557 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3558 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3559 PCM = getCurrentDirname();
3563 llvm::sys::path::append(PCM, Mod.
getASTFile());
3564 DIB.createCompileUnit(
3565 TheCU->getSourceLanguage(),
3568 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3569 llvm::DICompileUnit::FullDebug, Signature);
3573 llvm::DIModule *Parent =
3575 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3577 StringRef IncludePath = Mod.
getPath();
3578 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3579 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3580 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3583 llvm::DIModule *DIMod =
3584 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3585 RemapPath(IncludePath));
3586 ModuleCache[M].reset(DIMod);
3590llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3591 llvm::DIFile *Unit) {
3593 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3594 unsigned Line = getLineNumber(
ID->getLocation());
3596 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3602 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3603 if (
ID->getImplementation())
3604 Flags |= llvm::DINode::FlagObjcClassComplete;
3606 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3607 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3608 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3609 nullptr, llvm::DINodeArray(), RuntimeLang);
3611 QualType QTy(Ty, 0);
3612 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3615 LexicalBlockStack.emplace_back(RealDecl);
3616 RegionMap[Ty->
getDecl()].reset(RealDecl);
3619 SmallVector<llvm::Metadata *, 16> EltTys;
3621 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3623 llvm::DIType *SClassTy =
3624 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3628 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3629 llvm::DINode::FlagZero);
3630 EltTys.push_back(InhTag);
3634 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3635 SourceLocation Loc = PD->getLocation();
3636 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3637 unsigned PLine = getLineNumber(Loc);
3638 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3639 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3640 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3641 PD->getName(), PUnit, PLine,
3643 : getSelectorName(PD->getGetterName()),
3645 : getSelectorName(PD->getSetterName()),
3646 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3647 EltTys.push_back(PropertyNode);
3652 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3656 llvm::DenseSet<IsClassAndIdent> PropertySet;
3658 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3659 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3661 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3662 for (
auto *PD : ClassExt->properties()) {
3663 PropertySet.insert(GetIsClassAndIdent(PD));
3666 for (
const auto *PD :
ID->properties()) {
3669 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3675 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3676 unsigned FieldNo = 0;
3677 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3678 Field =
Field->getNextIvar(), ++FieldNo) {
3679 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3683 StringRef FieldName =
Field->getName();
3686 if (FieldName.empty())
3690 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3691 unsigned FieldLine = getLineNumber(
Field->getLocation());
3692 QualType FType =
Field->getType();
3699 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3700 : CGM.getContext().getTypeSize(FType);
3705 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3709 if (
Field->isBitField()) {
3711 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3712 FieldOffset %= CGM.getContext().getCharWidth();
3720 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3722 Flags = llvm::DINode::FlagProtected;
3724 Flags = llvm::DINode::FlagPrivate;
3726 Flags = llvm::DINode::FlagPublic;
3728 if (
Field->isBitField())
3729 Flags |= llvm::DINode::FlagBitField;
3731 llvm::MDNode *PropertyNode =
nullptr;
3732 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3733 if (ObjCPropertyImplDecl *PImpD =
3734 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3735 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3736 SourceLocation Loc = PD->getLocation();
3737 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3738 unsigned PLine = getLineNumber(Loc);
3739 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3740 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3741 PropertyNode = DBuilder.createObjCProperty(
3742 PD->getName(), PUnit, PLine,
3745 : getSelectorName(PD->getGetterName()),
3748 : getSelectorName(PD->getSetterName()),
3749 PD->getPropertyAttributes(),
3750 getOrCreateType(PD->getType(), PUnit));
3754 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3755 FieldSize, FieldAlign, FieldOffset, Flags,
3756 FieldTy, PropertyNode);
3757 EltTys.push_back(FieldTy);
3760 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3761 DBuilder.replaceArrays(RealDecl, Elements);
3763 LexicalBlockStack.pop_back();
3767llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3768 llvm::DIFile *Unit) {
3776 auto &Ctx = CGM.getContext();
3781 QualType CharVecTy =
3783 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3786 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3789 llvm::Metadata *Subscript;
3790 QualType QTy(Ty, 0);
3791 auto SizeExpr = SizeExprCache.find(QTy);
3792 if (SizeExpr != SizeExprCache.end())
3793 Subscript = DBuilder.getOrCreateSubrange(
3794 SizeExpr->getSecond() ,
nullptr ,
3795 nullptr ,
nullptr );
3798 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3799 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3800 Subscript = DBuilder.getOrCreateSubrange(
3801 CountNode ,
nullptr ,
nullptr ,
3804 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3809 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3812llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3813 llvm::DIFile *Unit) {
3817 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3822 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3823 auto *ColumnCountNode =
3824 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3825 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3826 auto *RowCountNode =
3827 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3828 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3829 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3830 ColumnCountNode ,
nullptr ,
nullptr ,
3832 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3833 RowCountNode ,
nullptr ,
nullptr ,
3835 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3836 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3839llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3844 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3859 Size = CGM.getContext().getTypeSize(Ty);
3866 SmallVector<llvm::Metadata *, 8> Subscripts;
3867 QualType EltTy(Ty, 0);
3868 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3877 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3878 Count = CAT->getZExtSize();
3879 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3880 if (Expr *Size = VAT->getSizeExpr()) {
3882 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3883 Count =
Result.Val.getInt().getExtValue();
3887 auto SizeNode = SizeExprCache.find(EltTy);
3888 if (SizeNode != SizeExprCache.end())
3889 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3890 SizeNode->getSecond() ,
nullptr ,
3891 nullptr ,
nullptr ));
3894 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3895 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3896 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3897 CountNode ,
nullptr ,
nullptr ,
3903 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3905 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3909llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3910 llvm::DIFile *Unit) {
3911 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3915llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3916 llvm::DIFile *Unit) {
3917 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3919 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3920 CGM.getCodeGenOpts().DwarfVersion < 4)
3921 Tag = llvm::dwarf::DW_TAG_reference_type;
3923 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3926llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3928 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3932 Size = CGM.getContext().getTypeSize(Ty);
3935 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3938 Flags |= llvm::DINode::FlagSingleInheritance;
3941 Flags |= llvm::DINode::FlagMultipleInheritance;
3944 Flags |= llvm::DINode::FlagVirtualInheritance;
3954 llvm::DIType *ClassType = getOrCreateType(T, U);
3956 return DBuilder.createMemberPointerType(
3960 const FunctionProtoType *FPT =
3962 return DBuilder.createMemberPointerType(
3963 getOrCreateInstanceMethodType(
3966 ClassType, Size, 0, Flags);
3969llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3971 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3974llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3978llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3980 return getOrCreateType(Ty->getWrappedType(), U);
3983llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3990 const EnumType *Ty) {
4002llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4005 bool isImportedFromModule =
4006 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4010 if (isImportedFromModule || !ED->getDefinition()) {
4017 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4018 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4019 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4020 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4022 unsigned Line = getLineNumber(ED->getLocation());
4023 StringRef EDName = ED->getName();
4024 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4025 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4026 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4028 ReplaceMap.emplace_back(
4029 std::piecewise_construct, std::make_tuple(Ty),
4030 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4034 return CreateTypeDefinition(Ty);
4037llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4040 SmallVector<llvm::Metadata *, 16> Enumerators;
4041 ED = ED->getDefinition();
4042 assert(ED &&
"An enumeration definition is required");
4043 for (
const auto *
Enum : ED->enumerators()) {
4044 Enumerators.push_back(
4045 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4048 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4049 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4050 EnumKind = Attr->getExtensibility();
4053 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4055 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4056 unsigned Line = getLineNumber(ED->getLocation());
4057 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4058 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4059 return DBuilder.createEnumerationType(
4060 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4061 0, Identifier, ED->isScoped(), EnumKind);
4066 StringRef Name, StringRef
Value) {
4067 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4068 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4074 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4075 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4076 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4081 llvm::DISubprogram *SynthSubprogram) {
4082 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4083 SynthSubprogram, ParentLocation);
4088 StringRef SynthFuncName,
4089 llvm::DIFile *SynthFile) {
4090 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4095 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4101 FuncName += Category;
4103 FuncName += FailureMsg;
4106 TrapLocation->getFile());
4112 Qualifiers InnerQuals = T.getLocalQualifiers();
4116 Quals += InnerQuals;
4118 switch (T->getTypeClass()) {
4120 return C.getQualifiedType(T.getTypePtr(), Quals);
4123 case Type::InjectedClassName:
4124 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4126 case Type::TemplateSpecialization: {
4128 if (Spec->isTypeAlias())
4129 return C.getQualifiedType(T.getTypePtr(), Quals);
4130 T = Spec->desugar();
4133 case Type::TypeOfExpr:
4139 case Type::Decltype:
4142 case Type::UnaryTransform:
4145 case Type::Attributed:
4148 case Type::BTFTagAttributed:
4151 case Type::CountAttributed:
4160 case Type::MacroQualified:
4163 case Type::SubstTemplateTypeParm:
4167 case Type::DeducedTemplateSpecialization: {
4169 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4173 case Type::PackIndexing: {
4177 case Type::Adjusted:
4184 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4189llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4192 if (It != TypeCache.end()) {
4194 if (llvm::Metadata *
V = It->second)
4207 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4214 RetainedTypes.push_back(
4215 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4218llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4222 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4224 llvm::raw_string_ostream OS(Name);
4225 Ty.
print(OS, getPrintingPolicy());
4232 if (
auto *T = getTypeOrNull(Ty))
4235 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4236 void *TyPtr = Ty.getAsOpaquePtr();
4239 TypeCache[TyPtr].reset(Res);
4244llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4252 auto Info = Reader->getSourceDescriptor(Idx);
4254 return getOrCreateModuleRef(*Info,
true);
4255 }
else if (ClangModuleMap) {
4268 auto Info = ASTSourceDescriptor(*M);
4269 return getOrCreateModuleRef(Info,
false);
4272 return getOrCreateModuleRef(PCHDescriptor,
false);
4279llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4282 return CreateQualifiedType(Ty, Unit);
4286#define TYPE(Class, Base)
4287#define ABSTRACT_TYPE(Class, Base)
4288#define NON_CANONICAL_TYPE(Class, Base)
4289#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4290#include "clang/AST/TypeNodes.inc"
4291 llvm_unreachable(
"Dependent types cannot show up in debug information");
4293 case Type::ExtVector:
4296 case Type::ConstantMatrix:
4298 case Type::ObjCObjectPointer:
4300 case Type::ObjCObject:
4302 case Type::ObjCTypeParam:
4304 case Type::ObjCInterface:
4312 case Type::BlockPointer:
4320 case Type::FunctionProto:
4321 case Type::FunctionNoProto:
4323 case Type::ConstantArray:
4324 case Type::VariableArray:
4325 case Type::IncompleteArray:
4326 case Type::ArrayParameter:
4329 case Type::LValueReference:
4331 case Type::RValueReference:
4334 case Type::MemberPointer:
4342 case Type::OverflowBehavior:
4347 case Type::TemplateSpecialization:
4349 case Type::HLSLAttributedResource:
4351 case Type::HLSLInlineSpirv:
4353 case Type::PredefinedSugar:
4355 case Type::CountAttributed:
4357 case Type::Attributed:
4358 case Type::BTFTagAttributed:
4359 case Type::Adjusted:
4361 case Type::DeducedTemplateSpecialization:
4364 case Type::MacroQualified:
4365 case Type::SubstTemplateTypeParm:
4366 case Type::TypeOfExpr:
4368 case Type::Decltype:
4369 case Type::PackIndexing:
4370 case Type::UnaryTransform:
4374 llvm_unreachable(
"type should have been unwrapped!");
4377llvm::DICompositeType *
4378CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4379 QualType QTy(Ty, 0);
4381 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4386 if (T && !T->isForwardDecl())
4390 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4395 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4398 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4403llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4405 bool NameIsSimplified =
false;
4408 StringRef RDName = getClassName(RD, &NameIsSimplified);
4410 llvm::DIFile *DefUnit =
nullptr;
4413 DefUnit = getOrCreateFile(Loc);
4414 Line = getLineNumber(Loc);
4417 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4421 auto *T = cast_or_null<llvm::DICompositeType>(
4422 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4430 return getOrCreateRecordFwdDecl(Ty, RDContext);
4443 auto Flags = llvm::DINode::FlagZero;
4444 if (NameIsSimplified)
4445 Flags |= llvm::DINode::FlagNameIsSimplified;
4446 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4448 Flags |= llvm::DINode::FlagTypePassByReference;
4450 Flags |= llvm::DINode::FlagTypePassByValue;
4453 if (!CXXRD->isTrivial())
4454 Flags |= llvm::DINode::FlagNonTrivial;
4457 if (CXXRD->isAnonymousStructOrUnion())
4458 Flags |= llvm::DINode::FlagExportSymbols;
4461 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4464 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4465 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4467 Flags, Identifier, Annotations);
4471 switch (RealDecl->getTag()) {
4473 llvm_unreachable(
"invalid composite type tag");
4475 case llvm::dwarf::DW_TAG_array_type:
4476 case llvm::dwarf::DW_TAG_enumeration_type:
4481 if (Identifier.empty())
4485 case llvm::dwarf::DW_TAG_structure_type:
4486 case llvm::dwarf::DW_TAG_union_type:
4487 case llvm::dwarf::DW_TAG_class_type:
4490 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4494 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4495 CXXRecordDecl *TemplateDecl =
4496 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4497 RegionMap[TemplateDecl].reset(RealDecl);
4499 RegionMap[RD].reset(RealDecl);
4501 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4503 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4504 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4505 CollectCXXTemplateParams(TSpecial, DefUnit));
4509void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4510 llvm::DICompositeType *RealDecl) {
4512 llvm::DIType *ContainingType =
nullptr;
4513 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4517 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4524 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4525 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4527 ContainingType = RealDecl;
4529 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4532llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4533 StringRef Name, uint64_t *Offset) {
4534 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4535 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4538 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4539 *Offset, llvm::DINode::FlagZero, FieldTy);
4540 *Offset += FieldSize;
4544void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4546 StringRef &LinkageName,
4547 llvm::DIScope *&FDContext,
4548 llvm::DINodeArray &TParamsArray,
4549 llvm::DINode::DIFlags &Flags) {
4551 bool NameIsSimplified =
false;
4552 Name = getFunctionName(FD, &NameIsSimplified);
4553 if (NameIsSimplified)
4554 Flags |= llvm::DINode::FlagNameIsSimplified;
4555 Name = getFunctionName(FD);
4558 LinkageName = CGM.getMangledName(GD);
4560 Flags |= llvm::DINode::FlagPrototyped;
4564 if (LinkageName == Name ||
4565 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4566 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4567 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4568 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4569 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4570 LinkageName = StringRef();
4574 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4575 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4576 CGM.getCodeGenOpts().EmitCodeView)) {
4577 if (
const NamespaceDecl *NSDecl =
4579 FDContext = getOrCreateNamespace(NSDecl);
4580 else if (
const RecordDecl *RDecl =
4582 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4583 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4586 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4589 Flags |= llvm::DINode::FlagNoReturn;
4591 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4595void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4596 unsigned &LineNo, QualType &T,
4597 StringRef &Name, StringRef &LinkageName,
4598 llvm::MDTuple *&TemplateParameters,
4599 llvm::DIScope *&VDContext) {
4608 llvm::APInt ConstVal(32, 1);
4609 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4611 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4618 LinkageName = CGM.getMangledName(VD);
4619 if (LinkageName == Name)
4620 LinkageName = StringRef();
4623 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4624 TemplateParameters = parameterNodes.get();
4626 TemplateParameters =
nullptr;
4644 DC = CGM.getContext().getTranslationUnitDecl();
4646 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4647 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4650llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4652 llvm::DINodeArray TParamsArray;
4653 StringRef Name, LinkageName;
4654 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4655 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4657 llvm::DIFile *Unit = getOrCreateFile(Loc);
4658 llvm::DIScope *DContext = Unit;
4659 unsigned Line = getLineNumber(Loc);
4660 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4665 SmallVector<QualType, 16> ArgTypes;
4666 for (
const ParmVarDecl *Parm : FD->
parameters())
4667 ArgTypes.push_back(Parm->getType());
4670 QualType FnType = CGM.getContext().getFunctionType(
4671 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4673 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4674 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4675 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4679 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4680 return DBuilder.createFunction(
4681 DContext, Name, LinkageName, Unit,
Line,
4682 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4683 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4685 CGM.getCodeGenOpts().DebugKeyInstructions);
4688 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4689 DContext, Name, LinkageName, Unit,
Line,
4690 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4691 TParamsArray.get(), getFunctionDeclaration(FD));
4693 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4694 std::make_tuple(CanonDecl),
4695 std::make_tuple(SP));
4699llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4700 return getFunctionFwdDeclOrStub(GD,
false);
4703llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4704 return getFunctionFwdDeclOrStub(GD,
true);
4707llvm::DIGlobalVariable *
4708CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4710 StringRef Name, LinkageName;
4712 llvm::DIFile *Unit = getOrCreateFile(Loc);
4713 llvm::DIScope *DContext = Unit;
4714 unsigned Line = getLineNumber(Loc);
4715 llvm::MDTuple *TemplateParameters =
nullptr;
4717 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4720 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4721 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4723 FwdDeclReplaceMap.emplace_back(
4724 std::piecewise_construct,
4726 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4730llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4735 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4736 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4737 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4741 if (I != DeclCache.end()) {
4743 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4744 return GVE->getVariable();
4752 if (IE != ImportedDeclCache.end()) {
4753 auto N = IE->second;
4754 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4756 return dyn_cast_or_null<llvm::DINode>(N);
4761 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4762 return getFunctionForwardDeclaration(FD);
4763 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4764 return getGlobalVariableForwardDeclaration(VD);
4769llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4770 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4773 const auto *FD = dyn_cast<FunctionDecl>(D);
4778 auto *S = getDeclContextDescriptor(D);
4781 if (MI == SPCache.end()) {
4783 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4787 if (MI != SPCache.end()) {
4788 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4789 if (SP && !SP->isDefinition())
4793 for (
auto *NextFD : FD->
redecls()) {
4794 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4795 if (MI != SPCache.end()) {
4796 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4797 if (SP && !SP->isDefinition())
4804llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4805 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4806 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4807 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4810 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4814 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4818 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4827 QualType QTy(
ID->getTypeForDecl(), 0);
4828 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4829 if (It == TypeCache.end())
4832 llvm::DISubprogram *FD = DBuilder.createFunction(
4833 InterfaceType, getObjCMethodName(OMD), StringRef(),
4834 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4835 DBuilder.finalizeSubprogram(FD);
4842llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4847 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4848 !CGM.getCodeGenOpts().EmitCodeView))
4851 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4853 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4856 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4859 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4860 return getOrCreateMethodType(
Method, F);
4862 const auto *FTy = FnType->
getAs<FunctionType>();
4865 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4867 SmallVector<llvm::Metadata *, 16> Elts;
4870 QualType ResultTy = OMethod->getReturnType();
4873 if (ResultTy == CGM.getContext().getObjCInstanceType())
4874 ResultTy = CGM.getContext().getPointerType(
4875 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4877 Elts.push_back(getOrCreateType(ResultTy, F));
4879 QualType SelfDeclTy;
4880 if (
auto *SelfDecl = OMethod->getSelfDecl())
4881 SelfDeclTy = SelfDecl->getType();
4882 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4885 if (!SelfDeclTy.
isNull())
4887 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4889 Elts.push_back(DBuilder.createArtificialType(
4890 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4892 for (
const auto *PI : OMethod->parameters())
4893 Elts.push_back(getOrCreateType(PI->getType(), F));
4895 if (OMethod->isVariadic())
4896 Elts.push_back(DBuilder.createUnspecifiedParameter());
4898 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4899 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4905 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4906 if (FD->isVariadic()) {
4907 SmallVector<llvm::Metadata *, 16> EltTys;
4908 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4909 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4911 EltTys.push_back(getOrCreateType(ParamType, F));
4912 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4913 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4914 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4927 CC = SrcFnTy->getCallConv();
4929 for (
const VarDecl *VD : Args)
4930 ArgTypes.push_back(VD->
getType());
4931 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4937 llvm::Function *Fn,
bool CurFuncIsThunk) {
4939 StringRef LinkageName;
4941 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4944 bool HasDecl = (D !=
nullptr);
4946 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4947 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4948 llvm::DIFile *Unit = getOrCreateFile(Loc);
4949 llvm::DIScope *FDContext = Unit;
4950 llvm::DINodeArray TParamsArray;
4951 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4954 LinkageName = Fn->getName();
4955 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4957 auto FI = SPCache.find(FD->getCanonicalDecl());
4958 if (FI != SPCache.end()) {
4959 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4960 if (SP && SP->isDefinition()) {
4961 LexicalBlockStack.emplace_back(SP);
4962 RegionMap[D].reset(SP);
4966 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4967 TParamsArray, Flags);
4970 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4971 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4972 Name = getObjCMethodName(OMD);
4973 Flags |= llvm::DINode::FlagPrototyped;
4979 if (Name != Fn->getName())
4980 LinkageName = Fn->getName();
4982 Name = Fn->getName();
4987 Flags |= llvm::DINode::FlagPrototyped;
4989 Name.consume_front(
"\01");
4993 "Unexpected DynamicInitKind !");
4997 Flags |= llvm::DINode::FlagArtificial;
5003 Flags |= llvm::DINode::FlagThunk;
5005 if (Fn->hasLocalLinkage())
5006 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5007 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5008 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5011 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5012 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5014 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5015 unsigned ScopeLine = getLineNumber(ScopeLoc);
5016 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5017 llvm::DISubprogram *
Decl =
nullptr;
5018 llvm::DINodeArray Annotations =
nullptr;
5021 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5022 : getFunctionDeclaration(D);
5023 Annotations = CollectBTFDeclTagAnnotations(D);
5031 llvm::DISubprogram *SP = DBuilder.createFunction(
5032 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5033 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5034 Annotations,
"", KeyInstructions);
5035 Fn->setSubprogram(SP);
5044 LexicalBlockStack.emplace_back(SP);
5047 RegionMap[D].reset(SP);
5051 QualType FnType, llvm::Function *Fn) {
5053 StringRef LinkageName;
5059 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5060 return GetName(D,
true);
5063 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5064 llvm::DIFile *Unit = getOrCreateFile(Loc);
5065 bool IsDeclForCallSite = Fn ?
true :
false;
5066 llvm::DIScope *FDContext =
5067 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5068 llvm::DINodeArray TParamsArray;
5071 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5072 TParamsArray, Flags);
5073 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5074 Name = getObjCMethodName(OMD);
5075 Flags |= llvm::DINode::FlagPrototyped;
5077 llvm_unreachable(
"not a function or ObjC method");
5079 Name.consume_front(
"\01");
5082 Flags |= llvm::DINode::FlagArtificial;
5087 unsigned LineNo = getLineNumber(Loc);
5088 unsigned ScopeLine = 0;
5089 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5090 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5091 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5093 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5094 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5096 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5097 llvm::DISubprogram *SP = DBuilder.createFunction(
5098 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5099 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5105 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5106 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5107 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5110 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5111 DBuilder.createParameterVariable(
5112 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5113 llvm::DINode::FlagZero, ParamAnnotations);
5119 if (IsDeclForCallSite)
5120 Fn->setSubprogram(SP);
5124 llvm::CallBase *CI) {
5125 if (!shouldGenerateVirtualCallSite())
5131 assert(CI &&
"Invalid Call Instruction.");
5132 if (!CI->isIndirectCall())
5136 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5137 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5145 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5148 if (
Func->getSubprogram())
5156 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5171 auto FI = SPCache.find(FD->getCanonicalDecl());
5172 llvm::DISubprogram *SP =
nullptr;
5173 if (FI != SPCache.end())
5174 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5175 if (!SP || !SP->isDefinition())
5176 SP = getFunctionStub(GD);
5177 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5178 LexicalBlockStack.emplace_back(SP);
5184 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5193 if (CurLoc.isInvalid() ||
5194 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5195 LexicalBlockStack.empty())
5198 llvm::MDNode *
Scope = LexicalBlockStack.back();
5199 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5200 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5204 llvm::MDNode *Back =
nullptr;
5205 if (!LexicalBlockStack.empty())
5206 Back = LexicalBlockStack.back().get();
5207 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5209 getColumnNumber(CurLoc)));
5212void CGDebugInfo::AppendAddressSpaceXDeref(
5214 std::optional<unsigned> DWARFAddressSpace =
5216 if (!DWARFAddressSpace)
5219 Expr.push_back(llvm::dwarf::DW_OP_constu);
5220 Expr.push_back(*DWARFAddressSpace);
5221 Expr.push_back(llvm::dwarf::DW_OP_swap);
5222 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5231 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5232 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5233 LexicalBlockStack.back(), CurInlinedAt));
5235 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5239 CreateLexicalBlock(Loc);
5244 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5249 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5252 LexicalBlockStack.pop_back();
5256 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5257 unsigned RCount = FnBeginRegionCount.back();
5258 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5261 while (LexicalBlockStack.size() != RCount) {
5264 LexicalBlockStack.pop_back();
5266 FnBeginRegionCount.pop_back();
5268 if (Fn && Fn->getSubprogram())
5269 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5272CGDebugInfo::BlockByRefType
5273CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5274 uint64_t *XOffset) {
5277 uint64_t FieldSize, FieldOffset;
5278 uint32_t FieldAlign;
5280 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5285 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5286 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5288 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5289 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5292 if (HasCopyAndDispose) {
5295 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5297 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5299 bool HasByrefExtendedLayout;
5302 HasByrefExtendedLayout) &&
5303 HasByrefExtendedLayout) {
5306 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5315 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5318 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5321 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5326 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5327 FieldSize = CGM.getContext().getTypeSize(FType);
5328 FieldAlign = CGM.getContext().toBits(Align);
5330 *XOffset = FieldOffset;
5331 llvm::DIType *FieldTy = DBuilder.createMemberType(
5332 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5333 llvm::DINode::FlagZero, WrappedTy);
5334 EltTys.push_back(FieldTy);
5335 FieldOffset += FieldSize;
5337 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5338 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5339 llvm::DINode::FlagZero,
nullptr, Elements),
5343llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5344 llvm::Value *Storage,
5345 std::optional<unsigned> ArgNo,
5347 const bool UsePointerValue) {
5348 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5349 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5350 if (VD->
hasAttr<NoDebugAttr>())
5355 llvm::DIFile *Unit =
nullptr;
5356 if (!VarIsArtificial)
5360 if (VD->
hasAttr<BlocksAttr>())
5361 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5363 Ty = getOrCreateType(VD->
getType(), Unit);
5373 if (!VarIsArtificial) {
5377 SmallVector<uint64_t, 13> Expr;
5378 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5385 Flags |= llvm::DINode::FlagArtificial;
5389 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5390 AppendAddressSpaceXDeref(AddressSpace, Expr);
5394 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5397 Flags |= llvm::DINode::FlagObjectPointer;
5398 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5399 if (PVD->isExplicitObjectParameter())
5400 Flags |= llvm::DINode::FlagObjectPointer;
5408 StringRef Name = VD->
getName();
5409 if (!Name.empty()) {
5415 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5417 offset = CGM.getContext().toCharUnitsFromBits(
5420 Expr.push_back(llvm::dwarf::DW_OP_deref);
5421 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5423 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5426 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5438 for (
const auto *Field : RD->
fields()) {
5439 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5440 StringRef FieldName =
Field->getName();
5448 auto *D = DBuilder.createAutoVariable(
5449 Scope, FieldName, Unit,
Line, FieldTy,
5450 CGM.getCodeGenOpts().OptimizationLevel != 0,
5451 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5454 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5455 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5458 Builder.GetInsertBlock());
5466 if (UsePointerValue) {
5467 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5468 "Debug info already contains DW_OP_deref.");
5469 Expr.push_back(llvm::dwarf::DW_OP_deref);
5473 llvm::DILocalVariable *D =
nullptr;
5475 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5476 D = DBuilder.createParameterVariable(
5477 Scope, Name, *ArgNo, Unit,
Line, Ty,
5478 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5487 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5493 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5494 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5495 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5496 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5498 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5504 if (Iter != CoroutineParameterMappings.end()) {
5505 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5506 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5507 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5509 if (Iter2 != ParamDbgMappings.end())
5510 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5516 D = RemapCoroArgToLocalVar();
5519 D = DBuilder.createAutoVariable(
5520 Scope, Name, Unit,
Line, Ty,
5521 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5524 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5525 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5526 Column, Scope, CurInlinedAt),
5527 Builder.GetInsertBlock());
5532llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5533 llvm::Value *Storage,
5534 std::optional<unsigned> ArgNo,
5536 const bool UsePointerValue) {
5537 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5538 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5539 if (BD->
hasAttr<NoDebugAttr>())
5546 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5547 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5555 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5557 SmallVector<uint64_t, 3> Expr;
5558 AppendAddressSpaceXDeref(AddressSpace, Expr);
5563 if (UsePointerValue) {
5564 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5565 "Debug info already contains DW_OP_deref.");
5566 Expr.push_back(llvm::dwarf::DW_OP_deref);
5571 StringRef Name = BD->
getName();
5574 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5575 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5576 llvm::DINode::FlagZero, Align);
5578 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5579 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5580 const unsigned fieldIndex = FD->getFieldIndex();
5581 const clang::CXXRecordDecl *parent =
5582 (
const CXXRecordDecl *)FD->getParent();
5583 const ASTRecordLayout &layout =
5584 CGM.getContext().getASTRecordLayout(parent);
5586 if (FD->isBitField()) {
5587 const CGRecordLayout &RL =
5588 CGM.getTypes().getCGRecordLayout(FD->getParent());
5593 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5599 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5600 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5601 Expr.push_back(Info.
Offset);
5604 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5605 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5606 }
else if (fieldOffset != 0) {
5607 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5608 "Unexpected non-bitfield with non-byte-aligned offset");
5609 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5611 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5614 }
else if (
const ArraySubscriptExpr *ASE =
5615 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5616 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5617 const uint64_t value = IL->getValue().getZExtValue();
5618 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5621 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5622 Expr.push_back(CGM.getContext()
5623 .toCharUnitsFromBits(value * typeSize)
5630 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5631 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5632 Column, Scope, CurInlinedAt),
5633 Builder.GetInsertBlock());
5638llvm::DILocalVariable *
5641 const bool UsePointerValue) {
5642 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5644 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5646 EmitDeclare(B, Storage, std::nullopt, Builder,
5653 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5657 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5658 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5660 if (D->
hasAttr<NoDebugAttr>())
5664 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5670 StringRef Name = D->
getName();
5676 CGM.getCodeGenOpts().OptimizationLevel != 0);
5679 DBuilder.insertLabel(L,
5680 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5681 Scope, CurInlinedAt),
5682 Builder.GetInsertBlock()->end());
5685llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5687 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5690 return DBuilder.createObjectPointerType(Ty,
true);
5695 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5696 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5697 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5699 if (Builder.GetInsertBlock() ==
nullptr)
5701 if (VD->
hasAttr<NoDebugAttr>())
5704 bool isByRef = VD->
hasAttr<BlocksAttr>();
5706 uint64_t XOffset = 0;
5707 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5710 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5712 Ty = getOrCreateType(VD->
getType(), Unit);
5716 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5718 Ty = CreateSelfType(VD->
getType(), Ty);
5721 const unsigned Line =
5725 const llvm::DataLayout &target = CGM.getDataLayout();
5732 addr.push_back(llvm::dwarf::DW_OP_deref);
5733 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5736 addr.push_back(llvm::dwarf::DW_OP_deref);
5737 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5740 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5742 addr.push_back(llvm::dwarf::DW_OP_deref);
5743 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5745 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5751 auto *D = DBuilder.createAutoVariable(
5753 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5756 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5757 LexicalBlockStack.back(), CurInlinedAt);
5758 auto *
Expr = DBuilder.createExpression(addr);
5760 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5762 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5765llvm::DILocalVariable *
5768 bool UsePointerValue) {
5769 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5770 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5774struct BlockLayoutChunk {
5775 uint64_t OffsetInBits;
5778bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5779 return l.OffsetInBits < r.OffsetInBits;
5783void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5785 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5786 SmallVectorImpl<llvm::Metadata *> &Fields) {
5790 if (CGM.getLangOpts().OpenCL) {
5791 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5792 BlockLayout.getElementOffsetInBits(0),
5794 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5795 BlockLayout.getElementOffsetInBits(1),
5799 BlockLayout.getElementOffsetInBits(0),
5801 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5802 BlockLayout.getElementOffsetInBits(1),
5806 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5807 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5808 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5809 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5810 BlockLayout.getElementOffsetInBits(3),
5812 Fields.push_back(createFieldType(
5817 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5824 llvm::AllocaInst *Alloca,
5826 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5832 llvm::DIFile *tunit = getOrCreateFile(loc);
5833 unsigned line = getLineNumber(loc);
5834 unsigned column = getColumnNumber(loc);
5839 const llvm::StructLayout *blockLayout =
5843 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5852 BlockLayoutChunk chunk;
5853 chunk.OffsetInBits =
5854 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5855 chunk.Capture =
nullptr;
5856 chunks.push_back(chunk);
5860 for (
const auto &capture :
blockDecl->captures()) {
5861 const VarDecl *variable = capture.getVariable();
5868 BlockLayoutChunk chunk;
5869 chunk.OffsetInBits =
5870 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5871 chunk.Capture = &capture;
5872 chunks.push_back(chunk);
5876 llvm::array_pod_sort(chunks.begin(), chunks.end());
5878 for (
const BlockLayoutChunk &Chunk : chunks) {
5879 uint64_t offsetInBits = Chunk.OffsetInBits;
5886 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5888 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5889 type = CGM.getContext().getCanonicalTagType(RDecl);
5891 llvm_unreachable(
"unexpected block declcontext");
5893 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5894 offsetInBits, tunit, tunit));
5899 StringRef name = variable->
getName();
5901 llvm::DIType *fieldType;
5903 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5908 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5909 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5910 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5911 PtrInfo.
Width, Align, offsetInBits,
5912 llvm::DINode::FlagZero, fieldType);
5916 offsetInBits, Align, tunit, tunit);
5918 fields.push_back(fieldType);
5922 llvm::raw_svector_ostream(typeName)
5923 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5925 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5927 llvm::DIType *
type =
5928 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5929 CGM.getContext().toBits(block.
BlockSize), 0,
5930 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5931 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5934 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5938 auto *debugVar = DBuilder.createParameterVariable(
5939 scope, Name, ArgNo, tunit, line,
type,
5940 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5943 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5944 llvm::DILocation::get(CGM.getLLVMContext(), line,
5945 column, scope, CurInlinedAt),
5946 Builder.GetInsertBlock());
5949llvm::DIDerivedType *
5950CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5955 if (MI != StaticDataMemberCache.end()) {
5956 assert(MI->second &&
"Static data member declaration should still exist");
5967llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5968 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5969 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5970 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5972 for (
const auto *Field : RD->
fields()) {
5973 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5974 StringRef FieldName = Field->getName();
5977 if (FieldName.empty()) {
5978 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5979 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5980 LineNo, LinkageName, Var, DContext);
5984 GVE = DBuilder.createGlobalVariableExpression(
5985 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5986 Var->hasLocalLinkage());
5987 Var->addDebugInfo(GVE);
5999 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6004 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6015 struct ReferencesAnonymous
6017 bool RefAnon =
false;
6018 bool VisitRecordType(RecordType *RT) {
6026 ReferencesAnonymous RT;
6039struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6040 bool Reconstitutable =
true;
6041 bool VisitVectorType(VectorType *FT) {
6042 Reconstitutable =
false;
6045 bool VisitAtomicType(AtomicType *FT) {
6046 Reconstitutable =
false;
6049 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6052 const EnumDecl *ED = ET->getDecl();
6054 Reconstitutable =
false;
6058 Reconstitutable =
false;
6063 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6067 return Reconstitutable;
6069 bool VisitRecordType(RecordType *RT,
bool =
false) {
6071 Reconstitutable =
false;
6081 ReconstitutableType T;
6083 return T.Reconstitutable;
6086bool CGDebugInfo::HasReconstitutableArgs(
6087 ArrayRef<TemplateArgument> Args)
const {
6088 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6128 llvm_unreachable(
"Other, unresolved, template arguments should "
6129 "not be seen here");
6134std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6135 bool *NameIsSimplified)
const {
6137 llvm::raw_string_ostream
OS(Name);
6138 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6141 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6142 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6144 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6145 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6147 std::optional<TemplateArgs> Args;
6149 bool IsOperatorOverload =
false;
6150 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6151 Args = GetTemplateArgs(RD);
6152 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6153 Args = GetTemplateArgs(FD);
6155 IsOperatorOverload |=
6158 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6159 Args = GetTemplateArgs(VD);
6183 bool Reconstitutable =
6184 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6186 PrintingPolicy PP = getPrintingPolicy();
6188 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6193 if (NameIsSimplified)
6194 *NameIsSimplified =
true;
6195 bool Mangled = TemplateNamesKind ==
6196 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6202 std::string EncodedOriginalName;
6203 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6208 printTemplateArgumentList(OS, Args->Args, PP);
6209 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6211 std::string CanonicalOriginalName;
6212 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6214 assert(EncodedOriginalName == CanonicalOriginalName);
6223 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6224 if (D->
hasAttr<NoDebugAttr>())
6227 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6228 return GetName(D,
true);
6234 if (Cached != DeclCache.end())
6235 return Var->addDebugInfo(
6239 llvm::DIFile *Unit =
nullptr;
6240 llvm::DIScope *DContext =
nullptr;
6242 StringRef DeclName, LinkageName;
6244 llvm::MDTuple *TemplateParameters =
nullptr;
6245 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6246 TemplateParameters, DContext);
6250 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6255 if (T->isUnionType() && DeclName.empty()) {
6256 const auto *RD = T->castAsRecordDecl();
6258 "unnamed non-anonymous struct or union?");
6259 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6264 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6265 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6266 if (D->
hasAttr<CUDASharedAttr>())
6269 else if (D->
hasAttr<CUDAConstantAttr>())
6273 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6275 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6276 GVE = DBuilder.createGlobalVariableExpression(
6277 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6278 Var->hasLocalLinkage(),
true,
6279 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6280 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6281 Align, Annotations);
6282 Var->addDebugInfo(GVE);
6288 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6289 if (VD->
hasAttr<NoDebugAttr>())
6291 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6292 return GetName(VD,
true);
6297 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6298 StringRef Name = VD->
getName();
6299 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6301 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6303 if (CGM.getCodeGenOpts().EmitCodeView) {
6314 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6315 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6316 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6326 auto *VarD = dyn_cast<VarDecl>(VD);
6327 if (VarD && VarD->isStaticDataMember()) {
6329 getDeclContextDescriptor(VarD);
6334 RetainedTypes.push_back(
6335 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6339 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6341 auto &GV = DeclCache[VD];
6345 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6346 llvm::MDTuple *TemplateParameters =
nullptr;
6350 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6351 TemplateParameters = parameterNodes.get();
6354 GV.reset(DBuilder.createGlobalVariableExpression(
6355 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6356 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6357 TemplateParameters, Align));
6362 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6363 if (D->
hasAttr<NoDebugAttr>())
6367 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6368 StringRef Name = D->
getName();
6369 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6371 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6372 llvm::DIGlobalVariableExpression *GVE =
6373 DBuilder.createGlobalVariableExpression(
6374 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6375 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6376 Var->addDebugInfo(GVE);
6383 if (CGM.getCodeGenOpts().getDebugInfo() <=
6384 llvm::codegenoptions::DebugLineTablesOnly)
6387 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6391 llvm::DIFile *Unit = DIL->getFile();
6392 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6397 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6398 llvm::Value *Var = Load->getPointerOperand();
6403 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6404 return DbgDeclare->getVariable()->getType() ==
Type;
6406 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6410 llvm::DILocalVariable *D =
6411 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6412 Type,
false, llvm::DINode::FlagArtificial);
6414 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6415 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6425 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6429 if (D->
hasAttr<NoDebugAttr>())
6432 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6447 if (!(DI = getDeclarationOrDefinition(
6448 AliaseeDecl.getCanonicalDecl().getDecl())))
6451 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6454 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6455 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6469 llvm::DIFile *
File = getOrCreateFile(Loc);
6470 llvm::DIGlobalVariableExpression *Debug =
6471 DBuilder.createGlobalVariableExpression(
6472 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6473 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6474 GV->addDebugInfo(Debug);
6477llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6478 if (!LexicalBlockStack.empty())
6479 return LexicalBlockStack.back();
6480 llvm::DIScope *Mod = getParentModuleOrNull(D);
6481 return getContextDescriptor(D, Mod ? Mod : TheCU);
6485 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6489 CGM.getCodeGenOpts().DebugExplicitImport) {
6493 DBuilder.createImportedModule(
6495 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6500 if (llvm::DINode *
Target =
6503 DBuilder.createImportedDeclaration(
6505 getOrCreateFile(Loc), getLineNumber(Loc));
6510 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6513 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6515 for (
const auto *USD : UD.
shadows()) {
6520 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6521 if (
const auto *AT = FD->getType()
6524 if (AT->getDeducedType().isNull())
6535 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6538 "We shouldn't be codegening an invalid UsingEnumDecl"
6539 " containing no decls");
6541 for (
const auto *USD : UD.
shadows())
6546 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6548 if (
Module *M = ID.getImportedModule()) {
6550 auto Loc = ID.getLocation();
6551 DBuilder.createImportedDeclaration(
6552 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6553 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6554 getLineNumber(Loc));
6558llvm::DIImportedEntity *
6560 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6562 auto &VH = NamespaceAliasCache[&NA];
6565 llvm::DIImportedEntity *R;
6567 if (
const auto *Underlying =
6570 R = DBuilder.createImportedDeclaration(
6573 getLineNumber(Loc), NA.
getName());
6575 R = DBuilder.createImportedDeclaration(
6578 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6584CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6588 auto I = NamespaceCache.find(NSDecl);
6589 if (I != NamespaceCache.end())
6592 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6594 llvm::DINamespace *NS =
6595 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6596 NamespaceCache[NSDecl].reset(NS);
6601 assert(TheCU &&
"no main compile unit");
6602 TheCU->setDWOId(Signature);
6608 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6609 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6611 ? CreateTypeDefinition(E.Type, E.Unit)
6613 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6617 for (
const auto &P : ObjCMethodCache) {
6618 if (P.second.empty())
6621 QualType QTy(P.first->getTypeForDecl(), 0);
6623 assert(It != TypeCache.end());
6625 llvm::DICompositeType *InterfaceDecl =
6628 auto CurElts = InterfaceDecl->getElements();
6632 for (
auto &SubprogramDirect : P.second)
6633 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6634 EltTys.push_back(SubprogramDirect.getPointer());
6636 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6637 DBuilder.replaceArrays(InterfaceDecl, Elements);
6640 for (
const auto &P : ReplaceMap) {
6643 assert(Ty->isForwardDecl());
6645 auto It = TypeCache.find(P.first);
6646 assert(It != TypeCache.end());
6649 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6653 for (
const auto &P : FwdDeclReplaceMap) {
6656 llvm::Metadata *Repl;
6658 auto It = DeclCache.find(P.first);
6662 if (It == DeclCache.end())
6667 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6668 Repl = GVE->getVariable();
6674 for (
auto &RT : RetainedTypes)
6675 if (
auto MD = TypeCache[RT])
6678 DBuilder.finalize();
6683 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6684 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6685 DBuilder.retainType(DieTy);
6689 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6690 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6691 DBuilder.retainType(DieTy);
6695 if (LexicalBlockStack.empty())
6696 return llvm::DebugLoc();
6698 llvm::MDNode *
Scope = LexicalBlockStack.back();
6699 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6700 getColumnNumber(Loc),
Scope);
6706 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6707 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6708 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6709 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6710 return llvm::DINode::FlagZero;
6715 bool SupportsDWARFv4Ext =
6716 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6717 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6718 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6720 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6721 return llvm::DINode::FlagZero;
6723 return llvm::DINode::FlagAllCallsDescribed;
6734 return DBuilder.createConstantValueExpression(
6735 Val.
getFloat().bitcastToAPInt().getZExtValue());
6740 llvm::APSInt
const &ValInt = Val.
getInt();
6741 std::optional<uint64_t> ValIntOpt;
6742 if (ValInt.isUnsigned())
6743 ValIntOpt = ValInt.tryZExtValue();
6744 else if (
auto tmp = ValInt.trySExtValue())
6747 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6750 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6755CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6757 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6758 CGF.CurLexicalScope =
this;
6760 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6765 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6778#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6780 Label = "__ubsan_check_" #Name; \
6784#undef SANITIZER_CHECK
6795#define SANITIZER(NAME, ID) \
6796 case SanitizerKind::SO_##ID: \
6797 Label = "__ubsan_check_" NAME; \
6799#include "clang/Basic/Sanitizers.def"
6801 llvm_unreachable(
"unexpected sanitizer kind");
6806 for (
unsigned int i = 0; i < Label.length(); i++)
6807 if (!std::isalpha(Label[i]))
6816 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6818 if (!DI || !CheckDebugLoc)
6819 return CheckDebugLoc;
6820 const auto &AnnotateDebugInfo =
6821 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6822 if (AnnotateDebugInfo.empty())
6823 return CheckDebugLoc;
6826 if (Ordinals.size() == 1)
6831 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6835 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6836 "ubsan_interface.h",
6838 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6841 return CheckDebugLoc;
6849 assert(!CGF->IsSanitizerScope);
6850 CGF->IsSanitizerScope =
true;
6854 assert(CGF->IsSanitizerScope);
6855 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
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.
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.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isStaticDataMember() const
Determines whether this is a static data member.
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,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
__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.