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();
2808 const TemplateParameterList *TList =
T->getTemplateParameters();
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());
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:
4356 case Type::LateParsedAttr:
4358 case Type::Attributed:
4359 case Type::BTFTagAttributed:
4360 case Type::Adjusted:
4362 case Type::DeducedTemplateSpecialization:
4365 case Type::MacroQualified:
4366 case Type::SubstTemplateTypeParm:
4367 case Type::TypeOfExpr:
4369 case Type::Decltype:
4370 case Type::PackIndexing:
4371 case Type::UnaryTransform:
4375 llvm_unreachable(
"type should have been unwrapped!");
4378llvm::DICompositeType *
4379CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4380 QualType QTy(Ty, 0);
4382 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4387 if (
T && !
T->isForwardDecl())
4391 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4396 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4399 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4404llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4406 bool NameIsSimplified =
false;
4409 StringRef RDName = getClassName(RD, &NameIsSimplified);
4411 llvm::DIFile *DefUnit =
nullptr;
4414 DefUnit = getOrCreateFile(Loc);
4415 Line = getLineNumber(Loc);
4418 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4422 auto *
T = cast_or_null<llvm::DICompositeType>(
4423 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4431 return getOrCreateRecordFwdDecl(Ty, RDContext);
4444 auto Flags = llvm::DINode::FlagZero;
4445 if (NameIsSimplified)
4446 Flags |= llvm::DINode::FlagNameIsSimplified;
4447 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4449 Flags |= llvm::DINode::FlagTypePassByReference;
4451 Flags |= llvm::DINode::FlagTypePassByValue;
4454 if (!CXXRD->isTrivial())
4455 Flags |= llvm::DINode::FlagNonTrivial;
4458 if (CXXRD->isAnonymousStructOrUnion())
4459 Flags |= llvm::DINode::FlagExportSymbols;
4462 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4465 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4466 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4468 Flags, Identifier, Annotations);
4472 switch (RealDecl->getTag()) {
4474 llvm_unreachable(
"invalid composite type tag");
4476 case llvm::dwarf::DW_TAG_array_type:
4477 case llvm::dwarf::DW_TAG_enumeration_type:
4482 if (Identifier.empty())
4486 case llvm::dwarf::DW_TAG_structure_type:
4487 case llvm::dwarf::DW_TAG_union_type:
4488 case llvm::dwarf::DW_TAG_class_type:
4491 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4495 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4496 CXXRecordDecl *TemplateDecl =
4497 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4498 RegionMap[TemplateDecl].reset(RealDecl);
4500 RegionMap[RD].reset(RealDecl);
4502 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4504 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4505 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4506 CollectCXXTemplateParams(TSpecial, DefUnit));
4510void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4511 llvm::DICompositeType *RealDecl) {
4513 llvm::DIType *ContainingType =
nullptr;
4514 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4518 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4525 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4526 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4528 ContainingType = RealDecl;
4530 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4533llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4534 StringRef Name, uint64_t *Offset) {
4535 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4536 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4539 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4540 *Offset, llvm::DINode::FlagZero, FieldTy);
4541 *Offset += FieldSize;
4545void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4547 StringRef &LinkageName,
4548 llvm::DIScope *&FDContext,
4549 llvm::DINodeArray &TParamsArray,
4550 llvm::DINode::DIFlags &Flags) {
4552 bool NameIsSimplified =
false;
4553 Name = getFunctionName(FD, &NameIsSimplified);
4554 if (NameIsSimplified)
4555 Flags |= llvm::DINode::FlagNameIsSimplified;
4556 Name = getFunctionName(FD);
4559 LinkageName = CGM.getMangledName(GD);
4561 Flags |= llvm::DINode::FlagPrototyped;
4565 if (LinkageName == Name ||
4566 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4567 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4568 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4569 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4570 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4571 LinkageName = StringRef();
4575 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4576 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4577 CGM.getCodeGenOpts().EmitCodeView)) {
4578 if (
const NamespaceDecl *NSDecl =
4580 FDContext = getOrCreateNamespace(NSDecl);
4581 else if (
const RecordDecl *RDecl =
4583 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4584 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4587 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4590 Flags |= llvm::DINode::FlagNoReturn;
4592 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4596void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4597 unsigned &LineNo, QualType &
T,
4598 StringRef &Name, StringRef &LinkageName,
4599 llvm::MDTuple *&TemplateParameters,
4600 llvm::DIScope *&VDContext) {
4609 llvm::APInt ConstVal(32, 1);
4610 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4612 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4619 LinkageName = CGM.getMangledName(VD);
4620 if (LinkageName == Name)
4621 LinkageName = StringRef();
4624 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4625 TemplateParameters = parameterNodes.get();
4627 TemplateParameters =
nullptr;
4645 DC = CGM.getContext().getTranslationUnitDecl();
4647 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4648 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4651llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4653 llvm::DINodeArray TParamsArray;
4654 StringRef Name, LinkageName;
4655 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4656 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4658 llvm::DIFile *Unit = getOrCreateFile(Loc);
4659 llvm::DIScope *DContext = Unit;
4660 unsigned Line = getLineNumber(Loc);
4661 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4666 SmallVector<QualType, 16> ArgTypes;
4667 for (
const ParmVarDecl *Parm : FD->
parameters())
4668 ArgTypes.push_back(Parm->getType());
4671 QualType FnType = CGM.getContext().getFunctionType(
4672 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4674 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4675 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4676 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4680 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4681 return DBuilder.createFunction(
4682 DContext, Name, LinkageName, Unit,
Line,
4683 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4684 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4686 CGM.getCodeGenOpts().DebugKeyInstructions);
4689 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4690 DContext, Name, LinkageName, Unit,
Line,
4691 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4692 TParamsArray.get(), getFunctionDeclaration(FD));
4694 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4695 std::make_tuple(CanonDecl),
4696 std::make_tuple(SP));
4700llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4701 return getFunctionFwdDeclOrStub(GD,
false);
4704llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4705 return getFunctionFwdDeclOrStub(GD,
true);
4708llvm::DIGlobalVariable *
4709CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4711 StringRef Name, LinkageName;
4713 llvm::DIFile *Unit = getOrCreateFile(Loc);
4714 llvm::DIScope *DContext = Unit;
4715 unsigned Line = getLineNumber(Loc);
4716 llvm::MDTuple *TemplateParameters =
nullptr;
4718 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4721 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4722 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4724 FwdDeclReplaceMap.emplace_back(
4725 std::piecewise_construct,
4727 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4731llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4736 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4737 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4738 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4742 if (I != DeclCache.end()) {
4744 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4745 return GVE->getVariable();
4753 if (IE != ImportedDeclCache.end()) {
4754 auto N = IE->second;
4755 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4757 return dyn_cast_or_null<llvm::DINode>(N);
4762 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4763 return getFunctionForwardDeclaration(FD);
4764 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4765 return getGlobalVariableForwardDeclaration(VD);
4770llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4771 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4774 const auto *FD = dyn_cast<FunctionDecl>(D);
4779 auto *S = getDeclContextDescriptor(D);
4782 if (MI == SPCache.end()) {
4784 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4788 if (MI != SPCache.end()) {
4789 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4790 if (SP && !SP->isDefinition())
4794 for (
auto *NextFD : FD->
redecls()) {
4795 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4796 if (MI != SPCache.end()) {
4797 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4798 if (SP && !SP->isDefinition())
4805llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4806 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4807 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4808 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4811 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4815 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4819 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4828 QualType QTy(
ID->getTypeForDecl(), 0);
4829 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4830 if (It == TypeCache.end())
4833 llvm::DISubprogram *FD = DBuilder.createFunction(
4834 InterfaceType, getObjCMethodName(OMD), StringRef(),
4835 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4836 DBuilder.finalizeSubprogram(FD);
4843llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4848 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4849 !CGM.getCodeGenOpts().EmitCodeView))
4852 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4854 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4857 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4860 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4861 return getOrCreateMethodType(
Method, F);
4863 const auto *FTy = FnType->
getAs<FunctionType>();
4866 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4868 SmallVector<llvm::Metadata *, 16> Elts;
4871 QualType ResultTy = OMethod->getReturnType();
4874 if (ResultTy == CGM.getContext().getObjCInstanceType())
4875 ResultTy = CGM.getContext().getPointerType(
4876 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4878 Elts.push_back(getOrCreateType(ResultTy, F));
4880 QualType SelfDeclTy;
4881 if (
auto *SelfDecl = OMethod->getSelfDecl())
4882 SelfDeclTy = SelfDecl->getType();
4883 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4886 if (!SelfDeclTy.
isNull())
4888 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4890 Elts.push_back(DBuilder.createArtificialType(
4891 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4893 for (
const auto *PI : OMethod->parameters())
4894 Elts.push_back(getOrCreateType(PI->getType(), F));
4896 if (OMethod->isVariadic())
4897 Elts.push_back(DBuilder.createUnspecifiedParameter());
4899 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4900 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4906 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4907 if (FD->isVariadic()) {
4908 SmallVector<llvm::Metadata *, 16> EltTys;
4909 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4910 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4912 EltTys.push_back(getOrCreateType(ParamType, F));
4913 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4914 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4915 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4928 CC = SrcFnTy->getCallConv();
4930 for (
const VarDecl *VD : Args)
4931 ArgTypes.push_back(VD->
getType());
4932 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4938 llvm::Function *Fn,
bool CurFuncIsThunk) {
4940 StringRef LinkageName;
4942 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4945 bool HasDecl = (D !=
nullptr);
4947 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4948 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4949 llvm::DIFile *Unit = getOrCreateFile(Loc);
4950 llvm::DIScope *FDContext = Unit;
4951 llvm::DINodeArray TParamsArray;
4952 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4955 LinkageName = Fn->getName();
4956 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4958 auto FI = SPCache.find(FD->getCanonicalDecl());
4959 if (FI != SPCache.end()) {
4960 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4961 if (SP && SP->isDefinition()) {
4962 LexicalBlockStack.emplace_back(SP);
4963 RegionMap[D].reset(SP);
4967 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4968 TParamsArray, Flags);
4971 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4972 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4973 Name = getObjCMethodName(OMD);
4974 Flags |= llvm::DINode::FlagPrototyped;
4980 if (Name != Fn->getName())
4981 LinkageName = Fn->getName();
4983 Name = Fn->getName();
4988 Flags |= llvm::DINode::FlagPrototyped;
4990 Name.consume_front(
"\01");
4994 "Unexpected DynamicInitKind !");
4998 Flags |= llvm::DINode::FlagArtificial;
5004 Flags |= llvm::DINode::FlagThunk;
5006 if (Fn->hasLocalLinkage())
5007 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5008 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5009 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5012 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5013 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5015 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5016 unsigned ScopeLine = getLineNumber(ScopeLoc);
5017 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5018 llvm::DISubprogram *
Decl =
nullptr;
5019 llvm::DINodeArray Annotations =
nullptr;
5022 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5023 : getFunctionDeclaration(D);
5024 Annotations = CollectBTFDeclTagAnnotations(D);
5032 llvm::DISubprogram *SP = DBuilder.createFunction(
5033 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5034 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5035 Annotations,
"", KeyInstructions);
5036 Fn->setSubprogram(SP);
5045 LexicalBlockStack.emplace_back(SP);
5048 RegionMap[D].reset(SP);
5052 QualType FnType, llvm::Function *Fn) {
5054 StringRef LinkageName;
5060 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5061 return GetName(D,
true);
5064 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5065 llvm::DIFile *Unit = getOrCreateFile(Loc);
5066 bool IsDeclForCallSite = Fn ?
true :
false;
5067 llvm::DIScope *FDContext =
5068 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5069 llvm::DINodeArray TParamsArray;
5072 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5073 TParamsArray, Flags);
5074 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5075 Name = getObjCMethodName(OMD);
5076 Flags |= llvm::DINode::FlagPrototyped;
5078 llvm_unreachable(
"not a function or ObjC method");
5080 Name.consume_front(
"\01");
5083 Flags |= llvm::DINode::FlagArtificial;
5088 unsigned LineNo = getLineNumber(Loc);
5089 unsigned ScopeLine = 0;
5090 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5091 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5092 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5094 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5095 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5097 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5098 llvm::DISubprogram *SP = DBuilder.createFunction(
5099 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5100 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5106 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5107 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5108 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5111 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5112 DBuilder.createParameterVariable(
5113 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5114 llvm::DINode::FlagZero, ParamAnnotations);
5120 if (IsDeclForCallSite)
5121 Fn->setSubprogram(SP);
5125 llvm::CallBase *CI) {
5126 if (!shouldGenerateVirtualCallSite())
5132 assert(CI &&
"Invalid Call Instruction.");
5133 if (!CI->isIndirectCall())
5137 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5138 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5146 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5149 if (
Func->getSubprogram())
5157 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5172 auto FI = SPCache.find(FD->getCanonicalDecl());
5173 llvm::DISubprogram *SP =
nullptr;
5174 if (FI != SPCache.end())
5175 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5176 if (!SP || !SP->isDefinition())
5177 SP = getFunctionStub(GD);
5178 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5179 LexicalBlockStack.emplace_back(SP);
5185 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5194 if (CurLoc.isInvalid() ||
5195 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5196 LexicalBlockStack.empty())
5199 llvm::MDNode *
Scope = LexicalBlockStack.back();
5200 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5201 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5205 llvm::MDNode *Back =
nullptr;
5206 if (!LexicalBlockStack.empty())
5207 Back = LexicalBlockStack.back().get();
5208 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5210 getColumnNumber(CurLoc)));
5213void CGDebugInfo::AppendAddressSpaceXDeref(
5215 std::optional<unsigned> DWARFAddressSpace =
5217 if (!DWARFAddressSpace)
5220 Expr.push_back(llvm::dwarf::DW_OP_constu);
5221 Expr.push_back(*DWARFAddressSpace);
5222 Expr.push_back(llvm::dwarf::DW_OP_swap);
5223 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5232 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5233 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5234 LexicalBlockStack.back(), CurInlinedAt));
5236 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5240 CreateLexicalBlock(Loc);
5245 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5250 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5253 LexicalBlockStack.pop_back();
5257 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5258 unsigned RCount = FnBeginRegionCount.back();
5259 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5262 while (LexicalBlockStack.size() != RCount) {
5265 LexicalBlockStack.pop_back();
5267 FnBeginRegionCount.pop_back();
5269 if (Fn && Fn->getSubprogram())
5270 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5273CGDebugInfo::BlockByRefType
5274CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5275 uint64_t *XOffset) {
5278 uint64_t FieldSize, FieldOffset;
5279 uint32_t FieldAlign;
5281 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5286 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5287 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5289 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5290 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5293 if (HasCopyAndDispose) {
5296 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5298 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5300 bool HasByrefExtendedLayout;
5303 HasByrefExtendedLayout) &&
5304 HasByrefExtendedLayout) {
5307 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5316 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5319 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5322 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5327 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5328 FieldSize = CGM.getContext().getTypeSize(FType);
5329 FieldAlign = CGM.getContext().toBits(Align);
5331 *XOffset = FieldOffset;
5332 llvm::DIType *FieldTy = DBuilder.createMemberType(
5333 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5334 llvm::DINode::FlagZero, WrappedTy);
5335 EltTys.push_back(FieldTy);
5336 FieldOffset += FieldSize;
5338 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5339 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5340 llvm::DINode::FlagZero,
nullptr, Elements),
5344llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5345 llvm::Value *Storage,
5346 std::optional<unsigned> ArgNo,
5348 const bool UsePointerValue) {
5349 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5350 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5351 if (VD->
hasAttr<NoDebugAttr>())
5356 llvm::DIFile *Unit =
nullptr;
5357 if (!VarIsArtificial)
5361 if (VD->
hasAttr<BlocksAttr>())
5362 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5364 Ty = getOrCreateType(VD->
getType(), Unit);
5374 if (!VarIsArtificial) {
5378 SmallVector<uint64_t, 13> Expr;
5379 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5386 Flags |= llvm::DINode::FlagArtificial;
5390 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5391 AppendAddressSpaceXDeref(AddressSpace, Expr);
5395 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5398 Flags |= llvm::DINode::FlagObjectPointer;
5399 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5400 if (PVD->isExplicitObjectParameter())
5401 Flags |= llvm::DINode::FlagObjectPointer;
5409 StringRef Name = VD->
getName();
5410 if (!Name.empty()) {
5416 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5418 offset = CGM.getContext().toCharUnitsFromBits(
5421 Expr.push_back(llvm::dwarf::DW_OP_deref);
5422 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5424 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5427 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5439 for (
const auto *Field : RD->
fields()) {
5440 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5441 StringRef FieldName =
Field->getName();
5449 auto *D = DBuilder.createAutoVariable(
5450 Scope, FieldName, Unit,
Line, FieldTy,
5451 CGM.getCodeGenOpts().OptimizationLevel != 0,
5452 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5455 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5456 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5459 Builder.GetInsertBlock());
5467 if (UsePointerValue) {
5468 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5469 "Debug info already contains DW_OP_deref.");
5470 Expr.push_back(llvm::dwarf::DW_OP_deref);
5474 llvm::DILocalVariable *D =
nullptr;
5476 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5477 D = DBuilder.createParameterVariable(
5478 Scope, Name, *ArgNo, Unit,
Line, Ty,
5479 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5488 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5494 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5495 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5496 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5497 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5499 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5505 if (Iter != CoroutineParameterMappings.end()) {
5506 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5507 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5508 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5510 if (Iter2 != ParamDbgMappings.end())
5511 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5517 D = RemapCoroArgToLocalVar();
5520 D = DBuilder.createAutoVariable(
5521 Scope, Name, Unit,
Line, Ty,
5522 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5525 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5526 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5527 Column, Scope, CurInlinedAt),
5528 Builder.GetInsertBlock());
5533llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5534 llvm::Value *Storage,
5535 std::optional<unsigned> ArgNo,
5537 const bool UsePointerValue) {
5538 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5539 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5540 if (BD->
hasAttr<NoDebugAttr>())
5547 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5548 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5556 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5558 SmallVector<uint64_t, 3> Expr;
5559 AppendAddressSpaceXDeref(AddressSpace, Expr);
5564 if (UsePointerValue) {
5565 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5566 "Debug info already contains DW_OP_deref.");
5567 Expr.push_back(llvm::dwarf::DW_OP_deref);
5572 StringRef Name = BD->
getName();
5575 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5576 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5577 llvm::DINode::FlagZero, Align);
5579 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5580 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5581 const unsigned fieldIndex = FD->getFieldIndex();
5582 const clang::CXXRecordDecl *parent =
5583 (
const CXXRecordDecl *)FD->getParent();
5584 const ASTRecordLayout &layout =
5585 CGM.getContext().getASTRecordLayout(parent);
5587 if (FD->isBitField()) {
5588 const CGRecordLayout &RL =
5589 CGM.getTypes().getCGRecordLayout(FD->getParent());
5594 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5600 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5601 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5602 Expr.push_back(Info.
Offset);
5605 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5606 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5607 }
else if (fieldOffset != 0) {
5608 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5609 "Unexpected non-bitfield with non-byte-aligned offset");
5610 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5612 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5615 }
else if (
const ArraySubscriptExpr *ASE =
5616 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5617 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5618 const uint64_t value = IL->getValue().getZExtValue();
5619 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5622 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5623 Expr.push_back(CGM.getContext()
5624 .toCharUnitsFromBits(value * typeSize)
5631 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5632 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5633 Column, Scope, CurInlinedAt),
5634 Builder.GetInsertBlock());
5639llvm::DILocalVariable *
5642 const bool UsePointerValue) {
5643 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5645 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5647 EmitDeclare(B, Storage, std::nullopt, Builder,
5654 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5658 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5659 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5661 if (D->
hasAttr<NoDebugAttr>())
5665 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5671 StringRef Name = D->
getName();
5677 CGM.getCodeGenOpts().OptimizationLevel != 0);
5680 DBuilder.insertLabel(L,
5681 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5682 Scope, CurInlinedAt),
5683 Builder.GetInsertBlock()->end());
5686llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5688 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5691 return DBuilder.createObjectPointerType(Ty,
true);
5696 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5697 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5698 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5700 if (Builder.GetInsertBlock() ==
nullptr)
5702 if (VD->
hasAttr<NoDebugAttr>())
5705 bool isByRef = VD->
hasAttr<BlocksAttr>();
5707 uint64_t XOffset = 0;
5708 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5711 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5713 Ty = getOrCreateType(VD->
getType(), Unit);
5717 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5719 Ty = CreateSelfType(VD->
getType(), Ty);
5722 const unsigned Line =
5726 const llvm::DataLayout &target = CGM.getDataLayout();
5733 addr.push_back(llvm::dwarf::DW_OP_deref);
5734 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5737 addr.push_back(llvm::dwarf::DW_OP_deref);
5738 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5741 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5743 addr.push_back(llvm::dwarf::DW_OP_deref);
5744 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5746 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5752 auto *D = DBuilder.createAutoVariable(
5754 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5757 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5758 LexicalBlockStack.back(), CurInlinedAt);
5759 auto *
Expr = DBuilder.createExpression(addr);
5761 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5763 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5766llvm::DILocalVariable *
5769 bool UsePointerValue) {
5770 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5771 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5775struct BlockLayoutChunk {
5776 uint64_t OffsetInBits;
5779bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5780 return l.OffsetInBits < r.OffsetInBits;
5784void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5786 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5787 SmallVectorImpl<llvm::Metadata *> &Fields) {
5791 if (CGM.getLangOpts().OpenCL) {
5792 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5793 BlockLayout.getElementOffsetInBits(0),
5795 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5796 BlockLayout.getElementOffsetInBits(1),
5800 BlockLayout.getElementOffsetInBits(0),
5802 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5803 BlockLayout.getElementOffsetInBits(1),
5807 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5808 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5809 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5810 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5811 BlockLayout.getElementOffsetInBits(3),
5813 Fields.push_back(createFieldType(
5818 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5825 llvm::AllocaInst *Alloca,
5827 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5833 llvm::DIFile *tunit = getOrCreateFile(loc);
5834 unsigned line = getLineNumber(loc);
5835 unsigned column = getColumnNumber(loc);
5840 const llvm::StructLayout *blockLayout =
5844 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5853 BlockLayoutChunk chunk;
5854 chunk.OffsetInBits =
5855 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5856 chunk.Capture =
nullptr;
5857 chunks.push_back(chunk);
5861 for (
const auto &capture :
blockDecl->captures()) {
5862 const VarDecl *variable = capture.getVariable();
5869 BlockLayoutChunk chunk;
5870 chunk.OffsetInBits =
5871 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5872 chunk.Capture = &capture;
5873 chunks.push_back(chunk);
5877 llvm::array_pod_sort(chunks.begin(), chunks.end());
5879 for (
const BlockLayoutChunk &Chunk : chunks) {
5880 uint64_t offsetInBits = Chunk.OffsetInBits;
5887 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5889 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5890 type = CGM.getContext().getCanonicalTagType(RDecl);
5892 llvm_unreachable(
"unexpected block declcontext");
5894 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5895 offsetInBits, tunit, tunit));
5900 StringRef name = variable->
getName();
5902 llvm::DIType *fieldType;
5904 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5909 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5910 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5911 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5912 PtrInfo.
Width, Align, offsetInBits,
5913 llvm::DINode::FlagZero, fieldType);
5917 offsetInBits, Align, tunit, tunit);
5919 fields.push_back(fieldType);
5923 llvm::raw_svector_ostream(typeName)
5924 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5926 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5928 llvm::DIType *
type =
5929 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5930 CGM.getContext().toBits(block.
BlockSize), 0,
5931 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5932 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5935 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5939 auto *debugVar = DBuilder.createParameterVariable(
5940 scope, Name, ArgNo, tunit, line,
type,
5941 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5944 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5945 llvm::DILocation::get(CGM.getLLVMContext(), line,
5946 column, scope, CurInlinedAt),
5947 Builder.GetInsertBlock());
5950llvm::DIDerivedType *
5951CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5956 if (MI != StaticDataMemberCache.end()) {
5957 assert(MI->second &&
"Static data member declaration should still exist");
5968llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5969 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5970 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5971 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5973 for (
const auto *Field : RD->
fields()) {
5974 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5975 StringRef FieldName = Field->getName();
5978 if (FieldName.empty()) {
5979 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5980 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5981 LineNo, LinkageName, Var, DContext);
5985 GVE = DBuilder.createGlobalVariableExpression(
5986 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5987 Var->hasLocalLinkage());
5988 Var->addDebugInfo(GVE);
6000 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6005 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6016 struct ReferencesAnonymous
6018 bool RefAnon =
false;
6019 bool VisitRecordType(RecordType *RT) {
6027 ReferencesAnonymous RT;
6040struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6041 bool Reconstitutable =
true;
6042 bool VisitVectorType(VectorType *FT) {
6043 Reconstitutable =
false;
6046 bool VisitAtomicType(AtomicType *FT) {
6047 Reconstitutable =
false;
6050 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6053 const EnumDecl *ED = ET->getDecl();
6055 Reconstitutable =
false;
6059 Reconstitutable =
false;
6064 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6068 return Reconstitutable;
6070 bool VisitRecordType(RecordType *RT,
bool =
false) {
6072 Reconstitutable =
false;
6082 ReconstitutableType
T;
6084 return T.Reconstitutable;
6087bool CGDebugInfo::HasReconstitutableArgs(
6088 ArrayRef<TemplateArgument> Args)
const {
6089 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6129 llvm_unreachable(
"Other, unresolved, template arguments should "
6130 "not be seen here");
6135std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6136 bool *NameIsSimplified)
const {
6138 llvm::raw_string_ostream
OS(Name);
6139 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6142 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6143 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6145 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6146 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6148 std::optional<TemplateArgs> Args;
6150 bool IsOperatorOverload =
false;
6151 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6152 Args = GetTemplateArgs(RD);
6153 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6154 Args = GetTemplateArgs(FD);
6156 IsOperatorOverload |=
6159 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6160 Args = GetTemplateArgs(VD);
6184 bool Reconstitutable =
6185 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6187 PrintingPolicy PP = getPrintingPolicy();
6189 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6194 if (NameIsSimplified)
6195 *NameIsSimplified =
true;
6196 bool Mangled = TemplateNamesKind ==
6197 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6203 std::string EncodedOriginalName;
6204 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6209 printTemplateArgumentList(OS, Args->Args, PP);
6210 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6212 std::string CanonicalOriginalName;
6213 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6215 assert(EncodedOriginalName == CanonicalOriginalName);
6224 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6225 if (D->
hasAttr<NoDebugAttr>())
6228 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6229 return GetName(D,
true);
6235 if (Cached != DeclCache.end())
6236 return Var->addDebugInfo(
6240 llvm::DIFile *Unit =
nullptr;
6241 llvm::DIScope *DContext =
nullptr;
6243 StringRef DeclName, LinkageName;
6245 llvm::MDTuple *TemplateParameters =
nullptr;
6246 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6247 TemplateParameters, DContext);
6251 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6256 if (
T->isUnionType() && DeclName.empty()) {
6257 const auto *RD =
T->castAsRecordDecl();
6259 "unnamed non-anonymous struct or union?");
6260 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6265 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6266 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6267 if (D->
hasAttr<CUDASharedAttr>())
6270 else if (D->
hasAttr<CUDAConstantAttr>())
6274 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6276 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6277 GVE = DBuilder.createGlobalVariableExpression(
6278 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6279 Var->hasLocalLinkage(),
true,
6280 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6281 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6282 Align, Annotations);
6283 Var->addDebugInfo(GVE);
6289 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6290 if (VD->
hasAttr<NoDebugAttr>())
6292 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6293 return GetName(VD,
true);
6298 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6299 StringRef Name = VD->
getName();
6300 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6302 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6304 if (CGM.getCodeGenOpts().EmitCodeView) {
6315 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6316 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6317 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6327 auto *VarD = dyn_cast<VarDecl>(VD);
6328 if (VarD && VarD->isStaticDataMember()) {
6330 getDeclContextDescriptor(VarD);
6335 RetainedTypes.push_back(
6336 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6340 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6342 auto &GV = DeclCache[VD];
6346 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6347 llvm::MDTuple *TemplateParameters =
nullptr;
6351 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6352 TemplateParameters = parameterNodes.get();
6355 GV.reset(DBuilder.createGlobalVariableExpression(
6356 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6357 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6358 TemplateParameters, Align));
6363 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6364 if (D->
hasAttr<NoDebugAttr>())
6368 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6369 StringRef Name = D->
getName();
6370 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6372 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6373 llvm::DIGlobalVariableExpression *GVE =
6374 DBuilder.createGlobalVariableExpression(
6375 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6376 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6377 Var->addDebugInfo(GVE);
6384 if (CGM.getCodeGenOpts().getDebugInfo() <=
6385 llvm::codegenoptions::DebugLineTablesOnly)
6388 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6392 llvm::DIFile *Unit = DIL->getFile();
6393 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6398 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6399 llvm::Value *Var = Load->getPointerOperand();
6404 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6405 return DbgDeclare->getVariable()->getType() ==
Type;
6407 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6411 llvm::DILocalVariable *D =
6412 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6413 Type,
false, llvm::DINode::FlagArtificial);
6415 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6416 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6426 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6430 if (D->
hasAttr<NoDebugAttr>())
6433 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6448 if (!(DI = getDeclarationOrDefinition(
6449 AliaseeDecl.getCanonicalDecl().getDecl())))
6452 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6455 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6456 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6470 llvm::DIFile *
File = getOrCreateFile(Loc);
6471 llvm::DIGlobalVariableExpression *Debug =
6472 DBuilder.createGlobalVariableExpression(
6473 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6474 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6475 GV->addDebugInfo(Debug);
6478llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6479 if (!LexicalBlockStack.empty())
6480 return LexicalBlockStack.back();
6481 llvm::DIScope *Mod = getParentModuleOrNull(D);
6482 return getContextDescriptor(D, Mod ? Mod : TheCU);
6486 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6490 CGM.getCodeGenOpts().DebugExplicitImport) {
6494 DBuilder.createImportedModule(
6496 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6501 if (llvm::DINode *
Target =
6504 DBuilder.createImportedDeclaration(
6506 getOrCreateFile(Loc), getLineNumber(Loc));
6511 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6514 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6516 for (
const auto *USD : UD.
shadows()) {
6521 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6522 if (
const auto *AT = FD->getType()
6525 if (AT->getDeducedType().isNull())
6536 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6539 "We shouldn't be codegening an invalid UsingEnumDecl"
6540 " containing no decls");
6542 for (
const auto *USD : UD.
shadows())
6547 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6549 if (
Module *M = ID.getImportedModule()) {
6551 auto Loc = ID.getLocation();
6552 DBuilder.createImportedDeclaration(
6553 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6554 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6555 getLineNumber(Loc));
6559llvm::DIImportedEntity *
6561 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6563 auto &VH = NamespaceAliasCache[&NA];
6566 llvm::DIImportedEntity *R;
6568 if (
const auto *Underlying =
6571 R = DBuilder.createImportedDeclaration(
6574 getLineNumber(Loc), NA.
getName());
6576 R = DBuilder.createImportedDeclaration(
6579 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6585CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6589 auto I = NamespaceCache.find(NSDecl);
6590 if (I != NamespaceCache.end())
6593 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6595 llvm::DINamespace *NS =
6596 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6597 NamespaceCache[NSDecl].reset(NS);
6602 assert(TheCU &&
"no main compile unit");
6603 TheCU->setDWOId(Signature);
6609 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6610 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6612 ? CreateTypeDefinition(E.Type, E.Unit)
6614 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6618 for (
const auto &P : ObjCMethodCache) {
6619 if (P.second.empty())
6622 QualType QTy(P.first->getTypeForDecl(), 0);
6624 assert(It != TypeCache.end());
6626 llvm::DICompositeType *InterfaceDecl =
6629 auto CurElts = InterfaceDecl->getElements();
6633 for (
auto &SubprogramDirect : P.second)
6634 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6635 EltTys.push_back(SubprogramDirect.getPointer());
6637 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6638 DBuilder.replaceArrays(InterfaceDecl, Elements);
6641 for (
const auto &P : ReplaceMap) {
6644 assert(Ty->isForwardDecl());
6646 auto It = TypeCache.find(P.first);
6647 assert(It != TypeCache.end());
6650 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6654 for (
const auto &P : FwdDeclReplaceMap) {
6657 llvm::Metadata *Repl;
6659 auto It = DeclCache.find(P.first);
6663 if (It == DeclCache.end())
6668 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6669 Repl = GVE->getVariable();
6675 for (
auto &RT : RetainedTypes)
6676 if (
auto MD = TypeCache[RT])
6679 DBuilder.finalize();
6684 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6685 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6686 DBuilder.retainType(DieTy);
6690 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6691 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6692 DBuilder.retainType(DieTy);
6696 if (LexicalBlockStack.empty())
6697 return llvm::DebugLoc();
6699 llvm::MDNode *
Scope = LexicalBlockStack.back();
6700 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6701 getColumnNumber(Loc),
Scope);
6707 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6708 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6709 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6710 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6711 return llvm::DINode::FlagZero;
6716 bool SupportsDWARFv4Ext =
6717 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6718 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6719 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6721 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6722 return llvm::DINode::FlagZero;
6724 return llvm::DINode::FlagAllCallsDescribed;
6735 return DBuilder.createConstantValueExpression(
6736 Val.
getFloat().bitcastToAPInt().getZExtValue());
6741 llvm::APSInt
const &ValInt = Val.
getInt();
6742 std::optional<uint64_t> ValIntOpt;
6743 if (ValInt.isUnsigned())
6744 ValIntOpt = ValInt.tryZExtValue();
6745 else if (
auto tmp = ValInt.trySExtValue())
6748 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6751 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6756CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6758 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6759 CGF.CurLexicalScope =
this;
6761 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6766 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6779#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6781 Label = "__ubsan_check_" #Name; \
6785#undef SANITIZER_CHECK
6796#define SANITIZER(NAME, ID) \
6797 case SanitizerKind::SO_##ID: \
6798 Label = "__ubsan_check_" NAME; \
6800#include "clang/Basic/Sanitizers.def"
6802 llvm_unreachable(
"unexpected sanitizer kind");
6807 for (
unsigned int i = 0; i < Label.length(); i++)
6808 if (!std::isalpha(Label[i]))
6817 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6819 if (!DI || !CheckDebugLoc)
6820 return CheckDebugLoc;
6821 const auto &AnnotateDebugInfo =
6822 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6823 if (AnnotateDebugInfo.empty())
6824 return CheckDebugLoc;
6827 if (Ordinals.size() == 1)
6832 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6836 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6837 "ubsan_interface.h",
6839 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6842 return CheckDebugLoc;
6850 assert(!CGF->IsSanitizerScope);
6851 CGF->IsSanitizerScope =
true;
6855 assert(CGF->IsSanitizerScope);
6856 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.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
unsigned PrettyEnums
Whether to print enumerators with a matching enumerator name or via cast.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.