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) {
432 PP.MSVCFormatting =
true;
442 PP.PrintAsCanonical =
true;
443 PP.UsePreferredNames =
false;
444 PP.AlwaysIncludeTypeForTemplateArgument =
true;
453StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
454 bool *NameIsSimplified) {
455 return internString(GetName(FD,
false, NameIsSimplified));
458StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
459 SmallString<256> MethodName;
460 llvm::raw_svector_ostream
OS(MethodName);
463 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
464 OS << OID->getName();
465 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
466 OS << OID->getName();
467 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
468 if (OC->IsClassExtension()) {
469 OS << OC->getClassInterface()->getName();
471 OS << OC->getIdentifier()->getNameStart() <<
'('
472 << OC->getIdentifier()->getNameStart() <<
')';
474 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
475 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
479 return internString(
OS.str());
482StringRef CGDebugInfo::getSelectorName(Selector S) {
486StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
487 bool *NameIsSimplified) {
490 return internString(GetName(RD,
false, NameIsSimplified));
496 return II->getName();
501 if (CGM.getCodeGenOpts().EmitCodeView) {
504 "Typedef should not be in another decl context!");
505 assert(D->getDeclName().getAsIdentifierInfo() &&
506 "Typedef was not named!");
507 return D->getDeclName().getAsIdentifierInfo()->getName();
510 if (CGM.getLangOpts().CPlusPlus) {
513 ASTContext &Context = CGM.getContext();
517 Name = DD->getName();
518 else if (
const TypedefNameDecl *TND =
522 Name = TND->getName();
525 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
526 if (CXXRD->isLambda())
528 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
531 SmallString<256> UnnamedType(
"<unnamed-type-");
534 return internString(UnnamedType);
542std::optional<llvm::DIFile::ChecksumKind>
543CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
546 if (!CGM.getCodeGenOpts().EmitCodeView &&
547 CGM.getCodeGenOpts().DwarfVersion < 5)
550 SourceManager &SM = CGM.getContext().getSourceManager();
551 std::optional<llvm::MemoryBufferRef> MemBuffer = SM.
getBufferOrNone(FID);
555 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
556 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
558 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
559 return llvm::DIFile::CSK_MD5;
561 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
562 return llvm::DIFile::CSK_SHA1;
564 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
565 return llvm::DIFile::CSK_SHA256;
569 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
572std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &SM,
574 if (!CGM.getCodeGenOpts().EmbedSource)
577 bool SourceInvalid =
false;
586llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
587 SourceManager &SM = CGM.getContext().getSourceManager();
590 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
596 FileName = TheCU->getFile()->getFilename();
597 CSInfo = TheCU->getFile()->getChecksum();
600 if (Loc == CurLoc && CurLocFile)
607 FileName = TheCU->getFile()->getFilename();
615 auto It = DIFileCache.find(
FileName.data());
616 if (It != DIFileCache.end()) {
618 if (llvm::Metadata *
V = It->second)
623 SmallString<64> Checksum;
625 std::optional<llvm::DIFile::ChecksumKind> CSKind =
626 computeChecksum(FID, Checksum);
628 CSInfo.emplace(*CSKind, Checksum);
634llvm::DIFile *CGDebugInfo::createFile(
636 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
637 std::optional<StringRef> Source) {
641 std::string CurDir =
remapDIPath(getCurrentDirname());
642 SmallString<128> DirBuf;
643 SmallString<128> FileBuf;
644 if (llvm::sys::path::is_absolute(RemappedFile)) {
647 auto FileIt = llvm::sys::path::begin(RemappedFile);
648 auto FileE = llvm::sys::path::end(RemappedFile);
649 auto CurDirIt = llvm::sys::path::begin(CurDir);
650 auto CurDirE = llvm::sys::path::end(CurDir);
651 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
652 llvm::sys::path::append(DirBuf, *CurDirIt);
653 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
659 for (; FileIt != FileE; ++FileIt)
660 llvm::sys::path::append(FileBuf, *FileIt);
665 if (!llvm::sys::path::is_absolute(
FileName))
669 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
670 DIFileCache[
FileName.data()].reset(F);
675 return CGM.getCodeGenOpts().remapDebugPathPrefix(Path);
683 if (DebugLoc == CurLoc)
698 if (DebugLoc == CurLoc)
704StringRef CGDebugInfo::getCurrentDirname() {
712 assert(CGO.DwarfVersion <= 5);
714 llvm::dwarf::SourceLanguage LangTag;
717 LangTag = llvm::dwarf::DW_LANG_HLSL;
719 LangTag = llvm::dwarf::DW_LANG_HIP;
721 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
722 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
723 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
724 else if (LO.CPlusPlus14)
725 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
726 else if (LO.CPlusPlus11)
727 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
729 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
730 }
else if (LO.ObjC) {
731 LangTag = llvm::dwarf::DW_LANG_ObjC;
732 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
733 LangTag = llvm::dwarf::DW_LANG_OpenCL;
734 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
735 LangTag = llvm::dwarf::DW_LANG_C11;
737 LangTag = llvm::dwarf::DW_LANG_C99;
739 LangTag = llvm::dwarf::DW_LANG_C89;
745static llvm::DISourceLanguageName
754 llvm::dwarf::SourceLanguageName LangTag;
757 LangTag = llvm::dwarf::DW_LNAME_HLSL;
759 LangTag = llvm::dwarf::DW_LNAME_HIP;
760 }
else if (LO.ObjC) {
761 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
763 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
766 }
else if (LO.ObjC) {
767 LangTag = llvm::dwarf::DW_LNAME_ObjC;
768 }
else if (LO.OpenCL) {
769 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
771 LangTag = llvm::dwarf::DW_LNAME_C;
775 return llvm::DISourceLanguageName(LangTag, LangVersion);
778void CGDebugInfo::CreateCompileUnit() {
779 SmallString<64> Checksum;
780 std::optional<llvm::DIFile::ChecksumKind> CSKind;
781 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
791 SourceManager &SM = CGM.getContext().getSourceManager();
792 auto &CGO = CGM.getCodeGenOpts();
793 const LangOptions &LO = CGM.getLangOpts();
794 std::string MainFileName = CGO.MainFileName;
795 if (MainFileName.empty())
796 MainFileName =
"<stdin>";
802 std::string MainFileDir;
805 MainFileDir = std::string(MainFile->getDir().getName());
806 if (!llvm::sys::path::is_absolute(MainFileName)) {
807 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
808 llvm::sys::path::Style Style =
810 ? (CGM.getTarget().
getTriple().isOSWindows()
811 ? llvm::sys::path::Style::windows_backslash
812 : llvm::sys::path::Style::posix)
813 : llvm::sys::path::Style::native;
814 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
815 MainFileName = std::string(
816 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
823 if (MainFile->getName() == MainFileName &&
825 MainFile->getName().rsplit(
'.').second)
827 MainFileName = CGM.getModule().getName().str();
836 unsigned RuntimeVers = 0;
840 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
842 case llvm::codegenoptions::NoDebugInfo:
843 case llvm::codegenoptions::LocTrackingOnly:
844 EmissionKind = llvm::DICompileUnit::NoDebug;
846 case llvm::codegenoptions::DebugLineTablesOnly:
847 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
849 case llvm::codegenoptions::DebugDirectivesOnly:
850 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
852 case llvm::codegenoptions::DebugInfoConstructor:
853 case llvm::codegenoptions::LimitedDebugInfo:
854 case llvm::codegenoptions::FullDebugInfo:
855 case llvm::codegenoptions::UnusedTypeInfo:
856 EmissionKind = llvm::DICompileUnit::FullDebug;
861 auto &CGOpts = CGM.getCodeGenOpts();
867 CSInfo.emplace(*CSKind, Checksum);
868 llvm::DIFile *CUFile = DBuilder.createFile(
872 StringRef Sysroot, SDK;
873 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
874 StringRef FullSysroot = CGM.getHeaderSearchOpts().Sysroot;
875 if (CGM.getCodeGenOpts().DebugRecordSysroot)
876 Sysroot = FullSysroot;
877 auto B = llvm::sys::path::rbegin(FullSysroot);
878 auto E = llvm::sys::path::rend(FullSysroot);
880 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
885 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
886 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
887 CGOpts.DebugNameTable);
888 if (CGM.getTarget().getTriple().isNVPTX())
889 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
890 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
891 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
894 TheCU = DBuilder.createCompileUnit(
896 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
897 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
898 CGOpts.PrepareForThinLTO,
899 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
900 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
901 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
904llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
908#define BUILTIN_TYPE(Id, SingletonId)
909#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
910#include "clang/AST/BuiltinTypes.def"
911 case BuiltinType::Dependent:
912 llvm_unreachable(
"Unexpected builtin type");
913 case BuiltinType::NullPtr:
914 return DBuilder.createNullPtrType();
915 case BuiltinType::Void:
917 case BuiltinType::ObjCClass:
920 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
921 "objc_class", TheCU, TheCU->getFile(), 0);
923 case BuiltinType::ObjCId: {
934 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
935 "objc_class", TheCU, TheCU->getFile(), 0);
937 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
939 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
941 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
942 (uint64_t)0, 0, llvm::DINode::FlagZero,
943 nullptr, llvm::DINodeArray());
945 DBuilder.replaceArrays(
946 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
947 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
948 llvm::DINode::FlagZero, ISATy)));
951 case BuiltinType::ObjCSel: {
953 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
954 "objc_selector", TheCU,
955 TheCU->getFile(), 0);
959#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
960 case BuiltinType::Id: \
961 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
963#include "clang/Basic/OpenCLImageTypes.def"
964 case BuiltinType::OCLSampler:
965 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
966 case BuiltinType::OCLEvent:
967 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
968 case BuiltinType::OCLClkEvent:
969 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
970 case BuiltinType::OCLQueue:
971 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
972 case BuiltinType::OCLReserveID:
973 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
974#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
975 case BuiltinType::Id: \
976 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
977#include "clang/Basic/OpenCLExtensionTypes.def"
978#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
979 case BuiltinType::Id: \
980 return getOrCreateStructPtrType(#Name, SingletonId);
981#include "clang/Basic/HLSLIntangibleTypes.def"
983#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
984#include "clang/Basic/AArch64ACLETypes.def"
986 if (BT->
getKind() == BuiltinType::MFloat8) {
987 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
988 BTName = BT->
getName(CGM.getLangOpts());
991 return DBuilder.createBasicType(BTName, Size, Encoding);
993 ASTContext::BuiltinVectorTypeInfo Info =
995 BT->
getKind() == BuiltinType::SveCount
996 ? ASTContext::BuiltinVectorTypeInfo(
997 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
999 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
1006 "Unsupported number of vectors for svcount_t");
1008 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
1009 llvm::Metadata *BitStride =
nullptr;
1010 if (BT->
getKind() == BuiltinType::SveBool) {
1011 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1012 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1013 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
1014 }
else if (BT->
getKind() == BuiltinType::SveCount) {
1016 Info.
ElementType = CGM.getContext().UnsignedCharTy;
1019 llvm::Metadata *LowerBound, *UpperBound;
1020 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1021 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1022 if (Info.
EC.isScalable()) {
1023 unsigned NumElemsPerVG = NumElems / 2;
1024 SmallVector<uint64_t, 9> Expr(
1025 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1026 46, 0, llvm::dwarf::DW_OP_mul,
1027 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1028 UpperBound = DBuilder.createExpression(Expr);
1030 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1031 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1033 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1034 nullptr, LowerBound, UpperBound,
nullptr);
1035 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1036 llvm::DIType *ElemTy =
1037 getOrCreateType(Info.
ElementType, TheCU->getFile());
1039 return DBuilder.createVectorType( 0, Align, ElemTy,
1040 SubscriptArray, BitStride);
1044#define PPC_VECTOR_TYPE(Name, Id, size) \
1045 case BuiltinType::Id:
1046#include "clang/Basic/PPCTypes.def"
1049#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1050#include "clang/Basic/RISCVVTypes.def"
1052 ASTContext::BuiltinVectorTypeInfo Info =
1053 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1055 unsigned ElementCount = Info.
EC.getKnownMinValue();
1056 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1058 bool Fractional =
false;
1061 unsigned FixedSize = ElementCount * SEW;
1062 if (Info.
ElementType == CGM.getContext().BoolTy) {
1065 }
else if (FixedSize < 64) {
1068 LMUL = 64 / FixedSize;
1070 LMUL = FixedSize / 64;
1074 SmallVector<uint64_t, 12> Expr(
1078 {llvm::dwarf::DW_OP_bregx,
1081 llvm::dwarf::DW_OP_constu,
1083 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1085 Expr.push_back(llvm::dwarf::DW_OP_div);
1087 Expr.push_back(llvm::dwarf::DW_OP_mul);
1090 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1092 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1095 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1096 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1097 auto *UpperBound = DBuilder.createExpression(Expr);
1098 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1099 nullptr, LowerBound, UpperBound,
nullptr);
1100 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1101 llvm::DIType *ElemTy =
1102 getOrCreateType(Info.
ElementType, TheCU->getFile());
1105 return DBuilder.createVectorType(0, Align, ElemTy,
1109#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1110 case BuiltinType::Id: { \
1113 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1114 MangledName, TheCU, TheCU->getFile(), 0); \
1115 return SingletonId; \
1117#include "clang/Basic/WebAssemblyReferenceTypes.def"
1118#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1119 case BuiltinType::Id: { \
1122 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1123 TheCU, TheCU->getFile(), 0); \
1124 return SingletonId; \
1126#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1127 case BuiltinType::Id: { \
1130 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1131 return SingletonId; \
1133#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1134 case BuiltinType::Id: { \
1137 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1138 return SingletonId; \
1140#include "clang/Basic/AMDGPUTypes.def"
1141#define SPIRV_TYPE(Name, Id, SingletonId) \
1142 case BuiltinType::Id: \
1143 return getOrCreateStructPtrType(Name, SingletonId);
1144#include "clang/Basic/SPIRVTypes.def"
1145 case BuiltinType::UChar:
1146 case BuiltinType::Char_U:
1147 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1149 case BuiltinType::Char_S:
1150 case BuiltinType::SChar:
1151 Encoding = llvm::dwarf::DW_ATE_signed_char;
1153 case BuiltinType::Char8:
1154 case BuiltinType::Char16:
1155 case BuiltinType::Char32:
1156 Encoding = llvm::dwarf::DW_ATE_UTF;
1158 case BuiltinType::UShort:
1159 case BuiltinType::UInt:
1160 case BuiltinType::UInt128:
1161 case BuiltinType::ULong:
1162 case BuiltinType::WChar_U:
1163 case BuiltinType::ULongLong:
1164 Encoding = llvm::dwarf::DW_ATE_unsigned;
1166 case BuiltinType::Short:
1167 case BuiltinType::Int:
1168 case BuiltinType::Int128:
1169 case BuiltinType::Long:
1170 case BuiltinType::WChar_S:
1171 case BuiltinType::LongLong:
1172 Encoding = llvm::dwarf::DW_ATE_signed;
1174 case BuiltinType::Bool:
1175 Encoding = llvm::dwarf::DW_ATE_boolean;
1177 case BuiltinType::Half:
1178 case BuiltinType::Float:
1179 case BuiltinType::LongDouble:
1180 case BuiltinType::Float16:
1181 case BuiltinType::BFloat16:
1182 case BuiltinType::Float128:
1183 case BuiltinType::Double:
1184 case BuiltinType::Ibm128:
1190 Encoding = llvm::dwarf::DW_ATE_float;
1192 case BuiltinType::ShortAccum:
1193 case BuiltinType::Accum:
1194 case BuiltinType::LongAccum:
1195 case BuiltinType::ShortFract:
1196 case BuiltinType::Fract:
1197 case BuiltinType::LongFract:
1198 case BuiltinType::SatShortFract:
1199 case BuiltinType::SatFract:
1200 case BuiltinType::SatLongFract:
1201 case BuiltinType::SatShortAccum:
1202 case BuiltinType::SatAccum:
1203 case BuiltinType::SatLongAccum:
1204 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1206 case BuiltinType::UShortAccum:
1207 case BuiltinType::UAccum:
1208 case BuiltinType::ULongAccum:
1209 case BuiltinType::UShortFract:
1210 case BuiltinType::UFract:
1211 case BuiltinType::ULongFract:
1212 case BuiltinType::SatUShortAccum:
1213 case BuiltinType::SatUAccum:
1214 case BuiltinType::SatULongAccum:
1215 case BuiltinType::SatUShortFract:
1216 case BuiltinType::SatUFract:
1217 case BuiltinType::SatULongFract:
1218 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1222 BTName = BT->
getName(CGM.getLangOpts());
1225 return DBuilder.createBasicType(BTName, Size, Encoding);
1228llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1229 SmallString<32> Name;
1230 llvm::raw_svector_ostream
OS(Name);
1231 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1234 ? llvm::dwarf::DW_ATE_unsigned
1235 : llvm::dwarf::DW_ATE_signed;
1236 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1237 Encoding, llvm::DINode::FlagZero, 0,
1241llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1243 return getOrCreateType(Ty->getUnderlyingType(), U);
1246llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1248 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1250 Encoding = llvm::dwarf::DW_ATE_lo_user;
1253 return DBuilder.createBasicType(
"complex", Size, Encoding);
1267 return llvm::dwarf::DW_TAG_const_type;
1271 return llvm::dwarf::DW_TAG_volatile_type;
1275 return llvm::dwarf::DW_TAG_restrict_type;
1277 return (llvm::dwarf::Tag)0;
1280llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1281 llvm::DIFile *Unit) {
1282 QualifierCollector Qc;
1296 bool AuthenticatesNullValues =
1299 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1300 llvm::DIType *FromTy = getOrCreateType(QualType(
T, 0), Unit);
1301 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1302 ExtraDiscr, IsaPointer,
1303 AuthenticatesNullValues);
1305 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1306 return getOrCreateType(QualType(
T, 0), Unit);
1310 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
1314 return DBuilder.createQualifiedType(Tag, FromTy);
1317llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1318 llvm::DIFile *Unit) {
1327 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1332 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1338 return DBuilder.createQualifiedType(Tag, FromTy);
1341llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1342 llvm::DIFile *Unit) {
1348 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1350 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1354llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1355 llvm::DIFile *Unit) {
1356 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1362 case llvm::dwarf::DW_LANG_C_plus_plus:
1363 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1364 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1365 case llvm::dwarf::DW_LANG_HIP:
1367 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1377 case llvm::dwarf::DW_LNAME_C_plus_plus:
1378 case llvm::dwarf::DW_LNAME_HIP:
1380 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1391 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1392 SourceLang.hasVersionedName())
1394 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1398 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1424 llvm::DICompileUnit *TheCU) {
1442 llvm::DICompileUnit *TheCU) {
1448 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1450 if (RD->isDynamicClass() &&
1456 llvm::raw_svector_ostream Out(Identifier);
1463 llvm::dwarf::Tag Tag;
1465 Tag = llvm::dwarf::DW_TAG_structure_type;
1467 Tag = llvm::dwarf::DW_TAG_union_type;
1472 Tag = llvm::dwarf::DW_TAG_class_type;
1477llvm::DICompositeType *
1478CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1479 llvm::DIScope *Ctx) {
1481 if (llvm::DIType *
T = getTypeOrNull(QualType(Ty, 0)))
1483 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1484 const unsigned Line =
1486 StringRef RDName = getClassName(RD);
1493 Size = CGM.getContext().getTypeSize(Ty);
1495 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1500 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1501 if (!CXXRD->hasDefinition() ||
1502 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1503 Flags |= llvm::DINode::FlagNonTrivial;
1506 SmallString<256> Identifier;
1508 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1510 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1513 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1514 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1515 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1516 CollectCXXTemplateParams(TSpecial, DefUnit));
1517 ReplaceMap.emplace_back(
1518 std::piecewise_construct, std::make_tuple(Ty),
1519 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1523llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1526 llvm::DIFile *Unit) {
1531 std::optional<unsigned> DWARFAddressSpace =
1532 CGM.getTarget().getDWARFAddressSpace(
1533 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1535 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1536 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
1537 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1538 Size, Align, DWARFAddressSpace);
1540 SmallVector<llvm::Metadata *, 4> Annots;
1541 CollectBTFTypeTagAnnotations(PointeeTy, Annots);
1543 llvm::DINodeArray Annotations =
nullptr;
1544 if (Annots.size() > 0)
1545 Annotations = DBuilder.getOrCreateArray(Annots);
1546 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1547 Align, DWARFAddressSpace, StringRef(),
1552llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1553 llvm::DIType *&
Cache) {
1556 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1557 TheCU, TheCU->getFile(), 0);
1558 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1559 Cache = DBuilder.createPointerType(
Cache, Size);
1563uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1564 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1565 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1575 if (CGM.getLangOpts().OpenCL) {
1576 FType = CGM.getContext().IntTy;
1577 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1578 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1580 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1581 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1582 FType = CGM.getContext().IntTy;
1583 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1584 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1586 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1587 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1588 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1589 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1590 EltTys.push_back(DBuilder.createMemberType(
1591 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1592 FieldOffset, llvm::DINode::FlagZero, DescTy));
1593 FieldOffset += FieldSize;
1599llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1600 llvm::DIFile *Unit) {
1601 SmallVector<llvm::Metadata *, 8> EltTys;
1604 llvm::DINodeArray Elements;
1607 FType = CGM.getContext().UnsignedLongTy;
1608 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1609 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1611 Elements = DBuilder.getOrCreateArray(EltTys);
1614 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1617 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1618 FieldOffset, 0, Flags,
nullptr, Elements);
1623 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1625 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1628 Elements = DBuilder.getOrCreateArray(EltTys);
1634 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1635 Flags,
nullptr, Elements);
1637 return DBuilder.createPointerType(EltTy, Size);
1640static llvm::SmallVector<TemplateArgument>
1642 assert(Ty->isTypeAlias());
1651 ArrayRef SubstArgs = Ty->template_arguments();
1654 if (Param->isParameterPack()) {
1663 if (SubstArgs.empty()) {
1672 SpecArgs.push_back(SubstArgs.front());
1673 SubstArgs = SubstArgs.drop_front();
1678llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1679 llvm::DIFile *Unit) {
1680 assert(Ty->isTypeAlias());
1681 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1683 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1691 SmallString<128> NS;
1692 llvm::raw_svector_ostream
OS(NS);
1694 auto PP = getPrintingPolicy();
1697 SourceLocation Loc =
AliasDecl->getLocation();
1699 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1700 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1709 llvm::raw_string_ostream
OS(Name);
1711 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1712 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1713 !HasReconstitutableArgs(Args.Args))
1714 printTemplateArgumentList(OS, Args.Args, PP);
1716 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1717 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1718 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1722 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1724 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1741 return llvm::DINode::FlagZero;
1745 return llvm::DINode::FlagPrivate;
1747 return llvm::DINode::FlagProtected;
1749 return llvm::DINode::FlagPublic;
1751 return llvm::DINode::FlagZero;
1753 llvm_unreachable(
"unexpected access enumerator");
1756llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1757 llvm::DIFile *Unit) {
1758 llvm::DIType *Underlying =
1774 SmallVector<llvm::Metadata *, 4> Annots;
1775 llvm::DINodeArray Annotations;
1777 CollectBTFDeclTagAnnotations(Ty->
getDecl(), Annots);
1778 if (!Annots.empty())
1779 Annotations = DBuilder.getOrCreateArray(Annots);
1781 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1786 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1787 getOrCreateFile(Loc), getLineNumber(Loc),
1788 getDeclContextDescriptor(Ty->
getDecl()), Align,
1789 Flags, Annotations);
1797 if (
T.isSPIROrSPIRV())
1798 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1803 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1805 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1807 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1809 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1811 return llvm::dwarf::DW_CC_BORLAND_pascal;
1813 return llvm::dwarf::DW_CC_LLVM_Win64;
1815 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1819 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1821 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1823 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1825 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1827 return llvm::dwarf::DW_CC_LLVM_Swift;
1829 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1831 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1833 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1835 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1837 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1839 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1841 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1842#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1856 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1862 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1864 Flags |= llvm::DINode::FlagLValueReference;
1866 Flags |= llvm::DINode::FlagRValueReference;
1870llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1871 llvm::DIFile *Unit) {
1872 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1874 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1880 SmallVector<llvm::Metadata *, 16> EltTys;
1883 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1885 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1889 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1892 for (
const QualType &ParamType : FPT->param_types())
1893 EltTys.push_back(getOrCreateType(ParamType, Unit));
1894 if (FPT->isVariadic())
1895 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1898 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1899 llvm::DIType *F = DBuilder.createSubroutineType(
1900 EltTypeArray, Flags,
1905llvm::DIDerivedType *
1906CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1907 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1908 StringRef Name = BitFieldDecl->
getName();
1909 QualType Ty = BitFieldDecl->
getType();
1910 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1913 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1914 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1917 llvm::DIFile *
File = getOrCreateFile(Loc);
1918 unsigned Line = getLineNumber(Loc);
1920 const CGBitFieldInfo &BitFieldInfo =
1921 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1923 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1930 if (CGM.getDataLayout().isBigEndian())
1932 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1934 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1935 return DBuilder.createBitFieldMemberType(
1936 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1937 Flags, DebugType, Annotations);
1940llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1941 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1942 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1944 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1969 if (PreviousFieldsDI.empty())
1973 auto *PreviousMDEntry =
1974 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1975 auto *PreviousMDField =
1976 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1977 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1978 PreviousMDField->getSizeInBits() == 0)
1982 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1984 assert(PreviousBitfield->isBitField());
1986 if (!PreviousBitfield->isZeroLengthBitField())
1989 QualType Ty = PreviousBitfield->getType();
1990 SourceLocation Loc = PreviousBitfield->getLocation();
1991 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1992 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1993 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1995 llvm::DIFile *
File = getOrCreateFile(Loc);
1996 unsigned Line = getLineNumber(Loc);
2002 llvm::DINode::DIFlags Flags =
2004 llvm::DINodeArray Annotations =
2005 CollectBTFDeclTagAnnotations(*PreviousBitfield);
2006 return DBuilder.createBitFieldMemberType(
2007 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
2008 Flags, DebugType, Annotations);
2011llvm::DIType *CGDebugInfo::createFieldType(
2013 uint64_t offsetInBits,
uint32_t AlignInBits, llvm::DIFile *tunit,
2014 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
2015 llvm::DIType *debugType = getOrCreateType(
type, tunit);
2018 llvm::DIFile *file = getOrCreateFile(loc);
2019 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2022 auto Align = AlignInBits;
2023 if (!
type->isIncompleteArrayType()) {
2024 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2025 SizeInBits = TI.
Width;
2031 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2032 offsetInBits, flags, debugType, Annotations);
2036CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2037 llvm::DIFile *FileScope) {
2041 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2044 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2045 SP = DBuilder.createFunction(
2046 FileScope, FuncName, StringRef(),
2047 FileScope, 0, DIFnTy,
2049 llvm::DINode::FlagArtificial,
2050 llvm::DISubprogram::SPFlagDefinition,
2051 nullptr,
nullptr,
nullptr,
2052 nullptr, StringRef(),
2053 CGM.getCodeGenOpts().DebugKeyInstructions);
2060CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2062 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2064 assert(
Capture.capturesVariable());
2066 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2067 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2069 return CaptureDecl->
getName();
2072void CGDebugInfo::CollectRecordLambdaFields(
2073 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2074 llvm::DIType *RecordTy) {
2079 unsigned fieldno = 0;
2082 I != E; ++I, ++Field, ++fieldno) {
2083 const LambdaCapture &
Capture = *I;
2085 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2087 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2097 Loc =
Field->getLocation();
2098 }
else if (
Capture.capturesVariable()) {
2101 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2102 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2109 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2111 elements.push_back(createFieldType(
2113 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2119template <
typename T>
2120static llvm::Constant *
2131 return llvm::ConstantDataArray::get(Ctx, Vals);
2144 const QualType ElemQTy = ArrayTy->getElementType();
2151 switch (ElemBitWidth) {
2167llvm::DIDerivedType *
2168CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2169 const RecordDecl *RD) {
2173 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2174 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2176 unsigned LineNumber = getLineNumber(Var->
getLocation());
2177 StringRef VName = Var->
getName();
2181 llvm::Constant *
C =
nullptr;
2186 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2187 if (
Value->isFloat())
2188 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2189 if (
Value->isArray())
2195 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2196 ? llvm::dwarf::DW_TAG_variable
2197 : llvm::dwarf::DW_TAG_member;
2199 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2200 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2205void CGDebugInfo::CollectRecordNormalField(
2206 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2207 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2208 const RecordDecl *RD) {
2213 if (
name.empty() && !
type->isRecordType())
2216 llvm::DIType *FieldType;
2218 llvm::DIDerivedType *BitFieldType;
2219 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2220 if (llvm::DIType *Separator =
2221 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2222 elements.push_back(Separator);
2225 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2228 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2231 elements.push_back(FieldType);
2234void CGDebugInfo::CollectRecordNestedType(
2235 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2236 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2243 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2244 elements.push_back(nestedType);
2247void CGDebugInfo::CollectRecordFields(
2248 const RecordDecl *record, llvm::DIFile *tunit,
2249 SmallVectorImpl<llvm::Metadata *> &elements,
2250 llvm::DICompositeType *RecordTy) {
2251 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2253 if (CXXDecl && CXXDecl->
isLambda())
2254 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2256 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2259 unsigned fieldNo = 0;
2263 for (
const auto *I : record->
decls())
2264 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2265 if (
V->hasAttr<NoDebugAttr>())
2270 if (CGM.getCodeGenOpts().EmitCodeView &&
2278 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2279 if (MI != StaticDataMemberCache.end()) {
2280 assert(MI->second &&
2281 "Static data member declaration should still exist");
2282 elements.push_back(MI->second);
2284 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2285 elements.push_back(Field);
2287 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2288 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2289 elements, RecordTy, record);
2293 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2296 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2301 if (!nestedType->isImplicit() &&
2302 nestedType->getDeclContext() == record)
2303 CollectRecordNestedType(nestedType, elements);
2309llvm::DISubroutineType *
2310CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2311 llvm::DIFile *Unit) {
2312 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2314 return cast_or_null<llvm::DISubroutineType>(
2315 getOrCreateType(QualType(
Func, 0), Unit));
2318 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2319 ThisType =
Method->getThisType();
2321 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2324llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2325 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2326 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2328 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2331llvm::DISubroutineType *
2332CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2333 const FunctionProtoType *
Func,
2334 llvm::DIFile *Unit,
bool SkipFirst) {
2335 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2350 getOrCreateType(CGM.getContext().getFunctionType(
2351 Func->getReturnType(),
Func->getParamTypes(), EPI),
2353 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2354 assert(Args.size() &&
"Invalid number of arguments!");
2356 SmallVector<llvm::Metadata *, 16> Elts;
2359 Elts.push_back(Args[0]);
2361 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2365 if (!HasExplicitObjectParameter) {
2366 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2369 DBuilder.createObjectPointerType(ThisPtrType,
true);
2370 Elts.push_back(ThisPtrType);
2374 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2375 Elts.push_back(Args[i]);
2378 if (HasExplicitObjectParameter) {
2379 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2380 "Expected at least return type and object parameter.");
2381 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2384 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2386 return DBuilder.createSubroutineType(
2387 EltTypeArray, OriginalFunc->getFlags(),
2394 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2402CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2405 const bool IsCtorOrDtor =
2408 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2415 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2418 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2421 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2424 return CGM.getMangledName(
Method);
2427bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2430 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2433llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2434 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2437 StringRef MethodName = getFunctionName(
Method);
2438 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2440 StringRef MethodLinkageName;
2447 MethodLinkageName = GetMethodLinkageName(
Method);
2450 llvm::DIFile *MethodDefUnit =
nullptr;
2451 unsigned MethodLine = 0;
2452 if (!
Method->isImplicit()) {
2453 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2454 MethodLine = getLineNumber(
Method->getLocation());
2458 llvm::DIType *ContainingType =
nullptr;
2459 unsigned VIndex = 0;
2460 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2461 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2462 int ThisAdjustment = 0;
2465 if (
Method->isPureVirtual())
2466 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2468 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2470 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2474 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2478 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2481 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2482 CGM.getContext().getLangOpts())
2486 MethodVFTableLocation ML =
2487 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2495 if (
Method->size_overridden_methods() == 0)
2496 Flags |= llvm::DINode::FlagIntroducedVirtual;
2501 ThisAdjustment = CGM.getCXXABI()
2502 .getVirtualFunctionPrologueThisAdjustment(GD)
2505 ContainingType = RecordTy;
2508 if (
Method->getCanonicalDecl()->isDeleted())
2509 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2511 if (
Method->isNoReturn())
2512 Flags |= llvm::DINode::FlagNoReturn;
2515 Flags |= llvm::DINode::FlagStaticMember;
2516 if (
Method->isImplicit())
2517 Flags |= llvm::DINode::FlagArtificial;
2519 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2520 if (CXXC->isExplicit())
2521 Flags |= llvm::DINode::FlagExplicit;
2522 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2523 if (CXXC->isExplicit())
2524 Flags |= llvm::DINode::FlagExplicit;
2526 if (
Method->hasPrototype())
2527 Flags |= llvm::DINode::FlagPrototyped;
2529 Flags |= llvm::DINode::FlagLValueReference;
2531 Flags |= llvm::DINode::FlagRValueReference;
2532 if (!
Method->isExternallyVisible())
2533 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2534 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2535 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2540 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
2541 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(
Method)) {
2542 if (
const auto *Def =
2543 dyn_cast_or_null<CXXConstructorDecl>(CD->getDefinition());
2544 Def && !Def->isDelegatingConstructor()) {
2550 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2551 llvm::DISubprogram *SP = DBuilder.createMethod(
2552 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2553 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2554 TParamsArray.get(),
nullptr,
2555 CGM.getCodeGenOpts().DebugKeyInstructions);
2557 SPCache[
Method->getCanonicalDecl()].reset(SP);
2562void CGDebugInfo::CollectCXXMemberFunctions(
2563 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2564 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2569 for (
const auto *I : RD->
decls()) {
2570 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2584 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2593 auto MI = SPCache.find(
Method->getCanonicalDecl());
2594 EltTys.push_back(MI == SPCache.end()
2595 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2596 :
static_cast<llvm::Metadata *
>(MI->second));
2600void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2601 SmallVectorImpl<llvm::Metadata *> &EltTys,
2602 llvm::DIType *RecordTy) {
2603 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2604 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2605 llvm::DINode::FlagZero);
2609 if (CGM.getCodeGenOpts().EmitCodeView) {
2610 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2611 llvm::DINode::FlagIndirectVirtualBase);
2615void CGDebugInfo::CollectCXXBasesAux(
2616 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2617 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2619 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2620 llvm::DINode::DIFlags StartingFlags) {
2621 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2622 for (
const auto &BI : Bases) {
2625 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2627 if (!SeenTypes.insert(Base).second)
2629 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2630 llvm::DINode::DIFlags BFlags = StartingFlags;
2634 if (BI.isVirtual()) {
2635 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2638 BaseOffset = 0 - CGM.getItaniumVTableContext()
2639 .getVirtualBaseOffsetOffset(RD, Base)
2645 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2646 VBPtrOffset = CGM.getContext()
2647 .getASTRecordLayout(RD)
2651 BFlags |= llvm::DINode::FlagVirtual;
2658 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2659 VBPtrOffset, BFlags);
2660 EltTys.push_back(DTy);
2665CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2666 llvm::DIFile *Unit) {
2668 return llvm::DINodeArray();
2669 TemplateArgs &Args = *OArgs;
2670 SmallVector<llvm::Metadata *, 16> TemplateParams;
2671 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2672 const TemplateArgument &TA = Args.Args[i];
2676 Name = Args.TList->getParam(i)->getName();
2680 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2681 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2682 TheCU, Name, TTy, defaultParameter));
2687 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2688 TheCU, Name, TTy, defaultParameter,
2689 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2694 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2695 llvm::Constant *
V =
nullptr;
2698 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2699 !D->
hasAttr<CUDADeviceAttr>()) {
2702 if (
const auto *VD = dyn_cast<VarDecl>(D))
2703 V = CGM.GetAddrOfGlobalVar(VD);
2706 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2707 MD && MD->isImplicitObjectMemberFunction())
2708 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2709 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2710 V = CGM.GetAddrOfFunction(FD);
2713 else if (
const auto *MPT =
2714 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2718 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2720 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2721 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2722 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2723 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2724 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2726 V = ConstantEmitter(CGM).emitAbstract(
2727 SourceLocation(), TPO->getValue(), TPO->getType());
2729 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2731 assert(
V &&
"Failed to find template parameter pointer");
2732 V =
V->stripPointerCasts();
2734 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2735 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2739 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2740 llvm::Constant *
V =
nullptr;
2743 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2749 if (MPT->isMemberDataPointer())
2750 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2752 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2753 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2754 TheCU, Name, TTy, defaultParameter,
V));
2758 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2759 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2761 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2762 TheCU, Name, TTy, defaultParameter,
V));
2765 std::string QualName;
2766 llvm::raw_string_ostream
OS(QualName);
2768 OS, getPrintingPolicy());
2769 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2770 TheCU, Name,
nullptr, QualName, defaultParameter));
2774 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2775 TheCU, Name,
nullptr,
2782 T = CGM.getContext().getLValueReferenceType(
T);
2783 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E,
T);
2784 assert(
V &&
"Expression in template argument isn't constant");
2785 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2786 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2787 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2793 "These argument types shouldn't exist in concrete types");
2796 return DBuilder.getOrCreateArray(TemplateParams);
2799std::optional<CGDebugInfo::TemplateArgs>
2800CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2808 return std::nullopt;
2810std::optional<CGDebugInfo::TemplateArgs>
2811CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2815 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2817 return std::nullopt;
2818 VarTemplateDecl *
T = TS->getSpecializedTemplate();
2819 const TemplateParameterList *TList =
T->getTemplateParameters();
2820 auto TA = TS->getTemplateArgs().asArray();
2821 return {{TList, TA}};
2823std::optional<CGDebugInfo::TemplateArgs>
2824CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2825 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2829 TemplateParameterList *TPList =
2830 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2831 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2832 return {{TPList, TAList.
asArray()}};
2834 return std::nullopt;
2838CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2839 llvm::DIFile *Unit) {
2840 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2843llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2844 llvm::DIFile *Unit) {
2845 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2848llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2849 llvm::DIFile *Unit) {
2850 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2853void CGDebugInfo::CollectBTFDeclTagAnnotations(
2854 const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2856 llvm::Metadata *Ops[2] = {
2857 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2858 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2859 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2863llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2864 if (!D->
hasAttr<BTFDeclTagAttr>())
2867 SmallVector<llvm::Metadata *, 4> Annotations;
2868 CollectBTFDeclTagAnnotations(D, Annotations);
2869 return DBuilder.getOrCreateArray(Annotations);
2872void CGDebugInfo::CollectBTFTypeTagAnnotations(
2873 QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
2874 const BTFTagAttributedType *BTFAttrTy;
2876 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
2878 BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
2881 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
2883 llvm::Metadata *Ops[2] = {
2884 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
2885 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
2886 Annotations.insert(Annotations.begin(),
2887 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2889 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
2893llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2895 return VTablePtrType;
2897 ASTContext &Context = CGM.getContext();
2900 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2901 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2902 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2904 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2905 std::optional<unsigned> DWARFAddressSpace =
2906 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2908 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2909 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2910 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2911 return VTablePtrType;
2914StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2926 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2928 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2938 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2939 VTable->isDeclarationForLinker())
2943 StringRef SymbolName =
"__clang_vtable";
2945 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2954 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2956 llvm::DIFile *Unit = getOrCreateFile(Loc);
2957 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2959 llvm::DINode::FlagArtificial;
2960 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2961 ? llvm::dwarf::DW_TAG_variable
2962 : llvm::dwarf::DW_TAG_member;
2963 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2964 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2968 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2972 llvm::DIGlobalVariableExpression *GVE =
2973 DBuilder.createGlobalVariableExpression(
2974 TheCU, SymbolName, VTable->getName(), Unit, 0,
2975 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2976 true,
nullptr, DT,
nullptr,
2978 VTable->addDebugInfo(GVE);
2981StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2983 llvm::Function *InitFn) {
2988 return InitFn->getName();
2998 llvm::raw_svector_ostream OS(QualifiedGV);
3000 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
3002 std::swap(Quals, GVName);
3006 llvm::raw_svector_ostream OS(InitName);
3008 OS << Quals <<
"::";
3013 llvm_unreachable(
"not an initializer");
3015 OS <<
"`dynamic initializer for '";
3018 OS <<
"`dynamic atexit destructor for '";
3025 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
3026 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
3027 getPrintingPolicy());
3032 return internString(
OS.str());
3035void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
3036 SmallVectorImpl<llvm::Metadata *> &EltTys) {
3045 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3052 llvm::DIType *VPtrTy =
nullptr;
3053 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
3054 CGM.getTarget().getCXXABI().isMicrosoft();
3055 if (NeedVTableShape) {
3057 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3058 const VTableLayout &VFTLayout =
3059 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3060 unsigned VSlotCount =
3062 unsigned VTableWidth = PtrWidth * VSlotCount;
3063 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3064 std::optional<unsigned> DWARFAddressSpace =
3065 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3068 llvm::DIType *VTableType = DBuilder.createPointerType(
3069 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3070 EltTys.push_back(VTableType);
3073 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3081 VPtrTy = getOrCreateVTablePtrType(Unit);
3083 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3084 llvm::DIType *VPtrMember =
3085 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3086 llvm::DINode::FlagArtificial, VPtrTy);
3087 EltTys.push_back(VPtrMember);
3092 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3093 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
3104 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3105 assert(!D.
isNull() &&
"null type");
3106 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
3107 assert(
T &&
"could not create debug info for type");
3116 if (CGM.getCodeGenOpts().getDebugInfo() <=
3117 llvm::codegenoptions::DebugLineTablesOnly)
3121 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3123 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3125 CI->setMetadata(
"heapallocsite", node);
3129 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3131 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3133 auto I = TypeCache.find(TyPtr);
3136 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3137 assert(!Res->isForwardDecl());
3138 TypeCache[TyPtr].reset(Res);
3142 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3143 !CGM.getLangOpts().CPlusPlus)
3149 if (RD->
hasAttr<DLLImportAttr>())
3152 if (MD->hasAttr<DLLImportAttr>())
3165 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3175 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3176 Explicit = TD->isExplicitInstantiationOrSpecialization();
3180 if (CXXDecl->
fields().empty())
3190 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3191 if (CXXRD->isDynamicClass() &&
3192 CGM.getVTableLinkage(CXXRD) ==
3193 llvm::GlobalValue::AvailableExternallyLinkage &&
3204 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3206 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3208 auto I = TypeCache.find(TyPtr);
3215 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3216 assert(!Res->isForwardDecl());
3217 TypeCache[TyPtr].reset(Res);
3224 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3225 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3252 bool HasNonDeletedCtor =
false;
3254 if (Ctor->isCopyOrMoveConstructor())
3261 if (CtorDef->isDelegatingConstructor())
3265 if (Ctor->isConstexpr() && !Ctor->isDeleted())
3268 if (!Ctor->isDeleted())
3269 HasNonDeletedCtor =
true;
3271 return HasNonDeletedCtor;
3287 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3290 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3291 RD->
hasAttr<StandaloneDebugAttr>())
3294 if (!LangOpts.CPlusPlus)
3300 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3316 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3317 Spec = SD->getSpecializationKind();
3326 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3337 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3338 llvm::DIType *
T = getTypeOrNull(Ty);
3339 if (
T &&
T->isForwardDecl())
3343llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3345 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3349 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3353 auto [Def, Pref] = CreateTypeDefinition(Ty);
3355 return Pref ? Pref : Def;
3358llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3359 llvm::DIFile *Unit) {
3363 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3367 return getOrCreateType(PNA->getTypedefType(), Unit);
3394 const auto *RT = QT->
getAs<RecordType>();
3398 auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
3399 if (!CRD || !CRD->hasDefinition())
3404 assert(CRD->isStandardLayout());
3410std::pair<llvm::DIType *, llvm::DIType *>
3411CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3415 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3423 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3427 return {FwdDecl,
nullptr};
3429 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3430 CollectContainingType(CXXDecl, FwdDecl);
3433 LexicalBlockStack.emplace_back(&*FwdDecl);
3434 RegionMap[RD].reset(FwdDecl);
3437 SmallVector<llvm::Metadata *, 16> EltTys;
3444 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3446 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3447 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3451 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3452 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3453 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3455 LexicalBlockStack.pop_back();
3456 RegionMap.erase(RD);
3458 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3459 DBuilder.replaceArrays(FwdDecl, Elements);
3461 if (FwdDecl->isTemporary())
3463 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3465 RegionMap[RD].reset(FwdDecl);
3467 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
3482 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3483 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3484 return {FwdDecl, PrefDI};
3486 return {FwdDecl,
nullptr};
3489llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3490 llvm::DIFile *Unit) {
3492 return getOrCreateType(Ty->getBaseType(), Unit);
3495llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3496 llvm::DIFile *Unit) {
3498 SourceLocation Loc = Ty->getDecl()->getLocation();
3501 return DBuilder.createTypedef(
3502 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3503 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3504 getDeclContextDescriptor(Ty->getDecl()));
3531llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3532 llvm::DIFile *Unit) {
3537 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3538 TheCU->getSourceLanguage().getUnversionedName());
3543 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3544 !
ID->getImplementation())
3545 return DBuilder.createForwardDecl(
3546 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3547 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3550 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3551 unsigned Line = getLineNumber(
ID->getLocation());
3555 ObjCInterfaceDecl *Def =
ID->getDefinition();
3557 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3558 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3559 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3560 DefUnit,
Line, RuntimeLang);
3561 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3565 return CreateTypeDefinition(Ty, Unit);
3568llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3569 bool CreateSkeletonCU) {
3574 auto ModRef = ModuleCache.find(M);
3575 if (ModRef != ModuleCache.end())
3579 SmallString<128> ConfigMacros;
3581 llvm::raw_svector_ostream
OS(ConfigMacros);
3582 const auto &PPOpts = CGM.getPreprocessorOpts();
3585 for (
auto &M : PPOpts.Macros) {
3588 const std::string &
Macro = M.first;
3589 bool Undef = M.second;
3590 OS <<
"\"-" << (Undef ?
'U' :
'D');
3591 for (
char c :
Macro)
3606 bool IsRootModule = M ? !M->
Parent :
true;
3610 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3611 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3612 "clang module without ASTFile must be specified by -fmodule-name");
3615 auto RemapPath = [
this](StringRef Path) -> std::string {
3617 StringRef Relative(Remapped);
3618 StringRef CompDir = TheCU->getDirectory();
3619 if (CompDir.empty())
3622 if (Relative.consume_front(CompDir))
3623 Relative.consume_front(llvm::sys::path::get_separator());
3625 return Relative.str();
3628 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3635 Signature = ModSig.truncatedValue();
3639 llvm::DIBuilder DIB(CGM.getModule());
3641 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3642 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3643 PCM = getCurrentDirname();
3647 llvm::sys::path::append(PCM, Mod.
getASTFile());
3648 DIB.createCompileUnit(
3649 TheCU->getSourceLanguage(),
3652 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3653 llvm::DICompileUnit::FullDebug, Signature);
3657 llvm::DIModule *Parent =
3659 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3661 StringRef IncludePath = Mod.
getPath();
3662 if (!CGM.getCodeGenOpts().DebugRecordSysroot) {
3663 StringRef Sysroot = CGM.getHeaderSearchOpts().Sysroot;
3664 if (!Sysroot.empty() && IncludePath.starts_with(Sysroot))
3667 llvm::DIModule *DIMod =
3668 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3669 RemapPath(IncludePath));
3670 ModuleCache[M].reset(DIMod);
3674llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3675 llvm::DIFile *Unit) {
3677 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3678 unsigned Line = getLineNumber(
ID->getLocation());
3680 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3686 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3687 if (
ID->getImplementation())
3688 Flags |= llvm::DINode::FlagObjcClassComplete;
3690 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3691 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3692 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3693 nullptr, llvm::DINodeArray(), RuntimeLang);
3695 QualType QTy(Ty, 0);
3696 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3699 LexicalBlockStack.emplace_back(RealDecl);
3700 RegionMap[Ty->
getDecl()].reset(RealDecl);
3703 SmallVector<llvm::Metadata *, 16> EltTys;
3705 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3707 llvm::DIType *SClassTy =
3708 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3712 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3713 llvm::DINode::FlagZero);
3714 EltTys.push_back(InhTag);
3718 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3719 SourceLocation Loc = PD->getLocation();
3720 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3721 unsigned PLine = getLineNumber(Loc);
3722 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3723 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3724 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3725 PD->getName(), PUnit, PLine,
3727 : getSelectorName(PD->getGetterName()),
3729 : getSelectorName(PD->getSetterName()),
3730 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3731 EltTys.push_back(PropertyNode);
3736 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3740 llvm::DenseSet<IsClassAndIdent> PropertySet;
3742 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3743 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3745 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3746 for (
auto *PD : ClassExt->properties()) {
3747 PropertySet.insert(GetIsClassAndIdent(PD));
3750 for (
const auto *PD :
ID->properties()) {
3753 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3759 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3760 unsigned FieldNo = 0;
3761 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3762 Field =
Field->getNextIvar(), ++FieldNo) {
3763 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3767 StringRef FieldName =
Field->getName();
3770 if (FieldName.empty())
3774 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3775 unsigned FieldLine = getLineNumber(
Field->getLocation());
3776 QualType FType =
Field->getType();
3783 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3784 : CGM.getContext().getTypeSize(FType);
3789 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3793 if (
Field->isBitField()) {
3795 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3796 FieldOffset %= CGM.getContext().getCharWidth();
3804 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3806 Flags = llvm::DINode::FlagProtected;
3808 Flags = llvm::DINode::FlagPrivate;
3810 Flags = llvm::DINode::FlagPublic;
3812 if (
Field->isBitField())
3813 Flags |= llvm::DINode::FlagBitField;
3815 llvm::MDNode *PropertyNode =
nullptr;
3816 ObjCPropertyDecl *SynthesizedProperty =
nullptr;
3817 llvm::DIFile *PUnit =
nullptr;
3819 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3820 if (ObjCPropertyImplDecl *PImpD =
3821 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3822 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3823 SynthesizedProperty = PD;
3824 SourceLocation Loc = PD->getLocation();
3825 PUnit = getOrCreateFile(Loc);
3826 PLine = getLineNumber(Loc);
3827 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3828 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3829 PropertyNode = DBuilder.createObjCProperty(
3830 PD->getName(), PUnit, PLine,
3833 : getSelectorName(PD->getGetterName()),
3836 : getSelectorName(PD->getSetterName()),
3837 PD->getPropertyAttributes(),
3838 getOrCreateType(PD->getType(), PUnit));
3842 auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3843 FieldSize, FieldAlign, FieldOffset,
3844 Flags, FieldTy, PropertyNode);
3845 EltTys.push_back(IvarTy);
3847 if (SynthesizedProperty) {
3848 assert(PUnit &&
"SynthesizedProperty implies PUnit");
3849 EltTys.push_back(DBuilder.createProperty(
3850 SynthesizedProperty->
getName(), PUnit, PLine,
3851 getOrCreateType(SynthesizedProperty->
getType(), PUnit), IvarTy));
3855 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3856 DBuilder.replaceArrays(RealDecl, Elements);
3858 LexicalBlockStack.pop_back();
3862llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3863 llvm::DIFile *Unit) {
3871 auto &Ctx = CGM.getContext();
3876 QualType CharVecTy =
3878 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3881 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3884 llvm::Metadata *Subscript;
3885 QualType QTy(Ty, 0);
3886 auto SizeExpr = SizeExprCache.find(QTy);
3887 if (SizeExpr != SizeExprCache.end())
3888 Subscript = DBuilder.getOrCreateSubrange(
3889 SizeExpr->getSecond() ,
nullptr ,
3890 nullptr ,
nullptr );
3893 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3894 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3895 Subscript = DBuilder.getOrCreateSubrange(
3896 CountNode ,
nullptr ,
nullptr ,
3899 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3904 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3907llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3908 llvm::DIFile *Unit) {
3912 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3917 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3918 auto *ColumnCountNode =
3919 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3920 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3921 auto *RowCountNode =
3922 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3923 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3924 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3925 ColumnCountNode ,
nullptr ,
nullptr ,
3927 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3928 RowCountNode ,
nullptr ,
nullptr ,
3930 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3931 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3934llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3939 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3954 Size = CGM.getContext().getTypeSize(Ty);
3961 SmallVector<llvm::Metadata *, 8> Subscripts;
3962 QualType EltTy(Ty, 0);
3963 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3972 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3973 Count = CAT->getZExtSize();
3974 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3975 if (Expr *Size = VAT->getSizeExpr()) {
3977 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3978 Count =
Result.Val.getInt().getExtValue();
3982 auto SizeNode = SizeExprCache.find(EltTy);
3983 if (SizeNode != SizeExprCache.end())
3984 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3985 SizeNode->getSecond() ,
nullptr ,
3986 nullptr ,
nullptr ));
3989 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3990 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3991 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3992 CountNode ,
nullptr ,
nullptr ,
3998 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
4000 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
4004llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
4005 llvm::DIFile *Unit) {
4006 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
4010llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
4011 llvm::DIFile *Unit) {
4012 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
4014 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
4015 CGM.getCodeGenOpts().DwarfVersion < 4)
4016 Tag = llvm::dwarf::DW_TAG_reference_type;
4018 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
4021llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
4023 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4027 Size = CGM.getContext().getTypeSize(Ty);
4030 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
4033 Flags |= llvm::DINode::FlagSingleInheritance;
4036 Flags |= llvm::DINode::FlagMultipleInheritance;
4039 Flags |= llvm::DINode::FlagVirtualInheritance;
4049 llvm::DIType *ClassType = getOrCreateType(
T, U);
4051 return DBuilder.createMemberPointerType(
4055 const FunctionProtoType *FPT =
4057 return DBuilder.createMemberPointerType(
4058 getOrCreateInstanceMethodType(
4061 ClassType, Size, 0, Flags);
4064llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
4066 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
4069llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
4073llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
4075 return getOrCreateType(Ty->getWrappedType(), U);
4078llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
4085 const EnumType *Ty) {
4097llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
4100 bool isImportedFromModule =
4101 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
4105 if (isImportedFromModule || !ED->getDefinition()) {
4112 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
4113 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4114 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
4115 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
4117 unsigned Line = getLineNumber(ED->getLocation());
4118 StringRef EDName = ED->getName();
4119 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
4120 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
4121 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
4123 ReplaceMap.emplace_back(
4124 std::piecewise_construct, std::make_tuple(Ty),
4125 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
4129 return CreateTypeDefinition(Ty);
4132llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
4135 SmallVector<llvm::Metadata *, 16> Enumerators;
4136 ED = ED->getDefinition();
4137 assert(ED &&
"An enumeration definition is required");
4138 for (
const auto *
Enum : ED->enumerators()) {
4139 Enumerators.push_back(
4140 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
4143 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
4144 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4145 EnumKind = Attr->getExtensibility();
4148 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4150 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4151 unsigned Line = getLineNumber(ED->getLocation());
4152 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4153 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4154 return DBuilder.createEnumerationType(
4155 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4156 0, Identifier, ED->isScoped(), EnumKind);
4161 StringRef Name, StringRef
Value) {
4162 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4163 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4169 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4170 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4171 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4176 llvm::DISubprogram *SynthSubprogram) {
4177 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4178 SynthSubprogram, ParentLocation);
4183 StringRef SynthFuncName,
4184 llvm::DIFile *SynthFile) {
4185 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4190 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4196 FuncName += Category;
4198 FuncName += FailureMsg;
4201 TrapLocation->getFile());
4211 Quals += InnerQuals;
4213 switch (
T->getTypeClass()) {
4215 return C.getQualifiedType(
T.getTypePtr(), Quals);
4218 case Type::InjectedClassName:
4219 return C.getQualifiedType(
T->getCanonicalTypeUnqualified().getTypePtr(),
4221 case Type::TemplateSpecialization: {
4223 if (Spec->isTypeAlias())
4224 return C.getQualifiedType(
T.getTypePtr(), Quals);
4225 T = Spec->desugar();
4228 case Type::TypeOfExpr:
4234 case Type::Decltype:
4237 case Type::UnaryTransform:
4240 case Type::Attributed:
4243 case Type::BTFTagAttributed:
4246 case Type::CountAttributed:
4255 case Type::MacroQualified:
4258 case Type::SubstTemplateTypeParm:
4262 case Type::DeducedTemplateSpecialization: {
4264 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4268 case Type::PackIndexing: {
4272 case Type::Adjusted:
4279 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
4284llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4287 if (It != TypeCache.end()) {
4289 if (llvm::Metadata *
V = It->second)
4302 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4309 RetainedTypes.push_back(
4310 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4313llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4317 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4319 llvm::raw_string_ostream OS(Name);
4320 Ty.
print(OS, getPrintingPolicy());
4327 if (
auto *
T = getTypeOrNull(Ty))
4330 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4331 void *TyPtr = Ty.getAsOpaquePtr();
4334 TypeCache[TyPtr].reset(Res);
4339llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4347 auto Info = Reader->getSourceDescriptor(Idx);
4349 return getOrCreateModuleRef(*Info,
true);
4350 }
else if (ClangModuleMap) {
4363 auto Info = ASTSourceDescriptor(*M);
4364 return getOrCreateModuleRef(Info,
false);
4367 return getOrCreateModuleRef(PCHDescriptor,
false);
4374llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4377 return CreateQualifiedType(Ty, Unit);
4381#define TYPE(Class, Base)
4382#define ABSTRACT_TYPE(Class, Base)
4383#define NON_CANONICAL_TYPE(Class, Base)
4384#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4385#include "clang/AST/TypeNodes.inc"
4386 llvm_unreachable(
"Dependent types cannot show up in debug information");
4388 case Type::ExtVector:
4391 case Type::ConstantMatrix:
4393 case Type::ObjCObjectPointer:
4395 case Type::ObjCObject:
4397 case Type::ObjCTypeParam:
4399 case Type::ObjCInterface:
4407 case Type::BlockPointer:
4415 case Type::FunctionProto:
4416 case Type::FunctionNoProto:
4418 case Type::ConstantArray:
4419 case Type::VariableArray:
4420 case Type::IncompleteArray:
4421 case Type::ArrayParameter:
4424 case Type::LValueReference:
4426 case Type::RValueReference:
4429 case Type::MemberPointer:
4437 case Type::OverflowBehavior:
4442 case Type::TemplateSpecialization:
4444 case Type::HLSLAttributedResource:
4446 case Type::HLSLInlineSpirv:
4448 case Type::PredefinedSugar:
4450 case Type::CountAttributed:
4451 case Type::LateParsedAttr:
4453 case Type::Attributed:
4454 case Type::BTFTagAttributed:
4455 case Type::Adjusted:
4457 case Type::DeducedTemplateSpecialization:
4460 case Type::MacroQualified:
4461 case Type::SubstTemplateTypeParm:
4462 case Type::TypeOfExpr:
4464 case Type::Decltype:
4465 case Type::PackIndexing:
4466 case Type::UnaryTransform:
4470 llvm_unreachable(
"type should have been unwrapped!");
4473llvm::DICompositeType *
4474CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4475 QualType QTy(Ty, 0);
4477 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4482 if (
T && !
T->isForwardDecl())
4486 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4491 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4494 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4499llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4501 bool NameIsSimplified =
false;
4504 StringRef RDName = getClassName(RD, &NameIsSimplified);
4506 llvm::DIFile *DefUnit =
nullptr;
4509 DefUnit = getOrCreateFile(Loc);
4510 Line = getLineNumber(Loc);
4513 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4517 auto *
T = cast_or_null<llvm::DICompositeType>(
4518 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4526 return getOrCreateRecordFwdDecl(Ty, RDContext);
4539 auto Flags = llvm::DINode::FlagZero;
4540 if (NameIsSimplified)
4541 Flags |= llvm::DINode::FlagNameIsSimplified;
4542 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4544 Flags |= llvm::DINode::FlagTypePassByReference;
4546 Flags |= llvm::DINode::FlagTypePassByValue;
4549 if (!CXXRD->isTrivial())
4550 Flags |= llvm::DINode::FlagNonTrivial;
4553 if (CXXRD->isAnonymousStructOrUnion())
4554 Flags |= llvm::DINode::FlagExportSymbols;
4557 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4560 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4561 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4563 Flags, Identifier, Annotations);
4567 switch (RealDecl->getTag()) {
4569 llvm_unreachable(
"invalid composite type tag");
4571 case llvm::dwarf::DW_TAG_array_type:
4572 case llvm::dwarf::DW_TAG_enumeration_type:
4577 if (Identifier.empty())
4581 case llvm::dwarf::DW_TAG_structure_type:
4582 case llvm::dwarf::DW_TAG_union_type:
4583 case llvm::dwarf::DW_TAG_class_type:
4586 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4590 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4591 CXXRecordDecl *TemplateDecl =
4592 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4593 RegionMap[TemplateDecl].reset(RealDecl);
4595 RegionMap[RD].reset(RealDecl);
4597 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4599 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4600 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4601 CollectCXXTemplateParams(TSpecial, DefUnit));
4605void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4606 llvm::DICompositeType *RealDecl) {
4608 llvm::DIType *ContainingType =
nullptr;
4609 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4613 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4620 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4621 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4623 ContainingType = RealDecl;
4625 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4628llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4629 StringRef Name, uint64_t *Offset) {
4630 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4631 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4634 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4635 *Offset, llvm::DINode::FlagZero, FieldTy);
4636 *Offset += FieldSize;
4640void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4642 StringRef &LinkageName,
4643 llvm::DIScope *&FDContext,
4644 llvm::DINodeArray &TParamsArray,
4645 llvm::DINode::DIFlags &Flags) {
4647 bool NameIsSimplified =
false;
4648 Name = getFunctionName(FD, &NameIsSimplified);
4649 if (NameIsSimplified)
4650 Flags |= llvm::DINode::FlagNameIsSimplified;
4651 Name = getFunctionName(FD);
4654 LinkageName = CGM.getMangledName(GD);
4656 Flags |= llvm::DINode::FlagPrototyped;
4660 if (LinkageName == Name ||
4661 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4662 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4663 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4664 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4665 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4666 LinkageName = StringRef();
4670 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4671 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4672 CGM.getCodeGenOpts().EmitCodeView)) {
4673 if (
const NamespaceDecl *NSDecl =
4675 FDContext = getOrCreateNamespace(NSDecl);
4676 else if (
const RecordDecl *RDecl =
4678 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4679 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4682 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4685 Flags |= llvm::DINode::FlagNoReturn;
4687 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4691void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4692 unsigned &LineNo, QualType &
T,
4693 StringRef &Name, StringRef &LinkageName,
4694 llvm::MDTuple *&TemplateParameters,
4695 llvm::DIScope *&VDContext) {
4704 llvm::APInt ConstVal(32, 1);
4705 QualType ET = CGM.getContext().getAsArrayType(
T)->getElementType();
4707 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4714 LinkageName = CGM.getMangledName(VD);
4715 if (LinkageName == Name)
4716 LinkageName = StringRef();
4719 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4720 TemplateParameters = parameterNodes.get();
4722 TemplateParameters =
nullptr;
4728 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4729 VDContext = LexicalBlockStack.back();
4748 DC = CGM.getContext().getTranslationUnitDecl();
4750 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4751 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4754llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4756 llvm::DINodeArray TParamsArray;
4757 StringRef Name, LinkageName;
4758 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4759 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4761 llvm::DIFile *Unit = getOrCreateFile(Loc);
4762 llvm::DIScope *DContext = Unit;
4763 unsigned Line = getLineNumber(Loc);
4764 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4769 SmallVector<QualType, 16> ArgTypes;
4770 for (
const ParmVarDecl *Parm : FD->
parameters())
4771 ArgTypes.push_back(Parm->getType());
4774 QualType FnType = CGM.getContext().getFunctionType(
4775 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4777 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4778 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4779 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4783 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4784 return DBuilder.createFunction(
4785 DContext, Name, LinkageName, Unit,
Line,
4786 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4787 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4789 CGM.getCodeGenOpts().DebugKeyInstructions);
4792 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4793 DContext, Name, LinkageName, Unit,
Line,
4794 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4795 TParamsArray.get(), getFunctionDeclaration(FD));
4797 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4798 std::make_tuple(CanonDecl),
4799 std::make_tuple(SP));
4803llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4804 return getFunctionFwdDeclOrStub(GD,
false);
4807llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4808 return getFunctionFwdDeclOrStub(GD,
true);
4811llvm::DIGlobalVariable *
4812CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4814 StringRef Name, LinkageName;
4816 llvm::DIFile *Unit = getOrCreateFile(Loc);
4817 llvm::DIScope *DContext = Unit;
4818 unsigned Line = getLineNumber(Loc);
4819 llvm::MDTuple *TemplateParameters =
nullptr;
4821 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4824 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4825 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4827 FwdDeclReplaceMap.emplace_back(
4828 std::piecewise_construct,
4830 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4834llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4839 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4840 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4841 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4845 if (I != DeclCache.end()) {
4847 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4848 return GVE->getVariable();
4856 if (IE != ImportedDeclCache.end()) {
4857 auto N = IE->second;
4858 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4860 return dyn_cast_or_null<llvm::DINode>(N);
4865 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4866 return getFunctionForwardDeclaration(FD);
4867 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4868 return getGlobalVariableForwardDeclaration(VD);
4873llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4874 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4877 const auto *FD = dyn_cast<FunctionDecl>(D);
4882 auto *S = getDeclContextDescriptor(D);
4885 if (MI == SPCache.end()) {
4887 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4891 if (MI != SPCache.end()) {
4892 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4893 if (SP && !SP->isDefinition())
4897 for (
auto *NextFD : FD->
redecls()) {
4898 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4899 if (MI != SPCache.end()) {
4900 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4901 if (SP && !SP->isDefinition())
4908llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4909 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4910 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4911 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4914 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4918 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4922 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4931 QualType QTy(
ID->getTypeForDecl(), 0);
4932 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4933 if (It == TypeCache.end())
4936 llvm::DISubprogram *FD = DBuilder.createFunction(
4937 InterfaceType, getObjCMethodName(OMD), StringRef(),
4938 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4939 DBuilder.finalizeSubprogram(FD);
4946llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4951 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4952 !CGM.getCodeGenOpts().EmitCodeView))
4955 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4957 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4960 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4963 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4964 return getOrCreateMethodType(
Method, F);
4966 const auto *FTy = FnType->
getAs<FunctionType>();
4969 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4971 SmallVector<llvm::Metadata *, 16> Elts;
4974 QualType ResultTy = OMethod->getReturnType();
4977 if (ResultTy == CGM.getContext().getObjCInstanceType())
4978 ResultTy = CGM.getContext().getPointerType(
4979 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4981 Elts.push_back(getOrCreateType(ResultTy, F));
4983 QualType SelfDeclTy;
4984 if (
auto *SelfDecl = OMethod->getSelfDecl())
4985 SelfDeclTy = SelfDecl->getType();
4986 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4989 if (!SelfDeclTy.
isNull())
4991 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4993 Elts.push_back(DBuilder.createArtificialType(
4994 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4996 for (
const auto *PI : OMethod->parameters())
4997 Elts.push_back(getOrCreateType(PI->getType(), F));
4999 if (OMethod->isVariadic())
5000 Elts.push_back(DBuilder.createUnspecifiedParameter());
5002 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
5003 return DBuilder.createSubroutineType(
5004 EltTypeArray, llvm::DINode::FlagZero,
5005 getDwarfCC(CC, CGM.getTarget().getTriple()));
5010 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
5011 if (FD->isVariadic()) {
5012 SmallVector<llvm::Metadata *, 16> EltTys;
5013 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
5014 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
5016 EltTys.push_back(getOrCreateType(ParamType, F));
5017 EltTys.push_back(DBuilder.createUnspecifiedParameter());
5018 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
5019 return DBuilder.createSubroutineType(
5020 EltTypeArray, llvm::DINode::FlagZero,
5021 getDwarfCC(CC, CGM.getTarget().getTriple()));
5033 CC = SrcFnTy->getCallConv();
5035 for (
const VarDecl *VD : Args)
5036 ArgTypes.push_back(VD->
getType());
5037 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
5043 llvm::Function *Fn,
bool CurFuncIsThunk) {
5045 StringRef LinkageName;
5047 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5050 bool HasDecl = (D !=
nullptr);
5052 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5053 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5054 llvm::DIFile *Unit = getOrCreateFile(Loc);
5055 llvm::DIScope *FDContext = Unit;
5056 llvm::DINodeArray TParamsArray;
5057 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
5060 LinkageName = Fn->getName();
5061 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
5063 auto FI = SPCache.find(FD->getCanonicalDecl());
5064 if (FI != SPCache.end()) {
5065 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5066 if (SP && SP->isDefinition()) {
5067 LexicalBlockStack.emplace_back(SP);
5068 RegionMap[D].reset(SP);
5072 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5073 TParamsArray, Flags);
5076 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
5077 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5078 Name = getObjCMethodName(OMD);
5079 Flags |= llvm::DINode::FlagPrototyped;
5085 if (Name != Fn->getName())
5086 LinkageName = Fn->getName();
5088 Name = Fn->getName();
5093 Flags |= llvm::DINode::FlagPrototyped;
5095 Name.consume_front(
"\01");
5099 "Unexpected DynamicInitKind !");
5103 Flags |= llvm::DINode::FlagArtificial;
5109 Flags |= llvm::DINode::FlagThunk;
5111 if (Fn->hasLocalLinkage())
5112 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
5113 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5114 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5117 llvm::DISubprogram::DISPFlags SPFlagsForDef =
5118 SPFlags | llvm::DISubprogram::SPFlagDefinition;
5120 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
5121 unsigned ScopeLine = getLineNumber(ScopeLoc);
5122 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
5123 llvm::DISubprogram *
Decl =
nullptr;
5124 llvm::DINodeArray Annotations =
nullptr;
5127 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
5128 : getFunctionDeclaration(D);
5129 Annotations = CollectBTFDeclTagAnnotations(D);
5137 llvm::DISubprogram *SP = DBuilder.createFunction(
5138 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
5139 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
5140 Annotations,
"", KeyInstructions);
5141 Fn->setSubprogram(SP);
5150 LexicalBlockStack.emplace_back(SP);
5153 RegionMap[D].reset(SP);
5157 QualType FnType, llvm::Function *Fn) {
5159 StringRef LinkageName;
5165 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5166 return GetName(D,
true);
5169 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5170 llvm::DIFile *Unit = getOrCreateFile(Loc);
5171 bool IsDeclForCallSite = Fn ?
true :
false;
5172 llvm::DIScope *FDContext =
5173 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5174 llvm::DINodeArray TParamsArray;
5177 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5178 TParamsArray, Flags);
5179 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5180 Name = getObjCMethodName(OMD);
5181 Flags |= llvm::DINode::FlagPrototyped;
5183 llvm_unreachable(
"not a function or ObjC method");
5185 Name.consume_front(
"\01");
5188 Flags |= llvm::DINode::FlagArtificial;
5193 unsigned LineNo = getLineNumber(Loc);
5194 unsigned ScopeLine = 0;
5195 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5196 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5197 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5199 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5200 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5202 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5203 llvm::DISubprogram *SP = DBuilder.createFunction(
5204 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5205 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5211 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5212 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5213 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5216 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5217 DBuilder.createParameterVariable(
5218 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5219 llvm::DINode::FlagZero, ParamAnnotations);
5225 if (IsDeclForCallSite)
5226 Fn->setSubprogram(SP);
5230 llvm::CallBase *CI) {
5231 if (!shouldGenerateVirtualCallSite())
5237 assert(CI &&
"Invalid Call Instruction.");
5238 if (!CI->isIndirectCall())
5242 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5243 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5251 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5254 if (
Func->getSubprogram())
5258 if (!
Func->isDeclaration())
5282 auto FI = SPCache.find(FD->getCanonicalDecl());
5283 llvm::DISubprogram *SP =
nullptr;
5284 if (FI != SPCache.end())
5285 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5286 if (!SP || !SP->isDefinition())
5287 SP = getFunctionStub(GD);
5288 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5289 LexicalBlockStack.emplace_back(SP);
5295 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5304 if (CurLoc.isInvalid() ||
5305 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5306 LexicalBlockStack.empty())
5309 llvm::MDNode *
Scope = LexicalBlockStack.back();
5310 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5311 CGM.getLLVMContext(), CurLocLine, CurLocColumn,
Scope, CurInlinedAt));
5315 llvm::MDNode *Back =
nullptr;
5316 if (!LexicalBlockStack.empty())
5317 Back = LexicalBlockStack.back().get();
5318 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5320 getColumnNumber(CurLoc)));
5323void CGDebugInfo::AppendAddressSpaceXDeref(
5325 std::optional<unsigned> DWARFAddressSpace =
5327 if (!DWARFAddressSpace)
5330 Expr.push_back(llvm::dwarf::DW_OP_constu);
5331 Expr.push_back(*DWARFAddressSpace);
5332 Expr.push_back(llvm::dwarf::DW_OP_swap);
5333 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5342 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5343 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5344 LexicalBlockStack.back(), CurInlinedAt));
5346 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5350 CreateLexicalBlock(Loc);
5355 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5360 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5363 LexicalBlockStack.pop_back();
5367 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5368 unsigned RCount = FnBeginRegionCount.back();
5369 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5372 while (LexicalBlockStack.size() != RCount) {
5375 LexicalBlockStack.pop_back();
5377 FnBeginRegionCount.pop_back();
5379 if (Fn && Fn->getSubprogram())
5380 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5383CGDebugInfo::BlockByRefType
5384CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5385 uint64_t *XOffset) {
5388 uint64_t FieldSize, FieldOffset;
5389 uint32_t FieldAlign;
5391 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5396 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5397 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5399 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5400 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5403 if (HasCopyAndDispose) {
5406 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5408 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5410 bool HasByrefExtendedLayout;
5413 HasByrefExtendedLayout) &&
5414 HasByrefExtendedLayout) {
5417 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5426 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5429 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5432 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5437 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5438 FieldSize = CGM.getContext().getTypeSize(FType);
5439 FieldAlign = CGM.getContext().toBits(Align);
5441 *XOffset = FieldOffset;
5442 llvm::DIType *FieldTy = DBuilder.createMemberType(
5443 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5444 llvm::DINode::FlagZero, WrappedTy);
5445 EltTys.push_back(FieldTy);
5446 FieldOffset += FieldSize;
5448 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5449 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5450 llvm::DINode::FlagZero,
nullptr, Elements),
5454llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5455 llvm::Value *Storage,
5456 std::optional<unsigned> ArgNo,
5458 const bool UsePointerValue) {
5459 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5460 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5461 if (VD->
hasAttr<NoDebugAttr>())
5466 llvm::DIFile *Unit =
nullptr;
5467 if (!VarIsArtificial)
5471 if (VD->
hasAttr<BlocksAttr>())
5472 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5474 Ty = getOrCreateType(VD->
getType(), Unit);
5484 if (!VarIsArtificial) {
5488 SmallVector<uint64_t, 13> Expr;
5489 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5496 Flags |= llvm::DINode::FlagArtificial;
5500 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5501 AppendAddressSpaceXDeref(AddressSpace, Expr);
5505 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5508 Flags |= llvm::DINode::FlagObjectPointer;
5509 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5510 if (PVD->isExplicitObjectParameter())
5511 Flags |= llvm::DINode::FlagObjectPointer;
5519 StringRef Name = VD->
getName();
5520 if (!Name.empty()) {
5526 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5528 offset = CGM.getContext().toCharUnitsFromBits(
5531 Expr.push_back(llvm::dwarf::DW_OP_deref);
5532 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5534 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5537 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5549 for (
const auto *Field : RD->
fields()) {
5550 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5551 StringRef FieldName =
Field->getName();
5559 auto *D = DBuilder.createAutoVariable(
5560 Scope, FieldName, Unit,
Line, FieldTy,
5561 CGM.getCodeGenOpts().OptimizationLevel != 0,
5562 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5565 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5566 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5569 Builder.GetInsertBlock());
5577 if (UsePointerValue) {
5578 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5579 "Debug info already contains DW_OP_deref.");
5580 Expr.push_back(llvm::dwarf::DW_OP_deref);
5584 llvm::DILocalVariable *D =
nullptr;
5586 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5587 D = DBuilder.createParameterVariable(
5588 Scope, Name, *ArgNo, Unit,
Line, Ty,
5589 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5598 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5604 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5605 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5606 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5607 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5609 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5615 if (Iter != CoroutineParameterMappings.end()) {
5616 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5617 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5618 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5620 if (Iter2 != ParamDbgMappings.end())
5621 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5627 D = RemapCoroArgToLocalVar();
5630 D = DBuilder.createAutoVariable(
5631 Scope, Name, Unit,
Line, Ty,
5632 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5635 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5636 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5637 Column, Scope, CurInlinedAt),
5638 Builder.GetInsertBlock());
5643llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5644 llvm::Value *Storage,
5645 std::optional<unsigned> ArgNo,
5647 const bool UsePointerValue) {
5648 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5649 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5650 if (BD->
hasAttr<NoDebugAttr>())
5657 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5658 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5666 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5668 SmallVector<uint64_t, 3> Expr;
5669 AppendAddressSpaceXDeref(AddressSpace, Expr);
5674 if (UsePointerValue) {
5675 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5676 "Debug info already contains DW_OP_deref.");
5677 Expr.push_back(llvm::dwarf::DW_OP_deref);
5682 StringRef Name = BD->
getName();
5685 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5686 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5687 llvm::DINode::FlagZero, Align);
5689 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5690 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5691 const unsigned fieldIndex = FD->getFieldIndex();
5692 const clang::CXXRecordDecl *parent =
5693 (
const CXXRecordDecl *)FD->getParent();
5694 const ASTRecordLayout &layout =
5695 CGM.getContext().getASTRecordLayout(parent);
5697 if (FD->isBitField()) {
5698 const CGRecordLayout &RL =
5699 CGM.getTypes().getCGRecordLayout(FD->getParent());
5704 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5710 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5711 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5712 Expr.push_back(Info.
Offset);
5715 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5716 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5717 }
else if (fieldOffset != 0) {
5718 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5719 "Unexpected non-bitfield with non-byte-aligned offset");
5720 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5722 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5725 }
else if (
const ArraySubscriptExpr *ASE =
5726 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5727 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5728 const uint64_t value = IL->getValue().getZExtValue();
5729 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5732 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5733 Expr.push_back(CGM.getContext()
5734 .toCharUnitsFromBits(value * typeSize)
5741 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5742 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5743 Column, Scope, CurInlinedAt),
5744 Builder.GetInsertBlock());
5749llvm::DILocalVariable *
5752 const bool UsePointerValue) {
5753 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5755 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5757 EmitDeclare(B, Storage, std::nullopt, Builder,
5764 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5768 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5769 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5771 if (D->
hasAttr<NoDebugAttr>())
5775 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5781 StringRef Name = D->
getName();
5787 CGM.getCodeGenOpts().OptimizationLevel != 0);
5790 DBuilder.insertLabel(L,
5791 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5792 Scope, CurInlinedAt),
5793 Builder.GetInsertBlock()->end());
5796llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5798 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5801 return DBuilder.createObjectPointerType(Ty,
true);
5806 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5807 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5808 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5810 if (Builder.GetInsertBlock() ==
nullptr)
5812 if (VD->
hasAttr<NoDebugAttr>())
5815 bool isByRef = VD->
hasAttr<BlocksAttr>();
5817 uint64_t XOffset = 0;
5818 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5821 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5823 Ty = getOrCreateType(VD->
getType(), Unit);
5827 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5829 Ty = CreateSelfType(VD->
getType(), Ty);
5832 const unsigned Line =
5836 const llvm::DataLayout &target = CGM.getDataLayout();
5843 addr.push_back(llvm::dwarf::DW_OP_deref);
5844 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5847 addr.push_back(llvm::dwarf::DW_OP_deref);
5848 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5851 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5853 addr.push_back(llvm::dwarf::DW_OP_deref);
5854 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5856 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5862 auto *D = DBuilder.createAutoVariable(
5864 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5867 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5868 LexicalBlockStack.back(), CurInlinedAt);
5869 auto *
Expr = DBuilder.createExpression(addr);
5871 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5873 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5876llvm::DILocalVariable *
5879 bool UsePointerValue) {
5880 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5881 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5885struct BlockLayoutChunk {
5886 uint64_t OffsetInBits;
5889bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5890 return l.OffsetInBits < r.OffsetInBits;
5894void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5896 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5897 SmallVectorImpl<llvm::Metadata *> &Fields) {
5901 if (CGM.getLangOpts().OpenCL) {
5902 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5903 BlockLayout.getElementOffsetInBits(0),
5905 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5906 BlockLayout.getElementOffsetInBits(1),
5910 BlockLayout.getElementOffsetInBits(0),
5912 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5913 BlockLayout.getElementOffsetInBits(1),
5917 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5918 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5919 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5920 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5921 BlockLayout.getElementOffsetInBits(3),
5923 Fields.push_back(createFieldType(
5928 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5935 llvm::AllocaInst *Alloca,
5937 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5943 llvm::DIFile *tunit = getOrCreateFile(loc);
5944 unsigned line = getLineNumber(loc);
5945 unsigned column = getColumnNumber(loc);
5950 const llvm::StructLayout *blockLayout =
5954 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5963 BlockLayoutChunk chunk;
5964 chunk.OffsetInBits =
5965 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5966 chunk.Capture =
nullptr;
5967 chunks.push_back(chunk);
5971 for (
const auto &capture :
blockDecl->captures()) {
5972 const VarDecl *variable = capture.getVariable();
5979 BlockLayoutChunk chunk;
5980 chunk.OffsetInBits =
5981 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5982 chunk.Capture = &capture;
5983 chunks.push_back(chunk);
5987 llvm::array_pod_sort(chunks.begin(), chunks.end());
5989 for (
const BlockLayoutChunk &Chunk : chunks) {
5990 uint64_t offsetInBits = Chunk.OffsetInBits;
5997 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5999 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
6000 type = CGM.getContext().getCanonicalTagType(RDecl);
6002 llvm_unreachable(
"unexpected block declcontext");
6004 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
6005 offsetInBits, tunit, tunit));
6010 StringRef name = variable->
getName();
6012 llvm::DIType *fieldType;
6014 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
6019 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
6020 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
6021 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
6022 PtrInfo.
Width, Align, offsetInBits,
6023 llvm::DINode::FlagZero, fieldType);
6027 offsetInBits, Align, tunit, tunit);
6029 fields.push_back(fieldType);
6033 llvm::raw_svector_ostream(typeName)
6034 <<
"__block_literal_" << CGM.getUniqueBlockCount();
6036 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
6038 llvm::DIType *
type =
6039 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
6040 CGM.getContext().toBits(block.
BlockSize), 0,
6041 llvm::DINode::FlagZero,
nullptr, fieldsArray);
6042 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
6045 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
6049 auto *debugVar = DBuilder.createParameterVariable(
6050 scope, Name, ArgNo, tunit, line,
type,
6051 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
6054 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
6055 llvm::DILocation::get(CGM.getLLVMContext(), line,
6056 column, scope, CurInlinedAt),
6057 Builder.GetInsertBlock());
6060llvm::DIDerivedType *
6061CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
6066 if (MI != StaticDataMemberCache.end()) {
6067 assert(MI->second &&
"Static data member declaration should still exist");
6078llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
6079 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
6080 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
6081 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6083 for (
const auto *Field : RD->
fields()) {
6084 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
6085 StringRef FieldName = Field->getName();
6088 if (FieldName.empty()) {
6089 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
6090 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
6091 LineNo, LinkageName, Var, DContext);
6095 GVE = DBuilder.createGlobalVariableExpression(
6096 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
6097 Var->hasLocalLinkage());
6098 Var->addDebugInfo(GVE);
6110 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
6115 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
6126 struct ReferencesAnonymous
6128 bool RefAnon =
false;
6129 bool VisitRecordType(RecordType *RT) {
6137 ReferencesAnonymous RT;
6150struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
6151 bool Reconstitutable =
true;
6152 bool VisitVectorType(VectorType *FT) {
6153 Reconstitutable =
false;
6156 bool VisitAtomicType(AtomicType *FT) {
6157 Reconstitutable =
false;
6160 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6163 const EnumDecl *ED = ET->getDecl();
6165 Reconstitutable =
false;
6169 Reconstitutable =
false;
6174 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6178 return Reconstitutable;
6180 bool VisitRecordType(RecordType *RT,
bool =
false) {
6182 Reconstitutable =
false;
6192 ReconstitutableType
T;
6194 return T.Reconstitutable;
6197bool CGDebugInfo::HasReconstitutableArgs(
6198 ArrayRef<TemplateArgument> Args)
const {
6199 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6239 llvm_unreachable(
"Other, unresolved, template arguments should "
6240 "not be seen here");
6245std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6246 bool *NameIsSimplified)
const {
6248 llvm::raw_string_ostream
OS(Name);
6249 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6252 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6253 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6255 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6256 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6258 std::optional<TemplateArgs> Args;
6260 bool IsOperatorOverload =
false;
6261 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6262 Args = GetTemplateArgs(RD);
6263 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6264 Args = GetTemplateArgs(FD);
6266 IsOperatorOverload |=
6269 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6270 Args = GetTemplateArgs(VD);
6294 bool Reconstitutable =
6295 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6297 PrintingPolicy PP = getPrintingPolicy();
6299 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6304 if (NameIsSimplified)
6305 *NameIsSimplified =
true;
6306 bool Mangled = TemplateNamesKind ==
6307 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6313 std::string EncodedOriginalName;
6314 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6319 printTemplateArgumentList(OS, Args->Args, PP);
6320 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6322 std::string CanonicalOriginalName;
6323 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6325 assert(EncodedOriginalName == CanonicalOriginalName);
6334 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6335 if (D->
hasAttr<NoDebugAttr>())
6338 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6339 return GetName(D,
true);
6345 if (Cached != DeclCache.end())
6346 return Var->addDebugInfo(
6350 llvm::DIFile *Unit =
nullptr;
6351 llvm::DIScope *DContext =
nullptr;
6353 StringRef DeclName, LinkageName;
6355 llvm::MDTuple *TemplateParameters =
nullptr;
6356 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
6357 TemplateParameters, DContext);
6361 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6366 if (
T->isUnionType() && DeclName.empty()) {
6367 const auto *RD =
T->castAsRecordDecl();
6369 "unnamed non-anonymous struct or union?");
6370 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6375 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6376 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6377 if (D->
hasAttr<CUDASharedAttr>())
6380 else if (D->
hasAttr<CUDAConstantAttr>())
6384 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6386 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6387 GVE = DBuilder.createGlobalVariableExpression(
6388 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
6389 Var->hasLocalLinkage(),
true,
6390 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6391 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6392 Align, Annotations);
6393 Var->addDebugInfo(GVE);
6399 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6400 if (VD->
hasAttr<NoDebugAttr>())
6402 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6403 return GetName(VD,
true);
6408 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6409 StringRef Name = VD->
getName();
6410 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6412 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6414 if (CGM.getCodeGenOpts().EmitCodeView) {
6425 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6426 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
6427 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6437 auto *VarD = dyn_cast<VarDecl>(VD);
6438 if (VarD && VarD->isStaticDataMember()) {
6440 getDeclContextDescriptor(VarD);
6445 RetainedTypes.push_back(
6446 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6450 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6452 auto &GV = DeclCache[VD];
6456 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6457 llvm::MDTuple *TemplateParameters =
nullptr;
6461 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6462 TemplateParameters = parameterNodes.get();
6465 GV.reset(DBuilder.createGlobalVariableExpression(
6466 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6467 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6468 TemplateParameters, Align));
6473 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6474 if (D->
hasAttr<NoDebugAttr>())
6478 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6479 StringRef Name = D->
getName();
6480 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6482 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6483 llvm::DIGlobalVariableExpression *GVE =
6484 DBuilder.createGlobalVariableExpression(
6485 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6486 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6487 Var->addDebugInfo(GVE);
6494 if (CGM.getCodeGenOpts().getDebugInfo() <=
6495 llvm::codegenoptions::DebugLineTablesOnly)
6498 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6502 llvm::DIFile *Unit = DIL->getFile();
6503 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6508 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6509 llvm::Value *Var = Load->getPointerOperand();
6514 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6515 return DbgDeclare->getVariable()->getType() ==
Type;
6517 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6521 llvm::DILocalVariable *D =
6522 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6523 Type,
false, llvm::DINode::FlagArtificial);
6525 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6526 DBuilder.insertDbgValue(
Value, D, DBuilder.createExpression(), DIL,
6536 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6540 if (D->
hasAttr<NoDebugAttr>())
6543 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6558 if (!(DI = getDeclarationOrDefinition(
6559 AliaseeDecl.getCanonicalDecl().getDecl())))
6562 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6565 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6566 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6580 llvm::DIFile *
File = getOrCreateFile(Loc);
6581 llvm::DIGlobalVariableExpression *Debug =
6582 DBuilder.createGlobalVariableExpression(
6583 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6584 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6585 GV->addDebugInfo(Debug);
6588llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6589 if (!LexicalBlockStack.empty())
6590 return LexicalBlockStack.back();
6591 llvm::DIScope *Mod = getParentModuleOrNull(D);
6592 return getContextDescriptor(D, Mod ? Mod : TheCU);
6596 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6600 CGM.getCodeGenOpts().DebugExplicitImport) {
6604 DBuilder.createImportedModule(
6606 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6611 if (llvm::DINode *
Target =
6614 DBuilder.createImportedDeclaration(
6616 getOrCreateFile(Loc), getLineNumber(Loc));
6621 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6624 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6626 for (
const auto *USD : UD.
shadows()) {
6631 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6632 if (
const auto *AT = FD->getType()
6635 if (AT->getDeducedType().isNull())
6646 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6649 "We shouldn't be codegening an invalid UsingEnumDecl"
6650 " containing no decls");
6652 for (
const auto *USD : UD.
shadows())
6657 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6659 if (
Module *M = ID.getImportedModule()) {
6661 auto Loc = ID.getLocation();
6662 DBuilder.createImportedDeclaration(
6663 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6664 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6665 getLineNumber(Loc));
6669llvm::DIImportedEntity *
6671 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6673 auto &VH = NamespaceAliasCache[&NA];
6676 llvm::DIImportedEntity *R;
6678 if (
const auto *Underlying =
6681 R = DBuilder.createImportedDeclaration(
6684 getLineNumber(Loc), NA.
getName());
6686 R = DBuilder.createImportedDeclaration(
6689 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6695CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6699 auto I = NamespaceCache.find(NSDecl);
6700 if (I != NamespaceCache.end())
6703 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6705 llvm::DINamespace *NS =
6706 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6707 NamespaceCache[NSDecl].reset(NS);
6712 assert(TheCU &&
"no main compile unit");
6713 TheCU->setDWOId(Signature);
6719 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6720 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6722 ? CreateTypeDefinition(E.Type, E.Unit)
6724 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6728 for (
const auto &P : ObjCMethodCache) {
6729 if (P.second.empty())
6732 QualType QTy(P.first->getTypeForDecl(), 0);
6734 assert(It != TypeCache.end());
6736 llvm::DICompositeType *InterfaceDecl =
6739 auto CurElts = InterfaceDecl->getElements();
6743 for (
auto &SubprogramDirect : P.second)
6744 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6745 EltTys.push_back(SubprogramDirect.getPointer());
6747 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6748 DBuilder.replaceArrays(InterfaceDecl, Elements);
6751 for (
const auto &P : ReplaceMap) {
6754 assert(Ty->isForwardDecl());
6756 auto It = TypeCache.find(P.first);
6757 assert(It != TypeCache.end());
6760 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6764 for (
const auto &P : FwdDeclReplaceMap) {
6767 llvm::Metadata *Repl;
6769 auto It = DeclCache.find(P.first);
6773 if (It == DeclCache.end())
6778 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6779 Repl = GVE->getVariable();
6785 for (
auto &RT : RetainedTypes)
6786 if (
auto MD = TypeCache[RT])
6789 DBuilder.finalize();
6794 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6795 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6796 DBuilder.retainType(DieTy);
6800 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6801 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6802 DBuilder.retainType(DieTy);
6806 if (LexicalBlockStack.empty())
6807 return llvm::DebugLoc();
6809 llvm::MDNode *
Scope = LexicalBlockStack.back();
6810 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6811 getColumnNumber(Loc),
Scope);
6817 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6818 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6819 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6820 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6821 return llvm::DINode::FlagZero;
6826 bool SupportsDWARFv4Ext =
6827 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6828 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6829 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6831 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6832 return llvm::DINode::FlagZero;
6834 return llvm::DINode::FlagAllCallsDescribed;
6845 return DBuilder.createConstantValueExpression(
6846 Val.
getFloat().bitcastToAPInt().getZExtValue());
6851 llvm::APSInt
const &ValInt = Val.
getInt();
6852 std::optional<uint64_t> ValIntOpt;
6853 if (ValInt.isUnsigned())
6854 ValIntOpt = ValInt.tryZExtValue();
6855 else if (
auto tmp = ValInt.trySExtValue())
6858 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6861 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6866CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6868 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6869 CGF.CurLexicalScope =
this;
6871 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6876 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6889#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6891 Label = "__ubsan_check_" #Name; \
6895#undef SANITIZER_CHECK
6906#define SANITIZER(NAME, ID) \
6907 case SanitizerKind::SO_##ID: \
6908 Label = "__ubsan_check_" NAME; \
6910#include "clang/Basic/Sanitizers.def"
6912 llvm_unreachable(
"unexpected sanitizer kind");
6917 for (
unsigned int i = 0; i < Label.length(); i++)
6918 if (!std::isalpha(Label[i]))
6927 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6929 if (!DI || !CheckDebugLoc)
6930 return CheckDebugLoc;
6931 const auto &AnnotateDebugInfo =
6932 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6933 if (AnnotateDebugInfo.empty())
6934 return CheckDebugLoc;
6937 if (Ordinals.size() == 1)
6942 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6946 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6947 "ubsan_interface.h",
6949 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6952 return CheckDebugLoc;
6960 assert(!CGF->IsSanitizerScope);
6961 CGF->IsSanitizerScope =
true;
6965 assert(CGF->IsSanitizerScope);
6966 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static unsigned getDwarfCC(CallingConv CC, const llvm::Triple &T)
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static void completeStandardLayoutUnionType(CGDebugInfo &DebugInfo, QualType QT)
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static void completeStandardLayoutUnionMembers(CGDebugInfo &DebugInfo, const CXXRecordDecl *RD)
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
capture_const_iterator captures_end() const
method_range methods() const
bool defaultedDefaultConstructorIsConstexpr() const
Determine whether a defaulted default constructor for this class would be constexpr.
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
const LambdaCapture * capture_const_iterator
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
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...
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void removeObjCLifetime()
void removeAddressSpace()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
RecordDecl * getDefinitionOrSelf() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __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 SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.