39#include "llvm/ADT/DenseSet.h"
40#include "llvm/ADT/SmallVector.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/IR/Constants.h"
43#include "llvm/IR/DataLayout.h"
44#include "llvm/IR/DerivedTypes.h"
45#include "llvm/IR/Instructions.h"
46#include "llvm/IR/Intrinsics.h"
47#include "llvm/IR/Metadata.h"
48#include "llvm/IR/Module.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/MD5.h"
51#include "llvm/Support/Path.h"
52#include "llvm/Support/SHA1.h"
53#include "llvm/Support/SHA256.h"
54#include "llvm/Support/TimeProfiler.h"
73 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
74 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
75 DBuilder(CGM.getModule()) {
80 assert(LexicalBlockStack.empty() &&
81 "Region stack mismatch, stack not empty!");
87 init(TemporaryLocation);
94 init(TemporaryLocation, DefaultToEmpty);
98 bool DefaultToEmpty) {
105 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
107 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
110 if (TemporaryLocation.
isValid()) {
111 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
115 if (DefaultToEmpty) {
116 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
121 assert(!DI->LexicalBlockStack.empty());
122 CGF->
Builder.SetCurrentDebugLocation(
123 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
124 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
138 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
140 CGF.
Builder.SetCurrentDebugLocation(std::move(Loc));
147 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
158 SavedLocation = DI.getLocation();
159 assert((DI.getInlinedAt() ==
160 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
161 "CGDebugInfo and IRBuilder are out of sync");
163 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
171 DI.EmitLocation(CGF->
Builder, SavedLocation);
184 if (LexicalBlockStack.empty())
188 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
190 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
193 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
194 LexicalBlockStack.pop_back();
195 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
196 LBF->getScope(), getOrCreateFile(CurLoc)));
197 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
198 isa<llvm::DISubprogram>(
Scope)) {
199 LexicalBlockStack.pop_back();
200 LexicalBlockStack.emplace_back(
201 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
205llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
206 llvm::DIScope *Mod = getParentModuleOrNull(D);
211llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
216 auto I = RegionMap.find(Context);
217 if (I != RegionMap.end()) {
218 llvm::Metadata *
V = I->second;
219 return dyn_cast_or_null<llvm::DIScope>(
V);
223 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
224 return getOrCreateNamespace(NSDecl);
226 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
227 if (!RDecl->isDependentType())
261StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
262 return internString(GetName(FD));
265StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
267 llvm::raw_svector_ostream OS(MethodName);
270 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
271 OS << OID->getName();
272 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
273 OS << OID->getName();
274 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
275 if (OC->IsClassExtension()) {
276 OS << OC->getClassInterface()->getName();
278 OS << OC->getIdentifier()->getNameStart() <<
'('
279 << OC->getIdentifier()->getNameStart() <<
')';
281 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
282 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
286 return internString(OS.str());
289StringRef CGDebugInfo::getSelectorName(
Selector S) {
290 return internString(S.getAsString());
293StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
294 if (isa<ClassTemplateSpecializationDecl>(RD)) {
296 return internString(GetName(RD));
302 return II->getName();
310 "Typedef should not be in another decl context!");
311 assert(D->getDeclName().getAsIdentifierInfo() &&
312 "Typedef was not named!");
313 return D->getDeclName().getAsIdentifierInfo()->getName();
323 Name = DD->getName();
328 Name = TND->getName();
331 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
332 if (CXXRD->isLambda())
340 return internString(UnnamedType);
348std::optional<llvm::DIFile::ChecksumKind>
357 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
361 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
364 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
365 return llvm::DIFile::CSK_MD5;
367 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
368 return llvm::DIFile::CSK_SHA1;
370 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
371 return llvm::DIFile::CSK_SHA256;
373 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
376std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
381 bool SourceInvalid =
false;
382 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
394 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
400 FileName = TheCU->getFile()->getFilename();
401 CSInfo = TheCU->getFile()->getChecksum();
407 FileName = TheCU->getFile()->getFilename();
415 auto It = DIFileCache.find(
FileName.data());
416 if (It != DIFileCache.end()) {
418 if (llvm::Metadata *
V = It->second)
419 return cast<llvm::DIFile>(
V);
425 std::optional<llvm::DIFile::ChecksumKind> CSKind =
426 computeChecksum(FID, Checksum);
428 CSInfo.emplace(*CSKind, Checksum);
430 return createFile(
FileName, CSInfo, getSource(
SM,
SM.getFileID(Loc)));
433llvm::DIFile *CGDebugInfo::createFile(
435 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
436 std::optional<StringRef> Source) {
440 std::string CurDir =
remapDIPath(getCurrentDirname());
443 if (llvm::sys::path::is_absolute(RemappedFile)) {
446 auto FileIt = llvm::sys::path::begin(RemappedFile);
447 auto FileE = llvm::sys::path::end(RemappedFile);
448 auto CurDirIt = llvm::sys::path::begin(CurDir);
449 auto CurDirE = llvm::sys::path::end(CurDir);
450 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
451 llvm::sys::path::append(DirBuf, *CurDirIt);
452 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
458 for (; FileIt != FileE; ++FileIt)
459 llvm::sys::path::append(FileBuf, *FileIt);
464 if (!llvm::sys::path::is_absolute(
FileName))
468 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
469 DIFileCache[
FileName.data()].reset(F);
476 if (llvm::sys::path::replace_path_prefix(
P, From, To))
478 return P.str().str();
485 return SM.getPresumedLoc(Loc).getLine();
488unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
501StringRef CGDebugInfo::getCurrentDirname() {
505 if (!CWDName.empty())
507 llvm::ErrorOr<std::string> CWD =
511 return CWDName = internString(*CWD);
514void CGDebugInfo::CreateCompileUnit() {
516 std::optional<llvm::DIFile::ChecksumKind> CSKind;
517 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
530 std::string MainFileName = CGO.MainFileName;
531 if (MainFileName.empty())
532 MainFileName =
"<stdin>";
538 std::string MainFileDir;
540 SM.getFileEntryRefForID(
SM.getMainFileID())) {
541 MainFileDir = std::string(MainFile->getDir().getName());
542 if (!llvm::sys::path::is_absolute(MainFileName)) {
544 llvm::sys::path::Style Style =
547 ? llvm::sys::path::Style::windows_backslash
548 : llvm::sys::path::Style::posix)
549 : llvm::sys::path::Style::native;
550 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
551 MainFileName = std::string(
552 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
559 if (MainFile->getName() == MainFileName &&
561 MainFile->getName().rsplit(
'.').second)
563 MainFileName = CGM.
getModule().getName().str();
565 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
569 llvm::dwarf::SourceLanguage LangTag;
572 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
573 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
574 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
575 else if (LO.CPlusPlus14)
576 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
577 else if (LO.CPlusPlus11)
578 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
580 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
581 }
else if (LO.ObjC) {
582 LangTag = llvm::dwarf::DW_LANG_ObjC;
583 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
585 LangTag = llvm::dwarf::DW_LANG_OpenCL;
586 }
else if (LO.RenderScript) {
587 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
588 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
589 LangTag = llvm::dwarf::DW_LANG_C11;
591 LangTag = llvm::dwarf::DW_LANG_C99;
593 LangTag = llvm::dwarf::DW_LANG_C89;
599 unsigned RuntimeVers = 0;
603 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
605 case llvm::codegenoptions::NoDebugInfo:
606 case llvm::codegenoptions::LocTrackingOnly:
607 EmissionKind = llvm::DICompileUnit::NoDebug;
609 case llvm::codegenoptions::DebugLineTablesOnly:
610 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
612 case llvm::codegenoptions::DebugDirectivesOnly:
613 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
615 case llvm::codegenoptions::DebugInfoConstructor:
616 case llvm::codegenoptions::LimitedDebugInfo:
617 case llvm::codegenoptions::FullDebugInfo:
618 case llvm::codegenoptions::UnusedTypeInfo:
619 EmissionKind = llvm::DICompileUnit::FullDebug;
630 CSInfo.emplace(*CSKind, Checksum);
631 llvm::DIFile *CUFile = DBuilder.createFile(
633 getSource(
SM,
SM.getMainFileID()));
635 StringRef Sysroot, SDK;
636 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
638 auto B = llvm::sys::path::rbegin(Sysroot);
639 auto E = llvm::sys::path::rend(Sysroot);
641 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
646 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
647 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
648 CGOpts.DebugNameTable);
650 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
652 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
655 TheCU = DBuilder.createCompileUnit(
656 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
657 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
658 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
659 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
660 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
663llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
667#define BUILTIN_TYPE(Id, SingletonId)
668#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
669#include "clang/AST/BuiltinTypes.def"
670 case BuiltinType::Dependent:
671 llvm_unreachable(
"Unexpected builtin type");
672 case BuiltinType::NullPtr:
673 return DBuilder.createNullPtrType();
674 case BuiltinType::Void:
676 case BuiltinType::ObjCClass:
679 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
680 "objc_class", TheCU, TheCU->getFile(), 0);
682 case BuiltinType::ObjCId: {
693 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
694 "objc_class", TheCU, TheCU->getFile(), 0);
698 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
700 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
701 0, 0, llvm::DINode::FlagZero,
nullptr,
702 llvm::DINodeArray());
704 DBuilder.replaceArrays(
705 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
706 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
707 llvm::DINode::FlagZero, ISATy)));
710 case BuiltinType::ObjCSel: {
712 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
713 "objc_selector", TheCU,
714 TheCU->getFile(), 0);
718#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
719 case BuiltinType::Id: \
720 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
722#include "clang/Basic/OpenCLImageTypes.def"
723 case BuiltinType::OCLSampler:
724 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
725 case BuiltinType::OCLEvent:
726 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
727 case BuiltinType::OCLClkEvent:
728 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
729 case BuiltinType::OCLQueue:
730 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
731 case BuiltinType::OCLReserveID:
732 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
733#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
734 case BuiltinType::Id: \
735 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
736#include "clang/Basic/OpenCLExtensionTypes.def"
738#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
739#include "clang/Basic/AArch64SVEACLETypes.def"
743 BT->
getKind() == BuiltinType::SveCount
747 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
754 "Unsupported number of vectors for svcount_t");
758 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
764 llvm::Metadata *LowerBound, *UpperBound;
765 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
767 if (Info.
EC.isScalable()) {
768 unsigned NumElemsPerVG = NumElems / 2;
770 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
771 46, 0, llvm::dwarf::DW_OP_mul,
772 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
773 UpperBound = DBuilder.createExpression(
Expr);
775 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
778 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
779 nullptr, LowerBound, UpperBound,
nullptr);
780 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
781 llvm::DIType *ElemTy =
782 getOrCreateType(Info.
ElementType, TheCU->getFile());
784 return DBuilder.createVectorType( 0, Align, ElemTy,
789#define PPC_VECTOR_TYPE(Name, Id, size) \
790 case BuiltinType::Id:
791#include "clang/Basic/PPCTypes.def"
794#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
795#include "clang/Basic/RISCVVTypes.def"
800 unsigned ElementCount = Info.
EC.getKnownMinValue();
803 bool Fractional =
false;
805 unsigned FixedSize = ElementCount * SEW;
809 }
else if (FixedSize < 64) {
812 LMUL = 64 / FixedSize;
814 LMUL = FixedSize / 64;
822 {llvm::dwarf::DW_OP_bregx,
825 llvm::dwarf::DW_OP_constu,
827 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
829 Expr.push_back(llvm::dwarf::DW_OP_div);
831 Expr.push_back(llvm::dwarf::DW_OP_mul);
833 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
836 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
838 auto *UpperBound = DBuilder.createExpression(
Expr);
839 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
840 nullptr, LowerBound, UpperBound,
nullptr);
841 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
842 llvm::DIType *ElemTy =
843 getOrCreateType(Info.
ElementType, TheCU->getFile());
846 return DBuilder.createVectorType(0, Align, ElemTy,
850#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
851 case BuiltinType::Id: { \
854 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
855 MangledName, TheCU, TheCU->getFile(), 0); \
856 return SingletonId; \
858#include "clang/Basic/WebAssemblyReferenceTypes.def"
860 case BuiltinType::UChar:
861 case BuiltinType::Char_U:
862 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
864 case BuiltinType::Char_S:
865 case BuiltinType::SChar:
866 Encoding = llvm::dwarf::DW_ATE_signed_char;
868 case BuiltinType::Char8:
869 case BuiltinType::Char16:
870 case BuiltinType::Char32:
873 case BuiltinType::UShort:
874 case BuiltinType::UInt:
875 case BuiltinType::UInt128:
876 case BuiltinType::ULong:
877 case BuiltinType::WChar_U:
878 case BuiltinType::ULongLong:
879 Encoding = llvm::dwarf::DW_ATE_unsigned;
881 case BuiltinType::Short:
882 case BuiltinType::Int:
883 case BuiltinType::Int128:
884 case BuiltinType::Long:
885 case BuiltinType::WChar_S:
886 case BuiltinType::LongLong:
887 Encoding = llvm::dwarf::DW_ATE_signed;
889 case BuiltinType::Bool:
890 Encoding = llvm::dwarf::DW_ATE_boolean;
892 case BuiltinType::Half:
893 case BuiltinType::Float:
894 case BuiltinType::LongDouble:
895 case BuiltinType::Float16:
896 case BuiltinType::BFloat16:
897 case BuiltinType::Float128:
898 case BuiltinType::Double:
899 case BuiltinType::Ibm128:
905 Encoding = llvm::dwarf::DW_ATE_float;
907 case BuiltinType::ShortAccum:
908 case BuiltinType::Accum:
909 case BuiltinType::LongAccum:
910 case BuiltinType::ShortFract:
911 case BuiltinType::Fract:
912 case BuiltinType::LongFract:
913 case BuiltinType::SatShortFract:
914 case BuiltinType::SatFract:
915 case BuiltinType::SatLongFract:
916 case BuiltinType::SatShortAccum:
917 case BuiltinType::SatAccum:
918 case BuiltinType::SatLongAccum:
919 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
921 case BuiltinType::UShortAccum:
922 case BuiltinType::UAccum:
923 case BuiltinType::ULongAccum:
924 case BuiltinType::UShortFract:
925 case BuiltinType::UFract:
926 case BuiltinType::ULongFract:
927 case BuiltinType::SatUShortAccum:
928 case BuiltinType::SatUAccum:
929 case BuiltinType::SatULongAccum:
930 case BuiltinType::SatUShortFract:
931 case BuiltinType::SatUFract:
932 case BuiltinType::SatULongFract:
933 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
940 return DBuilder.createBasicType(BTName, Size, Encoding);
943llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
945 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
947 ? llvm::dwarf::DW_ATE_unsigned
948 : llvm::dwarf::DW_ATE_signed;
954llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
956 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
958 Encoding = llvm::dwarf::DW_ATE_lo_user;
961 return DBuilder.createBasicType(
"complex", Size, Encoding);
975 return llvm::dwarf::DW_TAG_const_type;
979 return llvm::dwarf::DW_TAG_volatile_type;
983 return llvm::dwarf::DW_TAG_restrict_type;
985 return (llvm::dwarf::Tag)0;
988llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
989 llvm::DIFile *Unit) {
999 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1000 return getOrCreateType(
QualType(T, 0), Unit);
1007 return DBuilder.createQualifiedType(Tag, FromTy);
1011 llvm::DIFile *Unit) {
1020 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1031 return DBuilder.createQualifiedType(Tag, FromTy);
1035 llvm::DIFile *Unit) {
1043 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1047llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1048 llvm::DIFile *Unit) {
1049 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1055 switch (TheCU->getSourceLanguage()) {
1056 case llvm::dwarf::DW_LANG_C_plus_plus:
1057 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1058 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1060 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1061 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1089 llvm::DICompileUnit *TheCU) {
1107 llvm::DICompileUnit *TheCU) {
1113 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1115 if (RD->isDynamicClass() &&
1128 llvm::dwarf::Tag Tag;
1130 Tag = llvm::dwarf::DW_TAG_structure_type;
1132 Tag = llvm::dwarf::DW_TAG_union_type;
1137 Tag = llvm::dwarf::DW_TAG_class_type;
1142llvm::DICompositeType *
1143CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1144 llvm::DIScope *Ctx) {
1147 return cast<llvm::DICompositeType>(T);
1148 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1149 const unsigned Line =
1151 StringRef RDName = getClassName(RD);
1160 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1165 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1166 if (!CXXRD->hasDefinition() ||
1167 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1168 Flags |= llvm::DINode::FlagNonTrivial;
1175 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1179 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1180 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1181 CollectCXXTemplateParams(TSpecial, DefUnit));
1182 ReplaceMap.emplace_back(
1183 std::piecewise_construct, std::make_tuple(Ty),
1184 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1188llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1191 llvm::DIFile *Unit) {
1196 std::optional<unsigned> DWARFAddressSpace =
1201 auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1203 StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1205 llvm::Metadata *Ops[2] = {
1206 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1208 Annots.insert(Annots.begin(),
1211 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1214 llvm::DINodeArray Annotations =
nullptr;
1215 if (Annots.size() > 0)
1216 Annotations = DBuilder.getOrCreateArray(Annots);
1218 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1219 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1220 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1221 Size, Align, DWARFAddressSpace);
1223 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1224 Align, DWARFAddressSpace, StringRef(),
1228llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1229 llvm::DIType *&
Cache) {
1232 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1233 TheCU, TheCU->getFile(), 0);
1235 Cache = DBuilder.createPointerType(
Cache, Size);
1239uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1240 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1253 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1254 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1257 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1259 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1260 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1262 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1266 EltTys.push_back(DBuilder.createMemberType(
1267 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1268 FieldOffset, llvm::DINode::FlagZero, DescTy));
1269 FieldOffset += FieldSize;
1276 llvm::DIFile *Unit) {
1280 llvm::DINodeArray Elements;
1284 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1285 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1287 Elements = DBuilder.getOrCreateArray(EltTys);
1290 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1293 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1294 FieldOffset, 0, Flags,
nullptr, Elements);
1299 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1301 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1304 Elements = DBuilder.getOrCreateArray(EltTys);
1310 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1311 Flags,
nullptr, Elements);
1313 return DBuilder.createPointerType(EltTy, Size);
1317 llvm::DIFile *Unit) {
1322 if (isa<BuiltinTemplateDecl>(TD))
1325 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1330 llvm::raw_svector_ostream OS(NS);
1332 auto PP = getPrintingPolicy();
1348 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
1365 return llvm::DINode::FlagZero;
1369 return llvm::DINode::FlagPrivate;
1371 return llvm::DINode::FlagProtected;
1373 return llvm::DINode::FlagPublic;
1375 return llvm::DINode::FlagZero;
1377 llvm_unreachable(
"unexpected access enumerator");
1380llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1381 llvm::DIFile *Unit) {
1382 llvm::DIType *Underlying =
1394 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1396 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1398 if (isa<RecordDecl>(DC))
1401 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1402 getOrCreateFile(Loc), getLineNumber(Loc),
1403 getDeclContextDescriptor(Ty->
getDecl()), Align,
1404 Flags, Annotations);
1414 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1416 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1418 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1420 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1422 return llvm::dwarf::DW_CC_BORLAND_pascal;
1424 return llvm::dwarf::DW_CC_LLVM_Win64;
1426 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1430 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1432 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1434 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1436 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1439 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1441 return llvm::dwarf::DW_CC_LLVM_Swift;
1444 return llvm::dwarf::DW_CC_LLVM_Swift;
1446 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1448 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1450 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1452 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1454 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1460 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1462 Flags |= llvm::DINode::FlagLValueReference;
1464 Flags |= llvm::DINode::FlagRValueReference;
1468llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1469 llvm::DIFile *Unit) {
1470 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1472 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1481 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1483 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1487 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1490 for (
const QualType &ParamType : FPT->param_types())
1491 EltTys.push_back(getOrCreateType(ParamType, Unit));
1492 if (FPT->isVariadic())
1493 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1496 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1497 llvm::DIType *F = DBuilder.createSubroutineType(
1502llvm::DIDerivedType *
1503CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1504 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1505 StringRef Name = BitFieldDecl->
getName();
1507 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1508 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1510 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1511 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1514 llvm::DIFile *
File = getOrCreateFile(Loc);
1515 unsigned Line = getLineNumber(Loc);
1520 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1529 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1531 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1532 return DBuilder.createBitFieldMemberType(
1533 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1534 Flags, DebugType, Annotations);
1537llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1538 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1566 if (PreviousFieldsDI.empty())
1570 auto *PreviousMDEntry =
1571 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1572 auto *PreviousMDField =
1573 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1574 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1575 PreviousMDField->getSizeInBits() == 0)
1579 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1581 assert(PreviousBitfield->isBitField());
1584 if (!PreviousBitfield->isZeroLengthBitField(Context))
1587 QualType Ty = PreviousBitfield->getType();
1589 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1590 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1591 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1593 llvm::DIFile *
File = getOrCreateFile(Loc);
1594 unsigned Line = getLineNumber(Loc);
1597 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1600 llvm::DINode::DIFlags Flags =
1602 llvm::DINodeArray Annotations =
1603 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1604 return DBuilder.createBitFieldMemberType(
1605 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1606 Flags, DebugType, Annotations);
1609llvm::DIType *CGDebugInfo::createFieldType(
1611 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1612 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1613 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1616 llvm::DIFile *file = getOrCreateFile(loc);
1617 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1620 auto Align = AlignInBits;
1621 if (!
type->isIncompleteArrayType()) {
1623 SizeInBits = TI.
Width;
1629 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1630 offsetInBits, flags, debugType, Annotations);
1633void CGDebugInfo::CollectRecordLambdaFields(
1635 llvm::DIType *RecordTy) {
1641 unsigned fieldno = 0;
1644 I != E; ++I, ++Field, ++fieldno) {
1646 if (
C.capturesVariable()) {
1648 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1650 StringRef VName =
V->getName();
1651 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1653 llvm::DIType *FieldType = createFieldType(
1654 VName,
Field->getType(), Loc,
Field->getAccess(),
1655 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1656 elements.push_back(FieldType);
1657 }
else if (
C.capturesThis()) {
1663 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1665 StringRef ThisName =
1667 llvm::DIType *fieldType = createFieldType(
1671 elements.push_back(fieldType);
1676llvm::DIDerivedType *
1677CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1682 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1683 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1685 unsigned LineNumber = getLineNumber(Var->
getLocation());
1686 StringRef VName = Var->
getName();
1690 llvm::Constant *
C =
nullptr;
1696 if (
Value->isFloat())
1703 ? llvm::dwarf::DW_TAG_variable
1704 : llvm::dwarf::DW_TAG_member;
1706 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1707 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1712void CGDebugInfo::CollectRecordNormalField(
1713 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1720 if (
name.empty() && !
type->isRecordType())
1723 llvm::DIType *FieldType;
1725 llvm::DIDerivedType *BitFieldType;
1726 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1727 if (llvm::DIType *Separator =
1728 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1729 elements.push_back(Separator);
1732 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1735 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1738 elements.push_back(FieldType);
1741void CGDebugInfo::CollectRecordNestedType(
1745 if (isa<InjectedClassNameType>(Ty))
1748 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc));
1749 elements.push_back(nestedType);
1752void CGDebugInfo::CollectRecordFields(
1753 const RecordDecl *record, llvm::DIFile *tunit,
1755 llvm::DICompositeType *RecordTy) {
1756 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1758 if (CXXDecl && CXXDecl->
isLambda())
1759 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1764 unsigned fieldNo = 0;
1768 for (
const auto *I : record->
decls())
1769 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1770 if (
V->hasAttr<NoDebugAttr>())
1776 isa<VarTemplateSpecializationDecl>(
V))
1779 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1783 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1784 if (MI != StaticDataMemberCache.end()) {
1785 assert(MI->second &&
1786 "Static data member declaration should still exist");
1787 elements.push_back(MI->second);
1789 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1790 elements.push_back(Field);
1792 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1793 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1794 elements, RecordTy, record);
1801 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1803 if (isa<RecordDecl>(I) &&
1804 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1806 if (!nestedType->isImplicit() &&
1807 nestedType->getDeclContext() == record)
1808 CollectRecordNestedType(nestedType, elements);
1814llvm::DISubroutineType *
1815CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1816 llvm::DIFile *Unit) {
1819 return cast_or_null<llvm::DISubroutineType>(
1821 return getOrCreateInstanceMethodType(Method->
getThisType(),
Func, Unit);
1824llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1840 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
1842 Func->getReturnType(),
Func->getParamTypes(), EPI),
1844 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
1845 assert(Args.size() &&
"Invalid number of arguments!");
1850 Elts.push_back(Args[0]);
1854 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1856 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1859 llvm::DIType *PointeeType =
1861 llvm::DIType *ThisPtrType =
1862 DBuilder.createPointerType(PointeeType, Size, Align);
1867 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1868 Elts.push_back(ThisPtrType);
1870 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1872 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1873 Elts.push_back(ThisPtrType);
1877 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1878 Elts.push_back(Args[i]);
1880 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1882 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
1889 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1896llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1897 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1899 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1901 StringRef MethodName = getFunctionName(Method);
1902 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1906 StringRef MethodLinkageName;
1916 llvm::DIFile *MethodDefUnit =
nullptr;
1917 unsigned MethodLine = 0;
1919 MethodDefUnit = getOrCreateFile(Method->
getLocation());
1920 MethodLine = getLineNumber(Method->
getLocation());
1924 llvm::DIType *ContainingType =
nullptr;
1925 unsigned VIndex = 0;
1926 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1927 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
1932 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
1934 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
1939 if (!isa<CXXDestructorDecl>(Method))
1944 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
1956 Flags |= llvm::DINode::FlagIntroducedVirtual;
1965 ContainingType = RecordTy;
1969 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
1972 Flags |= llvm::DINode::FlagNoReturn;
1975 Flags |= llvm::DINode::FlagStaticMember;
1977 Flags |= llvm::DINode::FlagArtificial;
1979 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
1980 if (CXXC->isExplicit())
1981 Flags |= llvm::DINode::FlagExplicit;
1982 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
1983 if (CXXC->isExplicit())
1984 Flags |= llvm::DINode::FlagExplicit;
1987 Flags |= llvm::DINode::FlagPrototyped;
1989 Flags |= llvm::DINode::FlagLValueReference;
1991 Flags |= llvm::DINode::FlagRValueReference;
1993 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
1995 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
1999 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2003 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2004 llvm::DISubprogram *SP = DBuilder.createMethod(
2005 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2006 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2007 TParamsArray.get());
2014void CGDebugInfo::CollectCXXMemberFunctions(
2021 for (
const auto *I : RD->
decls()) {
2022 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2046 EltTys.push_back(MI == SPCache.end()
2047 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2048 :
static_cast<llvm::Metadata *
>(MI->second));
2052void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2054 llvm::DIType *RecordTy) {
2056 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2057 llvm::DINode::FlagZero);
2062 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2063 llvm::DINode::FlagIndirectVirtualBase);
2067void CGDebugInfo::CollectCXXBasesAux(
2072 llvm::DINode::DIFlags StartingFlags) {
2074 for (
const auto &BI : Bases) {
2077 if (!SeenTypes.insert(
Base).second)
2079 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2080 llvm::DINode::DIFlags BFlags = StartingFlags;
2082 uint32_t VBPtrOffset = 0;
2084 if (BI.isVirtual()) {
2101 BFlags |= llvm::DINode::FlagVirtual;
2108 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2109 VBPtrOffset, BFlags);
2110 EltTys.push_back(DTy);
2115CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2116 llvm::DIFile *Unit) {
2118 return llvm::DINodeArray();
2119 TemplateArgs &Args = *OArgs;
2121 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2126 Name = Args.TList->getParam(i)->getName();
2130 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2131 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2132 TheCU, Name, TTy, defaultParameter));
2137 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2138 TheCU, Name, TTy, defaultParameter,
2144 llvm::DIType *TTy = getOrCreateType(T, Unit);
2145 llvm::Constant *
V =
nullptr;
2149 !D->
hasAttr<CUDADeviceAttr>()) {
2152 if (
const auto *VD = dyn_cast<VarDecl>(D))
2156 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2157 MD && MD->isImplicitObjectMemberFunction())
2159 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2163 else if (
const auto *MPT =
2164 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2172 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2174 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2181 assert(
V &&
"Failed to find template parameter pointer");
2182 V =
V->stripPointerCasts();
2184 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2185 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2189 llvm::DIType *TTy = getOrCreateType(T, Unit);
2190 llvm::Constant *
V =
nullptr;
2193 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2199 if (MPT->isMemberDataPointer())
2202 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2203 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2204 TheCU, Name, TTy, defaultParameter,
V));
2208 llvm::DIType *TTy = getOrCreateType(T, Unit);
2211 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2212 TheCU, Name, TTy, defaultParameter,
V));
2215 std::string QualName;
2216 llvm::raw_string_ostream OS(QualName);
2218 OS, getPrintingPolicy());
2219 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2220 TheCU, Name,
nullptr, OS.str(), defaultParameter));
2224 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2225 TheCU, Name,
nullptr,
2234 assert(
V &&
"Expression in template argument isn't constant");
2235 llvm::DIType *TTy = getOrCreateType(T, Unit);
2236 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2237 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2243 "These argument types shouldn't exist in concrete types");
2246 return DBuilder.getOrCreateArray(TemplateParams);
2249std::optional<CGDebugInfo::TemplateArgs>
2250CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2258 return std::nullopt;
2260std::optional<CGDebugInfo::TemplateArgs>
2261CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2265 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2267 return std::nullopt;
2270 auto TA = TS->getTemplateArgs().asArray();
2271 return {{TList, TA}};
2273std::optional<CGDebugInfo::TemplateArgs>
2274CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2275 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2280 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2282 return {{TPList, TAList.
asArray()}};
2284 return std::nullopt;
2288CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2289 llvm::DIFile *Unit) {
2290 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2293llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2294 llvm::DIFile *Unit) {
2295 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2298llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2299 llvm::DIFile *Unit) {
2300 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2303llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2304 if (!D->
hasAttr<BTFDeclTagAttr>())
2309 llvm::Metadata *Ops[2] = {
2310 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2312 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2314 return DBuilder.getOrCreateArray(Annotations);
2317llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2319 return VTablePtrType;
2324 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2325 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2326 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2329 std::optional<unsigned> DWARFAddressSpace =
2332 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2333 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2334 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2335 return VTablePtrType;
2338StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2343StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2345 llvm::Function *InitFn) {
2350 return InitFn->getName();
2360 llvm::raw_svector_ostream OS(QualifiedGV);
2362 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2364 std::swap(Quals, GVName);
2368 llvm::raw_svector_ostream OS(InitName);
2370 OS << Quals <<
"::";
2375 llvm_unreachable(
"not an initializer");
2377 OS <<
"`dynamic initializer for '";
2380 OS <<
"`dynamic atexit destructor for '";
2387 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2389 getPrintingPolicy());
2394 return internString(OS.str());
2397void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2414 llvm::DIType *VPtrTy =
nullptr;
2417 if (NeedVTableShape) {
2422 unsigned VSlotCount =
2424 unsigned VTableWidth = PtrWidth * VSlotCount;
2426 std::optional<unsigned> DWARFAddressSpace =
2430 llvm::DIType *VTableType = DBuilder.createPointerType(
2431 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2432 EltTys.push_back(VTableType);
2435 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2443 VPtrTy = getOrCreateVTablePtrType(Unit);
2446 llvm::DIType *VPtrMember =
2447 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2448 llvm::DINode::FlagArtificial, VPtrTy);
2449 EltTys.push_back(VPtrMember);
2455 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
2467 assert(!D.
isNull() &&
"null type");
2468 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
2469 assert(T &&
"could not create debug info for type");
2479 llvm::codegenoptions::DebugLineTablesOnly)
2485 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2487 CI->setMetadata(
"heapallocsite", node);
2491 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2495 auto I = TypeCache.find(TyPtr);
2496 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2498 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2499 assert(!Res->isForwardDecl());
2500 TypeCache[TyPtr].reset(Res);
2504 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2511 if (RD->
hasAttr<DLLImportAttr>())
2514 if (MD->hasAttr<DLLImportAttr>())
2527 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2536 bool Explicit =
false;
2537 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2538 Explicit = TD->isExplicitInstantiationOrSpecialization();
2552 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2553 if (CXXRD->isDynamicClass() &&
2555 llvm::GlobalValue::AvailableExternallyLinkage &&
2566 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2570 auto I = TypeCache.find(TyPtr);
2571 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2578 assert(!Res->isForwardDecl());
2579 TypeCache[TyPtr].reset(Res);
2586 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2587 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2610 if (Ctor->isCopyOrMoveConstructor())
2612 if (!Ctor->isDeleted())
2631 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2634 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2635 RD->
hasAttr<StandaloneDebugAttr>())
2638 if (!LangOpts.CPlusPlus)
2644 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2660 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2661 Spec = SD->getSpecializationKind();
2670 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2682 llvm::DIType *T = getTypeOrNull(Ty);
2683 if (T && T->isForwardDecl())
2687llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2689 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2693 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2697 auto [Def, Pref] = CreateTypeDefinition(Ty);
2699 return Pref ? Pref : Def;
2702llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2703 llvm::DIFile *Unit) {
2707 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2711 return getOrCreateType(PNA->getTypedefType(), Unit);
2714std::pair<llvm::DIType *, llvm::DIType *>
2715CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2719 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2727 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2731 return {FwdDecl,
nullptr};
2733 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2734 CollectContainingType(CXXDecl, FwdDecl);
2737 LexicalBlockStack.emplace_back(&*FwdDecl);
2738 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2748 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2750 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2751 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2755 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2757 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2759 LexicalBlockStack.pop_back();
2760 RegionMap.erase(Ty->
getDecl());
2762 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2763 DBuilder.replaceArrays(FwdDecl, Elements);
2765 if (FwdDecl->isTemporary())
2767 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2769 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2771 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2772 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2773 return {FwdDecl, PrefDI};
2775 return {FwdDecl,
nullptr};
2779 llvm::DIFile *Unit) {
2785 llvm::DIFile *Unit) {
2790 return DBuilder.createTypedef(
2792 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
2793 getDeclContextDescriptor(Ty->
getDecl()));
2821 llvm::DIFile *Unit) {
2829 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2830 !
ID->getImplementation())
2831 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2833 getDeclContextDescriptor(ID), Unit, 0);
2836 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2837 unsigned Line = getLineNumber(
ID->getLocation());
2839 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2845 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2846 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2847 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
2848 DefUnit,
Line, RuntimeLang);
2849 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2853 return CreateTypeDefinition(Ty, Unit);
2857 bool CreateSkeletonCU) {
2862 auto ModRef = ModuleCache.find(M);
2863 if (ModRef != ModuleCache.end())
2864 return cast<llvm::DIModule>(ModRef->second);
2869 llvm::raw_svector_ostream OS(ConfigMacros);
2873 for (
auto &M : PPOpts.Macros) {
2876 const std::string &
Macro = M.first;
2877 bool Undef = M.second;
2878 OS <<
"\"-" << (Undef ?
'U' :
'D');
2879 for (
char c : Macro)
2894 bool IsRootModule = M ? !M->
Parent :
true;
2898 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
2900 "clang module without ASTFile must be specified by -fmodule-name");
2903 auto RemapPath = [
this](StringRef Path) -> std::string {
2905 StringRef Relative(Remapped);
2906 StringRef CompDir = TheCU->getDirectory();
2907 if (Relative.consume_front(CompDir))
2908 Relative.consume_front(llvm::sys::path::get_separator());
2910 return Relative.str();
2913 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
2920 Signature = ModSig.truncatedValue();
2926 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
2928 PCM = getCurrentDirname();
2932 llvm::sys::path::append(PCM, Mod.
getASTFile());
2933 DIB.createCompileUnit(
2934 TheCU->getSourceLanguage(),
2937 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
2938 llvm::DICompileUnit::FullDebug, Signature);
2943 IsRootModule ? nullptr
2946 std::string IncludePath = Mod.
getPath().str();
2947 llvm::DIModule *DIMod =
2949 RemapPath(IncludePath));
2950 ModuleCache[M].reset(DIMod);
2955 llvm::DIFile *Unit) {
2957 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2958 unsigned Line = getLineNumber(
ID->getLocation());
2959 unsigned RuntimeLang = TheCU->getSourceLanguage();
2965 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2966 if (
ID->getImplementation())
2967 Flags |= llvm::DINode::FlagObjcClassComplete;
2969 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2970 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
2971 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
2972 nullptr, llvm::DINodeArray(), RuntimeLang);
2975 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
2978 LexicalBlockStack.emplace_back(RealDecl);
2979 RegionMap[Ty->
getDecl()].reset(RealDecl);
2986 llvm::DIType *SClassTy =
2991 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
2992 llvm::DINode::FlagZero);
2993 EltTys.push_back(InhTag);
2999 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3000 unsigned PLine = getLineNumber(Loc);
3003 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3004 PD->getName(), PUnit, PLine,
3006 : getSelectorName(PD->getGetterName()),
3008 : getSelectorName(PD->getSetterName()),
3009 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3010 EltTys.push_back(PropertyNode);
3015 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3022 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3025 for (
auto *PD : ClassExt->properties()) {
3026 PropertySet.insert(GetIsClassAndIdent(PD));
3029 for (
const auto *PD :
ID->properties()) {
3032 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3039 unsigned FieldNo = 0;
3041 Field =
Field->getNextIvar(), ++FieldNo) {
3042 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3046 StringRef FieldName =
Field->getName();
3049 if (FieldName.empty())
3053 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3054 unsigned FieldLine = getLineNumber(
Field->getLocation());
3057 uint32_t FieldAlign = 0;
3062 FieldSize =
Field->isBitField()
3073 if (
Field->isBitField()) {
3084 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3086 Flags = llvm::DINode::FlagProtected;
3088 Flags = llvm::DINode::FlagPrivate;
3090 Flags = llvm::DINode::FlagPublic;
3092 if (
Field->isBitField())
3093 Flags |= llvm::DINode::FlagBitField;
3095 llvm::MDNode *PropertyNode =
nullptr;
3098 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3101 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3102 unsigned PLine = getLineNumber(Loc);
3105 PropertyNode = DBuilder.createObjCProperty(
3106 PD->getName(), PUnit, PLine,
3109 : getSelectorName(PD->getGetterName()),
3112 : getSelectorName(PD->getSetterName()),
3113 PD->getPropertyAttributes(),
3114 getOrCreateType(PD->getType(), PUnit));
3118 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3119 FieldSize, FieldAlign, FieldOffset, Flags,
3120 FieldTy, PropertyNode);
3121 EltTys.push_back(FieldTy);
3124 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3125 DBuilder.replaceArrays(RealDecl, Elements);
3127 LexicalBlockStack.pop_back();
3131llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3132 llvm::DIFile *Unit) {
3150 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3153 llvm::Metadata *Subscript;
3155 auto SizeExpr = SizeExprCache.find(QTy);
3156 if (SizeExpr != SizeExprCache.end())
3157 Subscript = DBuilder.getOrCreateSubrange(
3158 SizeExpr->getSecond() ,
nullptr ,
3159 nullptr ,
nullptr );
3162 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3163 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3164 Subscript = DBuilder.getOrCreateSubrange(
3165 CountNode ,
nullptr ,
nullptr ,
3168 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3173 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3177 llvm::DIFile *Unit) {
3181 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3187 auto *ColumnCountNode =
3188 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3190 auto *RowCountNode =
3191 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3193 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3194 ColumnCountNode ,
nullptr ,
nullptr ,
3196 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3197 RowCountNode ,
nullptr ,
nullptr ,
3199 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3200 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3203llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3208 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3232 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3241 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3242 Count = CAT->getSize().getZExtValue();
3243 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3244 if (
Expr *Size = VAT->getSizeExpr()) {
3247 Count =
Result.Val.getInt().getExtValue();
3251 auto SizeNode = SizeExprCache.find(EltTy);
3252 if (SizeNode != SizeExprCache.end())
3253 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3254 SizeNode->getSecond() ,
nullptr ,
3255 nullptr ,
nullptr ));
3258 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3260 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3261 CountNode ,
nullptr ,
nullptr ,
3267 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3269 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3274 llvm::DIFile *Unit) {
3275 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3280 llvm::DIFile *Unit) {
3281 llvm::dwarf::Tag Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3285 Tag = llvm::dwarf::DW_TAG_reference_type;
3287 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3292 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3302 Flags |= llvm::DINode::FlagSingleInheritance;
3305 Flags |= llvm::DINode::FlagMultipleInheritance;
3308 Flags |= llvm::DINode::FlagVirtualInheritance;
3318 return DBuilder.createMemberPointerType(
3324 return DBuilder.createMemberPointerType(
3325 getOrCreateInstanceMethodType(
3328 ClassType,
Size, 0, Flags);
3331llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3333 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3336llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3340llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3352 bool isImportedFromModule =
3364 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3365 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3366 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3367 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3370 StringRef EDName = ED->
getName();
3371 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3372 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3373 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3375 ReplaceMap.emplace_back(
3376 std::piecewise_construct, std::make_tuple(Ty),
3377 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3381 return CreateTypeDefinition(Ty);
3384llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3398 Enumerators.push_back(
3399 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3403 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3405 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3407 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3408 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3409 return DBuilder.createEnumerationType(
3410 EnumContext, ED->
getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3416 StringRef Name, StringRef
Value) {
3417 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3424 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3425 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3426 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3436 Quals += InnerQuals;
3441 case Type::TemplateSpecialization: {
3442 const auto *Spec = cast<TemplateSpecializationType>(T);
3443 if (Spec->isTypeAlias())
3445 T = Spec->desugar();
3448 case Type::TypeOfExpr:
3449 T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
3452 T = cast<TypeOfType>(T)->getUnmodifiedType();
3454 case Type::Decltype:
3455 T = cast<DecltypeType>(T)->getUnderlyingType();
3457 case Type::UnaryTransform:
3458 T = cast<UnaryTransformType>(T)->getUnderlyingType();
3460 case Type::Attributed:
3461 T = cast<AttributedType>(T)->getEquivalentType();
3463 case Type::BTFTagAttributed:
3464 T = cast<BTFTagAttributedType>(T)->getWrappedType();
3466 case Type::Elaborated:
3467 T = cast<ElaboratedType>(T)->getNamedType();
3470 T = cast<UsingType>(T)->getUnderlyingType();
3473 T = cast<ParenType>(T)->getInnerType();
3475 case Type::MacroQualified:
3476 T = cast<MacroQualifiedType>(T)->getUnderlyingType();
3478 case Type::SubstTemplateTypeParm:
3479 T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
3482 case Type::DeducedTemplateSpecialization: {
3483 QualType DT = cast<DeducedType>(T)->getDeducedType();
3484 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3488 case Type::PackIndexing: {
3489 T = cast<PackIndexingType>(T)->getSelectedType();
3492 case Type::Adjusted:
3495 T = cast<AdjustedType>(T)->getAdjustedType();
3499 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
3504llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3507 if (It != TypeCache.end()) {
3509 if (llvm::Metadata *
V = It->second)
3510 return cast<llvm::DIType>(
V);
3522 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3532llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3536 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3538 llvm::raw_string_ostream OS(Name);
3539 Ty.
print(OS, getPrintingPolicy());
3546 if (
auto *T = getTypeOrNull(Ty))
3549 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3550 void *TyPtr = Ty.getAsOpaquePtr();
3553 TypeCache[TyPtr].reset(Res);
3558llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3560 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
3566 auto Info = Reader->getSourceDescriptor(Idx);
3568 return getOrCreateModuleRef(*Info,
true);
3569 }
else if (ClangModuleMap) {
3583 return getOrCreateModuleRef(Info,
false);
3586 return getOrCreateModuleRef(PCHDescriptor,
false);
3593llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3596 return CreateQualifiedType(Ty, Unit);
3600#define TYPE(Class, Base)
3601#define ABSTRACT_TYPE(Class, Base)
3602#define NON_CANONICAL_TYPE(Class, Base)
3603#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3604#include "clang/AST/TypeNodes.inc"
3605 llvm_unreachable(
"Dependent types cannot show up in debug information");
3607 case Type::ExtVector:
3609 return CreateType(cast<VectorType>(Ty), Unit);
3610 case Type::ConstantMatrix:
3611 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3612 case Type::ObjCObjectPointer:
3613 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3614 case Type::ObjCObject:
3615 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3616 case Type::ObjCTypeParam:
3617 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3618 case Type::ObjCInterface:
3619 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3621 return CreateType(cast<BuiltinType>(Ty));
3623 return CreateType(cast<ComplexType>(Ty));
3625 return CreateType(cast<PointerType>(Ty), Unit);
3626 case Type::BlockPointer:
3627 return CreateType(cast<BlockPointerType>(Ty), Unit);
3629 return CreateType(cast<TypedefType>(Ty), Unit);
3631 return CreateType(cast<RecordType>(Ty));
3633 return CreateEnumType(cast<EnumType>(Ty));
3634 case Type::FunctionProto:
3635 case Type::FunctionNoProto:
3636 return CreateType(cast<FunctionType>(Ty), Unit);
3637 case Type::ConstantArray:
3638 case Type::VariableArray:
3639 case Type::IncompleteArray:
3640 return CreateType(cast<ArrayType>(Ty), Unit);
3642 case Type::LValueReference:
3643 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3644 case Type::RValueReference:
3645 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3647 case Type::MemberPointer:
3648 return CreateType(cast<MemberPointerType>(Ty), Unit);
3651 return CreateType(cast<AtomicType>(Ty), Unit);
3654 return CreateType(cast<BitIntType>(Ty));
3656 return CreateType(cast<PipeType>(Ty), Unit);
3658 case Type::TemplateSpecialization:
3659 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3662 case Type::Attributed:
3663 case Type::BTFTagAttributed:
3664 case Type::Adjusted:
3666 case Type::DeducedTemplateSpecialization:
3667 case Type::Elaborated:
3670 case Type::MacroQualified:
3671 case Type::SubstTemplateTypeParm:
3672 case Type::TypeOfExpr:
3674 case Type::Decltype:
3675 case Type::PackIndexing:
3676 case Type::UnaryTransform:
3680 llvm_unreachable(
"type should have been unwrapped!");
3683llvm::DICompositeType *
3684CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3687 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3692 if (T && !T->isForwardDecl())
3696 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3701 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
3704 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3709llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3713 StringRef RDName = getClassName(RD);
3715 llvm::DIFile *DefUnit =
nullptr;
3718 DefUnit = getOrCreateFile(Loc);
3719 Line = getLineNumber(Loc);
3722 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3726 auto *T = cast_or_null<llvm::DICompositeType>(
3735 return getOrCreateRecordFwdDecl(Ty, RDContext);
3748 auto Flags = llvm::DINode::FlagZero;
3749 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3751 Flags |= llvm::DINode::FlagTypePassByReference;
3753 Flags |= llvm::DINode::FlagTypePassByValue;
3756 if (!CXXRD->isTrivial())
3757 Flags |= llvm::DINode::FlagNonTrivial;
3760 if (CXXRD->isAnonymousStructOrUnion())
3761 Flags |= llvm::DINode::FlagExportSymbols;
3764 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3767 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
3768 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3774 switch (RealDecl->getTag()) {
3776 llvm_unreachable(
"invalid composite type tag");
3778 case llvm::dwarf::DW_TAG_array_type:
3779 case llvm::dwarf::DW_TAG_enumeration_type:
3788 case llvm::dwarf::DW_TAG_structure_type:
3789 case llvm::dwarf::DW_TAG_union_type:
3790 case llvm::dwarf::DW_TAG_class_type:
3793 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3797 RegionMap[Ty->
getDecl()].reset(RealDecl);
3800 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3801 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3802 CollectCXXTemplateParams(TSpecial, DefUnit));
3806void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3807 llvm::DICompositeType *RealDecl) {
3809 llvm::DIType *ContainingType =
nullptr;
3821 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3824 ContainingType = RealDecl;
3826 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3829llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3830 StringRef Name, uint64_t *Offset) {
3831 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3835 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3836 *Offset, llvm::DINode::FlagZero, FieldTy);
3837 *Offset += FieldSize;
3841void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3843 StringRef &LinkageName,
3844 llvm::DIScope *&FDContext,
3845 llvm::DINodeArray &TParamsArray,
3846 llvm::DINode::DIFlags &Flags) {
3848 Name = getFunctionName(FD);
3853 Flags |= llvm::DINode::FlagPrototyped;
3857 if (LinkageName == Name ||
3862 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
3863 LinkageName = StringRef();
3868 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
3872 FDContext = getOrCreateNamespace(NSDecl);
3875 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
3876 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
3882 Flags |= llvm::DINode::FlagNoReturn;
3884 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
3888void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
3890 StringRef &Name, StringRef &LinkageName,
3891 llvm::MDTuple *&TemplateParameters,
3892 llvm::DIScope *&VDContext) {
3901 llvm::APInt ConstVal(32, 1);
3912 if (LinkageName == Name)
3913 LinkageName = StringRef();
3915 if (isa<VarTemplateSpecializationDecl>(VD)) {
3916 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
3917 TemplateParameters = parameterNodes.get();
3919 TemplateParameters =
nullptr;
3939 llvm::DIScope *Mod = getParentModuleOrNull(VD);
3940 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
3943llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
3945 llvm::DINodeArray TParamsArray;
3946 StringRef Name, LinkageName;
3947 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3948 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
3950 llvm::DIFile *Unit = getOrCreateFile(Loc);
3951 llvm::DIScope *DContext = Unit;
3952 unsigned Line = getLineNumber(Loc);
3953 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
3955 auto *FD = cast<FunctionDecl>(GD.
getDecl());
3960 ArgTypes.push_back(Parm->getType());
3966 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
3968 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
3971 Flags |= getCallSiteRelatedAttrs();
3972 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
3973 return DBuilder.createFunction(
3974 DContext, Name, LinkageName, Unit,
Line,
3975 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
3976 TParamsArray.get(), getFunctionDeclaration(FD));
3979 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
3980 DContext, Name, LinkageName, Unit,
Line,
3981 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
3982 TParamsArray.get(), getFunctionDeclaration(FD));
3984 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
3985 std::make_tuple(CanonDecl),
3986 std::make_tuple(SP));
3990llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
3991 return getFunctionFwdDeclOrStub(GD,
false);
3994llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
3995 return getFunctionFwdDeclOrStub(GD,
true);
3998llvm::DIGlobalVariable *
3999CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4001 StringRef Name, LinkageName;
4003 llvm::DIFile *Unit = getOrCreateFile(Loc);
4004 llvm::DIScope *DContext = Unit;
4005 unsigned Line = getLineNumber(Loc);
4006 llvm::MDTuple *TemplateParameters =
nullptr;
4008 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4011 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4012 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4014 FwdDeclReplaceMap.emplace_back(
4015 std::piecewise_construct,
4017 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4021llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4026 if (
const auto *TD = dyn_cast<TypeDecl>(D))
4031 if (I != DeclCache.end()) {
4033 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4034 return GVE->getVariable();
4035 return cast<llvm::DINode>(N);
4042 if (IE != ImportedDeclCache.end()) {
4043 auto N = IE->second;
4044 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4045 return cast<llvm::DINode>(GVE);
4046 return dyn_cast_or_null<llvm::DINode>(N);
4051 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4052 return getFunctionForwardDeclaration(FD);
4053 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4054 return getGlobalVariableForwardDeclaration(VD);
4059llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4060 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4063 const auto *FD = dyn_cast<FunctionDecl>(D);
4068 auto *S = getDeclContextDescriptor(D);
4071 if (MI == SPCache.end()) {
4073 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4074 cast<llvm::DICompositeType>(S));
4077 if (MI != SPCache.end()) {
4078 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4079 if (SP && !SP->isDefinition())
4083 for (
auto *NextFD : FD->
redecls()) {
4084 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4085 if (MI != SPCache.end()) {
4086 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4087 if (SP && !SP->isDefinition())
4094llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4095 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4096 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4097 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4100 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4108 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4118 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4119 if (It == TypeCache.end())
4121 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4122 llvm::DISubprogram *FD = DBuilder.createFunction(
4123 InterfaceType, getObjCMethodName(OMD), StringRef(),
4124 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4125 DBuilder.finalizeSubprogram(FD);
4132llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4137 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4141 return DBuilder.createSubroutineType(
4142 DBuilder.getOrCreateTypeArray(std::nullopt));
4144 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
4145 return getOrCreateMethodType(Method, F);
4150 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4155 QualType ResultTy = OMethod->getReturnType();
4160 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4162 Elts.push_back(getOrCreateType(ResultTy, F));
4165 if (
auto *SelfDecl = OMethod->getSelfDecl())
4166 SelfDeclTy = SelfDecl->getType();
4167 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4170 if (!SelfDeclTy.
isNull())
4172 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4174 Elts.push_back(DBuilder.createArtificialType(
4177 for (
const auto *PI : OMethod->parameters())
4178 Elts.push_back(getOrCreateType(PI->getType(), F));
4180 if (OMethod->isVariadic())
4181 Elts.push_back(DBuilder.createUnspecifiedParameter());
4183 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4184 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4190 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4191 if (FD->isVariadic()) {
4193 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4194 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4196 EltTys.push_back(getOrCreateType(ParamType, F));
4197 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4198 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4199 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4203 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4212 CC = SrcFnTy->getCallConv();
4214 for (
const VarDecl *VD : Args)
4215 ArgTypes.push_back(VD->
getType());
4222 llvm::Function *Fn,
bool CurFuncIsThunk) {
4224 StringRef LinkageName;
4226 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4229 bool HasDecl = (D !=
nullptr);
4231 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4232 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4233 llvm::DIFile *Unit = getOrCreateFile(Loc);
4234 llvm::DIScope *FDContext = Unit;
4235 llvm::DINodeArray TParamsArray;
4238 LinkageName = Fn->getName();
4239 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4241 auto FI = SPCache.find(FD->getCanonicalDecl());
4242 if (FI != SPCache.end()) {
4243 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4244 if (SP && SP->isDefinition()) {
4245 LexicalBlockStack.emplace_back(SP);
4246 RegionMap[D].reset(SP);
4250 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4251 TParamsArray, Flags);
4252 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4253 Name = getObjCMethodName(OMD);
4254 Flags |= llvm::DINode::FlagPrototyped;
4255 }
else if (isa<VarDecl>(D) &&
4261 Name = Fn->getName();
4263 if (isa<BlockDecl>(D))
4266 Flags |= llvm::DINode::FlagPrototyped;
4268 if (Name.starts_with(
"\01"))
4269 Name = Name.substr(1);
4271 assert((!D || !isa<VarDecl>(D) ||
4273 "Unexpected DynamicInitKind !");
4276 isa<VarDecl>(D) || isa<CapturedDecl>(D)) {
4277 Flags |= llvm::DINode::FlagArtificial;
4283 Flags |= llvm::DINode::FlagThunk;
4285 if (Fn->hasLocalLinkage())
4286 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4288 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4290 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4291 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4292 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4294 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4295 unsigned ScopeLine = getLineNumber(ScopeLoc);
4296 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4297 llvm::DISubprogram *
Decl =
nullptr;
4298 llvm::DINodeArray Annotations =
nullptr;
4300 Decl = isa<ObjCMethodDecl>(D)
4301 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4302 : getFunctionDeclaration(D);
4303 Annotations = CollectBTFDeclTagAnnotations(D);
4311 llvm::DISubprogram *SP = DBuilder.createFunction(
4312 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4313 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4315 Fn->setSubprogram(SP);
4319 if (HasDecl && isa<FunctionDecl>(D))
4323 LexicalBlockStack.emplace_back(SP);
4326 RegionMap[D].reset(SP);
4330 QualType FnType, llvm::Function *Fn) {
4332 StringRef LinkageName;
4338 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4339 return GetName(D,
true);
4342 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4343 llvm::DIFile *Unit = getOrCreateFile(Loc);
4344 bool IsDeclForCallSite = Fn ?
true :
false;
4345 llvm::DIScope *FDContext =
4346 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4347 llvm::DINodeArray TParamsArray;
4348 if (isa<FunctionDecl>(D)) {
4350 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4351 TParamsArray, Flags);
4352 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4353 Name = getObjCMethodName(OMD);
4354 Flags |= llvm::DINode::FlagPrototyped;
4356 llvm_unreachable(
"not a function or ObjC method");
4358 if (!Name.empty() && Name[0] ==
'\01')
4359 Name = Name.substr(1);
4362 Flags |= llvm::DINode::FlagArtificial;
4367 unsigned LineNo = getLineNumber(Loc);
4368 unsigned ScopeLine = 0;
4369 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4371 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4373 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4374 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4375 llvm::DISubprogram *SP = DBuilder.createFunction(
4376 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4377 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4383 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4384 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4387 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4388 DBuilder.createParameterVariable(
4389 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4390 llvm::DINode::FlagZero, ParamAnnotations);
4396 if (IsDeclForCallSite)
4397 Fn->setSubprogram(SP);
4399 DBuilder.finalizeSubprogram(SP);
4407 auto *
Func = CallOrInvoke->getCalledFunction();
4410 if (
Func->getSubprogram())
4415 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4416 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4427 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4429 auto FI = SPCache.find(FD->getCanonicalDecl());
4430 llvm::DISubprogram *SP =
nullptr;
4431 if (FI != SPCache.end())
4432 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4433 if (!SP || !SP->isDefinition())
4434 SP = getFunctionStub(GD);
4435 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4436 LexicalBlockStack.emplace_back(SP);
4442 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4451 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4454 llvm::MDNode *
Scope = LexicalBlockStack.back();
4455 Builder.SetCurrentDebugLocation(
4456 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4457 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4461 llvm::MDNode *Back =
nullptr;
4462 if (!LexicalBlockStack.empty())
4463 Back = LexicalBlockStack.back().get();
4464 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4465 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4466 getColumnNumber(CurLoc)));
4469void CGDebugInfo::AppendAddressSpaceXDeref(
4471 std::optional<unsigned> DWARFAddressSpace =
4473 if (!DWARFAddressSpace)
4476 Expr.push_back(llvm::dwarf::DW_OP_constu);
4477 Expr.push_back(*DWARFAddressSpace);
4478 Expr.push_back(llvm::dwarf::DW_OP_swap);
4479 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4488 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4490 LexicalBlockStack.back(), CurInlinedAt));
4492 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4496 CreateLexicalBlock(Loc);
4501 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4506 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4509 LexicalBlockStack.pop_back();
4513 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4514 unsigned RCount = FnBeginRegionCount.back();
4515 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4518 while (LexicalBlockStack.size() != RCount) {
4521 LexicalBlockStack.pop_back();
4523 FnBeginRegionCount.pop_back();
4525 if (Fn && Fn->getSubprogram())
4526 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4529CGDebugInfo::BlockByRefType
4530CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4531 uint64_t *XOffset) {
4534 uint64_t FieldSize, FieldOffset;
4535 uint32_t FieldAlign;
4537 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4542 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4543 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4545 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4546 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4549 if (HasCopyAndDispose) {
4552 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4554 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4556 bool HasByrefExtendedLayout;
4559 HasByrefExtendedLayout) &&
4560 HasByrefExtendedLayout) {
4563 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4572 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4575 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4578 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4583 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4587 *XOffset = FieldOffset;
4588 llvm::DIType *FieldTy = DBuilder.createMemberType(
4589 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4590 llvm::DINode::FlagZero, WrappedTy);
4591 EltTys.push_back(FieldTy);
4592 FieldOffset += FieldSize;
4594 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4595 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4596 llvm::DINode::FlagZero,
nullptr, Elements),
4600llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4601 llvm::Value *Storage,
4602 std::optional<unsigned> ArgNo,
4604 const bool UsePointerValue) {
4606 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4607 if (VD->
hasAttr<NoDebugAttr>())
4613 llvm::DIFile *Unit =
nullptr;
4618 if (VD->
hasAttr<BlocksAttr>())
4619 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4621 Ty = getOrCreateType(VD->
getType(), Unit);
4636 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4638 Flags |= llvm::DINode::FlagArtificial;
4643 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4647 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4650 Flags |= llvm::DINode::FlagObjectPointer;
4657 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4658 StringRef Name = VD->
getName();
4659 if (!Name.empty()) {
4665 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4670 Expr.push_back(llvm::dwarf::DW_OP_deref);
4671 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4676 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4688 for (
const auto *Field : RD->
fields()) {
4689 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4690 StringRef FieldName =
Field->getName();
4693 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4698 auto *D = DBuilder.createAutoVariable(
4700 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4703 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4707 Builder.GetInsertBlock());
4715 if (UsePointerValue) {
4716 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4717 "Debug info already contains DW_OP_deref.");
4718 Expr.push_back(llvm::dwarf::DW_OP_deref);
4722 llvm::DILocalVariable *D =
nullptr;
4724 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4725 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit,
Line, Ty,
4736 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4739 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4742 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4743 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4744 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4747 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4753 if (
Iter != CoroutineParameterMappings.end()) {
4755 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4756 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4758 if (Iter2 != ParamDbgMappings.end())
4759 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4765 D = RemapCoroArgToLocalVar();
4768 D = DBuilder.createAutoVariable(
Scope, Name, Unit,
Line, Ty,
4772 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4775 Builder.GetInsertBlock());
4780llvm::DIType *CGDebugInfo::CreateBindingDeclType(
const BindingDecl *BD) {
4781 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4786 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4787 if (FD->isBitField()) {
4804 llvm::DIType *Ty = getOrCreateType(FinalTy, Unit);
4811 return getOrCreateType(BD->
getType(), Unit);
4814llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4815 llvm::Value *Storage,
4816 std::optional<unsigned> ArgNo,
4818 const bool UsePointerValue) {
4820 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4821 if (BD->
hasAttr<NoDebugAttr>())
4828 llvm::DIType *Ty = CreateBindingDeclType(BD);
4839 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4844 if (UsePointerValue) {
4845 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4846 "Debug info already contains DW_OP_deref.");
4847 Expr.push_back(llvm::dwarf::DW_OP_deref);
4852 StringRef Name = BD->
getName();
4853 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4854 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4856 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
4858 llvm::DINode::FlagZero, Align);
4861 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4862 const unsigned fieldIndex = FD->getFieldIndex();
4869 if (fieldOffset != 0) {
4875 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4881 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
4882 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
4883 const uint64_t value = IL->getValue().getZExtValue();
4887 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4896 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4899 Builder.GetInsertBlock());
4904llvm::DILocalVariable *
4907 const bool UsePointerValue) {
4910 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
4911 for (
auto *B : DD->bindings()) {
4912 EmitDeclare(B, Storage, std::nullopt, Builder,
4920 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
4925 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4927 if (D->
hasAttr<NoDebugAttr>())
4930 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4931 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
4937 StringRef Name = D->
getName();
4944 DBuilder.insertLabel(L,
4946 Scope, CurInlinedAt),
4947 Builder.GetInsertBlock());
4950llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
4952 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
4955 return DBuilder.createObjectPointerType(Ty);
4960 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
4962 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4964 if (Builder.GetInsertBlock() ==
nullptr)
4966 if (VD->
hasAttr<NoDebugAttr>())
4969 bool isByRef = VD->
hasAttr<BlocksAttr>();
4971 uint64_t XOffset = 0;
4972 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4975 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4977 Ty = getOrCreateType(VD->
getType(), Unit);
4981 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
4983 Ty = CreateSelfType(VD->
getType(), Ty);
4986 const unsigned Line =
4997 addr.push_back(llvm::dwarf::DW_OP_deref);
4998 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5001 addr.push_back(llvm::dwarf::DW_OP_deref);
5002 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5007 addr.push_back(llvm::dwarf::DW_OP_deref);
5008 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5016 auto *D = DBuilder.createAutoVariable(
5017 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5018 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5022 LexicalBlockStack.back(), CurInlinedAt);
5023 auto *
Expr = DBuilder.createExpression(addr);
5025 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint);
5027 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5030llvm::DILocalVariable *
5033 bool UsePointerValue) {
5035 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5039struct BlockLayoutChunk {
5040 uint64_t OffsetInBits;
5043bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5044 return l.OffsetInBits < r.OffsetInBits;
5048void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5050 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5056 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5057 BlockLayout.getElementOffsetInBits(0),
5059 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5060 BlockLayout.getElementOffsetInBits(1),
5064 BlockLayout.getElementOffsetInBits(0),
5066 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5067 BlockLayout.getElementOffsetInBits(1),
5071 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5072 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5074 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5075 BlockLayout.getElementOffsetInBits(3),
5077 Fields.push_back(createFieldType(
5082 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5089 llvm::AllocaInst *Alloca,
5097 llvm::DIFile *tunit = getOrCreateFile(loc);
5098 unsigned line = getLineNumber(loc);
5099 unsigned column = getColumnNumber(loc);
5104 const llvm::StructLayout *blockLayout =
5108 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5117 BlockLayoutChunk chunk;
5118 chunk.OffsetInBits =
5119 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5120 chunk.Capture =
nullptr;
5121 chunks.push_back(chunk);
5125 for (
const auto &capture :
blockDecl->captures()) {
5126 const VarDecl *variable = capture.getVariable();
5133 BlockLayoutChunk chunk;
5134 chunk.OffsetInBits =
5135 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5136 chunk.Capture = &capture;
5137 chunks.push_back(chunk);
5141 llvm::array_pod_sort(chunks.begin(), chunks.end());
5143 for (
const BlockLayoutChunk &Chunk : chunks) {
5144 uint64_t offsetInBits = Chunk.OffsetInBits;
5151 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5153 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5156 llvm_unreachable(
"unexpected block declcontext");
5158 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5159 offsetInBits, tunit, tunit));
5164 StringRef name = variable->
getName();
5166 llvm::DIType *fieldType;
5168 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5173 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5174 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5175 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5176 PtrInfo.
Width, Align, offsetInBits,
5177 llvm::DINode::FlagZero, fieldType);
5181 offsetInBits, Align, tunit, tunit);
5183 fields.push_back(fieldType);
5187 llvm::raw_svector_ostream(typeName)
5190 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5192 llvm::DIType *
type =
5193 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5195 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5199 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5200 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5203 auto *debugVar = DBuilder.createParameterVariable(
5204 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5207 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5209 column, scope, CurInlinedAt),
5210 Builder.GetInsertBlock());
5213llvm::DIDerivedType *
5214CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5219 if (MI != StaticDataMemberCache.end()) {
5220 assert(MI->second &&
"Static data member declaration should still exist");
5227 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
5228 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
5231llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5232 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5233 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5234 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5236 for (
const auto *Field : RD->
fields()) {
5237 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5238 StringRef FieldName = Field->getName();
5241 if (FieldName.empty()) {
5242 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5243 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5248 GVE = DBuilder.createGlobalVariableExpression(
5249 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5250 Var->hasLocalLinkage());
5251 Var->addDebugInfo(GVE);
5263 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5268 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5276 case TemplateArgument::Pack:
5277 return ReferencesAnonymousEntity(TA.getPackAsArray());
5278 case TemplateArgument::Type: {
5279 struct ReferencesAnonymous
5280 : public RecursiveASTVisitor<ReferencesAnonymous> {
5281 bool RefAnon = false;
5282 bool VisitRecordType(RecordType *RT) {
5283 if (ReferencesAnonymousEntity(RT)) {
5290 ReferencesAnonymous RT;
5291 RT.TraverseType(TA.getAsType());
5304 bool Reconstitutable =
true;
5306 Reconstitutable =
false;
5310 Reconstitutable =
false;
5313 bool VisitType(
Type *T) {
5317 Reconstitutable =
false;
5322 bool TraverseEnumType(
EnumType *ET) {
5325 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5327 Reconstitutable =
false;
5331 Reconstitutable =
false;
5341 return Reconstitutable;
5345 Reconstitutable =
false;
5355 ReconstitutableType T;
5357 return T.Reconstitutable;
5360std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5362 llvm::raw_string_ostream OS(Name);
5363 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5366 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5370 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5372 std::optional<TemplateArgs> Args;
5374 bool IsOperatorOverload =
false;
5375 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5376 Args = GetTemplateArgs(RD);
5377 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5378 Args = GetTemplateArgs(FD);
5380 IsOperatorOverload |=
5383 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5384 Args = GetTemplateArgs(VD);
5390 case TemplateArgument::Template:
5397 case TemplateArgument::Declaration:
5405 case TemplateArgument::NullPtr:
5409 case TemplateArgument::Pack:
5411 return HasReconstitutableArgs(TA.getPackAsArray());
5412 case TemplateArgument::Integral:
5417 return TA.getAsIntegral().getBitWidth() <= 64 &&
5418 IsReconstitutableType(TA.getIntegralType());
5419 case TemplateArgument::StructuralValue:
5421 case TemplateArgument::Type:
5422 return IsReconstitutableType(TA.getAsType());
5424 llvm_unreachable(
"Other, unresolved, template arguments should "
5425 "not be seen here");
5450 bool Reconstitutable =
5451 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5455 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5459 bool Mangled = TemplateNamesKind ==
5460 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5466 std::string EncodedOriginalName;
5467 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5475 std::string CanonicalOriginalName;
5476 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5478 assert(EncodedOriginalNameOS.str() == OriginalOS.str());
5488 if (D->
hasAttr<NoDebugAttr>())
5491 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5492 return GetName(D,
true);
5498 if (Cached != DeclCache.end())
5499 return Var->addDebugInfo(
5500 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5503 llvm::DIFile *Unit =
nullptr;
5504 llvm::DIScope *DContext =
nullptr;
5506 StringRef DeclName, LinkageName;
5508 llvm::MDTuple *TemplateParameters =
nullptr;
5509 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
5510 TemplateParameters, DContext);
5514 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5522 "unnamed non-anonymous struct or union?");
5523 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5530 if (D->
hasAttr<CUDASharedAttr>())
5533 else if (D->
hasAttr<CUDAConstantAttr>())
5537 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5539 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5540 GVE = DBuilder.createGlobalVariableExpression(
5541 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
5542 Var->hasLocalLinkage(),
true,
5543 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5544 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5545 Align, Annotations);
5546 Var->addDebugInfo(GVE);
5553 if (VD->
hasAttr<NoDebugAttr>())
5555 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5556 return GetName(VD,
true);
5561 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5562 StringRef Name = VD->
getName();
5563 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5565 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5566 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5567 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5580 llvm::DIType *EDTy =
5582 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5593 auto *VarD = dyn_cast<VarDecl>(VD);
5594 if (VarD && VarD->isStaticDataMember()) {
5595 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5596 getDeclContextDescriptor(VarD);
5601 RetainedTypes.push_back(
5606 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5608 auto &GV = DeclCache[VD];
5612 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
5613 llvm::MDTuple *TemplateParameters =
nullptr;
5615 if (isa<VarTemplateSpecializationDecl>(VD))
5617 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5618 TemplateParameters = parameterNodes.get();
5621 GV.reset(DBuilder.createGlobalVariableExpression(
5622 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5623 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5624 TemplateParameters, Align));
5630 if (D->
hasAttr<NoDebugAttr>())
5634 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5635 StringRef Name = D->
getName();
5636 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
5638 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5639 llvm::DIGlobalVariableExpression *GVE =
5640 DBuilder.createGlobalVariableExpression(
5641 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
5642 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5643 Var->addDebugInfo(GVE);
5654 const auto *D = cast<ValueDecl>(GD.
getDecl());
5655 if (D->
hasAttr<NoDebugAttr>())
5673 if (!(DI = getDeclarationOrDefinition(
5674 AliaseeDecl.getCanonicalDecl().getDecl())))
5677 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5680 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5681 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
5694 llvm::DIFile *
File = getOrCreateFile(Loc);
5695 llvm::DIGlobalVariableExpression *Debug =
5696 DBuilder.createGlobalVariableExpression(
5697 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
5698 getLineNumber(Loc), getOrCreateType(S->getType(),
File),
true);
5699 GV->addDebugInfo(Debug);
5702llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
5703 if (!LexicalBlockStack.empty())
5704 return LexicalBlockStack.back();
5705 llvm::DIScope *Mod = getParentModuleOrNull(D);
5706 return getContextDescriptor(D, Mod ? Mod : TheCU);
5718 DBuilder.createImportedModule(
5720 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
5725 if (llvm::DINode *
Target =
5728 DBuilder.createImportedDeclaration(
5730 getOrCreateFile(Loc), getLineNumber(Loc));
5738 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5740 for (
const auto *USD : UD.
shadows()) {
5745 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5746 if (
const auto *AT = FD->getType()
5749 if (AT->getDeducedType().isNull())
5763 "We shouldn't be codegening an invalid UsingEnumDecl"
5764 " containing no decls");
5766 for (
const auto *USD : UD.
shadows())
5771 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5773 if (
Module *M = ID.getImportedModule()) {
5775 auto Loc = ID.getLocation();
5776 DBuilder.createImportedDeclaration(
5777 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
5778 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
5779 getLineNumber(Loc));
5783llvm::DIImportedEntity *
5787 auto &VH = NamespaceAliasCache[&NA];
5789 return cast<llvm::DIImportedEntity>(VH);
5790 llvm::DIImportedEntity *R;
5792 if (
const auto *Underlying =
5795 R = DBuilder.createImportedDeclaration(
5798 getLineNumber(Loc), NA.
getName());
5800 R = DBuilder.createImportedDeclaration(
5803 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
5809CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
5813 auto I = NamespaceCache.find(NSDecl);
5814 if (I != NamespaceCache.end())
5815 return cast<llvm::DINamespace>(I->second);
5817 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
5819 llvm::DINamespace *NS =
5820 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
5821 NamespaceCache[NSDecl].reset(NS);
5826 assert(TheCU &&
"no main compile unit");
5827 TheCU->setDWOId(Signature);
5833 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
5834 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
5835 llvm::DIType *Ty = E.Type->getDecl()->getDefinition()
5836 ? CreateTypeDefinition(E.Type, E.Unit)
5838 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
5842 for (
const auto &
P : ObjCMethodCache) {
5843 if (
P.second.empty())
5846 QualType QTy(
P.first->getTypeForDecl(), 0);
5848 assert(It != TypeCache.end());
5850 llvm::DICompositeType *InterfaceDecl =
5851 cast<llvm::DICompositeType>(It->second);
5853 auto CurElts = InterfaceDecl->getElements();
5857 for (
auto &SubprogramDirect :
P.second)
5858 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
5859 EltTys.push_back(SubprogramDirect.getPointer());
5861 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5862 DBuilder.replaceArrays(InterfaceDecl, Elements);
5865 for (
const auto &
P : ReplaceMap) {
5867 auto *Ty = cast<llvm::DIType>(
P.second);
5868 assert(Ty->isForwardDecl());
5870 auto It = TypeCache.find(
P.first);
5871 assert(It != TypeCache.end());
5874 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
5875 cast<llvm::DIType>(It->second));
5878 for (
const auto &
P : FwdDeclReplaceMap) {
5880 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
5881 llvm::Metadata *Repl;
5883 auto It = DeclCache.find(
P.first);
5887 if (It == DeclCache.end())
5892 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
5893 Repl = GVE->getVariable();
5894 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
5899 for (
auto &RT : RetainedTypes)
5900 if (
auto MD = TypeCache[RT])
5901 DBuilder.retainType(cast<llvm::DIType>(MD));
5903 DBuilder.finalize();
5909 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
5910 DBuilder.retainType(DieTy);
5915 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
5916 DBuilder.retainType(DieTy);
5920 if (LexicalBlockStack.empty())
5921 return llvm::DebugLoc();
5923 llvm::MDNode *
Scope = LexicalBlockStack.back();
5924 return llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(Loc),
5925 getColumnNumber(Loc),
Scope);
5928llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
5932 DebugKind == llvm::codegenoptions::NoDebugInfo ||
5933 DebugKind == llvm::codegenoptions::LocTrackingOnly)
5934 return llvm::DINode::FlagZero;
5939 bool SupportsDWARFv4Ext =
5941 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
5942 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
5944 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
5945 return llvm::DINode::FlagZero;
5947 return llvm::DINode::FlagAllCallsDescribed;
5958 return DBuilder.createConstantValueExpression(
5959 Val.
getFloat().bitcastToAPInt().getZExtValue());
5964 llvm::APSInt
const &ValInt = Val.
getInt();
5965 std::optional<uint64_t> ValIntOpt;
5966 if (ValInt.isUnsigned())
5967 ValIntOpt = ValInt.tryZExtValue();
5968 else if (
auto tmp = ValInt.trySExtValue())
5971 ValIntOpt =
static_cast<uint64_t
>(*tmp);
5974 return DBuilder.createConstantValueExpression(ValIntOpt.value());
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
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 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 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 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++ template declaration subclasses.
Defines the clang::FileManager interface and associated types.
llvm::MachO::Target Target
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.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getEnumType(const EnumDecl *Decl) const
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 getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
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, if already known; otherwise, returns a NULL 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 getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
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.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
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.
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.
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
std::string getModuleName() const
StringRef getASTFile() const
StringRef getPath() 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.
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.
unsigned size_overridden_methods() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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
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.
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.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
bool hasMaybeUnusedDebugInfo() const
Check if maybe unused type info should be emitted.
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.
llvm::MDNode * getInlinedAt() const
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 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)
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 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 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::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
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.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
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 IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const
const LangOptions & getLangOpts() const
int getUniqueBlockCount()
Fetches the global unique block count.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
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.
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.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
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.
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.
enumerator_range enumerators() const
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
EnumDecl * getDefinition() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() 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.
bool isDeleted() const
Whether this function has been deleted.
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.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
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
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
QualType getPointeeType() const
const Type * getClass() 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)
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.
NamedDecl * 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
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.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
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()
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
field_iterator field_end() const
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
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 * getDecl() 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.
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 * getDecl() 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.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl() 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.
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.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
bool isIncompleteArrayType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isExtVectorBoolType() 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
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 (&&).
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.
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,...
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
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 PrintCanonicalTypes
Whether to print types as written or canonically.
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, where the name is u...
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
A this pointer adjustment.