40#include "llvm/ADT/DenseSet.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/DerivedTypes.h"
46#include "llvm/IR/Instruction.h"
47#include "llvm/IR/Instructions.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/Metadata.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/MD5.h"
52#include "llvm/Support/Path.h"
53#include "llvm/Support/SHA1.h"
54#include "llvm/Support/SHA256.h"
55#include "llvm/Support/TimeProfiler.h"
63 if (TI.isAlignRequired())
91 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
95 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
113 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
114 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
115 DBuilder(CGM.getModule()) {
120 assert(LexicalBlockStack.empty() &&
121 "Region stack mismatch, stack not empty!");
124void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
125 uint64_t Group, uint8_t Rank) {
126 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
130 Rank = std::min<uint8_t>(Rank, 7);
132 const llvm::DebugLoc &DL = I->getDebugLoc();
137 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
138 Group = DL->getAtomGroup();
139 Rank = DL->getAtomRank();
144 KeyInstructionsInfo.HighestEmittedAtom =
145 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
148 llvm::DILocation *NewDL = llvm::DILocation::get(
149 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
150 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
151 I->setDebugLoc(NewDL);
155 llvm::Value *Backup) {
157 KeyInstructionsInfo.CurrentAtom);
166 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
167 if (!SP || !SP->getKeyInstructionsEnabled())
170 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
172 llvm::Instruction *BackupI =
173 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
178 addInstSourceAtomMetadata(BackupI, Group, 2);
184 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
185 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
188 addInstSourceAtomMetadata(BackupI, Group, Rank++);
194 KeyInstructionsInfo.NextAtom = 1;
195 KeyInstructionsInfo.HighestEmittedAtom = 0;
196 KeyInstructionsInfo.CurrentAtom = 0;
202 OriginalAtom = DI->KeyInstructionsInfo.
CurrentAtom;
215 DI->KeyInstructionsInfo.
CurrentAtom = OriginalAtom;
221 init(TemporaryLocation);
228 init(TemporaryLocation, DefaultToEmpty);
232 bool DefaultToEmpty) {
239 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
241 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
244 if (TemporaryLocation.
isValid()) {
245 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
249 if (DefaultToEmpty) {
250 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
255 assert(!DI->LexicalBlockStack.empty());
256 CGF->
Builder.SetCurrentDebugLocation(
257 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
258 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
272 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
276 if (
Loc->getAtomGroup())
277 Loc = llvm::DILocation::get(
Loc->getContext(),
Loc.getLine(),
278 Loc->getColumn(),
Loc->getScope(),
279 Loc->getInlinedAt(),
Loc.isImplicitCode());
280 CGF.
Builder.SetCurrentDebugLocation(std::move(
Loc));
288 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
299 SavedLocation = DI.getLocation();
300 assert((DI.getInlinedAt() ==
301 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
302 "CGDebugInfo and IRBuilder are out of sync");
304 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
312 DI.EmitLocation(CGF->
Builder, SavedLocation);
325 if (LexicalBlockStack.empty())
329 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
331 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
334 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
335 LexicalBlockStack.pop_back();
336 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
337 LBF->getScope(), getOrCreateFile(CurLoc)));
338 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
339 isa<llvm::DISubprogram>(
Scope)) {
340 LexicalBlockStack.pop_back();
341 LexicalBlockStack.emplace_back(
342 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
346llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *
D) {
347 llvm::DIScope *Mod = getParentModuleOrNull(
D);
352llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
357 auto I = RegionMap.find(Context);
358 if (I != RegionMap.end()) {
359 llvm::Metadata *
V = I->second;
360 return dyn_cast_or_null<llvm::DIScope>(
V);
364 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
365 return getOrCreateNamespace(NSDecl);
367 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
368 if (!RDecl->isDependentType())
403StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
404 return internString(GetName(FD));
407StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
409 llvm::raw_svector_ostream OS(MethodName);
412 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
413 OS << OID->getName();
414 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
415 OS << OID->getName();
416 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
417 if (OC->IsClassExtension()) {
418 OS << OC->getClassInterface()->getName();
420 OS << OC->getIdentifier()->getNameStart() <<
'('
421 << OC->getIdentifier()->getNameStart() <<
')';
423 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
424 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
428 return internString(OS.str());
431StringRef CGDebugInfo::getSelectorName(
Selector S) {
432 return internString(S.getAsString());
435StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
436 if (isa<ClassTemplateSpecializationDecl>(RD)) {
438 return internString(GetName(RD));
444 return II->getName();
452 "Typedef should not be in another decl context!");
453 assert(
D->getDeclName().getAsIdentifierInfo() &&
454 "Typedef was not named!");
455 return D->getDeclName().getAsIdentifierInfo()->getName();
465 Name = DD->getName();
470 Name = TND->getName();
473 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
474 if (CXXRD->isLambda())
482 return internString(UnnamedType);
490std::optional<llvm::DIFile::ChecksumKind>
499 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
503 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
506 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
507 return llvm::DIFile::CSK_MD5;
509 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
510 return llvm::DIFile::CSK_SHA1;
512 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
513 return llvm::DIFile::CSK_SHA256;
517 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
520std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
525 bool SourceInvalid =
false;
526 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
538 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
544 FileName = TheCU->getFile()->getFilename();
545 CSInfo = TheCU->getFile()->getChecksum();
551 FileName = TheCU->getFile()->getFilename();
559 auto It = DIFileCache.find(
FileName.data());
560 if (It != DIFileCache.end()) {
562 if (llvm::Metadata *
V = It->second)
563 return cast<llvm::DIFile>(
V);
569 std::optional<llvm::DIFile::ChecksumKind> CSKind =
570 computeChecksum(FID, Checksum);
572 CSInfo.emplace(*CSKind, Checksum);
577llvm::DIFile *CGDebugInfo::createFile(
579 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
580 std::optional<StringRef> Source) {
584 std::string CurDir =
remapDIPath(getCurrentDirname());
587 if (llvm::sys::path::is_absolute(RemappedFile)) {
590 auto FileIt = llvm::sys::path::begin(RemappedFile);
591 auto FileE = llvm::sys::path::end(RemappedFile);
592 auto CurDirIt = llvm::sys::path::begin(CurDir);
593 auto CurDirE = llvm::sys::path::end(CurDir);
594 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
595 llvm::sys::path::append(DirBuf, *CurDirIt);
596 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
602 for (; FileIt != FileE; ++FileIt)
603 llvm::sys::path::append(FileBuf, *FileIt);
608 if (!llvm::sys::path::is_absolute(
FileName))
612 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
613 DIFileCache[
FileName.data()].reset(F);
620 if (llvm::sys::path::replace_path_prefix(
P, From, To))
622 return P.str().str();
629 return SM.getPresumedLoc(
Loc).getLine();
645StringRef CGDebugInfo::getCurrentDirname() {
649void CGDebugInfo::CreateCompileUnit() {
651 std::optional<llvm::DIFile::ChecksumKind> CSKind;
652 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
665 std::string MainFileName = CGO.MainFileName;
666 if (MainFileName.empty())
667 MainFileName =
"<stdin>";
673 std::string MainFileDir;
675 SM.getFileEntryRefForID(
SM.getMainFileID())) {
676 MainFileDir = std::string(MainFile->getDir().getName());
677 if (!llvm::sys::path::is_absolute(MainFileName)) {
679 llvm::sys::path::Style Style =
682 ? llvm::sys::path::Style::windows_backslash
683 : llvm::sys::path::Style::posix)
684 : llvm::sys::path::Style::native;
685 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
686 MainFileName = std::string(
687 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
694 if (MainFile->getName() == MainFileName &&
696 MainFile->getName().rsplit(
'.').second)
698 MainFileName = CGM.
getModule().getName().str();
700 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
704 llvm::dwarf::SourceLanguage LangTag;
707 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
708 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
709 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
710 else if (LO.CPlusPlus14)
711 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
712 else if (LO.CPlusPlus11)
713 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
715 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
716 }
else if (LO.ObjC) {
717 LangTag = llvm::dwarf::DW_LANG_ObjC;
718 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
720 LangTag = llvm::dwarf::DW_LANG_OpenCL;
721 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
722 LangTag = llvm::dwarf::DW_LANG_C11;
724 LangTag = llvm::dwarf::DW_LANG_C99;
726 LangTag = llvm::dwarf::DW_LANG_C89;
732 unsigned RuntimeVers = 0;
736 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
738 case llvm::codegenoptions::NoDebugInfo:
739 case llvm::codegenoptions::LocTrackingOnly:
740 EmissionKind = llvm::DICompileUnit::NoDebug;
742 case llvm::codegenoptions::DebugLineTablesOnly:
743 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
745 case llvm::codegenoptions::DebugDirectivesOnly:
746 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
748 case llvm::codegenoptions::DebugInfoConstructor:
749 case llvm::codegenoptions::LimitedDebugInfo:
750 case llvm::codegenoptions::FullDebugInfo:
751 case llvm::codegenoptions::UnusedTypeInfo:
752 EmissionKind = llvm::DICompileUnit::FullDebug;
763 CSInfo.emplace(*CSKind, Checksum);
764 llvm::DIFile *CUFile = DBuilder.createFile(
766 getSource(
SM,
SM.getMainFileID()));
768 StringRef Sysroot, SDK;
769 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
771 auto B = llvm::sys::path::rbegin(Sysroot);
772 auto E = llvm::sys::path::rend(Sysroot);
774 std::find_if(B,
E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
779 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
780 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
781 CGOpts.DebugNameTable);
783 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
785 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
788 TheCU = DBuilder.createCompileUnit(
789 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
790 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
791 CGOpts.PrepareForThinLTO,
792 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
793 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
794 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
797llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
801#define BUILTIN_TYPE(Id, SingletonId)
802#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
803#include "clang/AST/BuiltinTypes.def"
804 case BuiltinType::Dependent:
805 llvm_unreachable(
"Unexpected builtin type");
806 case BuiltinType::NullPtr:
807 return DBuilder.createNullPtrType();
808 case BuiltinType::Void:
810 case BuiltinType::ObjCClass:
813 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
814 "objc_class", TheCU, TheCU->getFile(), 0);
816 case BuiltinType::ObjCId: {
827 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
828 "objc_class", TheCU, TheCU->getFile(), 0);
832 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
834 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
835 (uint64_t)0, 0, llvm::DINode::FlagZero,
836 nullptr, llvm::DINodeArray());
838 DBuilder.replaceArrays(
839 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
840 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
841 llvm::DINode::FlagZero, ISATy)));
844 case BuiltinType::ObjCSel: {
846 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
847 "objc_selector", TheCU,
848 TheCU->getFile(), 0);
852#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
853 case BuiltinType::Id: \
854 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
856#include "clang/Basic/OpenCLImageTypes.def"
857 case BuiltinType::OCLSampler:
858 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
859 case BuiltinType::OCLEvent:
860 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
861 case BuiltinType::OCLClkEvent:
862 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
863 case BuiltinType::OCLQueue:
864 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
865 case BuiltinType::OCLReserveID:
866 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
867#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
868 case BuiltinType::Id: \
869 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
870#include "clang/Basic/OpenCLExtensionTypes.def"
871#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
872 case BuiltinType::Id: \
873 return getOrCreateStructPtrType(#Name, SingletonId);
874#include "clang/Basic/HLSLIntangibleTypes.def"
876#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
877#include "clang/Basic/AArch64ACLETypes.def"
879 if (BT->
getKind() == BuiltinType::MFloat8) {
880 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
884 return DBuilder.createBasicType(BTName, Size, Encoding);
888 BT->
getKind() == BuiltinType::SveCount
892 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
899 "Unsupported number of vectors for svcount_t");
903 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
909 llvm::Metadata *LowerBound, *UpperBound;
910 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
912 if (Info.
EC.isScalable()) {
913 unsigned NumElemsPerVG = NumElems / 2;
915 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
916 46, 0, llvm::dwarf::DW_OP_mul,
917 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
918 UpperBound = DBuilder.createExpression(
Expr);
920 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
923 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
924 nullptr, LowerBound, UpperBound,
nullptr);
925 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
926 llvm::DIType *ElemTy =
927 getOrCreateType(Info.
ElementType, TheCU->getFile());
929 return DBuilder.createVectorType( 0, Align, ElemTy,
934#define PPC_VECTOR_TYPE(Name, Id, size) \
935 case BuiltinType::Id:
936#include "clang/Basic/PPCTypes.def"
939#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
940#include "clang/Basic/RISCVVTypes.def"
945 unsigned ElementCount = Info.
EC.getKnownMinValue();
948 bool Fractional =
false;
951 unsigned FixedSize = ElementCount * SEW;
955 }
else if (FixedSize < 64) {
958 LMUL = 64 / FixedSize;
960 LMUL = FixedSize / 64;
968 {llvm::dwarf::DW_OP_bregx,
971 llvm::dwarf::DW_OP_constu,
973 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
975 Expr.push_back(llvm::dwarf::DW_OP_div);
977 Expr.push_back(llvm::dwarf::DW_OP_mul);
980 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
982 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
985 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
987 auto *UpperBound = DBuilder.createExpression(
Expr);
988 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
989 nullptr, LowerBound, UpperBound,
nullptr);
990 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
991 llvm::DIType *ElemTy =
992 getOrCreateType(Info.
ElementType, TheCU->getFile());
995 return DBuilder.createVectorType(0, Align, ElemTy,
999#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1000 case BuiltinType::Id: { \
1003 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1004 MangledName, TheCU, TheCU->getFile(), 0); \
1005 return SingletonId; \
1007#include "clang/Basic/WebAssemblyReferenceTypes.def"
1008#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1009 case BuiltinType::Id: { \
1012 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1013 TheCU, TheCU->getFile(), 0); \
1014 return SingletonId; \
1016#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1017 case BuiltinType::Id: { \
1020 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1021 return SingletonId; \
1023#include "clang/Basic/AMDGPUTypes.def"
1024 case BuiltinType::UChar:
1025 case BuiltinType::Char_U:
1026 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1028 case BuiltinType::Char_S:
1029 case BuiltinType::SChar:
1030 Encoding = llvm::dwarf::DW_ATE_signed_char;
1032 case BuiltinType::Char8:
1033 case BuiltinType::Char16:
1034 case BuiltinType::Char32:
1035 Encoding = llvm::dwarf::DW_ATE_UTF;
1037 case BuiltinType::UShort:
1038 case BuiltinType::UInt:
1039 case BuiltinType::UInt128:
1040 case BuiltinType::ULong:
1041 case BuiltinType::WChar_U:
1042 case BuiltinType::ULongLong:
1043 Encoding = llvm::dwarf::DW_ATE_unsigned;
1045 case BuiltinType::Short:
1046 case BuiltinType::Int:
1047 case BuiltinType::Int128:
1048 case BuiltinType::Long:
1049 case BuiltinType::WChar_S:
1050 case BuiltinType::LongLong:
1051 Encoding = llvm::dwarf::DW_ATE_signed;
1053 case BuiltinType::Bool:
1054 Encoding = llvm::dwarf::DW_ATE_boolean;
1056 case BuiltinType::Half:
1057 case BuiltinType::Float:
1058 case BuiltinType::LongDouble:
1059 case BuiltinType::Float16:
1060 case BuiltinType::BFloat16:
1061 case BuiltinType::Float128:
1062 case BuiltinType::Double:
1063 case BuiltinType::Ibm128:
1069 Encoding = llvm::dwarf::DW_ATE_float;
1071 case BuiltinType::ShortAccum:
1072 case BuiltinType::Accum:
1073 case BuiltinType::LongAccum:
1074 case BuiltinType::ShortFract:
1075 case BuiltinType::Fract:
1076 case BuiltinType::LongFract:
1077 case BuiltinType::SatShortFract:
1078 case BuiltinType::SatFract:
1079 case BuiltinType::SatLongFract:
1080 case BuiltinType::SatShortAccum:
1081 case BuiltinType::SatAccum:
1082 case BuiltinType::SatLongAccum:
1083 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1085 case BuiltinType::UShortAccum:
1086 case BuiltinType::UAccum:
1087 case BuiltinType::ULongAccum:
1088 case BuiltinType::UShortFract:
1089 case BuiltinType::UFract:
1090 case BuiltinType::ULongFract:
1091 case BuiltinType::SatUShortAccum:
1092 case BuiltinType::SatUAccum:
1093 case BuiltinType::SatULongAccum:
1094 case BuiltinType::SatUShortFract:
1095 case BuiltinType::SatUFract:
1096 case BuiltinType::SatULongFract:
1097 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1104 return DBuilder.createBasicType(BTName, Size, Encoding);
1107llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1109 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1111 ? llvm::dwarf::DW_ATE_unsigned
1112 : llvm::dwarf::DW_ATE_signed;
1118llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1120 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1122 Encoding = llvm::dwarf::DW_ATE_lo_user;
1125 return DBuilder.createBasicType(
"complex", Size, Encoding);
1139 return llvm::dwarf::DW_TAG_const_type;
1143 return llvm::dwarf::DW_TAG_volatile_type;
1147 return llvm::dwarf::DW_TAG_restrict_type;
1149 return (llvm::dwarf::Tag)0;
1152llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
1153 llvm::DIFile *Unit) {
1168 bool AuthenticatesNullValues =
1171 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1172 llvm::DIType *FromTy = getOrCreateType(
QualType(
T, 0), Unit);
1173 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1174 ExtraDiscr, IsaPointer,
1175 AuthenticatesNullValues);
1177 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1178 return getOrCreateType(
QualType(
T, 0), Unit);
1186 return DBuilder.createQualifiedType(Tag, FromTy);
1190 llvm::DIFile *Unit) {
1199 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1210 return DBuilder.createQualifiedType(Tag, FromTy);
1214 llvm::DIFile *Unit) {
1222 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1226llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1227 llvm::DIFile *Unit) {
1228 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1234 switch (TheCU->getSourceLanguage()) {
1235 case llvm::dwarf::DW_LANG_C_plus_plus:
1236 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1237 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1239 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1240 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1268 llvm::DICompileUnit *TheCU) {
1286 llvm::DICompileUnit *TheCU) {
1292 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1294 if (RD->isDynamicClass() &&
1307 llvm::dwarf::Tag Tag;
1309 Tag = llvm::dwarf::DW_TAG_structure_type;
1311 Tag = llvm::dwarf::DW_TAG_union_type;
1316 Tag = llvm::dwarf::DW_TAG_class_type;
1321llvm::DICompositeType *
1322CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1323 llvm::DIScope *Ctx) {
1325 if (llvm::DIType *
T = getTypeOrNull(
QualType(Ty, 0)))
1326 return cast<llvm::DICompositeType>(
T);
1327 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1328 const unsigned Line =
1330 StringRef RDName = getClassName(RD);
1336 if (
D &&
D->isCompleteDefinition())
1339 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1344 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1345 if (!CXXRD->hasDefinition() ||
1346 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1347 Flags |= llvm::DINode::FlagNonTrivial;
1354 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1358 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1359 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1360 CollectCXXTemplateParams(TSpecial, DefUnit));
1361 ReplaceMap.emplace_back(
1362 std::piecewise_construct, std::make_tuple(Ty),
1363 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1367llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1370 llvm::DIFile *Unit) {
1375 std::optional<unsigned> DWARFAddressSpace =
1381 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1383 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1386 StringRef
Tag = BTFAttrTy->
getAttr()->getBTFTypeTag();
1388 llvm::Metadata *Ops[2] = {
1389 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1391 Annots.insert(Annots.begin(),
1394 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->
getWrappedType());
1397 llvm::DINodeArray Annotations =
nullptr;
1398 if (Annots.size() > 0)
1399 Annotations = DBuilder.getOrCreateArray(Annots);
1401 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1402 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1403 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1404 Size, Align, DWARFAddressSpace);
1406 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1407 Align, DWARFAddressSpace, StringRef(),
1411llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1412 llvm::DIType *&
Cache) {
1415 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1416 TheCU, TheCU->getFile(), 0);
1418 Cache = DBuilder.createPointerType(
Cache, Size);
1422uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1423 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1436 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1437 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1440 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1442 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1443 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1445 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1449 EltTys.push_back(DBuilder.createMemberType(
1450 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1451 FieldOffset, llvm::DINode::FlagZero, DescTy));
1452 FieldOffset += FieldSize;
1459 llvm::DIFile *Unit) {
1463 llvm::DINodeArray Elements;
1467 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1468 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1470 Elements = DBuilder.getOrCreateArray(EltTys);
1473 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1476 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1477 FieldOffset, 0, Flags,
nullptr, Elements);
1482 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1484 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1487 Elements = DBuilder.getOrCreateArray(EltTys);
1493 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1494 Flags,
nullptr, Elements);
1496 return DBuilder.createPointerType(EltTy, Size);
1513 if (Param->isParameterPack()) {
1522 if (SubstArgs.empty()) {
1531 SpecArgs.push_back(SubstArgs.front());
1532 SubstArgs = SubstArgs.drop_front();
1538 llvm::DIFile *Unit) {
1543 if (isa<BuiltinTemplateDecl>(TD))
1546 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1551 llvm::raw_svector_ostream OS(NS);
1553 auto PP = getPrintingPolicy();
1559 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1568 llvm::raw_string_ostream OS(Name);
1571 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1572 !HasReconstitutableArgs(Args.Args))
1575 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1576 Src, Name, getOrCreateFile(
Loc), getLineNumber(
Loc),
1577 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1583 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(
Loc),
1600 return llvm::DINode::FlagZero;
1604 return llvm::DINode::FlagPrivate;
1606 return llvm::DINode::FlagProtected;
1608 return llvm::DINode::FlagPublic;
1610 return llvm::DINode::FlagZero;
1612 llvm_unreachable(
"unexpected access enumerator");
1615llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1616 llvm::DIFile *Unit) {
1617 llvm::DIType *Underlying =
1629 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1631 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1633 if (isa<RecordDecl>(DC))
1636 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1637 getOrCreateFile(
Loc), getLineNumber(
Loc),
1638 getDeclContextDescriptor(Ty->
getDecl()), Align,
1639 Flags, Annotations);
1649 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1651 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1653 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1655 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1657 return llvm::dwarf::DW_CC_BORLAND_pascal;
1659 return llvm::dwarf::DW_CC_LLVM_Win64;
1661 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1665 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1667 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1669 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1671 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1673 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1675 return llvm::dwarf::DW_CC_LLVM_Swift;
1677 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1679 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1681 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1683 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1685 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1687 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1689 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1690#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1704 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1710 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1712 Flags |= llvm::DINode::FlagLValueReference;
1714 Flags |= llvm::DINode::FlagRValueReference;
1718llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1719 llvm::DIFile *Unit) {
1720 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1722 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1731 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1733 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1737 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1740 for (
const QualType &ParamType : FPT->param_types())
1741 EltTys.push_back(getOrCreateType(ParamType, Unit));
1742 if (FPT->isVariadic())
1743 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1746 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1747 llvm::DIType *F = DBuilder.createSubroutineType(
1752llvm::DIDerivedType *
1753CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1754 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1755 StringRef Name = BitFieldDecl->
getName();
1757 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1758 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1760 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1761 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1764 llvm::DIFile *
File = getOrCreateFile(
Loc);
1765 unsigned Line = getLineNumber(
Loc);
1770 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1779 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1781 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1782 return DBuilder.createBitFieldMemberType(
1783 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1784 Flags, DebugType, Annotations);
1787llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1788 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1816 if (PreviousFieldsDI.empty())
1820 auto *PreviousMDEntry =
1821 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1822 auto *PreviousMDField =
1823 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1824 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1825 PreviousMDField->getSizeInBits() == 0)
1829 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1831 assert(PreviousBitfield->isBitField());
1833 if (!PreviousBitfield->isZeroLengthBitField())
1836 QualType Ty = PreviousBitfield->getType();
1838 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1839 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1840 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1842 llvm::DIFile *
File = getOrCreateFile(
Loc);
1843 unsigned Line = getLineNumber(
Loc);
1846 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1849 llvm::DINode::DIFlags Flags =
1851 llvm::DINodeArray Annotations =
1852 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1853 return DBuilder.createBitFieldMemberType(
1854 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1855 Flags, DebugType, Annotations);
1858llvm::DIType *CGDebugInfo::createFieldType(
1860 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1861 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1862 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1865 llvm::DIFile *file = getOrCreateFile(loc);
1866 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1869 auto Align = AlignInBits;
1870 if (!
type->isIncompleteArrayType()) {
1872 SizeInBits = TI.
Width;
1878 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1879 offsetInBits, flags, debugType, Annotations);
1883CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
1884 llvm::DIFile *FileScope) {
1888 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
1891 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1892 SP = DBuilder.createFunction(
1893 FileScope, FuncName, StringRef(),
1894 FileScope, 0, DIFnTy,
1896 llvm::DINode::FlagArtificial,
1897 llvm::DISubprogram::SPFlagDefinition,
1898 nullptr,
nullptr,
nullptr,
1899 nullptr, StringRef(),
1906void CGDebugInfo::CollectRecordLambdaFields(
1908 llvm::DIType *RecordTy) {
1914 unsigned fieldno = 0;
1917 I !=
E; ++I, ++Field, ++fieldno) {
1919 if (
C.capturesVariable()) {
1921 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1923 StringRef VName =
V->getName();
1924 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1926 llvm::DIType *FieldType = createFieldType(
1928 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1929 elements.push_back(FieldType);
1930 }
else if (
C.capturesThis()) {
1936 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1938 StringRef ThisName =
1940 llvm::DIType *fieldType = createFieldType(
1944 elements.push_back(fieldType);
1949llvm::DIDerivedType *
1950CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1955 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1956 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1958 unsigned LineNumber = getLineNumber(Var->
getLocation());
1959 StringRef VName = Var->
getName();
1963 llvm::Constant *
C =
nullptr;
1969 if (
Value->isFloat())
1976 ? llvm::dwarf::DW_TAG_variable
1977 : llvm::dwarf::DW_TAG_member;
1979 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1980 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1985void CGDebugInfo::CollectRecordNormalField(
1986 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1993 if (
name.empty() && !
type->isRecordType())
1996 llvm::DIType *FieldType;
1998 llvm::DIDerivedType *BitFieldType;
1999 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2000 if (llvm::DIType *Separator =
2001 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2002 elements.push_back(Separator);
2005 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2008 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2011 elements.push_back(FieldType);
2014void CGDebugInfo::CollectRecordNestedType(
2020 if (isa<InjectedClassNameType>(Ty))
2023 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(
Loc)))
2024 elements.push_back(nestedType);
2027void CGDebugInfo::CollectRecordFields(
2028 const RecordDecl *record, llvm::DIFile *tunit,
2030 llvm::DICompositeType *RecordTy) {
2031 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2033 if (CXXDecl && CXXDecl->
isLambda())
2034 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2039 unsigned fieldNo = 0;
2043 for (
const auto *I : record->
decls())
2044 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2045 if (
V->hasAttr<NoDebugAttr>())
2051 isa<VarTemplateSpecializationDecl>(
V))
2054 if (isa<VarTemplatePartialSpecializationDecl>(
V))
2058 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2059 if (MI != StaticDataMemberCache.end()) {
2060 assert(MI->second &&
2061 "Static data member declaration should still exist");
2062 elements.push_back(MI->second);
2064 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2065 elements.push_back(Field);
2067 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2068 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2069 elements, RecordTy, record);
2076 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2078 if (isa<RecordDecl>(I) &&
2079 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
2081 if (!nestedType->isImplicit() &&
2082 nestedType->getDeclContext() == record)
2083 CollectRecordNestedType(nestedType, elements);
2089llvm::DISubroutineType *
2091 llvm::DIFile *Unit) {
2094 return cast_or_null<llvm::DISubroutineType>(
2098 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2099 ThisType =
Method->getThisType();
2101 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2104llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2108 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2111llvm::DISubroutineType *
2112CGDebugInfo::getOrCreateInstanceMethodType(
QualType ThisPtr,
2114 llvm::DIFile *Unit,
bool SkipFirst) {
2129 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
2131 Func->getReturnType(),
Func->getParamTypes(), EPI),
2133 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2134 assert(Args.size() &&
"Invalid number of arguments!");
2139 Elts.push_back(Args[0]);
2141 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2145 if (!HasExplicitObjectParameter) {
2146 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2149 DBuilder.createObjectPointerType(ThisPtrType,
true);
2150 Elts.push_back(ThisPtrType);
2154 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2155 Elts.push_back(Args[i]);
2158 if (HasExplicitObjectParameter) {
2159 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2160 "Expected at least return type and object parameter.");
2161 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2164 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2166 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2173 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2180llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2183 isa<CXXConstructorDecl>(
Method) || isa<CXXDestructorDecl>(
Method);
2185 StringRef MethodName = getFunctionName(
Method);
2186 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2190 StringRef MethodLinkageName;
2200 llvm::DIFile *MethodDefUnit =
nullptr;
2201 unsigned MethodLine = 0;
2202 if (!
Method->isImplicit()) {
2203 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2204 MethodLine = getLineNumber(
Method->getLocation());
2208 llvm::DIType *ContainingType =
nullptr;
2209 unsigned VIndex = 0;
2210 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2211 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2215 if (
Method->isPureVirtual())
2216 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2218 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2223 if (!isa<CXXDestructorDecl>(
Method))
2228 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2239 if (
Method->size_overridden_methods() == 0)
2240 Flags |= llvm::DINode::FlagIntroducedVirtual;
2249 ContainingType = RecordTy;
2252 if (
Method->getCanonicalDecl()->isDeleted())
2253 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2255 if (
Method->isNoReturn())
2256 Flags |= llvm::DINode::FlagNoReturn;
2259 Flags |= llvm::DINode::FlagStaticMember;
2260 if (
Method->isImplicit())
2261 Flags |= llvm::DINode::FlagArtificial;
2263 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2264 if (CXXC->isExplicit())
2265 Flags |= llvm::DINode::FlagExplicit;
2266 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2267 if (CXXC->isExplicit())
2268 Flags |= llvm::DINode::FlagExplicit;
2270 if (
Method->hasPrototype())
2271 Flags |= llvm::DINode::FlagPrototyped;
2273 Flags |= llvm::DINode::FlagLValueReference;
2275 Flags |= llvm::DINode::FlagRValueReference;
2276 if (!
Method->isExternallyVisible())
2277 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2279 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2283 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2287 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2288 llvm::DISubprogram *SP = DBuilder.createMethod(
2289 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2290 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2291 TParamsArray.get(),
nullptr,
2294 SPCache[
Method->getCanonicalDecl()].reset(SP);
2299void CGDebugInfo::CollectCXXMemberFunctions(
2306 for (
const auto *I : RD->
decls()) {
2307 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2330 auto MI = SPCache.find(
Method->getCanonicalDecl());
2331 EltTys.push_back(MI == SPCache.end()
2332 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2333 :
static_cast<llvm::Metadata *
>(MI->second));
2337void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2339 llvm::DIType *RecordTy) {
2340 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2341 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2342 llvm::DINode::FlagZero);
2347 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2348 llvm::DINode::FlagIndirectVirtualBase);
2352void CGDebugInfo::CollectCXXBasesAux(
2357 llvm::DINode::DIFlags StartingFlags) {
2359 for (
const auto &BI : Bases) {
2361 cast<CXXRecordDecl>(
2364 if (!SeenTypes.insert(
Base).second)
2366 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2367 llvm::DINode::DIFlags BFlags = StartingFlags;
2371 if (BI.isVirtual()) {
2388 BFlags |= llvm::DINode::FlagVirtual;
2395 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2396 VBPtrOffset, BFlags);
2397 EltTys.push_back(DTy);
2402CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2403 llvm::DIFile *Unit) {
2405 return llvm::DINodeArray();
2406 TemplateArgs &Args = *OArgs;
2408 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2413 Name = Args.TList->getParam(i)->getName();
2417 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2418 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2419 TheCU, Name, TTy, defaultParameter));
2424 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2425 TheCU, Name, TTy, defaultParameter,
2431 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2432 llvm::Constant *
V =
nullptr;
2439 if (
const auto *VD = dyn_cast<VarDecl>(
D))
2443 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D);
2444 MD && MD->isImplicitObjectMemberFunction())
2446 else if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
2450 else if (
const auto *MPT =
2451 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2459 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(
D)) {
2461 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
2468 assert(
V &&
"Failed to find template parameter pointer");
2469 V =
V->stripPointerCasts();
2471 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2472 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2476 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2477 llvm::Constant *
V =
nullptr;
2480 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2486 if (MPT->isMemberDataPointer())
2489 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2490 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2491 TheCU, Name, TTy, defaultParameter,
V));
2495 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2498 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2499 TheCU, Name, TTy, defaultParameter,
V));
2502 std::string QualName;
2503 llvm::raw_string_ostream OS(QualName);
2505 OS, getPrintingPolicy());
2506 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2507 TheCU, Name,
nullptr, QualName, defaultParameter));
2511 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2512 TheCU, Name,
nullptr,
2521 assert(
V &&
"Expression in template argument isn't constant");
2522 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2523 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2524 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2530 "These argument types shouldn't exist in concrete types");
2533 return DBuilder.getOrCreateArray(TemplateParams);
2536std::optional<CGDebugInfo::TemplateArgs>
2537CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2545 return std::nullopt;
2547std::optional<CGDebugInfo::TemplateArgs>
2548CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2552 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2554 return std::nullopt;
2557 auto TA = TS->getTemplateArgs().asArray();
2558 return {{TList, TA}};
2560std::optional<CGDebugInfo::TemplateArgs>
2561CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2562 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2567 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2569 return {{TPList, TAList.
asArray()}};
2571 return std::nullopt;
2575CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2576 llvm::DIFile *Unit) {
2577 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2580llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2581 llvm::DIFile *Unit) {
2582 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2585llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2586 llvm::DIFile *Unit) {
2587 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2590llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *
D) {
2596 llvm::Metadata *Ops[2] = {
2597 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2599 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2601 return DBuilder.getOrCreateArray(Annotations);
2604llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2606 return VTablePtrType;
2611 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2612 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2613 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2616 std::optional<unsigned> DWARFAddressSpace =
2619 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2620 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2621 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2622 return VTablePtrType;
2625StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2640 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2644 StringRef SymbolName =
"_vtable$";
2655 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2656 auto *Ctxt = cast<llvm::DICompositeType>(DContext);
2657 llvm::DIFile *Unit = getOrCreateFile(
Loc);
2658 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2660 llvm::DINode::FlagArtificial;
2662 ? llvm::dwarf::DW_TAG_variable
2663 : llvm::dwarf::DW_TAG_member;
2664 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2665 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2673 llvm::DIGlobalVariableExpression *GVE =
2674 DBuilder.createGlobalVariableExpression(
2675 TheCU, SymbolName, VTable->getName(), Unit, 0,
2676 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2677 true,
nullptr, DT,
nullptr,
2679 VTable->addDebugInfo(GVE);
2682StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2684 llvm::Function *InitFn) {
2689 return InitFn->getName();
2699 llvm::raw_svector_ostream OS(QualifiedGV);
2701 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2703 std::swap(Quals, GVName);
2707 llvm::raw_svector_ostream OS(InitName);
2709 OS << Quals <<
"::";
2714 llvm_unreachable(
"not an initializer");
2716 OS <<
"`dynamic initializer for '";
2719 OS <<
"`dynamic atexit destructor for '";
2726 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2728 getPrintingPolicy());
2733 return internString(OS.str());
2736void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2753 llvm::DIType *VPtrTy =
nullptr;
2756 if (NeedVTableShape) {
2761 unsigned VSlotCount =
2763 unsigned VTableWidth = PtrWidth * VSlotCount;
2765 std::optional<unsigned> DWARFAddressSpace =
2769 llvm::DIType *VTableType = DBuilder.createPointerType(
2770 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2771 EltTys.push_back(VTableType);
2774 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2782 VPtrTy = getOrCreateVTablePtrType(Unit);
2785 llvm::DIType *VPtrMember =
2786 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2787 llvm::DINode::FlagArtificial, VPtrTy);
2788 EltTys.push_back(VPtrMember);
2794 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(
Loc));
2806 assert(!
D.isNull() &&
"null type");
2807 llvm::DIType *
T = getOrCreateType(
D, getOrCreateFile(
Loc));
2808 assert(
T &&
"could not create debug info for type");
2810 RetainedTypes.push_back(
D.getAsOpaquePtr());
2818 llvm::codegenoptions::DebugLineTablesOnly)
2824 node = getOrCreateType(AllocatedTy, getOrCreateFile(
Loc));
2826 CI->setMetadata(
"heapallocsite", node);
2830 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2834 auto I = TypeCache.find(TyPtr);
2835 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2837 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
2838 assert(!Res->isForwardDecl());
2839 TypeCache[TyPtr].reset(Res);
2843 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2850 if (RD->
hasAttr<DLLImportAttr>())
2853 if (MD->hasAttr<DLLImportAttr>())
2866 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2876 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2877 Explicit = TD->isExplicitInstantiationOrSpecialization();
2881 if (CXXDecl->
fields().empty())
2891 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2892 if (CXXRD->isDynamicClass() &&
2894 llvm::GlobalValue::AvailableExternallyLinkage &&
2905 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2909 auto I = TypeCache.find(TyPtr);
2910 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2916 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
2917 assert(!Res->isForwardDecl());
2918 TypeCache[TyPtr].reset(Res);
2925 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2926 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2949 if (Ctor->isCopyOrMoveConstructor())
2951 if (!Ctor->isDeleted())
2970 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2973 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2974 RD->
hasAttr<StandaloneDebugAttr>())
2977 if (!LangOpts.CPlusPlus)
2983 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2999 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3000 Spec = SD->getSpecializationKind();
3009 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3021 llvm::DIType *
T = getTypeOrNull(Ty);
3022 if (
T &&
T->isForwardDecl())
3026llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3028 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3032 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3036 auto [Def, Pref] = CreateTypeDefinition(Ty);
3038 return Pref ? Pref : Def;
3041llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3042 llvm::DIFile *Unit) {
3046 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3050 return getOrCreateType(PNA->getTypedefType(), Unit);
3053std::pair<llvm::DIType *, llvm::DIType *>
3054CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3058 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3066 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3069 if (!
D || !
D->isCompleteDefinition())
3070 return {FwdDecl,
nullptr};
3072 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3073 CollectContainingType(CXXDecl, FwdDecl);
3076 LexicalBlockStack.emplace_back(&*FwdDecl);
3077 RegionMap[RD].reset(FwdDecl);
3087 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3089 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3090 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3094 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3095 if (CXXDecl && !CGM.
getCodeGenOpts().DebugOmitUnreferencedMethods)
3096 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3098 LexicalBlockStack.pop_back();
3099 RegionMap.erase(RD);
3101 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3102 DBuilder.replaceArrays(FwdDecl, Elements);
3104 if (FwdDecl->isTemporary())
3106 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3108 RegionMap[RD].reset(FwdDecl);
3110 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3111 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3112 return {FwdDecl, PrefDI};
3114 return {FwdDecl,
nullptr};
3118 llvm::DIFile *Unit) {
3124 llvm::DIFile *Unit) {
3129 return DBuilder.createTypedef(
3132 getDeclContextDescriptor(Ty->
getDecl()));
3160 llvm::DIFile *Unit) {
3166 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
3171 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3172 !
ID->getImplementation())
3173 return DBuilder.createForwardDecl(
3174 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3175 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3178 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3179 unsigned Line = getLineNumber(
ID->getLocation());
3185 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3186 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3187 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3188 DefUnit,
Line, RuntimeLang);
3189 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3193 return CreateTypeDefinition(Ty, Unit);
3197 bool CreateSkeletonCU) {
3204 return cast<llvm::DIModule>(ModRef->second);
3209 llvm::raw_svector_ostream OS(ConfigMacros);
3213 for (
auto &M : PPOpts.Macros) {
3216 const std::string &
Macro = M.first;
3217 bool Undef = M.second;
3218 OS <<
"\"-" << (Undef ?
'U' :
'D');
3234 bool IsRootModule = M ? !M->
Parent :
true;
3238 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3240 "clang module without ASTFile must be specified by -fmodule-name");
3243 auto RemapPath = [
this](StringRef
Path) -> std::string {
3245 StringRef Relative(Remapped);
3246 StringRef CompDir = TheCU->getDirectory();
3247 if (CompDir.empty())
3250 if (Relative.consume_front(CompDir))
3251 Relative.consume_front(llvm::sys::path::get_separator());
3253 return Relative.str();
3256 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3263 Signature = ModSig.truncatedValue();
3269 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3271 PCM = getCurrentDirname();
3275 llvm::sys::path::append(PCM, Mod.
getASTFile());
3276 DIB.createCompileUnit(
3277 TheCU->getSourceLanguage(),
3280 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3281 llvm::DICompileUnit::FullDebug, Signature);
3286 IsRootModule ? nullptr
3289 std::string IncludePath = Mod.
getPath().str();
3290 llvm::DIModule *DIMod =
3292 RemapPath(IncludePath));
3298 llvm::DIFile *Unit) {
3300 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3301 unsigned Line = getLineNumber(
ID->getLocation());
3302 unsigned RuntimeLang = TheCU->getSourceLanguage();
3308 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3309 if (
ID->getImplementation())
3310 Flags |= llvm::DINode::FlagObjcClassComplete;
3312 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3313 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3314 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3315 nullptr, llvm::DINodeArray(), RuntimeLang);
3318 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3321 LexicalBlockStack.emplace_back(RealDecl);
3322 RegionMap[Ty->
getDecl()].reset(RealDecl);
3329 llvm::DIType *SClassTy =
3334 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3335 llvm::DINode::FlagZero);
3336 EltTys.push_back(InhTag);
3342 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3343 unsigned PLine = getLineNumber(
Loc);
3346 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3347 PD->getName(), PUnit, PLine,
3349 : getSelectorName(PD->getGetterName()),
3351 : getSelectorName(PD->getSetterName()),
3352 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3353 EltTys.push_back(PropertyNode);
3358 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3362 llvm::DenseSet<IsClassAndIdent> PropertySet;
3365 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3368 for (
auto *PD : ClassExt->properties()) {
3369 PropertySet.insert(GetIsClassAndIdent(PD));
3372 for (
const auto *PD :
ID->properties()) {
3375 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3382 unsigned FieldNo = 0;
3384 Field =
Field->getNextIvar(), ++FieldNo) {
3385 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3389 StringRef FieldName =
Field->getName();
3392 if (FieldName.empty())
3396 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3397 unsigned FieldLine = getLineNumber(
Field->getLocation());
3405 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3415 if (
Field->isBitField()) {
3426 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3428 Flags = llvm::DINode::FlagProtected;
3430 Flags = llvm::DINode::FlagPrivate;
3432 Flags = llvm::DINode::FlagPublic;
3434 if (
Field->isBitField())
3435 Flags |= llvm::DINode::FlagBitField;
3437 llvm::MDNode *PropertyNode =
nullptr;
3440 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3443 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3444 unsigned PLine = getLineNumber(
Loc);
3447 PropertyNode = DBuilder.createObjCProperty(
3448 PD->getName(), PUnit, PLine,
3451 : getSelectorName(PD->getGetterName()),
3454 : getSelectorName(PD->getSetterName()),
3455 PD->getPropertyAttributes(),
3456 getOrCreateType(PD->getType(), PUnit));
3460 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3461 FieldSize, FieldAlign, FieldOffset, Flags,
3462 FieldTy, PropertyNode);
3463 EltTys.push_back(FieldTy);
3466 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3467 DBuilder.replaceArrays(RealDecl, Elements);
3469 LexicalBlockStack.pop_back();
3473llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3474 llvm::DIFile *Unit) {
3492 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3495 llvm::Metadata *Subscript;
3497 auto SizeExpr = SizeExprCache.find(QTy);
3498 if (SizeExpr != SizeExprCache.end())
3499 Subscript = DBuilder.getOrCreateSubrange(
3500 SizeExpr->getSecond() ,
nullptr ,
3501 nullptr ,
nullptr );
3504 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3505 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3506 Subscript = DBuilder.getOrCreateSubrange(
3507 CountNode ,
nullptr ,
nullptr ,
3510 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3515 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3519 llvm::DIFile *Unit) {
3523 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3529 auto *ColumnCountNode =
3530 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3532 auto *RowCountNode =
3533 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3535 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3536 ColumnCountNode ,
nullptr ,
nullptr ,
3538 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3539 RowCountNode ,
nullptr ,
nullptr ,
3541 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3542 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3545llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3550 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3574 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3583 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3584 Count = CAT->getZExtSize();
3585 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3586 if (
Expr *Size = VAT->getSizeExpr()) {
3589 Count =
Result.Val.getInt().getExtValue();
3593 auto SizeNode = SizeExprCache.find(EltTy);
3594 if (SizeNode != SizeExprCache.end())
3595 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3596 SizeNode->getSecond() ,
nullptr ,
3597 nullptr ,
nullptr ));
3600 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3602 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3603 CountNode ,
nullptr ,
nullptr ,
3609 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3611 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3616 llvm::DIFile *Unit) {
3617 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3622 llvm::DIFile *Unit) {
3623 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3627 Tag = llvm::dwarf::DW_TAG_reference_type;
3629 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3634 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3644 Flags |= llvm::DINode::FlagSingleInheritance;
3647 Flags |= llvm::DINode::FlagMultipleInheritance;
3650 Flags |= llvm::DINode::FlagVirtualInheritance;
3660 llvm::DIType *ClassType = getOrCreateType(
T,
U);
3662 return DBuilder.createMemberPointerType(
3668 return DBuilder.createMemberPointerType(
3669 getOrCreateInstanceMethodType(
3672 ClassType,
Size, 0, Flags);
3675llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3677 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3680llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3708llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3711 bool isImportedFromModule =
3712 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3716 if (isImportedFromModule || !ED->getDefinition()) {
3723 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3724 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3725 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3726 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3728 unsigned Line = getLineNumber(ED->getLocation());
3729 StringRef EDName = ED->getName();
3730 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3731 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3732 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3734 ReplaceMap.emplace_back(
3735 std::piecewise_construct, std::make_tuple(Ty),
3736 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3740 return CreateTypeDefinition(Ty);
3743llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3747 ED = ED->getDefinition();
3748 assert(ED &&
"An enumeration definition is required");
3749 for (
const auto *
Enum : ED->enumerators()) {
3750 Enumerators.push_back(
3751 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3754 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3755 if (
auto *
Attr = ED->getAttr<EnumExtensibilityAttr>())
3756 EnumKind =
Attr->getExtensibility();
3759 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3761 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3762 unsigned Line = getLineNumber(ED->getLocation());
3763 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3764 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
3765 return DBuilder.createEnumerationType(
3766 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3772 StringRef Name, StringRef
Value) {
3773 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3780 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3781 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3782 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3786 StringRef FuncName) {
3787 llvm::DISubprogram *SP =
3788 createInlinedSubprogram(FuncName, Location->getFile());
3794 llvm::DebugLoc TrapLocation, StringRef
Category, StringRef FailureMsg) {
3802 FuncName += FailureMsg;
3814 Quals += InnerQuals;
3818 return C.getQualifiedType(
T.getTypePtr(), Quals);
3821 case Type::InjectedClassName:
3824 case Type::TemplateSpecialization: {
3825 const auto *Spec = cast<TemplateSpecializationType>(
T);
3826 if (Spec->isTypeAlias())
3827 return C.getQualifiedType(
T.getTypePtr(), Quals);
3831 case Type::TypeOfExpr:
3832 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3835 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3837 case Type::Decltype:
3838 T = cast<DecltypeType>(
T)->getUnderlyingType();
3840 case Type::UnaryTransform:
3841 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3843 case Type::Attributed:
3844 T = cast<AttributedType>(
T)->getEquivalentType();
3846 case Type::BTFTagAttributed:
3847 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3849 case Type::CountAttributed:
3850 T = cast<CountAttributedType>(
T)->
desugar();
3856 T = cast<ParenType>(
T)->getInnerType();
3858 case Type::MacroQualified:
3859 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3861 case Type::SubstTemplateTypeParm:
3862 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3865 case Type::DeducedTemplateSpecialization: {
3866 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3867 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3871 case Type::PackIndexing: {
3872 T = cast<PackIndexingType>(
T)->getSelectedType();
3875 case Type::Adjusted:
3878 T = cast<AdjustedType>(
T)->getAdjustedType();
3882 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3887llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3890 if (It != TypeCache.end()) {
3892 if (llvm::Metadata *
V = It->second)
3893 return cast<llvm::DIType>(
V);
3905 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3912 RetainedTypes.push_back(
3916llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3920 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3922 llvm::raw_string_ostream OS(Name);
3923 Ty.
print(OS, getPrintingPolicy());
3930 if (
auto *
T = getTypeOrNull(Ty))
3933 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3934 void *TyPtr = Ty.getAsOpaquePtr();
3937 TypeCache[TyPtr].reset(Res);
3942llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *
D) {
3950 auto Info = Reader->getSourceDescriptor(Idx);
3952 return getOrCreateModuleRef(*Info,
true);
3953 }
else if (ClangModuleMap) {
3967 return getOrCreateModuleRef(Info,
false);
3970 return getOrCreateModuleRef(PCHDescriptor,
false);
3977llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3980 return CreateQualifiedType(Ty, Unit);
3984#define TYPE(Class, Base)
3985#define ABSTRACT_TYPE(Class, Base)
3986#define NON_CANONICAL_TYPE(Class, Base)
3987#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3988#include "clang/AST/TypeNodes.inc"
3989 llvm_unreachable(
"Dependent types cannot show up in debug information");
3991 case Type::ExtVector:
3993 return CreateType(cast<VectorType>(Ty), Unit);
3994 case Type::ConstantMatrix:
3995 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3996 case Type::ObjCObjectPointer:
3997 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3998 case Type::ObjCObject:
3999 return CreateType(cast<ObjCObjectType>(Ty), Unit);
4000 case Type::ObjCTypeParam:
4001 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
4002 case Type::ObjCInterface:
4003 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
4005 return CreateType(cast<BuiltinType>(Ty));
4007 return CreateType(cast<ComplexType>(Ty));
4009 return CreateType(cast<PointerType>(Ty), Unit);
4010 case Type::BlockPointer:
4011 return CreateType(cast<BlockPointerType>(Ty), Unit);
4013 return CreateType(cast<TypedefType>(Ty), Unit);
4015 return CreateType(cast<RecordType>(Ty));
4017 return CreateEnumType(cast<EnumType>(Ty));
4018 case Type::FunctionProto:
4019 case Type::FunctionNoProto:
4020 return CreateType(cast<FunctionType>(Ty), Unit);
4021 case Type::ConstantArray:
4022 case Type::VariableArray:
4023 case Type::IncompleteArray:
4024 case Type::ArrayParameter:
4025 return CreateType(cast<ArrayType>(Ty), Unit);
4027 case Type::LValueReference:
4028 return CreateType(cast<LValueReferenceType>(Ty), Unit);
4029 case Type::RValueReference:
4030 return CreateType(cast<RValueReferenceType>(Ty), Unit);
4032 case Type::MemberPointer:
4033 return CreateType(cast<MemberPointerType>(Ty), Unit);
4036 return CreateType(cast<AtomicType>(Ty), Unit);
4039 return CreateType(cast<BitIntType>(Ty));
4041 return CreateType(cast<PipeType>(Ty), Unit);
4043 case Type::TemplateSpecialization:
4044 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
4045 case Type::HLSLAttributedResource:
4046 return CreateType(cast<HLSLAttributedResourceType>(Ty), Unit);
4047 case Type::HLSLInlineSpirv:
4048 return CreateType(cast<HLSLInlineSpirvType>(Ty), Unit);
4049 case Type::PredefinedSugar:
4050 return getOrCreateType(cast<PredefinedSugarType>(Ty)->desugar(), Unit);
4051 case Type::CountAttributed:
4053 case Type::Attributed:
4054 case Type::BTFTagAttributed:
4055 case Type::Adjusted:
4057 case Type::DeducedTemplateSpecialization:
4060 case Type::MacroQualified:
4061 case Type::SubstTemplateTypeParm:
4062 case Type::TypeOfExpr:
4064 case Type::Decltype:
4065 case Type::PackIndexing:
4066 case Type::UnaryTransform:
4070 llvm_unreachable(
"type should have been unwrapped!");
4073llvm::DICompositeType *
4074CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4077 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4082 if (
T && !
T->isForwardDecl())
4086 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4091 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
4094 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4099llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4103 StringRef RDName = getClassName(RD);
4105 llvm::DIFile *DefUnit =
nullptr;
4108 DefUnit = getOrCreateFile(
Loc);
4112 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4116 auto *
T = cast_or_null<llvm::DICompositeType>(
4124 if (!
D || !
D->isCompleteDefinition())
4125 return getOrCreateRecordFwdDecl(Ty, RDContext);
4138 auto Flags = llvm::DINode::FlagZero;
4139 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4141 Flags |= llvm::DINode::FlagTypePassByReference;
4143 Flags |= llvm::DINode::FlagTypePassByValue;
4146 if (!CXXRD->isTrivial())
4147 Flags |= llvm::DINode::FlagNonTrivial;
4150 if (CXXRD->isAnonymousStructOrUnion())
4151 Flags |= llvm::DINode::FlagExportSymbols;
4154 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4157 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
4158 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4164 switch (RealDecl->getTag()) {
4166 llvm_unreachable(
"invalid composite type tag");
4168 case llvm::dwarf::DW_TAG_array_type:
4169 case llvm::dwarf::DW_TAG_enumeration_type:
4178 case llvm::dwarf::DW_TAG_structure_type:
4179 case llvm::dwarf::DW_TAG_union_type:
4180 case llvm::dwarf::DW_TAG_class_type:
4183 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4193 RegionMap[RD].reset(RealDecl);
4197 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4198 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4199 CollectCXXTemplateParams(TSpecial, DefUnit));
4203void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4204 llvm::DICompositeType *RealDecl) {
4206 llvm::DIType *ContainingType =
nullptr;
4219 ContainingType = getOrCreateType(
T, getOrCreateFile(RD->
getLocation()));
4221 ContainingType = RealDecl;
4223 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4226llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
4227 StringRef Name, uint64_t *Offset) {
4228 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4232 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4233 *Offset, llvm::DINode::FlagZero, FieldTy);
4234 *Offset += FieldSize;
4238void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
4240 StringRef &LinkageName,
4241 llvm::DIScope *&FDContext,
4242 llvm::DINodeArray &TParamsArray,
4243 llvm::DINode::DIFlags &Flags) {
4245 Name = getFunctionName(FD);
4250 Flags |= llvm::DINode::FlagPrototyped;
4254 if (LinkageName == Name ||
4259 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4260 LinkageName = StringRef();
4265 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4269 FDContext = getOrCreateNamespace(NSDecl);
4272 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4273 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4279 Flags |= llvm::DINode::FlagNoReturn;
4281 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4285void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4287 StringRef &Name, StringRef &LinkageName,
4288 llvm::MDTuple *&TemplateParameters,
4289 llvm::DIScope *&VDContext) {
4298 llvm::APInt ConstVal(32, 1);
4309 if (LinkageName == Name)
4310 LinkageName = StringRef();
4312 if (isa<VarTemplateSpecializationDecl>(VD)) {
4313 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4314 TemplateParameters = parameterNodes.get();
4316 TemplateParameters =
nullptr;
4336 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4337 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4340llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4342 llvm::DINodeArray TParamsArray;
4343 StringRef Name, LinkageName;
4344 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4345 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4347 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4348 llvm::DIScope *DContext = Unit;
4349 unsigned Line = getLineNumber(
Loc);
4350 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4352 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4357 ArgTypes.push_back(Parm->getType());
4363 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4365 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4368 Flags |= getCallSiteRelatedAttrs();
4369 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4370 return DBuilder.createFunction(
4371 DContext, Name, LinkageName, Unit,
Line,
4372 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4373 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4378 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4379 DContext, Name, LinkageName, Unit,
Line,
4380 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4381 TParamsArray.get(), getFunctionDeclaration(FD));
4383 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4384 std::make_tuple(CanonDecl),
4385 std::make_tuple(SP));
4389llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4390 return getFunctionFwdDeclOrStub(GD,
false);
4393llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4394 return getFunctionFwdDeclOrStub(GD,
true);
4397llvm::DIGlobalVariable *
4398CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4400 StringRef Name, LinkageName;
4402 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4403 llvm::DIScope *DContext = Unit;
4404 unsigned Line = getLineNumber(
Loc);
4405 llvm::MDTuple *TemplateParameters =
nullptr;
4407 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4410 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4411 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4413 FwdDeclReplaceMap.emplace_back(
4414 std::piecewise_construct,
4416 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4420llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *
D) {
4425 if (
const auto *TD = dyn_cast<TypeDecl>(
D)) {
4427 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4431 if (I != DeclCache.end()) {
4433 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4434 return GVE->getVariable();
4435 return cast<llvm::DINode>(N);
4442 if (IE != ImportedDeclCache.end()) {
4443 auto N = IE->second;
4444 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4445 return cast<llvm::DINode>(GVE);
4446 return dyn_cast_or_null<llvm::DINode>(N);
4451 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4452 return getFunctionForwardDeclaration(FD);
4453 else if (
const auto *VD = dyn_cast<VarDecl>(
D))
4454 return getGlobalVariableForwardDeclaration(VD);
4459llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *
D) {
4460 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4463 const auto *FD = dyn_cast<FunctionDecl>(
D);
4468 auto *S = getDeclContextDescriptor(
D);
4471 if (MI == SPCache.end()) {
4473 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4474 cast<llvm::DICompositeType>(S));
4477 if (MI != SPCache.end()) {
4478 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4479 if (SP && !SP->isDefinition())
4483 for (
auto *NextFD : FD->
redecls()) {
4484 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4485 if (MI != SPCache.end()) {
4486 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4487 if (SP && !SP->isDefinition())
4494llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4495 const Decl *
D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4496 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4497 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4500 const auto *OMD = dyn_cast<ObjCMethodDecl>(
D);
4508 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4518 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4519 if (It == TypeCache.end())
4521 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4522 llvm::DISubprogram *FD = DBuilder.createFunction(
4523 InterfaceType, getObjCMethodName(OMD), StringRef(),
4524 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4525 DBuilder.finalizeSubprogram(FD);
4532llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *
D,
4537 if (!
D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4541 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4543 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(
D)) {
4546 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4549 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(
D))
4550 return getOrCreateMethodType(
Method, F);
4555 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(
D)) {
4560 QualType ResultTy = OMethod->getReturnType();
4565 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4567 Elts.push_back(getOrCreateType(ResultTy, F));
4570 if (
auto *SelfDecl = OMethod->getSelfDecl())
4571 SelfDeclTy = SelfDecl->getType();
4572 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4575 if (!SelfDeclTy.
isNull())
4577 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4579 Elts.push_back(DBuilder.createArtificialType(
4582 for (
const auto *PI : OMethod->parameters())
4583 Elts.push_back(getOrCreateType(PI->getType(), F));
4585 if (OMethod->isVariadic())
4586 Elts.push_back(DBuilder.createUnspecifiedParameter());
4588 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4589 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4595 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4596 if (FD->isVariadic()) {
4598 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4599 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4601 EltTys.push_back(getOrCreateType(ParamType, F));
4602 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4603 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4604 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4608 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4617 CC = SrcFnTy->getCallConv();
4619 for (
const VarDecl *VD : Args)
4620 ArgTypes.push_back(VD->
getType());
4627 llvm::Function *Fn,
bool CurFuncIsThunk) {
4629 StringRef LinkageName;
4631 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4634 bool HasDecl = (
D !=
nullptr);
4636 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4637 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4638 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4639 llvm::DIScope *FDContext = Unit;
4640 llvm::DINodeArray TParamsArray;
4641 bool KeyInstructions = CGM.
getCodeGenOpts().DebugKeyInstructions;
4644 LinkageName = Fn->getName();
4645 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
4647 auto FI = SPCache.find(FD->getCanonicalDecl());
4648 if (FI != SPCache.end()) {
4649 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4650 if (SP && SP->isDefinition()) {
4651 LexicalBlockStack.emplace_back(SP);
4652 RegionMap[
D].reset(SP);
4656 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4657 TParamsArray, Flags);
4660 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4661 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4662 Name = getObjCMethodName(OMD);
4663 Flags |= llvm::DINode::FlagPrototyped;
4664 }
else if (isa<VarDecl>(
D) &&
4670 Name = Fn->getName();
4672 if (isa<BlockDecl>(
D))
4675 Flags |= llvm::DINode::FlagPrototyped;
4677 Name.consume_front(
"\01");
4679 assert((!
D || !isa<VarDecl>(
D) ||
4681 "Unexpected DynamicInitKind !");
4684 isa<VarDecl>(
D) || isa<CapturedDecl>(
D)) {
4685 Flags |= llvm::DINode::FlagArtificial;
4691 Flags |= llvm::DINode::FlagThunk;
4693 if (Fn->hasLocalLinkage())
4694 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4696 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4698 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4699 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4700 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4702 const unsigned LineNo = getLineNumber(
Loc.
isValid() ?
Loc : CurLoc);
4703 unsigned ScopeLine = getLineNumber(ScopeLoc);
4704 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(
D, FnType, Unit);
4705 llvm::DISubprogram *
Decl =
nullptr;
4706 llvm::DINodeArray Annotations =
nullptr;
4708 Decl = isa<ObjCMethodDecl>(
D)
4709 ? getObjCMethodDeclaration(
D, DIFnType, LineNo, Flags, SPFlags)
4710 : getFunctionDeclaration(
D);
4711 Annotations = CollectBTFDeclTagAnnotations(
D);
4719 llvm::DISubprogram *SP = DBuilder.createFunction(
4720 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4721 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4722 Annotations,
"", KeyInstructions);
4723 Fn->setSubprogram(SP);
4728 if (HasDecl && isa<FunctionDecl>(
D))
4732 LexicalBlockStack.emplace_back(SP);
4735 RegionMap[
D].reset(SP);
4739 QualType FnType, llvm::Function *Fn) {
4741 StringRef LinkageName;
4747 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4748 return GetName(
D,
true);
4751 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4752 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4753 bool IsDeclForCallSite = Fn ?
true :
false;
4754 llvm::DIScope *FDContext =
4755 IsDeclForCallSite ? Unit : getDeclContextDescriptor(
D);
4756 llvm::DINodeArray TParamsArray;
4757 if (isa<FunctionDecl>(
D)) {
4759 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4760 TParamsArray, Flags);
4761 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4762 Name = getObjCMethodName(OMD);
4763 Flags |= llvm::DINode::FlagPrototyped;
4765 llvm_unreachable(
"not a function or ObjC method");
4767 Name.consume_front(
"\01");
4770 Flags |= llvm::DINode::FlagArtificial;
4775 unsigned LineNo = getLineNumber(
Loc);
4776 unsigned ScopeLine = 0;
4777 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4779 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4781 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
4782 llvm::DISubroutineType *STy = getOrCreateFunctionType(
D, FnType, Unit);
4784 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
4785 llvm::DISubprogram *SP = DBuilder.createFunction(
4786 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4787 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
4794 if (
auto *FD = dyn_cast<FunctionDecl>(
D)) {
4795 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4798 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4799 DBuilder.createParameterVariable(
4800 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4801 llvm::DINode::FlagZero, ParamAnnotations);
4807 if (IsDeclForCallSite)
4808 Fn->setSubprogram(SP);
4816 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
4819 if (
Func->getSubprogram())
4824 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4825 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4836 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4838 auto FI = SPCache.find(FD->getCanonicalDecl());
4839 llvm::DISubprogram *SP =
nullptr;
4840 if (FI != SPCache.end())
4841 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4842 if (!SP || !SP->isDefinition())
4843 SP = getFunctionStub(GD);
4844 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4845 LexicalBlockStack.emplace_back(SP);
4851 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4860 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4863 llvm::MDNode *
Scope = LexicalBlockStack.back();
4864 Builder.SetCurrentDebugLocation(
4865 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4866 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4870 llvm::MDNode *Back =
nullptr;
4871 if (!LexicalBlockStack.empty())
4872 Back = LexicalBlockStack.back().get();
4873 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4874 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4875 getColumnNumber(CurLoc)));
4878void CGDebugInfo::AppendAddressSpaceXDeref(
4880 std::optional<unsigned> DWARFAddressSpace =
4882 if (!DWARFAddressSpace)
4885 Expr.push_back(llvm::dwarf::DW_OP_constu);
4886 Expr.push_back(*DWARFAddressSpace);
4887 Expr.push_back(llvm::dwarf::DW_OP_swap);
4888 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4897 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4899 LexicalBlockStack.back(), CurInlinedAt));
4901 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4905 CreateLexicalBlock(
Loc);
4910 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4915 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4918 LexicalBlockStack.pop_back();
4922 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4923 unsigned RCount = FnBeginRegionCount.back();
4924 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4927 while (LexicalBlockStack.size() != RCount) {
4930 LexicalBlockStack.pop_back();
4932 FnBeginRegionCount.pop_back();
4934 if (Fn && Fn->getSubprogram())
4935 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4938CGDebugInfo::BlockByRefType
4939CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4940 uint64_t *XOffset) {
4943 uint64_t FieldSize, FieldOffset;
4944 uint32_t FieldAlign;
4946 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4951 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4952 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4954 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4955 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4958 if (HasCopyAndDispose) {
4961 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4963 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4965 bool HasByrefExtendedLayout;
4968 HasByrefExtendedLayout) &&
4969 HasByrefExtendedLayout) {
4972 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4981 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4984 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4987 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4992 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4996 *XOffset = FieldOffset;
4997 llvm::DIType *FieldTy = DBuilder.createMemberType(
4998 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4999 llvm::DINode::FlagZero, WrappedTy);
5000 EltTys.push_back(FieldTy);
5001 FieldOffset += FieldSize;
5003 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5004 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5005 llvm::DINode::FlagZero,
nullptr, Elements),
5009llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5010 llvm::Value *Storage,
5011 std::optional<unsigned> ArgNo,
5013 const bool UsePointerValue) {
5015 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5016 if (VD->
hasAttr<NoDebugAttr>())
5021 llvm::DIFile *Unit =
nullptr;
5022 if (!VarIsArtificial)
5026 if (VD->
hasAttr<BlocksAttr>())
5027 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5029 Ty = getOrCreateType(VD->
getType(), Unit);
5039 if (!VarIsArtificial) {
5044 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5045 if (VarIsArtificial)
5046 Flags |= llvm::DINode::FlagArtificial;
5051 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5055 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5058 Flags |= llvm::DINode::FlagObjectPointer;
5059 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5060 if (PVD->isExplicitObjectParameter())
5061 Flags |= llvm::DINode::FlagObjectPointer;
5068 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5069 StringRef Name = VD->
getName();
5070 if (!Name.empty()) {
5076 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5081 Expr.push_back(llvm::dwarf::DW_OP_deref);
5082 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5087 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5099 for (
const auto *Field : RD->
fields()) {
5100 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5101 StringRef FieldName =
Field->getName();
5104 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
5109 auto *
D = DBuilder.createAutoVariable(
5112 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5115 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
5119 Builder.GetInsertBlock());
5127 if (UsePointerValue) {
5128 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
5129 "Debug info already contains DW_OP_deref.");
5130 Expr.push_back(llvm::dwarf::DW_OP_deref);
5134 llvm::DILocalVariable *
D =
nullptr;
5136 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5137 D = DBuilder.createParameterVariable(
5139 CGM.
getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5148 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5151 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
5154 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5155 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5156 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5159 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5165 if (
Iter != CoroutineParameterMappings.end()) {
5167 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5168 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
5170 if (Iter2 != ParamDbgMappings.end())
5171 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5177 D = RemapCoroArgToLocalVar();
5180 D = DBuilder.createAutoVariable(
5185 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
5188 Builder.GetInsertBlock());
5193llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5194 llvm::Value *Storage,
5195 std::optional<unsigned> ArgNo,
5197 const bool UsePointerValue) {
5199 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5200 if (BD->
hasAttr<NoDebugAttr>())
5207 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5208 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5219 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5224 if (UsePointerValue) {
5225 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
5226 "Debug info already contains DW_OP_deref.");
5227 Expr.push_back(llvm::dwarf::DW_OP_deref);
5232 StringRef Name = BD->
getName();
5233 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5235 llvm::DILocalVariable *
D = DBuilder.createAutoVariable(
5237 llvm::DINode::FlagZero, Align);
5240 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5241 const unsigned fieldIndex = FD->getFieldIndex();
5247 if (FD->isBitField()) {
5254 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5260 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5261 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5266 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5267 }
else if (fieldOffset != 0) {
5269 "Unexpected non-bitfield with non-byte-aligned offset");
5270 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5276 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5277 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5278 const uint64_t value = IL->getValue().getZExtValue();
5282 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5291 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
5294 Builder.GetInsertBlock());
5299llvm::DILocalVariable *
5302 const bool UsePointerValue) {
5305 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5307 EmitDeclare(B, Storage, std::nullopt, Builder,
5314 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5319 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5324 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5325 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
5331 StringRef Name =
D->getName();
5340 DBuilder.insertLabel(L,
5342 Scope, CurInlinedAt),
5343 Builder.GetInsertBlock()->end());
5346llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5348 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5351 return DBuilder.createObjectPointerType(Ty,
true);
5356 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5358 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5360 if (Builder.GetInsertBlock() ==
nullptr)
5362 if (VD->
hasAttr<NoDebugAttr>())
5365 bool isByRef = VD->
hasAttr<BlocksAttr>();
5367 uint64_t XOffset = 0;
5368 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5371 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5373 Ty = getOrCreateType(VD->
getType(), Unit);
5377 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5379 Ty = CreateSelfType(VD->
getType(), Ty);
5382 const unsigned Line =
5393 addr.push_back(llvm::dwarf::DW_OP_deref);
5394 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5397 addr.push_back(llvm::dwarf::DW_OP_deref);
5398 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5403 addr.push_back(llvm::dwarf::DW_OP_deref);
5404 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5412 auto *
D = DBuilder.createAutoVariable(
5413 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5414 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5418 LexicalBlockStack.back(), CurInlinedAt);
5419 auto *
Expr = DBuilder.createExpression(addr);
5421 DBuilder.insertDeclare(Storage,
D,
Expr, DL, InsertPoint->getIterator());
5423 DBuilder.insertDeclare(Storage,
D,
Expr, DL, Builder.GetInsertBlock());
5426llvm::DILocalVariable *
5429 bool UsePointerValue) {
5431 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5435struct BlockLayoutChunk {
5436 uint64_t OffsetInBits;
5439bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5440 return l.OffsetInBits < r.OffsetInBits;
5444void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5446 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5453 BlockLayout.getElementOffsetInBits(0),
5456 BlockLayout.getElementOffsetInBits(1),
5460 BlockLayout.getElementOffsetInBits(0),
5463 BlockLayout.getElementOffsetInBits(1),
5467 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5468 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5470 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType,
Loc,
AS_public,
5471 BlockLayout.getElementOffsetInBits(3),
5473 Fields.push_back(createFieldType(
5478 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5485 llvm::AllocaInst *Alloca,
5493 llvm::DIFile *tunit = getOrCreateFile(loc);
5494 unsigned line = getLineNumber(loc);
5495 unsigned column = getColumnNumber(loc);
5500 const llvm::StructLayout *blockLayout =
5504 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5513 BlockLayoutChunk chunk;
5514 chunk.OffsetInBits =
5515 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5516 chunk.Capture =
nullptr;
5517 chunks.push_back(chunk);
5521 for (
const auto &capture :
blockDecl->captures()) {
5522 const VarDecl *variable = capture.getVariable();
5529 BlockLayoutChunk chunk;
5530 chunk.OffsetInBits =
5531 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5532 chunk.Capture = &capture;
5533 chunks.push_back(chunk);
5537 llvm::array_pod_sort(chunks.begin(), chunks.end());
5539 for (
const BlockLayoutChunk &Chunk : chunks) {
5540 uint64_t offsetInBits = Chunk.OffsetInBits;
5547 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5549 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5552 llvm_unreachable(
"unexpected block declcontext");
5554 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5555 offsetInBits, tunit, tunit));
5560 StringRef name = variable->
getName();
5562 llvm::DIType *fieldType;
5564 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5569 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5570 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5571 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5572 PtrInfo.
Width, Align, offsetInBits,
5573 llvm::DINode::FlagZero, fieldType);
5577 offsetInBits, Align, tunit, tunit);
5579 fields.push_back(fieldType);
5583 llvm::raw_svector_ostream(typeName)
5586 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5588 llvm::DIType *
type =
5589 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5591 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5595 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5596 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5599 auto *debugVar = DBuilder.createParameterVariable(
5600 scope, Name, ArgNo, tunit, line,
type,
5604 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5606 column, scope, CurInlinedAt),
5607 Builder.GetInsertBlock());
5610llvm::DIDerivedType *
5611CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *
D) {
5612 if (!
D || !
D->isStaticDataMember())
5616 if (MI != StaticDataMemberCache.end()) {
5617 assert(MI->second &&
"Static data member declaration should still exist");
5624 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(
D));
5625 return CreateRecordStaticField(
D, Ctxt, cast<RecordDecl>(DC));
5628llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5629 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5630 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5631 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5633 for (
const auto *Field : RD->
fields()) {
5634 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5635 StringRef FieldName = Field->getName();
5638 if (FieldName.empty()) {
5639 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5641 CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
5642 Unit, LineNo, LinkageName, Var, DContext);
5646 GVE = DBuilder.createGlobalVariableExpression(
5647 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5648 Var->hasLocalLinkage());
5649 Var->addDebugInfo(GVE);
5666 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5674 case TemplateArgument::Pack:
5675 return ReferencesAnonymousEntity(TA.getPackAsArray());
5676 case TemplateArgument::Type: {
5677 struct ReferencesAnonymous
5678 : public RecursiveASTVisitor<ReferencesAnonymous> {
5679 bool RefAnon = false;
5680 bool VisitRecordType(RecordType *RT) {
5681 if (ReferencesAnonymousEntity(RT)) {
5688 ReferencesAnonymous RT;
5689 RT.TraverseType(TA.getAsType());
5702 bool Reconstitutable =
true;
5704 Reconstitutable =
false;
5708 Reconstitutable =
false;
5711 bool VisitType(
Type *
T) {
5715 Reconstitutable =
false;
5720 bool TraverseEnumType(
EnumType *ET,
bool =
false) {
5724 if (!ED->getIdentifier()) {
5725 Reconstitutable =
false;
5728 if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
5729 Reconstitutable =
false;
5739 return Reconstitutable;
5741 bool VisitRecordType(
RecordType *RT,
bool =
false) {
5743 Reconstitutable =
false;
5753 ReconstitutableType
T;
5755 return T.Reconstitutable;
5758bool CGDebugInfo::HasReconstitutableArgs(
5762 case TemplateArgument::Template:
5769 case TemplateArgument::Declaration:
5778 case TemplateArgument::NullPtr:
5782 case TemplateArgument::Pack:
5785 return HasReconstitutableArgs(TA.getPackAsArray());
5786 case TemplateArgument::Integral:
5791 return TA.getAsIntegral().getBitWidth() <= 64 &&
5792 IsReconstitutableType(TA.getIntegralType());
5793 case TemplateArgument::StructuralValue:
5795 case TemplateArgument::Type:
5796 return IsReconstitutableType(TA.getAsType());
5797 case TemplateArgument::Expression:
5798 return IsReconstitutableType(TA.getAsExpr()->getType());
5800 llvm_unreachable(
"Other, unresolved, template arguments should "
5801 "not be seen here");
5806std::string CGDebugInfo::GetName(
const Decl *
D,
bool Qualified)
const {
5808 llvm::raw_string_ostream OS(Name);
5809 const NamedDecl *ND = dyn_cast<NamedDecl>(
D);
5812 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5816 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5818 std::optional<TemplateArgs> Args;
5820 bool IsOperatorOverload =
false;
5821 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5822 Args = GetTemplateArgs(RD);
5823 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5824 Args = GetTemplateArgs(FD);
5826 IsOperatorOverload |=
5829 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5830 Args = GetTemplateArgs(VD);
5854 bool Reconstitutable =
5855 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5859 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5863 bool Mangled = TemplateNamesKind ==
5864 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5870 std::string EncodedOriginalName;
5871 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5879 std::string CanonicalOriginalName;
5880 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5882 assert(EncodedOriginalName == CanonicalOriginalName);
5895 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5896 return GetName(
D,
true);
5902 if (Cached != DeclCache.end())
5903 return Var->addDebugInfo(
5904 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5907 llvm::DIFile *Unit =
nullptr;
5908 llvm::DIScope *DContext =
nullptr;
5910 StringRef DeclName, LinkageName;
5912 llvm::MDTuple *TemplateParameters =
nullptr;
5913 collectVarDeclProps(
D, Unit, LineNo,
T, DeclName, LinkageName,
5914 TemplateParameters, DContext);
5918 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5926 "unnamed non-anonymous struct or union?");
5927 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5937 else if (
D->
hasAttr<CUDAConstantAttr>())
5941 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5943 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
5944 GVE = DBuilder.createGlobalVariableExpression(
5945 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5946 Var->hasLocalLinkage(),
true,
5947 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5948 getOrCreateStaticDataMemberDeclarationOrNull(
D), TemplateParameters,
5949 Align, Annotations);
5950 Var->addDebugInfo(GVE);
5957 if (VD->
hasAttr<NoDebugAttr>())
5959 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5960 return GetName(VD,
true);
5965 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5966 StringRef Name = VD->
getName();
5967 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5969 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5970 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5976 if (isa<RecordDecl>(ED->getDeclContext()))
5983 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(
T, Unit);
5984 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5994 auto *VarD = dyn_cast<VarDecl>(VD);
5995 if (VarD && VarD->isStaticDataMember()) {
5996 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5997 getDeclContextDescriptor(VarD);
6002 RetainedTypes.push_back(
6007 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6009 auto &GV = DeclCache[VD];
6013 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6014 llvm::MDTuple *TemplateParameters =
nullptr;
6016 if (isa<VarTemplateSpecializationDecl>(VD))
6018 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6019 TemplateParameters = parameterNodes.get();
6022 GV.reset(DBuilder.createGlobalVariableExpression(
6023 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6024 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6025 TemplateParameters, Align));
6035 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
6036 StringRef Name =
D->getName();
6037 llvm::DIType *Ty = getOrCreateType(
D->getType(), Unit);
6039 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
6040 llvm::DIGlobalVariableExpression *GVE =
6041 DBuilder.createGlobalVariableExpression(
6042 DContext, Name, StringRef(), Unit, getLineNumber(
D->
getLocation()),
6043 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6044 Var->addDebugInfo(GVE);
6052 llvm::codegenoptions::DebugLineTablesOnly)
6055 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6059 llvm::DIFile *Unit = DIL->getFile();
6060 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6065 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6066 llvm::Value *Var = Load->getPointerOperand();
6071 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6072 return DbgDeclare->getVariable()->getType() ==
Type;
6074 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6078 llvm::DILocalVariable *
D =
6079 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6080 Type,
false, llvm::DINode::FlagArtificial);
6082 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6083 DBuilder.insertDbgValueIntrinsic(
Value,
D, DBuilder.createExpression(), DIL,
6096 const auto *
D = cast<ValueDecl>(GD.
getDecl());
6115 if (!(DI = getDeclarationOrDefinition(
6116 AliaseeDecl.getCanonicalDecl().getDecl())))
6119 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
6122 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6123 DContext, DI, getOrCreateFile(
Loc), getLineNumber(
Loc),
D->getName());
6136 llvm::DIFile *
File = getOrCreateFile(
Loc);
6137 llvm::DIGlobalVariableExpression *Debug =
6138 DBuilder.createGlobalVariableExpression(
6139 nullptr, StringRef(), StringRef(), getOrCreateFile(
Loc),
6140 getLineNumber(
Loc), getOrCreateType(S->getType(),
File),
true);
6141 GV->addDebugInfo(Debug);
6144llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *
D) {
6145 if (!LexicalBlockStack.empty())
6146 return LexicalBlockStack.back();
6147 llvm::DIScope *Mod = getParentModuleOrNull(
D);
6148 return getContextDescriptor(
D, Mod ? Mod : TheCU);
6160 DBuilder.createImportedModule(
6162 getOrCreateNamespace(NSDecl), getOrCreateFile(
Loc), getLineNumber(
Loc));
6167 if (llvm::DINode *
Target =
6170 DBuilder.createImportedDeclaration(
6172 getOrCreateFile(
Loc), getLineNumber(
Loc));
6180 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6182 for (
const auto *USD : UD.
shadows()) {
6187 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6188 if (
const auto *AT = FD->getType()
6191 if (AT->getDeducedType().isNull())
6205 "We shouldn't be codegening an invalid UsingEnumDecl"
6206 " containing no decls");
6208 for (
const auto *USD : UD.
shadows())
6213 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6215 if (
Module *M = ID.getImportedModule()) {
6217 auto Loc = ID.getLocation();
6218 DBuilder.createImportedDeclaration(
6219 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
6220 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(
Loc),
6221 getLineNumber(
Loc));
6225llvm::DIImportedEntity *
6229 auto &VH = NamespaceAliasCache[&NA];
6231 return cast<llvm::DIImportedEntity>(VH);
6232 llvm::DIImportedEntity *R;
6234 if (
const auto *Underlying =
6237 R = DBuilder.createImportedDeclaration(
6242 R = DBuilder.createImportedDeclaration(
6251CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6255 auto I = NamespaceCache.find(NSDecl);
6256 if (I != NamespaceCache.end())
6257 return cast<llvm::DINamespace>(I->second);
6259 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6261 llvm::DINamespace *NS =
6262 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6263 NamespaceCache[NSDecl].reset(NS);
6268 assert(TheCU &&
"no main compile unit");
6269 TheCU->setDWOId(Signature);
6275 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6276 ObjCInterfaceCacheEntry
E = ObjCInterfaceCache[i];
6277 llvm::DIType *Ty =
E.Type->getDecl()->getDefinition()
6278 ? CreateTypeDefinition(
E.Type,
E.Unit)
6280 DBuilder.replaceTemporary(llvm::TempDIType(
E.Decl), Ty);
6284 for (
const auto &
P : ObjCMethodCache) {
6285 if (
P.second.empty())
6288 QualType QTy(
P.first->getTypeForDecl(), 0);
6290 assert(It != TypeCache.end());
6292 llvm::DICompositeType *InterfaceDecl =
6293 cast<llvm::DICompositeType>(It->second);
6295 auto CurElts = InterfaceDecl->getElements();
6299 for (
auto &SubprogramDirect :
P.second)
6300 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6301 EltTys.push_back(SubprogramDirect.getPointer());
6303 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6304 DBuilder.replaceArrays(InterfaceDecl, Elements);
6307 for (
const auto &
P : ReplaceMap) {
6309 auto *Ty = cast<llvm::DIType>(
P.second);
6310 assert(Ty->isForwardDecl());
6312 auto It = TypeCache.find(
P.first);
6313 assert(It != TypeCache.end());
6316 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6317 cast<llvm::DIType>(It->second));
6320 for (
const auto &
P : FwdDeclReplaceMap) {
6322 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
6323 llvm::Metadata *Repl;
6325 auto It = DeclCache.find(
P.first);
6329 if (It == DeclCache.end())
6334 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6335 Repl = GVE->getVariable();
6336 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
6341 for (
auto &RT : RetainedTypes)
6342 if (
auto MD = TypeCache[RT])
6343 DBuilder.retainType(cast<llvm::DIType>(MD));
6345 DBuilder.finalize();
6351 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6352 DBuilder.retainType(DieTy);
6357 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6358 DBuilder.retainType(DieTy);
6362 if (LexicalBlockStack.empty())
6363 return llvm::DebugLoc();
6365 llvm::MDNode *
Scope = LexicalBlockStack.back();
6370llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6374 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6375 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6376 return llvm::DINode::FlagZero;
6381 bool SupportsDWARFv4Ext =
6383 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6384 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6386 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6387 return llvm::DINode::FlagZero;
6389 return llvm::DINode::FlagAllCallsDescribed;
6400 return DBuilder.createConstantValueExpression(
6401 Val.
getFloat().bitcastToAPInt().getZExtValue());
6406 llvm::APSInt
const &ValInt = Val.
getInt();
6407 std::optional<uint64_t> ValIntOpt;
6408 if (ValInt.isUnsigned())
6409 ValIntOpt = ValInt.tryZExtValue();
6410 else if (
auto tmp = ValInt.trySExtValue())
6413 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6416 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6424 CGF.CurLexicalScope =
this;
6431 DI->EmitLexicalBlockEnd(CGF.Builder,
Range.
getEnd());
6435 if (PerformCleanup) {
6444#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6446 Label = "__ubsan_check_" #Name; \
6450#undef SANITIZER_CHECK
6461#define SANITIZER(NAME, ID) \
6462 case SanitizerKind::SO_##ID: \
6463 Label = "__ubsan_check_" NAME; \
6465#include "clang/Basic/Sanitizers.def"
6467 llvm_unreachable(
"unexpected sanitizer kind");
6472 for (
unsigned int i = 0; i <
Label.length(); i++)
6473 if (!std::isalpha(
Label[i]))
6482 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6484 if (!DI || !CheckDebugLoc)
6485 return CheckDebugLoc;
6486 const auto &AnnotateDebugInfo =
6488 if (AnnotateDebugInfo.empty())
6489 return CheckDebugLoc;
6492 if (Ordinals.size() == 1)
6497 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); }))
6498 return DI->CreateSyntheticInlineAt(CheckDebugLoc,
Label);
6500 return CheckDebugLoc;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static 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 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 bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
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)
llvm::MachO::Target Target
constexpr llvm::StringRef ClangTrapPrefix
#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.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
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.
BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const
Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
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.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
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.
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType UnsignedLongTy
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.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedCharTy
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
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
unsigned getTargetAddressSpace(LangAS AS) const
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
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
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
const BTFTypeTagAttr * getAttr() const
QualType getWrappedType() const
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.
A fixed int type of a specified bitwidth.
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
This class is used for builtin types like 'int'.
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
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
llvm::iterator_range< base_class_const_iterator > base_class_const_range
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
A wrapper class around a pointer that always points to its canonical declaration.
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...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
SanitizerSet SanitizeAnnotateDebugInfo
Set of sanitizer checks, for which the instrumentation will be annotated with extra debug info.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
bool hasMaybeUnusedDebugInfo() const
Check if maybe unused type info should be emitted.
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
virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.
@ RAA_Indirect
Pass it as a pointer to temporary memory.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
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 setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
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 EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, const FunctionDecl *CalleeDecl)
Emit debug info for an extern function being called.
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.
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 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 directi...
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...
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.
uint64_t HighestEmittedAtom
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.
unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar)
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
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.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
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 PreprocessorOptions & getPreprocessorOpts() const
ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)
Get the address of a GUID.
llvm::Module & getModule() const
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
const LangOptions & getLangOpts() const
int getUniqueBlockCount()
Fetches the global unique block count.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
unsigned getVtableGlobalVarAlignment(const VarDecl *D=nullptr)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)
Get the address of a template parameter object.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
MicrosoftVTableContext & getMicrosoftVTableContext()
const HeaderSearchOptions & getHeaderSearchOpts() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::LLVMContext & getLLVMContext()
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const GlobalDecl getMangledNameDecl(StringRef)
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
unsigned getTargetAddressSpace(QualType T) const
llvm::Constant * getPointer() const
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
virtual bool shouldEmitDWARFBitFieldSeparators() const
Complex values, per C99 6.2.5p11.
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
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.
Represents a ValueDecl that came out of a declarator.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getOriginalDecl() 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...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
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 * 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
QualType getWrappedType() const
Represents an arbitrary, user-specified SPIR-V type instruction.
One of these records is kept for each identifier that is lexed.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
An lvalue reference type, per C++11 [dcl.ref].
Represents the declaration of a label.
Describes the capture of a variable or of this, or of a C++1y init-capture.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
virtual std::string getLambdaString(const CXXRecordDecl *Lambda)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
The module cache used for compiling modules implicitly.
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.
ObjCCategoryDecl - Represents a category declaration.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCImplementationDecl * getImplementation() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
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()
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents a class type in Objective C.
QualType getBaseType() const
Gets the base type of this object type.
Represents one property declaration in an Objective-C interface.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a type parameter type in Objective C.
ObjCTypeParamDecl * getDecl() const
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
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.
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
A qualifier set is used to build a set of qualifiers.
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
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
RecordDecl * getDefinitionOrSelf() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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.
Smart pointer class that efficiently represents Objective-C method names.
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.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
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
TagDecl * getOriginalDecl() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual unsigned getVtblPtrAddressSpace() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A template argument list.
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.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
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.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
ArrayRef< NamedDecl * > asArray()
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
Represents a declaration of a type.
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
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isBitIntType() const
RecordDecl * castAsRecordDecl() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
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.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
Declaration of a variable template.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
The JSON file list parser is used to communicate input to InstallAPI.
@ 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...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Result
The result type of a method or function.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_Deleting
Deleting dtor.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
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
@ 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,...
Structure with information about how a bitfield should be accessed.
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.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
unsigned char PointerWidthInBits
The width of a pointer into the generic address space.
EvalResult is a struct with detailed info about an evaluated expression.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
Describes how types, statements, expressions, and declarations should be printed.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
A this pointer adjustment.