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);
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();
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);
1330 if (Param->isParameterPack()) {
1339 if (SubstArgs.empty()) {
1348 SpecArgs.push_back(SubstArgs.front());
1349 SubstArgs = SubstArgs.drop_front();
1355 llvm::DIFile *Unit) {
1360 if (isa<BuiltinTemplateDecl>(TD))
1363 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1368 llvm::raw_svector_ostream OS(NS);
1370 auto PP = getPrintingPolicy();
1397 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1406 llvm::raw_string_ostream OS(Name);
1409 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1410 !HasReconstitutableArgs(Args.Args))
1413 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1414 Src, Name, getOrCreateFile(
Loc), getLineNumber(
Loc),
1415 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1430 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(
Loc),
1447 return llvm::DINode::FlagZero;
1451 return llvm::DINode::FlagPrivate;
1453 return llvm::DINode::FlagProtected;
1455 return llvm::DINode::FlagPublic;
1457 return llvm::DINode::FlagZero;
1459 llvm_unreachable(
"unexpected access enumerator");
1462llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1463 llvm::DIFile *Unit) {
1464 llvm::DIType *Underlying =
1476 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1478 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1480 if (isa<RecordDecl>(DC))
1483 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1484 getOrCreateFile(
Loc), getLineNumber(
Loc),
1485 getDeclContextDescriptor(Ty->
getDecl()), Align,
1486 Flags, Annotations);
1496 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1498 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1500 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1502 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1504 return llvm::dwarf::DW_CC_BORLAND_pascal;
1506 return llvm::dwarf::DW_CC_LLVM_Win64;
1508 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1512 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1514 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1516 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1518 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1521 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1523 return llvm::dwarf::DW_CC_LLVM_Swift;
1525 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1527 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1529 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1531 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1533 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1535 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1537 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1543 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1545 Flags |= llvm::DINode::FlagLValueReference;
1547 Flags |= llvm::DINode::FlagRValueReference;
1551llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1552 llvm::DIFile *Unit) {
1553 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1555 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1564 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1566 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1570 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1573 for (
const QualType &ParamType : FPT->param_types())
1574 EltTys.push_back(getOrCreateType(ParamType, Unit));
1575 if (FPT->isVariadic())
1576 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1579 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1580 llvm::DIType *F = DBuilder.createSubroutineType(
1585llvm::DIDerivedType *
1586CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1587 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1588 StringRef Name = BitFieldDecl->
getName();
1590 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1591 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1593 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1594 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1597 llvm::DIFile *
File = getOrCreateFile(
Loc);
1598 unsigned Line = getLineNumber(
Loc);
1603 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1612 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1614 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1615 return DBuilder.createBitFieldMemberType(
1616 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1617 Flags, DebugType, Annotations);
1620llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1621 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1649 if (PreviousFieldsDI.empty())
1653 auto *PreviousMDEntry =
1654 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1655 auto *PreviousMDField =
1656 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1657 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1658 PreviousMDField->getSizeInBits() == 0)
1662 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1664 assert(PreviousBitfield->isBitField());
1667 if (!PreviousBitfield->isZeroLengthBitField(Context))
1670 QualType Ty = PreviousBitfield->getType();
1672 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1673 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1674 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1676 llvm::DIFile *
File = getOrCreateFile(
Loc);
1677 unsigned Line = getLineNumber(
Loc);
1680 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1683 llvm::DINode::DIFlags Flags =
1685 llvm::DINodeArray Annotations =
1686 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1687 return DBuilder.createBitFieldMemberType(
1688 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1689 Flags, DebugType, Annotations);
1692llvm::DIType *CGDebugInfo::createFieldType(
1694 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1695 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1696 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1699 llvm::DIFile *file = getOrCreateFile(loc);
1700 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1703 auto Align = AlignInBits;
1704 if (!
type->isIncompleteArrayType()) {
1706 SizeInBits = TI.
Width;
1712 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1713 offsetInBits, flags, debugType, Annotations);
1716void CGDebugInfo::CollectRecordLambdaFields(
1718 llvm::DIType *RecordTy) {
1724 unsigned fieldno = 0;
1727 I != E; ++I, ++Field, ++fieldno) {
1729 if (
C.capturesVariable()) {
1731 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1733 StringRef VName =
V->getName();
1734 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1736 llvm::DIType *FieldType = createFieldType(
1738 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1739 elements.push_back(FieldType);
1740 }
else if (
C.capturesThis()) {
1746 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1748 StringRef ThisName =
1750 llvm::DIType *fieldType = createFieldType(
1754 elements.push_back(fieldType);
1759llvm::DIDerivedType *
1760CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1765 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1766 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1768 unsigned LineNumber = getLineNumber(Var->
getLocation());
1769 StringRef VName = Var->
getName();
1773 llvm::Constant *
C =
nullptr;
1779 if (
Value->isFloat())
1786 ? llvm::dwarf::DW_TAG_variable
1787 : llvm::dwarf::DW_TAG_member;
1789 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1790 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1795void CGDebugInfo::CollectRecordNormalField(
1796 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1803 if (
name.empty() && !
type->isRecordType())
1806 llvm::DIType *FieldType;
1808 llvm::DIDerivedType *BitFieldType;
1809 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1810 if (llvm::DIType *Separator =
1811 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1812 elements.push_back(Separator);
1815 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1818 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1821 elements.push_back(FieldType);
1824void CGDebugInfo::CollectRecordNestedType(
1828 if (isa<InjectedClassNameType>(Ty))
1831 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(
Loc));
1832 elements.push_back(nestedType);
1835void CGDebugInfo::CollectRecordFields(
1836 const RecordDecl *record, llvm::DIFile *tunit,
1838 llvm::DICompositeType *RecordTy) {
1839 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1841 if (CXXDecl && CXXDecl->
isLambda())
1842 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1847 unsigned fieldNo = 0;
1851 for (
const auto *I : record->
decls())
1852 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1853 if (
V->hasAttr<NoDebugAttr>())
1859 isa<VarTemplateSpecializationDecl>(
V))
1862 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1866 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1867 if (MI != StaticDataMemberCache.end()) {
1868 assert(MI->second &&
1869 "Static data member declaration should still exist");
1870 elements.push_back(MI->second);
1872 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1873 elements.push_back(Field);
1875 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1876 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1877 elements, RecordTy, record);
1884 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1886 if (isa<RecordDecl>(I) &&
1887 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1889 if (!nestedType->isImplicit() &&
1890 nestedType->getDeclContext() == record)
1891 CollectRecordNestedType(nestedType, elements);
1897llvm::DISubroutineType *
1898CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1899 llvm::DIFile *Unit) {
1902 return cast_or_null<llvm::DISubroutineType>(
1904 return getOrCreateInstanceMethodType(Method->
getThisType(),
Func, Unit);
1907llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1923 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
1925 Func->getReturnType(),
Func->getParamTypes(), EPI),
1927 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
1928 assert(Args.size() &&
"Invalid number of arguments!");
1933 Elts.push_back(Args[0]);
1937 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1939 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1942 llvm::DIType *PointeeType =
1944 llvm::DIType *ThisPtrType =
1945 DBuilder.createPointerType(PointeeType, Size, Align);
1950 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1951 Elts.push_back(ThisPtrType);
1953 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1955 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1956 Elts.push_back(ThisPtrType);
1960 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1961 Elts.push_back(Args[i]);
1963 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1965 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
1972 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1979llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1980 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1982 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1984 StringRef MethodName = getFunctionName(Method);
1985 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1989 StringRef MethodLinkageName;
1999 llvm::DIFile *MethodDefUnit =
nullptr;
2000 unsigned MethodLine = 0;
2002 MethodDefUnit = getOrCreateFile(Method->
getLocation());
2003 MethodLine = getLineNumber(Method->
getLocation());
2007 llvm::DIType *ContainingType =
nullptr;
2008 unsigned VIndex = 0;
2009 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2010 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2015 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2017 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2022 if (!isa<CXXDestructorDecl>(Method))
2027 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
2039 Flags |= llvm::DINode::FlagIntroducedVirtual;
2048 ContainingType = RecordTy;
2052 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2055 Flags |= llvm::DINode::FlagNoReturn;
2058 Flags |= llvm::DINode::FlagStaticMember;
2060 Flags |= llvm::DINode::FlagArtificial;
2062 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
2063 if (CXXC->isExplicit())
2064 Flags |= llvm::DINode::FlagExplicit;
2065 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
2066 if (CXXC->isExplicit())
2067 Flags |= llvm::DINode::FlagExplicit;
2070 Flags |= llvm::DINode::FlagPrototyped;
2072 Flags |= llvm::DINode::FlagLValueReference;
2074 Flags |= llvm::DINode::FlagRValueReference;
2076 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2078 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2082 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2086 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2087 llvm::DISubprogram *SP = DBuilder.createMethod(
2088 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2089 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2090 TParamsArray.get());
2097void CGDebugInfo::CollectCXXMemberFunctions(
2104 for (
const auto *I : RD->
decls()) {
2105 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2129 EltTys.push_back(MI == SPCache.end()
2130 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2131 :
static_cast<llvm::Metadata *
>(MI->second));
2135void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2137 llvm::DIType *RecordTy) {
2139 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2140 llvm::DINode::FlagZero);
2145 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2146 llvm::DINode::FlagIndirectVirtualBase);
2150void CGDebugInfo::CollectCXXBasesAux(
2155 llvm::DINode::DIFlags StartingFlags) {
2157 for (
const auto &BI : Bases) {
2160 if (!SeenTypes.insert(
Base).second)
2162 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2163 llvm::DINode::DIFlags BFlags = StartingFlags;
2165 uint32_t VBPtrOffset = 0;
2167 if (BI.isVirtual()) {
2184 BFlags |= llvm::DINode::FlagVirtual;
2191 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2192 VBPtrOffset, BFlags);
2193 EltTys.push_back(DTy);
2198CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2199 llvm::DIFile *Unit) {
2201 return llvm::DINodeArray();
2202 TemplateArgs &Args = *OArgs;
2204 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2209 Name = Args.TList->getParam(i)->getName();
2213 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2214 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2215 TheCU, Name, TTy, defaultParameter));
2220 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2221 TheCU, Name, TTy, defaultParameter,
2227 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2228 llvm::Constant *
V =
nullptr;
2232 !D->
hasAttr<CUDADeviceAttr>()) {
2235 if (
const auto *VD = dyn_cast<VarDecl>(D))
2239 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2240 MD && MD->isImplicitObjectMemberFunction())
2242 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2246 else if (
const auto *MPT =
2247 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2255 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2257 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2264 assert(
V &&
"Failed to find template parameter pointer");
2265 V =
V->stripPointerCasts();
2267 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2268 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2272 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2273 llvm::Constant *
V =
nullptr;
2276 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2282 if (MPT->isMemberDataPointer())
2285 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2286 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2287 TheCU, Name, TTy, defaultParameter,
V));
2291 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2294 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2295 TheCU, Name, TTy, defaultParameter,
V));
2298 std::string QualName;
2299 llvm::raw_string_ostream OS(QualName);
2301 OS, getPrintingPolicy());
2302 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2303 TheCU, Name,
nullptr, OS.str(), defaultParameter));
2307 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2308 TheCU, Name,
nullptr,
2317 assert(
V &&
"Expression in template argument isn't constant");
2318 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2319 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2320 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2326 "These argument types shouldn't exist in concrete types");
2329 return DBuilder.getOrCreateArray(TemplateParams);
2332std::optional<CGDebugInfo::TemplateArgs>
2333CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2341 return std::nullopt;
2343std::optional<CGDebugInfo::TemplateArgs>
2344CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2348 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2350 return std::nullopt;
2353 auto TA = TS->getTemplateArgs().asArray();
2354 return {{TList, TA}};
2356std::optional<CGDebugInfo::TemplateArgs>
2357CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2358 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2363 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2365 return {{TPList, TAList.
asArray()}};
2367 return std::nullopt;
2371CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2372 llvm::DIFile *Unit) {
2373 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2376llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2377 llvm::DIFile *Unit) {
2378 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2381llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2382 llvm::DIFile *Unit) {
2383 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2386llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2387 if (!D->
hasAttr<BTFDeclTagAttr>())
2392 llvm::Metadata *Ops[2] = {
2393 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2395 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2397 return DBuilder.getOrCreateArray(Annotations);
2400llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2402 return VTablePtrType;
2407 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2408 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2409 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2412 std::optional<unsigned> DWARFAddressSpace =
2415 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2416 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2417 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2418 return VTablePtrType;
2421StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2426StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2428 llvm::Function *InitFn) {
2433 return InitFn->getName();
2443 llvm::raw_svector_ostream OS(QualifiedGV);
2445 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2447 std::swap(Quals, GVName);
2451 llvm::raw_svector_ostream OS(InitName);
2453 OS << Quals <<
"::";
2458 llvm_unreachable(
"not an initializer");
2460 OS <<
"`dynamic initializer for '";
2463 OS <<
"`dynamic atexit destructor for '";
2470 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2472 getPrintingPolicy());
2477 return internString(OS.str());
2480void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2497 llvm::DIType *VPtrTy =
nullptr;
2500 if (NeedVTableShape) {
2505 unsigned VSlotCount =
2507 unsigned VTableWidth = PtrWidth * VSlotCount;
2509 std::optional<unsigned> DWARFAddressSpace =
2513 llvm::DIType *VTableType = DBuilder.createPointerType(
2514 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2515 EltTys.push_back(VTableType);
2518 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2526 VPtrTy = getOrCreateVTablePtrType(Unit);
2529 llvm::DIType *VPtrMember =
2530 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2531 llvm::DINode::FlagArtificial, VPtrTy);
2532 EltTys.push_back(VPtrMember);
2538 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(
Loc));
2550 assert(!D.
isNull() &&
"null type");
2551 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(
Loc));
2552 assert(
T &&
"could not create debug info for type");
2562 llvm::codegenoptions::DebugLineTablesOnly)
2568 node = getOrCreateType(AllocatedTy, getOrCreateFile(
Loc));
2570 CI->setMetadata(
"heapallocsite", node);
2574 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2578 auto I = TypeCache.find(TyPtr);
2579 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2581 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2582 assert(!Res->isForwardDecl());
2583 TypeCache[TyPtr].reset(Res);
2587 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2594 if (RD->
hasAttr<DLLImportAttr>())
2597 if (MD->hasAttr<DLLImportAttr>())
2610 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2619 bool Explicit =
false;
2620 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2621 Explicit = TD->isExplicitInstantiationOrSpecialization();
2635 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2636 if (CXXRD->isDynamicClass() &&
2638 llvm::GlobalValue::AvailableExternallyLinkage &&
2649 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2653 auto I = TypeCache.find(TyPtr);
2654 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2661 assert(!Res->isForwardDecl());
2662 TypeCache[TyPtr].reset(Res);
2669 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2670 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2693 if (Ctor->isCopyOrMoveConstructor())
2695 if (!Ctor->isDeleted())
2714 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2717 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2718 RD->
hasAttr<StandaloneDebugAttr>())
2721 if (!LangOpts.CPlusPlus)
2727 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2743 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2744 Spec = SD->getSpecializationKind();
2753 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2765 llvm::DIType *
T = getTypeOrNull(Ty);
2766 if (
T &&
T->isForwardDecl())
2770llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2772 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2776 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2780 auto [Def, Pref] = CreateTypeDefinition(Ty);
2782 return Pref ? Pref : Def;
2785llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2786 llvm::DIFile *Unit) {
2790 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2794 return getOrCreateType(PNA->getTypedefType(), Unit);
2797std::pair<llvm::DIType *, llvm::DIType *>
2798CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2802 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2810 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2814 return {FwdDecl,
nullptr};
2816 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2817 CollectContainingType(CXXDecl, FwdDecl);
2820 LexicalBlockStack.emplace_back(&*FwdDecl);
2821 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2831 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2833 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2834 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2838 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2840 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2842 LexicalBlockStack.pop_back();
2843 RegionMap.erase(Ty->
getDecl());
2845 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2846 DBuilder.replaceArrays(FwdDecl, Elements);
2848 if (FwdDecl->isTemporary())
2850 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2852 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2854 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2855 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2856 return {FwdDecl, PrefDI};
2858 return {FwdDecl,
nullptr};
2862 llvm::DIFile *Unit) {
2868 llvm::DIFile *Unit) {
2873 return DBuilder.createTypedef(
2876 getDeclContextDescriptor(Ty->
getDecl()));
2904 llvm::DIFile *Unit) {
2912 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2913 !
ID->getImplementation())
2914 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2916 getDeclContextDescriptor(ID), Unit, 0);
2919 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2920 unsigned Line = getLineNumber(
ID->getLocation());
2922 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2928 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2929 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2930 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
2931 DefUnit,
Line, RuntimeLang);
2932 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2936 return CreateTypeDefinition(Ty, Unit);
2940 bool CreateSkeletonCU) {
2945 auto ModRef = ModuleCache.find(M);
2946 if (ModRef != ModuleCache.end())
2947 return cast<llvm::DIModule>(ModRef->second);
2952 llvm::raw_svector_ostream OS(ConfigMacros);
2956 for (
auto &M : PPOpts.Macros) {
2959 const std::string &
Macro = M.first;
2960 bool Undef = M.second;
2961 OS <<
"\"-" << (Undef ?
'U' :
'D');
2962 for (
char c : Macro)
2977 bool IsRootModule = M ? !M->
Parent :
true;
2981 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
2983 "clang module without ASTFile must be specified by -fmodule-name");
2986 auto RemapPath = [
this](StringRef Path) -> std::string {
2988 StringRef Relative(Remapped);
2989 StringRef CompDir = TheCU->getDirectory();
2990 if (Relative.consume_front(CompDir))
2991 Relative.consume_front(llvm::sys::path::get_separator());
2993 return Relative.str();
2996 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3003 Signature = ModSig.truncatedValue();
3009 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3011 PCM = getCurrentDirname();
3015 llvm::sys::path::append(PCM, Mod.
getASTFile());
3016 DIB.createCompileUnit(
3017 TheCU->getSourceLanguage(),
3020 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3021 llvm::DICompileUnit::FullDebug, Signature);
3026 IsRootModule ? nullptr
3029 std::string IncludePath = Mod.
getPath().str();
3030 llvm::DIModule *DIMod =
3032 RemapPath(IncludePath));
3033 ModuleCache[M].reset(DIMod);
3038 llvm::DIFile *Unit) {
3040 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3041 unsigned Line = getLineNumber(
ID->getLocation());
3042 unsigned RuntimeLang = TheCU->getSourceLanguage();
3048 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3049 if (
ID->getImplementation())
3050 Flags |= llvm::DINode::FlagObjcClassComplete;
3052 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3053 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3054 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3055 nullptr, llvm::DINodeArray(), RuntimeLang);
3058 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3061 LexicalBlockStack.emplace_back(RealDecl);
3062 RegionMap[Ty->
getDecl()].reset(RealDecl);
3069 llvm::DIType *SClassTy =
3074 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3075 llvm::DINode::FlagZero);
3076 EltTys.push_back(InhTag);
3082 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3083 unsigned PLine = getLineNumber(
Loc);
3086 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3087 PD->getName(), PUnit, PLine,
3089 : getSelectorName(PD->getGetterName()),
3091 : getSelectorName(PD->getSetterName()),
3092 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3093 EltTys.push_back(PropertyNode);
3098 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3105 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3108 for (
auto *PD : ClassExt->properties()) {
3109 PropertySet.insert(GetIsClassAndIdent(PD));
3112 for (
const auto *PD :
ID->properties()) {
3115 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3122 unsigned FieldNo = 0;
3124 Field =
Field->getNextIvar(), ++FieldNo) {
3125 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3129 StringRef FieldName =
Field->getName();
3132 if (FieldName.empty())
3136 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3137 unsigned FieldLine = getLineNumber(
Field->getLocation());
3140 uint32_t FieldAlign = 0;
3145 FieldSize =
Field->isBitField()
3156 if (
Field->isBitField()) {
3167 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3169 Flags = llvm::DINode::FlagProtected;
3171 Flags = llvm::DINode::FlagPrivate;
3173 Flags = llvm::DINode::FlagPublic;
3175 if (
Field->isBitField())
3176 Flags |= llvm::DINode::FlagBitField;
3178 llvm::MDNode *PropertyNode =
nullptr;
3181 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3184 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3185 unsigned PLine = getLineNumber(
Loc);
3188 PropertyNode = DBuilder.createObjCProperty(
3189 PD->getName(), PUnit, PLine,
3192 : getSelectorName(PD->getGetterName()),
3195 : getSelectorName(PD->getSetterName()),
3196 PD->getPropertyAttributes(),
3197 getOrCreateType(PD->getType(), PUnit));
3201 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3202 FieldSize, FieldAlign, FieldOffset, Flags,
3203 FieldTy, PropertyNode);
3204 EltTys.push_back(FieldTy);
3207 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3208 DBuilder.replaceArrays(RealDecl, Elements);
3210 LexicalBlockStack.pop_back();
3214llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3215 llvm::DIFile *Unit) {
3233 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3236 llvm::Metadata *Subscript;
3238 auto SizeExpr = SizeExprCache.find(QTy);
3239 if (SizeExpr != SizeExprCache.end())
3240 Subscript = DBuilder.getOrCreateSubrange(
3241 SizeExpr->getSecond() ,
nullptr ,
3242 nullptr ,
nullptr );
3245 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3246 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3247 Subscript = DBuilder.getOrCreateSubrange(
3248 CountNode ,
nullptr ,
nullptr ,
3251 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3256 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3260 llvm::DIFile *Unit) {
3264 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3270 auto *ColumnCountNode =
3271 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3273 auto *RowCountNode =
3274 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3276 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3277 ColumnCountNode ,
nullptr ,
nullptr ,
3279 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3280 RowCountNode ,
nullptr ,
nullptr ,
3282 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3283 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3286llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3291 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3315 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3324 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3325 Count = CAT->getZExtSize();
3326 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3327 if (
Expr *Size = VAT->getSizeExpr()) {
3330 Count =
Result.Val.getInt().getExtValue();
3334 auto SizeNode = SizeExprCache.find(EltTy);
3335 if (SizeNode != SizeExprCache.end())
3336 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3337 SizeNode->getSecond() ,
nullptr ,
3338 nullptr ,
nullptr ));
3341 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3343 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3344 CountNode ,
nullptr ,
nullptr ,
3350 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3352 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3357 llvm::DIFile *Unit) {
3358 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3363 llvm::DIFile *Unit) {
3364 llvm::dwarf::Tag Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3368 Tag = llvm::dwarf::DW_TAG_reference_type;
3370 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3375 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3385 Flags |= llvm::DINode::FlagSingleInheritance;
3388 Flags |= llvm::DINode::FlagMultipleInheritance;
3391 Flags |= llvm::DINode::FlagVirtualInheritance;
3401 return DBuilder.createMemberPointerType(
3407 return DBuilder.createMemberPointerType(
3408 getOrCreateInstanceMethodType(
3411 ClassType,
Size, 0, Flags);
3414llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3416 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3419llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3423llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3435 bool isImportedFromModule =
3447 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3448 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3449 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3450 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3453 StringRef EDName = ED->
getName();
3454 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3455 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3456 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3458 ReplaceMap.emplace_back(
3459 std::piecewise_construct, std::make_tuple(Ty),
3460 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3464 return CreateTypeDefinition(Ty);
3467llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3481 Enumerators.push_back(
3482 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3486 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3488 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3490 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3491 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3492 return DBuilder.createEnumerationType(
3493 EnumContext, ED->
getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3499 StringRef Name, StringRef
Value) {
3500 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3507 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3508 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3509 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3519 Quals += InnerQuals;
3523 return C.getQualifiedType(
T.getTypePtr(), Quals);
3524 case Type::TemplateSpecialization: {
3525 const auto *Spec = cast<TemplateSpecializationType>(
T);
3526 if (Spec->isTypeAlias())
3527 return C.getQualifiedType(
T.getTypePtr(), Quals);
3531 case Type::TypeOfExpr:
3532 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3535 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3537 case Type::Decltype:
3538 T = cast<DecltypeType>(
T)->getUnderlyingType();
3540 case Type::UnaryTransform:
3541 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3543 case Type::Attributed:
3544 T = cast<AttributedType>(
T)->getEquivalentType();
3546 case Type::BTFTagAttributed:
3547 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3549 case Type::CountAttributed:
3550 T = cast<CountAttributedType>(
T)->
desugar();
3552 case Type::Elaborated:
3553 T = cast<ElaboratedType>(
T)->getNamedType();
3556 T = cast<UsingType>(
T)->getUnderlyingType();
3559 T = cast<ParenType>(
T)->getInnerType();
3561 case Type::MacroQualified:
3562 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3564 case Type::SubstTemplateTypeParm:
3565 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3568 case Type::DeducedTemplateSpecialization: {
3569 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3570 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3574 case Type::PackIndexing: {
3575 T = cast<PackIndexingType>(
T)->getSelectedType();
3578 case Type::Adjusted:
3581 T = cast<AdjustedType>(
T)->getAdjustedType();
3585 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3590llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3593 if (It != TypeCache.end()) {
3595 if (llvm::Metadata *
V = It->second)
3596 return cast<llvm::DIType>(
V);
3608 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3618llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3622 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3624 llvm::raw_string_ostream OS(Name);
3625 Ty.
print(OS, getPrintingPolicy());
3632 if (
auto *
T = getTypeOrNull(Ty))
3635 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3636 void *TyPtr = Ty.getAsOpaquePtr();
3639 TypeCache[TyPtr].reset(Res);
3644llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3646 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
3652 auto Info = Reader->getSourceDescriptor(Idx);
3654 return getOrCreateModuleRef(*Info,
true);
3655 }
else if (ClangModuleMap) {
3669 return getOrCreateModuleRef(Info,
false);
3672 return getOrCreateModuleRef(PCHDescriptor,
false);
3679llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3682 return CreateQualifiedType(Ty, Unit);
3686#define TYPE(Class, Base)
3687#define ABSTRACT_TYPE(Class, Base)
3688#define NON_CANONICAL_TYPE(Class, Base)
3689#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3690#include "clang/AST/TypeNodes.inc"
3691 llvm_unreachable(
"Dependent types cannot show up in debug information");
3693 case Type::ExtVector:
3695 return CreateType(cast<VectorType>(Ty), Unit);
3696 case Type::ConstantMatrix:
3697 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3698 case Type::ObjCObjectPointer:
3699 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3700 case Type::ObjCObject:
3701 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3702 case Type::ObjCTypeParam:
3703 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3704 case Type::ObjCInterface:
3705 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3707 return CreateType(cast<BuiltinType>(Ty));
3709 return CreateType(cast<ComplexType>(Ty));
3711 return CreateType(cast<PointerType>(Ty), Unit);
3712 case Type::BlockPointer:
3713 return CreateType(cast<BlockPointerType>(Ty), Unit);
3715 return CreateType(cast<TypedefType>(Ty), Unit);
3717 return CreateType(cast<RecordType>(Ty));
3719 return CreateEnumType(cast<EnumType>(Ty));
3720 case Type::FunctionProto:
3721 case Type::FunctionNoProto:
3722 return CreateType(cast<FunctionType>(Ty), Unit);
3723 case Type::ConstantArray:
3724 case Type::VariableArray:
3725 case Type::IncompleteArray:
3726 case Type::ArrayParameter:
3727 return CreateType(cast<ArrayType>(Ty), Unit);
3729 case Type::LValueReference:
3730 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3731 case Type::RValueReference:
3732 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3734 case Type::MemberPointer:
3735 return CreateType(cast<MemberPointerType>(Ty), Unit);
3738 return CreateType(cast<AtomicType>(Ty), Unit);
3741 return CreateType(cast<BitIntType>(Ty));
3743 return CreateType(cast<PipeType>(Ty), Unit);
3745 case Type::TemplateSpecialization:
3746 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3748 case Type::CountAttributed:
3750 case Type::Attributed:
3751 case Type::BTFTagAttributed:
3752 case Type::Adjusted:
3754 case Type::DeducedTemplateSpecialization:
3755 case Type::Elaborated:
3758 case Type::MacroQualified:
3759 case Type::SubstTemplateTypeParm:
3760 case Type::TypeOfExpr:
3762 case Type::Decltype:
3763 case Type::PackIndexing:
3764 case Type::UnaryTransform:
3768 llvm_unreachable(
"type should have been unwrapped!");
3771llvm::DICompositeType *
3772CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3775 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3780 if (
T && !
T->isForwardDecl())
3784 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3789 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
3792 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3797llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3801 StringRef RDName = getClassName(RD);
3803 llvm::DIFile *DefUnit =
nullptr;
3806 DefUnit = getOrCreateFile(
Loc);
3810 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3814 auto *
T = cast_or_null<llvm::DICompositeType>(
3823 return getOrCreateRecordFwdDecl(Ty, RDContext);
3836 auto Flags = llvm::DINode::FlagZero;
3837 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3839 Flags |= llvm::DINode::FlagTypePassByReference;
3841 Flags |= llvm::DINode::FlagTypePassByValue;
3844 if (!CXXRD->isTrivial())
3845 Flags |= llvm::DINode::FlagNonTrivial;
3848 if (CXXRD->isAnonymousStructOrUnion())
3849 Flags |= llvm::DINode::FlagExportSymbols;
3852 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3855 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
3856 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3862 switch (RealDecl->getTag()) {
3864 llvm_unreachable(
"invalid composite type tag");
3866 case llvm::dwarf::DW_TAG_array_type:
3867 case llvm::dwarf::DW_TAG_enumeration_type:
3876 case llvm::dwarf::DW_TAG_structure_type:
3877 case llvm::dwarf::DW_TAG_union_type:
3878 case llvm::dwarf::DW_TAG_class_type:
3881 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3885 RegionMap[Ty->
getDecl()].reset(RealDecl);
3888 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3889 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3890 CollectCXXTemplateParams(TSpecial, DefUnit));
3894void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3895 llvm::DICompositeType *RealDecl) {
3897 llvm::DIType *ContainingType =
nullptr;
3909 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3912 ContainingType = RealDecl;
3914 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3917llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3918 StringRef Name, uint64_t *Offset) {
3919 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3923 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3924 *Offset, llvm::DINode::FlagZero, FieldTy);
3925 *Offset += FieldSize;
3929void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3931 StringRef &LinkageName,
3932 llvm::DIScope *&FDContext,
3933 llvm::DINodeArray &TParamsArray,
3934 llvm::DINode::DIFlags &Flags) {
3936 Name = getFunctionName(FD);
3941 Flags |= llvm::DINode::FlagPrototyped;
3945 if (LinkageName == Name ||
3950 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
3951 LinkageName = StringRef();
3956 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
3960 FDContext = getOrCreateNamespace(NSDecl);
3963 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
3964 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
3970 Flags |= llvm::DINode::FlagNoReturn;
3972 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
3976void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
3978 StringRef &Name, StringRef &LinkageName,
3979 llvm::MDTuple *&TemplateParameters,
3980 llvm::DIScope *&VDContext) {
3989 llvm::APInt ConstVal(32, 1);
4000 if (LinkageName == Name)
4001 LinkageName = StringRef();
4003 if (isa<VarTemplateSpecializationDecl>(VD)) {
4004 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4005 TemplateParameters = parameterNodes.get();
4007 TemplateParameters =
nullptr;
4027 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4028 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4031llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4033 llvm::DINodeArray TParamsArray;
4034 StringRef Name, LinkageName;
4035 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4036 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4038 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4039 llvm::DIScope *DContext = Unit;
4040 unsigned Line = getLineNumber(
Loc);
4041 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4043 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4048 ArgTypes.push_back(Parm->getType());
4054 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4056 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4059 Flags |= getCallSiteRelatedAttrs();
4060 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4061 return DBuilder.createFunction(
4062 DContext, Name, LinkageName, Unit,
Line,
4063 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4064 TParamsArray.get(), getFunctionDeclaration(FD));
4067 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4068 DContext, Name, LinkageName, Unit,
Line,
4069 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4070 TParamsArray.get(), getFunctionDeclaration(FD));
4072 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4073 std::make_tuple(CanonDecl),
4074 std::make_tuple(SP));
4078llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4079 return getFunctionFwdDeclOrStub(GD,
false);
4082llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4083 return getFunctionFwdDeclOrStub(GD,
true);
4086llvm::DIGlobalVariable *
4087CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4089 StringRef Name, LinkageName;
4091 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4092 llvm::DIScope *DContext = Unit;
4093 unsigned Line = getLineNumber(
Loc);
4094 llvm::MDTuple *TemplateParameters =
nullptr;
4096 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4099 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4100 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4102 FwdDeclReplaceMap.emplace_back(
4103 std::piecewise_construct,
4105 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4109llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4114 if (
const auto *TD = dyn_cast<TypeDecl>(D))
4119 if (I != DeclCache.end()) {
4121 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4122 return GVE->getVariable();
4123 return cast<llvm::DINode>(N);
4130 if (IE != ImportedDeclCache.end()) {
4131 auto N = IE->second;
4132 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4133 return cast<llvm::DINode>(GVE);
4134 return dyn_cast_or_null<llvm::DINode>(N);
4139 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4140 return getFunctionForwardDeclaration(FD);
4141 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4142 return getGlobalVariableForwardDeclaration(VD);
4147llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4148 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4151 const auto *FD = dyn_cast<FunctionDecl>(D);
4156 auto *S = getDeclContextDescriptor(D);
4159 if (MI == SPCache.end()) {
4161 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4162 cast<llvm::DICompositeType>(S));
4165 if (MI != SPCache.end()) {
4166 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4167 if (SP && !SP->isDefinition())
4171 for (
auto *NextFD : FD->
redecls()) {
4172 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4173 if (MI != SPCache.end()) {
4174 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4175 if (SP && !SP->isDefinition())
4182llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4183 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4184 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4185 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4188 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4196 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4206 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4207 if (It == TypeCache.end())
4209 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4210 llvm::DISubprogram *FD = DBuilder.createFunction(
4211 InterfaceType, getObjCMethodName(OMD), StringRef(),
4212 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4213 DBuilder.finalizeSubprogram(FD);
4220llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4225 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4229 return DBuilder.createSubroutineType(
4230 DBuilder.getOrCreateTypeArray(std::nullopt));
4232 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
4233 return getOrCreateMethodType(Method, F);
4238 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4243 QualType ResultTy = OMethod->getReturnType();
4248 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4250 Elts.push_back(getOrCreateType(ResultTy, F));
4253 if (
auto *SelfDecl = OMethod->getSelfDecl())
4254 SelfDeclTy = SelfDecl->getType();
4255 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4258 if (!SelfDeclTy.
isNull())
4260 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4262 Elts.push_back(DBuilder.createArtificialType(
4265 for (
const auto *PI : OMethod->parameters())
4266 Elts.push_back(getOrCreateType(PI->getType(), F));
4268 if (OMethod->isVariadic())
4269 Elts.push_back(DBuilder.createUnspecifiedParameter());
4271 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4272 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4278 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4279 if (FD->isVariadic()) {
4281 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4282 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4284 EltTys.push_back(getOrCreateType(ParamType, F));
4285 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4286 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4287 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4291 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4300 CC = SrcFnTy->getCallConv();
4302 for (
const VarDecl *VD : Args)
4303 ArgTypes.push_back(VD->
getType());
4310 llvm::Function *Fn,
bool CurFuncIsThunk) {
4312 StringRef LinkageName;
4314 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4317 bool HasDecl = (D !=
nullptr);
4319 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4320 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4321 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4322 llvm::DIScope *FDContext = Unit;
4323 llvm::DINodeArray TParamsArray;
4326 LinkageName = Fn->getName();
4327 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4329 auto FI = SPCache.find(FD->getCanonicalDecl());
4330 if (FI != SPCache.end()) {
4331 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4332 if (SP && SP->isDefinition()) {
4333 LexicalBlockStack.emplace_back(SP);
4334 RegionMap[D].reset(SP);
4338 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4339 TParamsArray, Flags);
4340 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4341 Name = getObjCMethodName(OMD);
4342 Flags |= llvm::DINode::FlagPrototyped;
4343 }
else if (isa<VarDecl>(D) &&
4349 Name = Fn->getName();
4351 if (isa<BlockDecl>(D))
4354 Flags |= llvm::DINode::FlagPrototyped;
4356 if (Name.starts_with(
"\01"))
4357 Name = Name.substr(1);
4359 assert((!D || !isa<VarDecl>(D) ||
4361 "Unexpected DynamicInitKind !");
4364 isa<VarDecl>(D) || isa<CapturedDecl>(D)) {
4365 Flags |= llvm::DINode::FlagArtificial;
4371 Flags |= llvm::DINode::FlagThunk;
4373 if (Fn->hasLocalLinkage())
4374 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4376 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4378 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4379 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4380 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4382 const unsigned LineNo = getLineNumber(
Loc.
isValid() ?
Loc : CurLoc);
4383 unsigned ScopeLine = getLineNumber(ScopeLoc);
4384 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4385 llvm::DISubprogram *
Decl =
nullptr;
4386 llvm::DINodeArray Annotations =
nullptr;
4388 Decl = isa<ObjCMethodDecl>(D)
4389 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4390 : getFunctionDeclaration(D);
4391 Annotations = CollectBTFDeclTagAnnotations(D);
4399 llvm::DISubprogram *SP = DBuilder.createFunction(
4400 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4401 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4403 Fn->setSubprogram(SP);
4407 if (HasDecl && isa<FunctionDecl>(D))
4411 LexicalBlockStack.emplace_back(SP);
4414 RegionMap[D].reset(SP);
4418 QualType FnType, llvm::Function *Fn) {
4420 StringRef LinkageName;
4426 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4427 return GetName(D,
true);
4430 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4431 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4432 bool IsDeclForCallSite = Fn ?
true :
false;
4433 llvm::DIScope *FDContext =
4434 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4435 llvm::DINodeArray TParamsArray;
4436 if (isa<FunctionDecl>(D)) {
4438 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4439 TParamsArray, Flags);
4440 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4441 Name = getObjCMethodName(OMD);
4442 Flags |= llvm::DINode::FlagPrototyped;
4444 llvm_unreachable(
"not a function or ObjC method");
4446 if (!Name.empty() && Name[0] ==
'\01')
4447 Name = Name.substr(1);
4450 Flags |= llvm::DINode::FlagArtificial;
4455 unsigned LineNo = getLineNumber(
Loc);
4456 unsigned ScopeLine = 0;
4457 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4459 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4461 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4462 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4463 llvm::DISubprogram *SP = DBuilder.createFunction(
4464 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4465 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4471 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4472 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4475 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4476 DBuilder.createParameterVariable(
4477 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4478 llvm::DINode::FlagZero, ParamAnnotations);
4484 if (IsDeclForCallSite)
4485 Fn->setSubprogram(SP);
4487 DBuilder.finalizeSubprogram(SP);
4495 auto *
Func = CallOrInvoke->getCalledFunction();
4498 if (
Func->getSubprogram())
4503 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4504 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4515 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4517 auto FI = SPCache.find(FD->getCanonicalDecl());
4518 llvm::DISubprogram *SP =
nullptr;
4519 if (FI != SPCache.end())
4520 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4521 if (!SP || !SP->isDefinition())
4522 SP = getFunctionStub(GD);
4523 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4524 LexicalBlockStack.emplace_back(SP);
4530 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4539 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4542 llvm::MDNode *
Scope = LexicalBlockStack.back();
4543 Builder.SetCurrentDebugLocation(
4544 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4545 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4549 llvm::MDNode *Back =
nullptr;
4550 if (!LexicalBlockStack.empty())
4551 Back = LexicalBlockStack.back().get();
4552 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4553 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4554 getColumnNumber(CurLoc)));
4557void CGDebugInfo::AppendAddressSpaceXDeref(
4559 std::optional<unsigned> DWARFAddressSpace =
4561 if (!DWARFAddressSpace)
4564 Expr.push_back(llvm::dwarf::DW_OP_constu);
4565 Expr.push_back(*DWARFAddressSpace);
4566 Expr.push_back(llvm::dwarf::DW_OP_swap);
4567 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4576 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4578 LexicalBlockStack.back(), CurInlinedAt));
4580 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4584 CreateLexicalBlock(
Loc);
4589 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4594 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4597 LexicalBlockStack.pop_back();
4601 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4602 unsigned RCount = FnBeginRegionCount.back();
4603 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4606 while (LexicalBlockStack.size() != RCount) {
4609 LexicalBlockStack.pop_back();
4611 FnBeginRegionCount.pop_back();
4613 if (Fn && Fn->getSubprogram())
4614 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4617CGDebugInfo::BlockByRefType
4618CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4619 uint64_t *XOffset) {
4622 uint64_t FieldSize, FieldOffset;
4623 uint32_t FieldAlign;
4625 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4630 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4631 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4633 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4634 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4637 if (HasCopyAndDispose) {
4640 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4642 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4644 bool HasByrefExtendedLayout;
4647 HasByrefExtendedLayout) &&
4648 HasByrefExtendedLayout) {
4651 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4660 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4663 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4666 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4671 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4675 *XOffset = FieldOffset;
4676 llvm::DIType *FieldTy = DBuilder.createMemberType(
4677 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4678 llvm::DINode::FlagZero, WrappedTy);
4679 EltTys.push_back(FieldTy);
4680 FieldOffset += FieldSize;
4682 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4683 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4684 llvm::DINode::FlagZero,
nullptr, Elements),
4688llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4689 llvm::Value *Storage,
4690 std::optional<unsigned> ArgNo,
4692 const bool UsePointerValue) {
4694 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4695 if (VD->
hasAttr<NoDebugAttr>())
4701 llvm::DIFile *Unit =
nullptr;
4706 if (VD->
hasAttr<BlocksAttr>())
4707 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4709 Ty = getOrCreateType(VD->
getType(), Unit);
4724 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4726 Flags |= llvm::DINode::FlagArtificial;
4731 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4735 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4738 Flags |= llvm::DINode::FlagObjectPointer;
4745 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4746 StringRef Name = VD->
getName();
4747 if (!Name.empty()) {
4753 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4758 Expr.push_back(llvm::dwarf::DW_OP_deref);
4759 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4764 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4776 for (
const auto *Field : RD->
fields()) {
4777 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4778 StringRef FieldName =
Field->getName();
4781 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4786 auto *D = DBuilder.createAutoVariable(
4788 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4791 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4795 Builder.GetInsertBlock());
4803 if (UsePointerValue) {
4804 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4805 "Debug info already contains DW_OP_deref.");
4806 Expr.push_back(llvm::dwarf::DW_OP_deref);
4810 llvm::DILocalVariable *D =
nullptr;
4812 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4813 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit,
Line, Ty,
4824 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4827 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4830 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4831 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4832 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4835 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4841 if (
Iter != CoroutineParameterMappings.end()) {
4843 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4844 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4846 if (Iter2 != ParamDbgMappings.end())
4847 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4853 D = RemapCoroArgToLocalVar();
4856 D = DBuilder.createAutoVariable(
Scope, Name, Unit,
Line, Ty,
4860 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4863 Builder.GetInsertBlock());
4868llvm::DIType *CGDebugInfo::CreateBindingDeclType(
const BindingDecl *BD) {
4869 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4874 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4875 if (FD->isBitField()) {
4892 llvm::DIType *Ty = getOrCreateType(FinalTy, Unit);
4899 return getOrCreateType(BD->
getType(), Unit);
4902llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4903 llvm::Value *Storage,
4904 std::optional<unsigned> ArgNo,
4906 const bool UsePointerValue) {
4908 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4909 if (BD->
hasAttr<NoDebugAttr>())
4916 llvm::DIType *Ty = CreateBindingDeclType(BD);
4927 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4932 if (UsePointerValue) {
4933 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4934 "Debug info already contains DW_OP_deref.");
4935 Expr.push_back(llvm::dwarf::DW_OP_deref);
4940 StringRef Name = BD->
getName();
4941 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4942 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4944 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
4946 llvm::DINode::FlagZero, Align);
4949 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4950 const unsigned fieldIndex = FD->getFieldIndex();
4957 if (fieldOffset != 0) {
4963 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4969 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
4970 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
4971 const uint64_t value = IL->getValue().getZExtValue();
4975 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4984 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4987 Builder.GetInsertBlock());
4992llvm::DILocalVariable *
4995 const bool UsePointerValue) {
4998 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
4999 for (
auto *B : DD->bindings()) {
5000 EmitDeclare(B, Storage, std::nullopt, Builder,
5008 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5013 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5015 if (D->
hasAttr<NoDebugAttr>())
5018 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5019 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5025 StringRef Name = D->
getName();
5032 DBuilder.insertLabel(L,
5034 Scope, CurInlinedAt),
5035 Builder.GetInsertBlock());
5038llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5040 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5043 return DBuilder.createObjectPointerType(Ty);
5048 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5050 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5052 if (Builder.GetInsertBlock() ==
nullptr)
5054 if (VD->
hasAttr<NoDebugAttr>())
5057 bool isByRef = VD->
hasAttr<BlocksAttr>();
5059 uint64_t XOffset = 0;
5060 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5063 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5065 Ty = getOrCreateType(VD->
getType(), Unit);
5069 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5071 Ty = CreateSelfType(VD->
getType(), Ty);
5074 const unsigned Line =
5085 addr.push_back(llvm::dwarf::DW_OP_deref);
5086 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5089 addr.push_back(llvm::dwarf::DW_OP_deref);
5090 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5095 addr.push_back(llvm::dwarf::DW_OP_deref);
5096 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5104 auto *D = DBuilder.createAutoVariable(
5105 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5106 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5110 LexicalBlockStack.back(), CurInlinedAt);
5111 auto *
Expr = DBuilder.createExpression(addr);
5113 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint);
5115 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5118llvm::DILocalVariable *
5121 bool UsePointerValue) {
5123 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5127struct BlockLayoutChunk {
5128 uint64_t OffsetInBits;
5131bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5132 return l.OffsetInBits < r.OffsetInBits;
5136void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5138 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5145 BlockLayout.getElementOffsetInBits(0),
5148 BlockLayout.getElementOffsetInBits(1),
5152 BlockLayout.getElementOffsetInBits(0),
5155 BlockLayout.getElementOffsetInBits(1),
5159 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5160 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5162 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType,
Loc,
AS_public,
5163 BlockLayout.getElementOffsetInBits(3),
5165 Fields.push_back(createFieldType(
5170 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5177 llvm::AllocaInst *Alloca,
5185 llvm::DIFile *tunit = getOrCreateFile(loc);
5186 unsigned line = getLineNumber(loc);
5187 unsigned column = getColumnNumber(loc);
5192 const llvm::StructLayout *blockLayout =
5196 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5205 BlockLayoutChunk chunk;
5206 chunk.OffsetInBits =
5207 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5208 chunk.Capture =
nullptr;
5209 chunks.push_back(chunk);
5213 for (
const auto &capture :
blockDecl->captures()) {
5214 const VarDecl *variable = capture.getVariable();
5221 BlockLayoutChunk chunk;
5222 chunk.OffsetInBits =
5223 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5224 chunk.Capture = &capture;
5225 chunks.push_back(chunk);
5229 llvm::array_pod_sort(chunks.begin(), chunks.end());
5231 for (
const BlockLayoutChunk &Chunk : chunks) {
5232 uint64_t offsetInBits = Chunk.OffsetInBits;
5239 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5241 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5244 llvm_unreachable(
"unexpected block declcontext");
5246 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5247 offsetInBits, tunit, tunit));
5252 StringRef name = variable->
getName();
5254 llvm::DIType *fieldType;
5256 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5261 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5262 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5263 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5264 PtrInfo.
Width, Align, offsetInBits,
5265 llvm::DINode::FlagZero, fieldType);
5269 offsetInBits, Align, tunit, tunit);
5271 fields.push_back(fieldType);
5275 llvm::raw_svector_ostream(typeName)
5278 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5280 llvm::DIType *
type =
5281 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5283 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5287 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5288 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5291 auto *debugVar = DBuilder.createParameterVariable(
5292 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5295 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5297 column, scope, CurInlinedAt),
5298 Builder.GetInsertBlock());
5301llvm::DIDerivedType *
5302CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5307 if (MI != StaticDataMemberCache.end()) {
5308 assert(MI->second &&
"Static data member declaration should still exist");
5315 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
5316 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
5319llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5320 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5321 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5322 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5324 for (
const auto *Field : RD->
fields()) {
5325 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5326 StringRef FieldName = Field->getName();
5329 if (FieldName.empty()) {
5330 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5331 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5336 GVE = DBuilder.createGlobalVariableExpression(
5337 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5338 Var->hasLocalLinkage());
5339 Var->addDebugInfo(GVE);
5351 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5356 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5364 case TemplateArgument::Pack:
5365 return ReferencesAnonymousEntity(TA.getPackAsArray());
5366 case TemplateArgument::Type: {
5367 struct ReferencesAnonymous
5368 : public RecursiveASTVisitor<ReferencesAnonymous> {
5369 bool RefAnon = false;
5370 bool VisitRecordType(RecordType *RT) {
5371 if (ReferencesAnonymousEntity(RT)) {
5378 ReferencesAnonymous RT;
5379 RT.TraverseType(TA.getAsType());
5392 bool Reconstitutable =
true;
5394 Reconstitutable =
false;
5398 Reconstitutable =
false;
5401 bool VisitType(
Type *
T) {
5405 Reconstitutable =
false;
5410 bool TraverseEnumType(
EnumType *ET) {
5413 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5415 Reconstitutable =
false;
5419 Reconstitutable =
false;
5429 return Reconstitutable;
5433 Reconstitutable =
false;
5443 ReconstitutableType
T;
5445 return T.Reconstitutable;
5448bool CGDebugInfo::HasReconstitutableArgs(
5452 case TemplateArgument::Template:
5459 case TemplateArgument::Declaration:
5468 case TemplateArgument::NullPtr:
5472 case TemplateArgument::Pack:
5475 return HasReconstitutableArgs(TA.getPackAsArray());
5476 case TemplateArgument::Integral:
5481 return TA.getAsIntegral().getBitWidth() <= 64 &&
5482 IsReconstitutableType(TA.getIntegralType());
5483 case TemplateArgument::StructuralValue:
5485 case TemplateArgument::Type:
5486 return IsReconstitutableType(TA.getAsType());
5487 case TemplateArgument::Expression:
5488 return IsReconstitutableType(TA.getAsExpr()->getType());
5490 llvm_unreachable(
"Other, unresolved, template arguments should "
5491 "not be seen here");
5496std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5498 llvm::raw_string_ostream OS(Name);
5499 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5502 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5506 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5508 std::optional<TemplateArgs> Args;
5510 bool IsOperatorOverload =
false;
5511 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5512 Args = GetTemplateArgs(RD);
5513 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5514 Args = GetTemplateArgs(FD);
5516 IsOperatorOverload |=
5519 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5520 Args = GetTemplateArgs(VD);
5544 bool Reconstitutable =
5545 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5549 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5553 bool Mangled = TemplateNamesKind ==
5554 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5560 std::string EncodedOriginalName;
5561 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5569 std::string CanonicalOriginalName;
5570 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5572 assert(EncodedOriginalNameOS.str() == OriginalOS.str());
5582 if (D->
hasAttr<NoDebugAttr>())
5585 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5586 return GetName(D,
true);
5592 if (Cached != DeclCache.end())
5593 return Var->addDebugInfo(
5594 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5597 llvm::DIFile *Unit =
nullptr;
5598 llvm::DIScope *DContext =
nullptr;
5600 StringRef DeclName, LinkageName;
5602 llvm::MDTuple *TemplateParameters =
nullptr;
5603 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5604 TemplateParameters, DContext);
5608 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5616 "unnamed non-anonymous struct or union?");
5617 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5624 if (D->
hasAttr<CUDASharedAttr>())
5627 else if (D->
hasAttr<CUDAConstantAttr>())
5631 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5633 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5634 GVE = DBuilder.createGlobalVariableExpression(
5635 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5636 Var->hasLocalLinkage(),
true,
5637 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5638 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5639 Align, Annotations);
5640 Var->addDebugInfo(GVE);
5647 if (VD->
hasAttr<NoDebugAttr>())
5649 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5650 return GetName(VD,
true);
5655 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5656 StringRef Name = VD->
getName();
5657 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5659 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5660 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5661 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5674 llvm::DIType *EDTy =
5676 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5687 auto *VarD = dyn_cast<VarDecl>(VD);
5688 if (VarD && VarD->isStaticDataMember()) {
5689 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5690 getDeclContextDescriptor(VarD);
5695 RetainedTypes.push_back(
5700 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5702 auto &GV = DeclCache[VD];
5706 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
5707 llvm::MDTuple *TemplateParameters =
nullptr;
5709 if (isa<VarTemplateSpecializationDecl>(VD))
5711 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5712 TemplateParameters = parameterNodes.get();
5715 GV.reset(DBuilder.createGlobalVariableExpression(
5716 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5717 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5718 TemplateParameters, Align));
5724 if (D->
hasAttr<NoDebugAttr>())
5728 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5729 StringRef Name = D->
getName();
5730 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
5732 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5733 llvm::DIGlobalVariableExpression *GVE =
5734 DBuilder.createGlobalVariableExpression(
5735 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
5736 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5737 Var->addDebugInfo(GVE);
5748 const auto *D = cast<ValueDecl>(GD.
getDecl());
5749 if (D->
hasAttr<NoDebugAttr>())
5767 if (!(DI = getDeclarationOrDefinition(
5768 AliaseeDecl.getCanonicalDecl().getDecl())))
5771 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5774 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5775 DContext, DI, getOrCreateFile(
Loc), getLineNumber(
Loc), D->getName());
5788 llvm::DIFile *
File = getOrCreateFile(
Loc);
5789 llvm::DIGlobalVariableExpression *Debug =
5790 DBuilder.createGlobalVariableExpression(
5791 nullptr, StringRef(), StringRef(), getOrCreateFile(
Loc),
5792 getLineNumber(
Loc), getOrCreateType(S->getType(),
File),
true);
5793 GV->addDebugInfo(Debug);
5796llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
5797 if (!LexicalBlockStack.empty())
5798 return LexicalBlockStack.back();
5799 llvm::DIScope *Mod = getParentModuleOrNull(D);
5800 return getContextDescriptor(D, Mod ? Mod : TheCU);
5812 DBuilder.createImportedModule(
5814 getOrCreateNamespace(NSDecl), getOrCreateFile(
Loc), getLineNumber(
Loc));
5819 if (llvm::DINode *
Target =
5822 DBuilder.createImportedDeclaration(
5824 getOrCreateFile(
Loc), getLineNumber(
Loc));
5832 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5834 for (
const auto *USD : UD.
shadows()) {
5839 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5840 if (
const auto *AT = FD->getType()
5843 if (AT->getDeducedType().isNull())
5857 "We shouldn't be codegening an invalid UsingEnumDecl"
5858 " containing no decls");
5860 for (
const auto *USD : UD.
shadows())
5865 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5867 if (
Module *M = ID.getImportedModule()) {
5869 auto Loc = ID.getLocation();
5870 DBuilder.createImportedDeclaration(
5871 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
5872 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(
Loc),
5873 getLineNumber(
Loc));
5877llvm::DIImportedEntity *
5881 auto &VH = NamespaceAliasCache[&NA];
5883 return cast<llvm::DIImportedEntity>(VH);
5884 llvm::DIImportedEntity *R;
5886 if (
const auto *Underlying =
5889 R = DBuilder.createImportedDeclaration(
5894 R = DBuilder.createImportedDeclaration(
5903CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
5907 auto I = NamespaceCache.find(NSDecl);
5908 if (I != NamespaceCache.end())
5909 return cast<llvm::DINamespace>(I->second);
5911 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
5913 llvm::DINamespace *NS =
5914 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
5915 NamespaceCache[NSDecl].reset(NS);
5920 assert(TheCU &&
"no main compile unit");
5921 TheCU->setDWOId(Signature);
5927 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
5928 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
5929 llvm::DIType *Ty = E.Type->getDecl()->getDefinition()
5930 ? CreateTypeDefinition(E.Type, E.Unit)
5932 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
5936 for (
const auto &
P : ObjCMethodCache) {
5937 if (
P.second.empty())
5940 QualType QTy(
P.first->getTypeForDecl(), 0);
5942 assert(It != TypeCache.end());
5944 llvm::DICompositeType *InterfaceDecl =
5945 cast<llvm::DICompositeType>(It->second);
5947 auto CurElts = InterfaceDecl->getElements();
5951 for (
auto &SubprogramDirect :
P.second)
5952 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
5953 EltTys.push_back(SubprogramDirect.getPointer());
5955 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5956 DBuilder.replaceArrays(InterfaceDecl, Elements);
5959 for (
const auto &
P : ReplaceMap) {
5961 auto *Ty = cast<llvm::DIType>(
P.second);
5962 assert(Ty->isForwardDecl());
5964 auto It = TypeCache.find(
P.first);
5965 assert(It != TypeCache.end());
5968 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
5969 cast<llvm::DIType>(It->second));
5972 for (
const auto &
P : FwdDeclReplaceMap) {
5974 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
5975 llvm::Metadata *Repl;
5977 auto It = DeclCache.find(
P.first);
5981 if (It == DeclCache.end())
5986 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
5987 Repl = GVE->getVariable();
5988 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
5993 for (
auto &RT : RetainedTypes)
5994 if (
auto MD = TypeCache[RT])
5995 DBuilder.retainType(cast<llvm::DIType>(MD));
5997 DBuilder.finalize();
6003 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6004 DBuilder.retainType(DieTy);
6009 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6010 DBuilder.retainType(DieTy);
6014 if (LexicalBlockStack.empty())
6015 return llvm::DebugLoc();
6017 llvm::MDNode *
Scope = LexicalBlockStack.back();
6022llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6026 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6027 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6028 return llvm::DINode::FlagZero;
6033 bool SupportsDWARFv4Ext =
6035 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6036 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6038 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6039 return llvm::DINode::FlagZero;
6041 return llvm::DINode::FlagAllCallsDescribed;
6052 return DBuilder.createConstantValueExpression(
6053 Val.
getFloat().bitcastToAPInt().getZExtValue());
6058 llvm::APSInt
const &ValInt = Val.
getInt();
6059 std::optional<uint64_t> ValIntOpt;
6060 if (ValInt.isUnsigned())
6061 ValIntOpt = ValInt.tryZExtValue();
6062 else if (
auto tmp = ValInt.trySExtValue())
6065 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6068 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 llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static 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
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.
ArrayRef< NamedDecl * > asArray()
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
Represents a declaration of a type.
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 isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
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.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
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.