39#include "llvm/ADT/DenseSet.h"
40#include "llvm/ADT/SmallVector.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/IR/Constants.h"
43#include "llvm/IR/DataLayout.h"
44#include "llvm/IR/DerivedTypes.h"
45#include "llvm/IR/Instructions.h"
46#include "llvm/IR/Intrinsics.h"
47#include "llvm/IR/Metadata.h"
48#include "llvm/IR/Module.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/MD5.h"
51#include "llvm/Support/Path.h"
52#include "llvm/Support/SHA1.h"
53#include "llvm/Support/SHA256.h"
54#include "llvm/Support/TimeProfiler.h"
73 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
74 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
75 DBuilder(CGM.getModule()) {
80 assert(LexicalBlockStack.empty() &&
81 "Region stack mismatch, stack not empty!");
87 init(TemporaryLocation);
94 init(TemporaryLocation, DefaultToEmpty);
98 bool DefaultToEmpty) {
105 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
107 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
110 if (TemporaryLocation.
isValid()) {
111 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
115 if (DefaultToEmpty) {
116 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
121 assert(!DI->LexicalBlockStack.empty());
122 CGF->
Builder.SetCurrentDebugLocation(
123 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
124 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
138 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
140 CGF.
Builder.SetCurrentDebugLocation(std::move(Loc));
147 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
158 SavedLocation = DI.getLocation();
159 assert((DI.getInlinedAt() ==
160 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
161 "CGDebugInfo and IRBuilder are out of sync");
163 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
171 DI.EmitLocation(CGF->
Builder, SavedLocation);
184 if (LexicalBlockStack.empty())
188 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
190 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
193 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
194 LexicalBlockStack.pop_back();
195 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
196 LBF->getScope(), getOrCreateFile(CurLoc)));
197 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
198 isa<llvm::DISubprogram>(
Scope)) {
199 LexicalBlockStack.pop_back();
200 LexicalBlockStack.emplace_back(
201 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
205llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
206 llvm::DIScope *Mod = getParentModuleOrNull(D);
211llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
216 auto I = RegionMap.find(Context);
217 if (I != RegionMap.end()) {
218 llvm::Metadata *
V = I->second;
219 return dyn_cast_or_null<llvm::DIScope>(
V);
223 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
224 return getOrCreateNamespace(NSDecl);
226 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
227 if (!RDecl->isDependentType())
261StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
262 return internString(GetName(FD));
265StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
267 llvm::raw_svector_ostream OS(MethodName);
270 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
271 OS << OID->getName();
272 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
273 OS << OID->getName();
274 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
275 if (OC->IsClassExtension()) {
276 OS << OC->getClassInterface()->getName();
278 OS << OC->getIdentifier()->getNameStart() <<
'('
279 << OC->getIdentifier()->getNameStart() <<
')';
281 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
282 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
286 return internString(OS.str());
289StringRef CGDebugInfo::getSelectorName(
Selector S) {
290 return internString(S.getAsString());
293StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
294 if (isa<ClassTemplateSpecializationDecl>(RD)) {
296 return internString(GetName(RD));
302 return II->getName();
310 "Typedef should not be in another decl context!");
311 assert(D->getDeclName().getAsIdentifierInfo() &&
312 "Typedef was not named!");
313 return D->getDeclName().getAsIdentifierInfo()->getName();
323 Name = DD->getName();
328 Name = TND->getName();
331 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
332 if (CXXRD->isLambda())
340 return internString(UnnamedType);
348std::optional<llvm::DIFile::ChecksumKind>
357 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
361 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
364 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
365 return llvm::DIFile::CSK_MD5;
367 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
368 return llvm::DIFile::CSK_SHA1;
370 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
371 return llvm::DIFile::CSK_SHA256;
373 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
376std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
381 bool SourceInvalid =
false;
382 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
394 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
400 FileName = TheCU->getFile()->getFilename();
401 CSInfo = TheCU->getFile()->getChecksum();
407 FileName = TheCU->getFile()->getFilename();
415 auto It = DIFileCache.find(
FileName.data());
416 if (It != DIFileCache.end()) {
418 if (llvm::Metadata *
V = It->second)
419 return cast<llvm::DIFile>(
V);
425 std::optional<llvm::DIFile::ChecksumKind> CSKind =
426 computeChecksum(FID, Checksum);
428 CSInfo.emplace(*CSKind, Checksum);
430 return createFile(
FileName, CSInfo, getSource(
SM,
SM.getFileID(Loc)));
433llvm::DIFile *CGDebugInfo::createFile(
435 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
436 std::optional<StringRef> Source) {
440 std::string CurDir =
remapDIPath(getCurrentDirname());
443 if (llvm::sys::path::is_absolute(RemappedFile)) {
446 auto FileIt = llvm::sys::path::begin(RemappedFile);
447 auto FileE = llvm::sys::path::end(RemappedFile);
448 auto CurDirIt = llvm::sys::path::begin(CurDir);
449 auto CurDirE = llvm::sys::path::end(CurDir);
450 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
451 llvm::sys::path::append(DirBuf, *CurDirIt);
452 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
458 for (; FileIt != FileE; ++FileIt)
459 llvm::sys::path::append(FileBuf, *FileIt);
464 if (!llvm::sys::path::is_absolute(
FileName))
468 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
469 DIFileCache[
FileName.data()].reset(F);
476 if (llvm::sys::path::replace_path_prefix(
P, From, To))
478 return P.str().str();
485 return SM.getPresumedLoc(Loc).getLine();
488unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
501StringRef CGDebugInfo::getCurrentDirname() {
505 if (!CWDName.empty())
507 llvm::ErrorOr<std::string> CWD =
511 return CWDName = internString(*CWD);
514void CGDebugInfo::CreateCompileUnit() {
516 std::optional<llvm::DIFile::ChecksumKind> CSKind;
517 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
530 std::string MainFileName = CGO.MainFileName;
531 if (MainFileName.empty())
532 MainFileName =
"<stdin>";
538 std::string MainFileDir;
540 SM.getFileEntryRefForID(
SM.getMainFileID())) {
541 MainFileDir = std::string(MainFile->getDir().getName());
542 if (!llvm::sys::path::is_absolute(MainFileName)) {
544 llvm::sys::path::Style Style =
547 ? llvm::sys::path::Style::windows_backslash
548 : llvm::sys::path::Style::posix)
549 : llvm::sys::path::Style::native;
550 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
551 MainFileName = std::string(
552 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
559 if (MainFile->getName() == MainFileName &&
561 MainFile->getName().rsplit(
'.').second)
563 MainFileName = CGM.
getModule().getName().str();
565 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
569 llvm::dwarf::SourceLanguage LangTag;
572 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
573 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
574 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
575 else if (LO.CPlusPlus14)
576 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
577 else if (LO.CPlusPlus11)
578 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
580 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
581 }
else if (LO.ObjC) {
582 LangTag = llvm::dwarf::DW_LANG_ObjC;
583 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
585 LangTag = llvm::dwarf::DW_LANG_OpenCL;
586 }
else if (LO.RenderScript) {
587 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
588 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
589 LangTag = llvm::dwarf::DW_LANG_C11;
591 LangTag = llvm::dwarf::DW_LANG_C99;
593 LangTag = llvm::dwarf::DW_LANG_C89;
599 unsigned RuntimeVers = 0;
603 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
605 case llvm::codegenoptions::NoDebugInfo:
606 case llvm::codegenoptions::LocTrackingOnly:
607 EmissionKind = llvm::DICompileUnit::NoDebug;
609 case llvm::codegenoptions::DebugLineTablesOnly:
610 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
612 case llvm::codegenoptions::DebugDirectivesOnly:
613 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
615 case llvm::codegenoptions::DebugInfoConstructor:
616 case llvm::codegenoptions::LimitedDebugInfo:
617 case llvm::codegenoptions::FullDebugInfo:
618 case llvm::codegenoptions::UnusedTypeInfo:
619 EmissionKind = llvm::DICompileUnit::FullDebug;
630 CSInfo.emplace(*CSKind, Checksum);
631 llvm::DIFile *CUFile = DBuilder.createFile(
633 getSource(
SM,
SM.getMainFileID()));
635 StringRef Sysroot, SDK;
636 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
638 auto B = llvm::sys::path::rbegin(Sysroot);
639 auto E = llvm::sys::path::rend(Sysroot);
641 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
646 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
647 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
648 CGOpts.DebugNameTable);
650 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
652 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
655 TheCU = DBuilder.createCompileUnit(
656 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
657 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
658 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
659 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
660 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
663llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
667#define BUILTIN_TYPE(Id, SingletonId)
668#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
669#include "clang/AST/BuiltinTypes.def"
670 case BuiltinType::Dependent:
671 llvm_unreachable(
"Unexpected builtin type");
672 case BuiltinType::NullPtr:
673 return DBuilder.createNullPtrType();
674 case BuiltinType::Void:
676 case BuiltinType::ObjCClass:
679 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
680 "objc_class", TheCU, TheCU->getFile(), 0);
682 case BuiltinType::ObjCId: {
693 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
694 "objc_class", TheCU, TheCU->getFile(), 0);
698 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
700 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
701 0, 0, llvm::DINode::FlagZero,
nullptr,
702 llvm::DINodeArray());
704 DBuilder.replaceArrays(
705 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
706 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
707 llvm::DINode::FlagZero, ISATy)));
710 case BuiltinType::ObjCSel: {
712 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
713 "objc_selector", TheCU,
714 TheCU->getFile(), 0);
718#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
719 case BuiltinType::Id: \
720 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
722#include "clang/Basic/OpenCLImageTypes.def"
723 case BuiltinType::OCLSampler:
724 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
725 case BuiltinType::OCLEvent:
726 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
727 case BuiltinType::OCLClkEvent:
728 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
729 case BuiltinType::OCLQueue:
730 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
731 case BuiltinType::OCLReserveID:
732 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
733#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
734 case BuiltinType::Id: \
735 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
736#include "clang/Basic/OpenCLExtensionTypes.def"
738#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
739#include "clang/Basic/AArch64SVEACLETypes.def"
743 BT->
getKind() == BuiltinType::SveCount
747 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
754 "Unsupported number of vectors for svcount_t");
758 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
764 llvm::Metadata *LowerBound, *UpperBound;
765 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
767 if (Info.
EC.isScalable()) {
768 unsigned NumElemsPerVG = NumElems / 2;
770 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
771 46, 0, llvm::dwarf::DW_OP_mul,
772 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
773 UpperBound = DBuilder.createExpression(
Expr);
775 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
778 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
779 nullptr, LowerBound, UpperBound,
nullptr);
780 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
781 llvm::DIType *ElemTy =
782 getOrCreateType(Info.
ElementType, TheCU->getFile());
784 return DBuilder.createVectorType( 0, Align, ElemTy,
789#define PPC_VECTOR_TYPE(Name, Id, size) \
790 case BuiltinType::Id:
791#include "clang/Basic/PPCTypes.def"
794#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
795#include "clang/Basic/RISCVVTypes.def"
800 unsigned ElementCount = Info.
EC.getKnownMinValue();
803 bool Fractional =
false;
805 unsigned FixedSize = ElementCount * SEW;
809 }
else if (FixedSize < 64) {
812 LMUL = 64 / FixedSize;
814 LMUL = FixedSize / 64;
822 {llvm::dwarf::DW_OP_bregx,
825 llvm::dwarf::DW_OP_constu,
827 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
829 Expr.push_back(llvm::dwarf::DW_OP_div);
831 Expr.push_back(llvm::dwarf::DW_OP_mul);
833 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
836 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
838 auto *UpperBound = DBuilder.createExpression(
Expr);
839 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
840 nullptr, LowerBound, UpperBound,
nullptr);
841 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
842 llvm::DIType *ElemTy =
843 getOrCreateType(Info.
ElementType, TheCU->getFile());
846 return DBuilder.createVectorType(0, Align, ElemTy,
850#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
851 case BuiltinType::Id: { \
854 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
855 MangledName, TheCU, TheCU->getFile(), 0); \
856 return SingletonId; \
858#include "clang/Basic/WebAssemblyReferenceTypes.def"
860 case BuiltinType::UChar:
861 case BuiltinType::Char_U:
862 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
864 case BuiltinType::Char_S:
865 case BuiltinType::SChar:
866 Encoding = llvm::dwarf::DW_ATE_signed_char;
868 case BuiltinType::Char8:
869 case BuiltinType::Char16:
870 case BuiltinType::Char32:
873 case BuiltinType::UShort:
874 case BuiltinType::UInt:
875 case BuiltinType::UInt128:
876 case BuiltinType::ULong:
877 case BuiltinType::WChar_U:
878 case BuiltinType::ULongLong:
879 Encoding = llvm::dwarf::DW_ATE_unsigned;
881 case BuiltinType::Short:
882 case BuiltinType::Int:
883 case BuiltinType::Int128:
884 case BuiltinType::Long:
885 case BuiltinType::WChar_S:
886 case BuiltinType::LongLong:
887 Encoding = llvm::dwarf::DW_ATE_signed;
889 case BuiltinType::Bool:
890 Encoding = llvm::dwarf::DW_ATE_boolean;
892 case BuiltinType::Half:
893 case BuiltinType::Float:
894 case BuiltinType::LongDouble:
895 case BuiltinType::Float16:
896 case BuiltinType::BFloat16:
897 case BuiltinType::Float128:
898 case BuiltinType::Double:
899 case BuiltinType::Ibm128:
905 Encoding = llvm::dwarf::DW_ATE_float;
907 case BuiltinType::ShortAccum:
908 case BuiltinType::Accum:
909 case BuiltinType::LongAccum:
910 case BuiltinType::ShortFract:
911 case BuiltinType::Fract:
912 case BuiltinType::LongFract:
913 case BuiltinType::SatShortFract:
914 case BuiltinType::SatFract:
915 case BuiltinType::SatLongFract:
916 case BuiltinType::SatShortAccum:
917 case BuiltinType::SatAccum:
918 case BuiltinType::SatLongAccum:
919 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
921 case BuiltinType::UShortAccum:
922 case BuiltinType::UAccum:
923 case BuiltinType::ULongAccum:
924 case BuiltinType::UShortFract:
925 case BuiltinType::UFract:
926 case BuiltinType::ULongFract:
927 case BuiltinType::SatUShortAccum:
928 case BuiltinType::SatUAccum:
929 case BuiltinType::SatULongAccum:
930 case BuiltinType::SatUShortFract:
931 case BuiltinType::SatUFract:
932 case BuiltinType::SatULongFract:
933 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
940 return DBuilder.createBasicType(BTName, Size, Encoding);
943llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
945 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
947 ? llvm::dwarf::DW_ATE_unsigned
948 : llvm::dwarf::DW_ATE_signed;
954llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
956 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
958 Encoding = llvm::dwarf::DW_ATE_lo_user;
961 return DBuilder.createBasicType(
"complex", Size, Encoding);
975 return llvm::dwarf::DW_TAG_const_type;
979 return llvm::dwarf::DW_TAG_volatile_type;
983 return llvm::dwarf::DW_TAG_restrict_type;
985 return (llvm::dwarf::Tag)0;
988llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
989 llvm::DIFile *Unit) {
999 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1000 return getOrCreateType(
QualType(
T, 0), Unit);
1007 return DBuilder.createQualifiedType(Tag, FromTy);
1011 llvm::DIFile *Unit) {
1020 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1031 return DBuilder.createQualifiedType(Tag, FromTy);
1035 llvm::DIFile *Unit) {
1043 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1047llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1048 llvm::DIFile *Unit) {
1049 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1055 switch (TheCU->getSourceLanguage()) {
1056 case llvm::dwarf::DW_LANG_C_plus_plus:
1057 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1058 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1060 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1061 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1089 llvm::DICompileUnit *TheCU) {
1107 llvm::DICompileUnit *TheCU) {
1113 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1115 if (RD->isDynamicClass() &&
1128 llvm::dwarf::Tag Tag;
1130 Tag = llvm::dwarf::DW_TAG_structure_type;
1132 Tag = llvm::dwarf::DW_TAG_union_type;
1137 Tag = llvm::dwarf::DW_TAG_class_type;
1142llvm::DICompositeType *
1143CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1144 llvm::DIScope *Ctx) {
1147 return cast<llvm::DICompositeType>(
T);
1148 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1149 const unsigned Line =
1151 StringRef RDName = getClassName(RD);
1160 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1165 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1166 if (!CXXRD->hasDefinition() ||
1167 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1168 Flags |= llvm::DINode::FlagNonTrivial;
1175 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1179 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1180 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1181 CollectCXXTemplateParams(TSpecial, DefUnit));
1182 ReplaceMap.emplace_back(
1183 std::piecewise_construct, std::make_tuple(Ty),
1184 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1188llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1191 llvm::DIFile *Unit) {
1196 std::optional<unsigned> DWARFAddressSpace =
1201 auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1203 StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1205 llvm::Metadata *Ops[2] = {
1206 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1208 Annots.insert(Annots.begin(),
1211 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1214 llvm::DINodeArray Annotations =
nullptr;
1215 if (Annots.size() > 0)
1216 Annotations = DBuilder.getOrCreateArray(Annots);
1218 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1219 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1220 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1221 Size, Align, DWARFAddressSpace);
1223 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1224 Align, DWARFAddressSpace, StringRef(),
1228llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1229 llvm::DIType *&
Cache) {
1232 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1233 TheCU, TheCU->getFile(), 0);
1235 Cache = DBuilder.createPointerType(
Cache, Size);
1239uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1240 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1253 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1254 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1257 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1259 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1260 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1262 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1266 EltTys.push_back(DBuilder.createMemberType(
1267 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1268 FieldOffset, llvm::DINode::FlagZero, DescTy));
1269 FieldOffset += FieldSize;
1276 llvm::DIFile *Unit) {
1280 llvm::DINodeArray Elements;
1284 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1285 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1287 Elements = DBuilder.getOrCreateArray(EltTys);
1290 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1293 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1294 FieldOffset, 0, Flags,
nullptr, Elements);
1299 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1301 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1304 Elements = DBuilder.getOrCreateArray(EltTys);
1310 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1311 Flags,
nullptr, Elements);
1313 return DBuilder.createPointerType(EltTy, Size);
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();
1395 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1404 llvm::raw_string_ostream OS(Name);
1407 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1408 !HasReconstitutableArgs(Args.Args))
1411 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1412 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1413 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1428 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
1445 return llvm::DINode::FlagZero;
1449 return llvm::DINode::FlagPrivate;
1451 return llvm::DINode::FlagProtected;
1453 return llvm::DINode::FlagPublic;
1455 return llvm::DINode::FlagZero;
1457 llvm_unreachable(
"unexpected access enumerator");
1460llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1461 llvm::DIFile *Unit) {
1462 llvm::DIType *Underlying =
1474 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1476 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1478 if (isa<RecordDecl>(DC))
1481 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1482 getOrCreateFile(Loc), getLineNumber(Loc),
1483 getDeclContextDescriptor(Ty->
getDecl()), Align,
1484 Flags, Annotations);
1494 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1496 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1498 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1500 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1502 return llvm::dwarf::DW_CC_BORLAND_pascal;
1504 return llvm::dwarf::DW_CC_LLVM_Win64;
1506 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1510 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1512 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1514 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1516 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1519 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1521 return llvm::dwarf::DW_CC_LLVM_Swift;
1523 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1525 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1527 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1529 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1531 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1533 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1535 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1541 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1543 Flags |= llvm::DINode::FlagLValueReference;
1545 Flags |= llvm::DINode::FlagRValueReference;
1549llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1550 llvm::DIFile *Unit) {
1551 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1553 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1562 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1564 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1568 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1571 for (
const QualType &ParamType : FPT->param_types())
1572 EltTys.push_back(getOrCreateType(ParamType, Unit));
1573 if (FPT->isVariadic())
1574 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1577 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1578 llvm::DIType *F = DBuilder.createSubroutineType(
1583llvm::DIDerivedType *
1584CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1585 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1586 StringRef Name = BitFieldDecl->
getName();
1588 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1589 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1591 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1592 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1595 llvm::DIFile *
File = getOrCreateFile(Loc);
1596 unsigned Line = getLineNumber(Loc);
1601 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1610 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1612 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1613 return DBuilder.createBitFieldMemberType(
1614 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1615 Flags, DebugType, Annotations);
1618llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1619 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1647 if (PreviousFieldsDI.empty())
1651 auto *PreviousMDEntry =
1652 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1653 auto *PreviousMDField =
1654 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1655 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1656 PreviousMDField->getSizeInBits() == 0)
1660 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1662 assert(PreviousBitfield->isBitField());
1665 if (!PreviousBitfield->isZeroLengthBitField(Context))
1668 QualType Ty = PreviousBitfield->getType();
1670 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1671 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1672 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1674 llvm::DIFile *
File = getOrCreateFile(Loc);
1675 unsigned Line = getLineNumber(Loc);
1678 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1681 llvm::DINode::DIFlags Flags =
1683 llvm::DINodeArray Annotations =
1684 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1685 return DBuilder.createBitFieldMemberType(
1686 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1687 Flags, DebugType, Annotations);
1690llvm::DIType *CGDebugInfo::createFieldType(
1692 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1693 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1694 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1697 llvm::DIFile *file = getOrCreateFile(loc);
1698 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1701 auto Align = AlignInBits;
1702 if (!
type->isIncompleteArrayType()) {
1704 SizeInBits = TI.
Width;
1710 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1711 offsetInBits, flags, debugType, Annotations);
1714void CGDebugInfo::CollectRecordLambdaFields(
1716 llvm::DIType *RecordTy) {
1722 unsigned fieldno = 0;
1725 I != E; ++I, ++Field, ++fieldno) {
1727 if (
C.capturesVariable()) {
1729 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1731 StringRef VName =
V->getName();
1732 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1734 llvm::DIType *FieldType = createFieldType(
1735 VName,
Field->getType(), Loc,
Field->getAccess(),
1736 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1737 elements.push_back(FieldType);
1738 }
else if (
C.capturesThis()) {
1744 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1746 StringRef ThisName =
1748 llvm::DIType *fieldType = createFieldType(
1752 elements.push_back(fieldType);
1757llvm::DIDerivedType *
1758CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1763 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1764 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1766 unsigned LineNumber = getLineNumber(Var->
getLocation());
1767 StringRef VName = Var->
getName();
1771 llvm::Constant *
C =
nullptr;
1777 if (
Value->isFloat())
1784 ? llvm::dwarf::DW_TAG_variable
1785 : llvm::dwarf::DW_TAG_member;
1787 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1788 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1793void CGDebugInfo::CollectRecordNormalField(
1794 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1801 if (
name.empty() && !
type->isRecordType())
1804 llvm::DIType *FieldType;
1806 llvm::DIDerivedType *BitFieldType;
1807 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1808 if (llvm::DIType *Separator =
1809 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1810 elements.push_back(Separator);
1813 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1816 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1819 elements.push_back(FieldType);
1822void CGDebugInfo::CollectRecordNestedType(
1826 if (isa<InjectedClassNameType>(Ty))
1829 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc));
1830 elements.push_back(nestedType);
1833void CGDebugInfo::CollectRecordFields(
1834 const RecordDecl *record, llvm::DIFile *tunit,
1836 llvm::DICompositeType *RecordTy) {
1837 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1839 if (CXXDecl && CXXDecl->
isLambda())
1840 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1845 unsigned fieldNo = 0;
1849 for (
const auto *I : record->
decls())
1850 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1851 if (
V->hasAttr<NoDebugAttr>())
1857 isa<VarTemplateSpecializationDecl>(
V))
1860 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1864 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1865 if (MI != StaticDataMemberCache.end()) {
1866 assert(MI->second &&
1867 "Static data member declaration should still exist");
1868 elements.push_back(MI->second);
1870 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1871 elements.push_back(Field);
1873 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1874 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1875 elements, RecordTy, record);
1882 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1884 if (isa<RecordDecl>(I) &&
1885 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1887 if (!nestedType->isImplicit() &&
1888 nestedType->getDeclContext() == record)
1889 CollectRecordNestedType(nestedType, elements);
1895llvm::DISubroutineType *
1896CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1897 llvm::DIFile *Unit) {
1900 return cast_or_null<llvm::DISubroutineType>(
1902 return getOrCreateInstanceMethodType(Method->
getThisType(),
Func, Unit);
1905llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1921 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
1923 Func->getReturnType(),
Func->getParamTypes(), EPI),
1925 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
1926 assert(Args.size() &&
"Invalid number of arguments!");
1931 Elts.push_back(Args[0]);
1935 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1937 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1940 llvm::DIType *PointeeType =
1942 llvm::DIType *ThisPtrType =
1943 DBuilder.createPointerType(PointeeType, Size, Align);
1948 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1949 Elts.push_back(ThisPtrType);
1951 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1953 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1954 Elts.push_back(ThisPtrType);
1958 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1959 Elts.push_back(Args[i]);
1961 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1963 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
1970 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1977llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1978 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1980 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1982 StringRef MethodName = getFunctionName(Method);
1983 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1987 StringRef MethodLinkageName;
1997 llvm::DIFile *MethodDefUnit =
nullptr;
1998 unsigned MethodLine = 0;
2000 MethodDefUnit = getOrCreateFile(Method->
getLocation());
2001 MethodLine = getLineNumber(Method->
getLocation());
2005 llvm::DIType *ContainingType =
nullptr;
2006 unsigned VIndex = 0;
2007 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2008 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2013 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2015 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2020 if (!isa<CXXDestructorDecl>(Method))
2025 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
2037 Flags |= llvm::DINode::FlagIntroducedVirtual;
2046 ContainingType = RecordTy;
2050 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2053 Flags |= llvm::DINode::FlagNoReturn;
2056 Flags |= llvm::DINode::FlagStaticMember;
2058 Flags |= llvm::DINode::FlagArtificial;
2060 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
2061 if (CXXC->isExplicit())
2062 Flags |= llvm::DINode::FlagExplicit;
2063 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
2064 if (CXXC->isExplicit())
2065 Flags |= llvm::DINode::FlagExplicit;
2068 Flags |= llvm::DINode::FlagPrototyped;
2070 Flags |= llvm::DINode::FlagLValueReference;
2072 Flags |= llvm::DINode::FlagRValueReference;
2074 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2076 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2080 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2084 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2085 llvm::DISubprogram *SP = DBuilder.createMethod(
2086 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2087 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2088 TParamsArray.get());
2095void CGDebugInfo::CollectCXXMemberFunctions(
2102 for (
const auto *I : RD->
decls()) {
2103 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2127 EltTys.push_back(MI == SPCache.end()
2128 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2129 :
static_cast<llvm::Metadata *
>(MI->second));
2133void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2135 llvm::DIType *RecordTy) {
2137 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2138 llvm::DINode::FlagZero);
2143 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2144 llvm::DINode::FlagIndirectVirtualBase);
2148void CGDebugInfo::CollectCXXBasesAux(
2153 llvm::DINode::DIFlags StartingFlags) {
2155 for (
const auto &BI : Bases) {
2158 if (!SeenTypes.insert(
Base).second)
2160 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2161 llvm::DINode::DIFlags BFlags = StartingFlags;
2163 uint32_t VBPtrOffset = 0;
2165 if (BI.isVirtual()) {
2182 BFlags |= llvm::DINode::FlagVirtual;
2189 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2190 VBPtrOffset, BFlags);
2191 EltTys.push_back(DTy);
2196CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2197 llvm::DIFile *Unit) {
2199 return llvm::DINodeArray();
2200 TemplateArgs &Args = *OArgs;
2202 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2207 Name = Args.TList->getParam(i)->getName();
2211 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2212 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2213 TheCU, Name, TTy, defaultParameter));
2218 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2219 TheCU, Name, TTy, defaultParameter,
2225 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2226 llvm::Constant *
V =
nullptr;
2230 !D->
hasAttr<CUDADeviceAttr>()) {
2233 if (
const auto *VD = dyn_cast<VarDecl>(D))
2237 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2238 MD && MD->isImplicitObjectMemberFunction())
2240 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2244 else if (
const auto *MPT =
2245 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2253 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2255 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2262 assert(
V &&
"Failed to find template parameter pointer");
2263 V =
V->stripPointerCasts();
2265 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2266 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2270 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2271 llvm::Constant *
V =
nullptr;
2274 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2280 if (MPT->isMemberDataPointer())
2283 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2284 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2285 TheCU, Name, TTy, defaultParameter,
V));
2289 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2292 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2293 TheCU, Name, TTy, defaultParameter,
V));
2296 std::string QualName;
2297 llvm::raw_string_ostream OS(QualName);
2299 OS, getPrintingPolicy());
2300 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2301 TheCU, Name,
nullptr, OS.str(), defaultParameter));
2305 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2306 TheCU, Name,
nullptr,
2315 assert(
V &&
"Expression in template argument isn't constant");
2316 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2317 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2318 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2324 "These argument types shouldn't exist in concrete types");
2327 return DBuilder.getOrCreateArray(TemplateParams);
2330std::optional<CGDebugInfo::TemplateArgs>
2331CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2339 return std::nullopt;
2341std::optional<CGDebugInfo::TemplateArgs>
2342CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2346 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2348 return std::nullopt;
2351 auto TA = TS->getTemplateArgs().asArray();
2352 return {{TList, TA}};
2354std::optional<CGDebugInfo::TemplateArgs>
2355CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2356 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2361 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2363 return {{TPList, TAList.
asArray()}};
2365 return std::nullopt;
2369CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2370 llvm::DIFile *Unit) {
2371 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2374llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2375 llvm::DIFile *Unit) {
2376 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2379llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2380 llvm::DIFile *Unit) {
2381 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2384llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2385 if (!D->
hasAttr<BTFDeclTagAttr>())
2390 llvm::Metadata *Ops[2] = {
2391 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2393 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2395 return DBuilder.getOrCreateArray(Annotations);
2398llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2400 return VTablePtrType;
2405 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2406 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2407 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2410 std::optional<unsigned> DWARFAddressSpace =
2413 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2414 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2415 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2416 return VTablePtrType;
2419StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2424StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2426 llvm::Function *InitFn) {
2431 return InitFn->getName();
2441 llvm::raw_svector_ostream OS(QualifiedGV);
2443 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2445 std::swap(Quals, GVName);
2449 llvm::raw_svector_ostream OS(InitName);
2451 OS << Quals <<
"::";
2456 llvm_unreachable(
"not an initializer");
2458 OS <<
"`dynamic initializer for '";
2461 OS <<
"`dynamic atexit destructor for '";
2468 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2470 getPrintingPolicy());
2475 return internString(OS.str());
2478void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2495 llvm::DIType *VPtrTy =
nullptr;
2498 if (NeedVTableShape) {
2503 unsigned VSlotCount =
2505 unsigned VTableWidth = PtrWidth * VSlotCount;
2507 std::optional<unsigned> DWARFAddressSpace =
2511 llvm::DIType *VTableType = DBuilder.createPointerType(
2512 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2513 EltTys.push_back(VTableType);
2516 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2524 VPtrTy = getOrCreateVTablePtrType(Unit);
2527 llvm::DIType *VPtrMember =
2528 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2529 llvm::DINode::FlagArtificial, VPtrTy);
2530 EltTys.push_back(VPtrMember);
2536 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
2548 assert(!D.
isNull() &&
"null type");
2549 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
2550 assert(
T &&
"could not create debug info for type");
2560 llvm::codegenoptions::DebugLineTablesOnly)
2566 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
2568 CI->setMetadata(
"heapallocsite", node);
2572 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2576 auto I = TypeCache.find(TyPtr);
2577 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2579 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2580 assert(!Res->isForwardDecl());
2581 TypeCache[TyPtr].reset(Res);
2585 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2592 if (RD->
hasAttr<DLLImportAttr>())
2595 if (MD->hasAttr<DLLImportAttr>())
2608 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2617 bool Explicit =
false;
2618 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2619 Explicit = TD->isExplicitInstantiationOrSpecialization();
2633 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2634 if (CXXRD->isDynamicClass() &&
2636 llvm::GlobalValue::AvailableExternallyLinkage &&
2647 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2651 auto I = TypeCache.find(TyPtr);
2652 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2659 assert(!Res->isForwardDecl());
2660 TypeCache[TyPtr].reset(Res);
2667 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2668 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2691 if (Ctor->isCopyOrMoveConstructor())
2693 if (!Ctor->isDeleted())
2712 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2715 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2716 RD->
hasAttr<StandaloneDebugAttr>())
2719 if (!LangOpts.CPlusPlus)
2725 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2741 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2742 Spec = SD->getSpecializationKind();
2751 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2763 llvm::DIType *
T = getTypeOrNull(Ty);
2764 if (
T &&
T->isForwardDecl())
2768llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2770 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2774 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2778 auto [Def, Pref] = CreateTypeDefinition(Ty);
2780 return Pref ? Pref : Def;
2783llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2784 llvm::DIFile *Unit) {
2788 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2792 return getOrCreateType(PNA->getTypedefType(), Unit);
2795std::pair<llvm::DIType *, llvm::DIType *>
2796CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2800 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2808 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2812 return {FwdDecl,
nullptr};
2814 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2815 CollectContainingType(CXXDecl, FwdDecl);
2818 LexicalBlockStack.emplace_back(&*FwdDecl);
2819 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2829 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2831 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2832 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2836 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2838 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2840 LexicalBlockStack.pop_back();
2841 RegionMap.erase(Ty->
getDecl());
2843 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2844 DBuilder.replaceArrays(FwdDecl, Elements);
2846 if (FwdDecl->isTemporary())
2848 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2850 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2852 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2853 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2854 return {FwdDecl, PrefDI};
2856 return {FwdDecl,
nullptr};
2860 llvm::DIFile *Unit) {
2866 llvm::DIFile *Unit) {
2871 return DBuilder.createTypedef(
2873 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
2874 getDeclContextDescriptor(Ty->
getDecl()));
2902 llvm::DIFile *Unit) {
2910 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2911 !
ID->getImplementation())
2912 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2914 getDeclContextDescriptor(ID), Unit, 0);
2917 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2918 unsigned Line = getLineNumber(
ID->getLocation());
2920 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2926 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2927 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2928 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
2929 DefUnit,
Line, RuntimeLang);
2930 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2934 return CreateTypeDefinition(Ty, Unit);
2938 bool CreateSkeletonCU) {
2943 auto ModRef = ModuleCache.find(M);
2944 if (ModRef != ModuleCache.end())
2945 return cast<llvm::DIModule>(ModRef->second);
2950 llvm::raw_svector_ostream OS(ConfigMacros);
2954 for (
auto &M : PPOpts.Macros) {
2957 const std::string &
Macro = M.first;
2958 bool Undef = M.second;
2959 OS <<
"\"-" << (Undef ?
'U' :
'D');
2960 for (
char c : Macro)
2975 bool IsRootModule = M ? !M->
Parent :
true;
2979 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
2981 "clang module without ASTFile must be specified by -fmodule-name");
2984 auto RemapPath = [
this](StringRef Path) -> std::string {
2986 StringRef Relative(Remapped);
2987 StringRef CompDir = TheCU->getDirectory();
2988 if (Relative.consume_front(CompDir))
2989 Relative.consume_front(llvm::sys::path::get_separator());
2991 return Relative.str();
2994 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3001 Signature = ModSig.truncatedValue();
3007 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3009 PCM = getCurrentDirname();
3013 llvm::sys::path::append(PCM, Mod.
getASTFile());
3014 DIB.createCompileUnit(
3015 TheCU->getSourceLanguage(),
3018 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3019 llvm::DICompileUnit::FullDebug, Signature);
3024 IsRootModule ? nullptr
3027 std::string IncludePath = Mod.
getPath().str();
3028 llvm::DIModule *DIMod =
3030 RemapPath(IncludePath));
3031 ModuleCache[M].reset(DIMod);
3036 llvm::DIFile *Unit) {
3038 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3039 unsigned Line = getLineNumber(
ID->getLocation());
3040 unsigned RuntimeLang = TheCU->getSourceLanguage();
3046 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3047 if (
ID->getImplementation())
3048 Flags |= llvm::DINode::FlagObjcClassComplete;
3050 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3051 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3052 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3053 nullptr, llvm::DINodeArray(), RuntimeLang);
3056 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3059 LexicalBlockStack.emplace_back(RealDecl);
3060 RegionMap[Ty->
getDecl()].reset(RealDecl);
3067 llvm::DIType *SClassTy =
3072 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3073 llvm::DINode::FlagZero);
3074 EltTys.push_back(InhTag);
3080 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3081 unsigned PLine = getLineNumber(Loc);
3084 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3085 PD->getName(), PUnit, PLine,
3087 : getSelectorName(PD->getGetterName()),
3089 : getSelectorName(PD->getSetterName()),
3090 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3091 EltTys.push_back(PropertyNode);
3096 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3103 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3106 for (
auto *PD : ClassExt->properties()) {
3107 PropertySet.insert(GetIsClassAndIdent(PD));
3110 for (
const auto *PD :
ID->properties()) {
3113 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3120 unsigned FieldNo = 0;
3122 Field =
Field->getNextIvar(), ++FieldNo) {
3123 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3127 StringRef FieldName =
Field->getName();
3130 if (FieldName.empty())
3134 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3135 unsigned FieldLine = getLineNumber(
Field->getLocation());
3138 uint32_t FieldAlign = 0;
3143 FieldSize =
Field->isBitField()
3154 if (
Field->isBitField()) {
3165 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3167 Flags = llvm::DINode::FlagProtected;
3169 Flags = llvm::DINode::FlagPrivate;
3171 Flags = llvm::DINode::FlagPublic;
3173 if (
Field->isBitField())
3174 Flags |= llvm::DINode::FlagBitField;
3176 llvm::MDNode *PropertyNode =
nullptr;
3179 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3182 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3183 unsigned PLine = getLineNumber(Loc);
3186 PropertyNode = DBuilder.createObjCProperty(
3187 PD->getName(), PUnit, PLine,
3190 : getSelectorName(PD->getGetterName()),
3193 : getSelectorName(PD->getSetterName()),
3194 PD->getPropertyAttributes(),
3195 getOrCreateType(PD->getType(), PUnit));
3199 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3200 FieldSize, FieldAlign, FieldOffset, Flags,
3201 FieldTy, PropertyNode);
3202 EltTys.push_back(FieldTy);
3205 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3206 DBuilder.replaceArrays(RealDecl, Elements);
3208 LexicalBlockStack.pop_back();
3212llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3213 llvm::DIFile *Unit) {
3231 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3234 llvm::Metadata *Subscript;
3236 auto SizeExpr = SizeExprCache.find(QTy);
3237 if (SizeExpr != SizeExprCache.end())
3238 Subscript = DBuilder.getOrCreateSubrange(
3239 SizeExpr->getSecond() ,
nullptr ,
3240 nullptr ,
nullptr );
3243 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3244 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3245 Subscript = DBuilder.getOrCreateSubrange(
3246 CountNode ,
nullptr ,
nullptr ,
3249 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3254 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3258 llvm::DIFile *Unit) {
3262 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3268 auto *ColumnCountNode =
3269 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3271 auto *RowCountNode =
3272 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3274 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3275 ColumnCountNode ,
nullptr ,
nullptr ,
3277 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3278 RowCountNode ,
nullptr ,
nullptr ,
3280 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3281 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3284llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3289 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3313 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3322 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3323 Count = CAT->getZExtSize();
3324 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3325 if (
Expr *Size = VAT->getSizeExpr()) {
3328 Count =
Result.Val.getInt().getExtValue();
3332 auto SizeNode = SizeExprCache.find(EltTy);
3333 if (SizeNode != SizeExprCache.end())
3334 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3335 SizeNode->getSecond() ,
nullptr ,
3336 nullptr ,
nullptr ));
3339 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3341 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3342 CountNode ,
nullptr ,
nullptr ,
3348 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3350 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3355 llvm::DIFile *Unit) {
3356 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3361 llvm::DIFile *Unit) {
3362 llvm::dwarf::Tag Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3366 Tag = llvm::dwarf::DW_TAG_reference_type;
3368 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3373 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3383 Flags |= llvm::DINode::FlagSingleInheritance;
3386 Flags |= llvm::DINode::FlagMultipleInheritance;
3389 Flags |= llvm::DINode::FlagVirtualInheritance;
3399 return DBuilder.createMemberPointerType(
3405 return DBuilder.createMemberPointerType(
3406 getOrCreateInstanceMethodType(
3409 ClassType,
Size, 0, Flags);
3412llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3414 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3417llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3421llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3433 bool isImportedFromModule =
3445 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3446 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3447 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3448 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3451 StringRef EDName = ED->
getName();
3452 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3453 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3454 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3456 ReplaceMap.emplace_back(
3457 std::piecewise_construct, std::make_tuple(Ty),
3458 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3462 return CreateTypeDefinition(Ty);
3465llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3479 Enumerators.push_back(
3480 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3484 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3486 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3488 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3489 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3490 return DBuilder.createEnumerationType(
3491 EnumContext, ED->
getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3497 StringRef Name, StringRef
Value) {
3498 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3505 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3506 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3507 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3517 Quals += InnerQuals;
3521 return C.getQualifiedType(
T.getTypePtr(), Quals);
3522 case Type::TemplateSpecialization: {
3523 const auto *Spec = cast<TemplateSpecializationType>(
T);
3524 if (Spec->isTypeAlias())
3525 return C.getQualifiedType(
T.getTypePtr(), Quals);
3529 case Type::TypeOfExpr:
3530 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3533 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3535 case Type::Decltype:
3536 T = cast<DecltypeType>(
T)->getUnderlyingType();
3538 case Type::UnaryTransform:
3539 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3541 case Type::Attributed:
3542 T = cast<AttributedType>(
T)->getEquivalentType();
3544 case Type::BTFTagAttributed:
3545 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3547 case Type::CountAttributed:
3548 T = cast<CountAttributedType>(
T)->
desugar();
3550 case Type::Elaborated:
3551 T = cast<ElaboratedType>(
T)->getNamedType();
3554 T = cast<UsingType>(
T)->getUnderlyingType();
3557 T = cast<ParenType>(
T)->getInnerType();
3559 case Type::MacroQualified:
3560 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3562 case Type::SubstTemplateTypeParm:
3563 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3566 case Type::DeducedTemplateSpecialization: {
3567 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3568 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3572 case Type::PackIndexing: {
3573 T = cast<PackIndexingType>(
T)->getSelectedType();
3576 case Type::Adjusted:
3579 T = cast<AdjustedType>(
T)->getAdjustedType();
3583 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3588llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3591 if (It != TypeCache.end()) {
3593 if (llvm::Metadata *
V = It->second)
3594 return cast<llvm::DIType>(
V);
3606 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3616llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3620 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3622 llvm::raw_string_ostream OS(Name);
3623 Ty.
print(OS, getPrintingPolicy());
3630 if (
auto *
T = getTypeOrNull(Ty))
3633 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3634 void *TyPtr = Ty.getAsOpaquePtr();
3637 TypeCache[TyPtr].reset(Res);
3642llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3644 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
3650 auto Info = Reader->getSourceDescriptor(Idx);
3652 return getOrCreateModuleRef(*Info,
true);
3653 }
else if (ClangModuleMap) {
3667 return getOrCreateModuleRef(Info,
false);
3670 return getOrCreateModuleRef(PCHDescriptor,
false);
3677llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3680 return CreateQualifiedType(Ty, Unit);
3684#define TYPE(Class, Base)
3685#define ABSTRACT_TYPE(Class, Base)
3686#define NON_CANONICAL_TYPE(Class, Base)
3687#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3688#include "clang/AST/TypeNodes.inc"
3689 llvm_unreachable(
"Dependent types cannot show up in debug information");
3691 case Type::ExtVector:
3693 return CreateType(cast<VectorType>(Ty), Unit);
3694 case Type::ConstantMatrix:
3695 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3696 case Type::ObjCObjectPointer:
3697 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3698 case Type::ObjCObject:
3699 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3700 case Type::ObjCTypeParam:
3701 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3702 case Type::ObjCInterface:
3703 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3705 return CreateType(cast<BuiltinType>(Ty));
3707 return CreateType(cast<ComplexType>(Ty));
3709 return CreateType(cast<PointerType>(Ty), Unit);
3710 case Type::BlockPointer:
3711 return CreateType(cast<BlockPointerType>(Ty), Unit);
3713 return CreateType(cast<TypedefType>(Ty), Unit);
3715 return CreateType(cast<RecordType>(Ty));
3717 return CreateEnumType(cast<EnumType>(Ty));
3718 case Type::FunctionProto:
3719 case Type::FunctionNoProto:
3720 return CreateType(cast<FunctionType>(Ty), Unit);
3721 case Type::ConstantArray:
3722 case Type::VariableArray:
3723 case Type::IncompleteArray:
3724 case Type::ArrayParameter:
3725 return CreateType(cast<ArrayType>(Ty), Unit);
3727 case Type::LValueReference:
3728 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3729 case Type::RValueReference:
3730 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3732 case Type::MemberPointer:
3733 return CreateType(cast<MemberPointerType>(Ty), Unit);
3736 return CreateType(cast<AtomicType>(Ty), Unit);
3739 return CreateType(cast<BitIntType>(Ty));
3741 return CreateType(cast<PipeType>(Ty), Unit);
3743 case Type::TemplateSpecialization:
3744 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3746 case Type::CountAttributed:
3748 case Type::Attributed:
3749 case Type::BTFTagAttributed:
3750 case Type::Adjusted:
3752 case Type::DeducedTemplateSpecialization:
3753 case Type::Elaborated:
3756 case Type::MacroQualified:
3757 case Type::SubstTemplateTypeParm:
3758 case Type::TypeOfExpr:
3760 case Type::Decltype:
3761 case Type::PackIndexing:
3762 case Type::UnaryTransform:
3766 llvm_unreachable(
"type should have been unwrapped!");
3769llvm::DICompositeType *
3770CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3773 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3778 if (
T && !
T->isForwardDecl())
3782 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3787 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
3790 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3795llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3799 StringRef RDName = getClassName(RD);
3801 llvm::DIFile *DefUnit =
nullptr;
3804 DefUnit = getOrCreateFile(Loc);
3805 Line = getLineNumber(Loc);
3808 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3812 auto *
T = cast_or_null<llvm::DICompositeType>(
3821 return getOrCreateRecordFwdDecl(Ty, RDContext);
3834 auto Flags = llvm::DINode::FlagZero;
3835 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3837 Flags |= llvm::DINode::FlagTypePassByReference;
3839 Flags |= llvm::DINode::FlagTypePassByValue;
3842 if (!CXXRD->isTrivial())
3843 Flags |= llvm::DINode::FlagNonTrivial;
3846 if (CXXRD->isAnonymousStructOrUnion())
3847 Flags |= llvm::DINode::FlagExportSymbols;
3850 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3853 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
3854 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3860 switch (RealDecl->getTag()) {
3862 llvm_unreachable(
"invalid composite type tag");
3864 case llvm::dwarf::DW_TAG_array_type:
3865 case llvm::dwarf::DW_TAG_enumeration_type:
3874 case llvm::dwarf::DW_TAG_structure_type:
3875 case llvm::dwarf::DW_TAG_union_type:
3876 case llvm::dwarf::DW_TAG_class_type:
3879 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3883 RegionMap[Ty->
getDecl()].reset(RealDecl);
3886 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3887 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3888 CollectCXXTemplateParams(TSpecial, DefUnit));
3892void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3893 llvm::DICompositeType *RealDecl) {
3895 llvm::DIType *ContainingType =
nullptr;
3907 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3910 ContainingType = RealDecl;
3912 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3915llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3916 StringRef Name, uint64_t *Offset) {
3917 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3921 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3922 *Offset, llvm::DINode::FlagZero, FieldTy);
3923 *Offset += FieldSize;
3927void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3929 StringRef &LinkageName,
3930 llvm::DIScope *&FDContext,
3931 llvm::DINodeArray &TParamsArray,
3932 llvm::DINode::DIFlags &Flags) {
3934 Name = getFunctionName(FD);
3939 Flags |= llvm::DINode::FlagPrototyped;
3943 if (LinkageName == Name ||
3948 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
3949 LinkageName = StringRef();
3954 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
3958 FDContext = getOrCreateNamespace(NSDecl);
3961 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
3962 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
3968 Flags |= llvm::DINode::FlagNoReturn;
3970 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
3974void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
3976 StringRef &Name, StringRef &LinkageName,
3977 llvm::MDTuple *&TemplateParameters,
3978 llvm::DIScope *&VDContext) {
3987 llvm::APInt ConstVal(32, 1);
3998 if (LinkageName == Name)
3999 LinkageName = StringRef();
4001 if (isa<VarTemplateSpecializationDecl>(VD)) {
4002 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4003 TemplateParameters = parameterNodes.get();
4005 TemplateParameters =
nullptr;
4025 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4026 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4029llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4031 llvm::DINodeArray TParamsArray;
4032 StringRef Name, LinkageName;
4033 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4034 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4036 llvm::DIFile *Unit = getOrCreateFile(Loc);
4037 llvm::DIScope *DContext = Unit;
4038 unsigned Line = getLineNumber(Loc);
4039 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4041 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4046 ArgTypes.push_back(Parm->getType());
4052 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4054 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4057 Flags |= getCallSiteRelatedAttrs();
4058 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4059 return DBuilder.createFunction(
4060 DContext, Name, LinkageName, Unit,
Line,
4061 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4062 TParamsArray.get(), getFunctionDeclaration(FD));
4065 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4066 DContext, Name, LinkageName, Unit,
Line,
4067 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4068 TParamsArray.get(), getFunctionDeclaration(FD));
4070 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4071 std::make_tuple(CanonDecl),
4072 std::make_tuple(SP));
4076llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4077 return getFunctionFwdDeclOrStub(GD,
false);
4080llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4081 return getFunctionFwdDeclOrStub(GD,
true);
4084llvm::DIGlobalVariable *
4085CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4087 StringRef Name, LinkageName;
4089 llvm::DIFile *Unit = getOrCreateFile(Loc);
4090 llvm::DIScope *DContext = Unit;
4091 unsigned Line = getLineNumber(Loc);
4092 llvm::MDTuple *TemplateParameters =
nullptr;
4094 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4097 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4098 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4100 FwdDeclReplaceMap.emplace_back(
4101 std::piecewise_construct,
4103 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4107llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4112 if (
const auto *TD = dyn_cast<TypeDecl>(D))
4117 if (I != DeclCache.end()) {
4119 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4120 return GVE->getVariable();
4121 return cast<llvm::DINode>(N);
4128 if (IE != ImportedDeclCache.end()) {
4129 auto N = IE->second;
4130 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4131 return cast<llvm::DINode>(GVE);
4132 return dyn_cast_or_null<llvm::DINode>(N);
4137 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4138 return getFunctionForwardDeclaration(FD);
4139 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4140 return getGlobalVariableForwardDeclaration(VD);
4145llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4146 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4149 const auto *FD = dyn_cast<FunctionDecl>(D);
4154 auto *S = getDeclContextDescriptor(D);
4157 if (MI == SPCache.end()) {
4159 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4160 cast<llvm::DICompositeType>(S));
4163 if (MI != SPCache.end()) {
4164 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4165 if (SP && !SP->isDefinition())
4169 for (
auto *NextFD : FD->
redecls()) {
4170 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4171 if (MI != SPCache.end()) {
4172 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4173 if (SP && !SP->isDefinition())
4180llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4181 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4182 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4183 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4186 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4194 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4204 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4205 if (It == TypeCache.end())
4207 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4208 llvm::DISubprogram *FD = DBuilder.createFunction(
4209 InterfaceType, getObjCMethodName(OMD), StringRef(),
4210 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4211 DBuilder.finalizeSubprogram(FD);
4218llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4223 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4227 return DBuilder.createSubroutineType(
4228 DBuilder.getOrCreateTypeArray(std::nullopt));
4230 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
4231 return getOrCreateMethodType(Method, F);
4236 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4241 QualType ResultTy = OMethod->getReturnType();
4246 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4248 Elts.push_back(getOrCreateType(ResultTy, F));
4251 if (
auto *SelfDecl = OMethod->getSelfDecl())
4252 SelfDeclTy = SelfDecl->getType();
4253 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4256 if (!SelfDeclTy.
isNull())
4258 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4260 Elts.push_back(DBuilder.createArtificialType(
4263 for (
const auto *PI : OMethod->parameters())
4264 Elts.push_back(getOrCreateType(PI->getType(), F));
4266 if (OMethod->isVariadic())
4267 Elts.push_back(DBuilder.createUnspecifiedParameter());
4269 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4270 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4276 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4277 if (FD->isVariadic()) {
4279 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4280 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4282 EltTys.push_back(getOrCreateType(ParamType, F));
4283 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4284 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4285 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4289 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4298 CC = SrcFnTy->getCallConv();
4300 for (
const VarDecl *VD : Args)
4301 ArgTypes.push_back(VD->
getType());
4308 llvm::Function *Fn,
bool CurFuncIsThunk) {
4310 StringRef LinkageName;
4312 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4315 bool HasDecl = (D !=
nullptr);
4317 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4318 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4319 llvm::DIFile *Unit = getOrCreateFile(Loc);
4320 llvm::DIScope *FDContext = Unit;
4321 llvm::DINodeArray TParamsArray;
4324 LinkageName = Fn->getName();
4325 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4327 auto FI = SPCache.find(FD->getCanonicalDecl());
4328 if (FI != SPCache.end()) {
4329 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4330 if (SP && SP->isDefinition()) {
4331 LexicalBlockStack.emplace_back(SP);
4332 RegionMap[D].reset(SP);
4336 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4337 TParamsArray, Flags);
4338 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4339 Name = getObjCMethodName(OMD);
4340 Flags |= llvm::DINode::FlagPrototyped;
4341 }
else if (isa<VarDecl>(D) &&
4347 Name = Fn->getName();
4349 if (isa<BlockDecl>(D))
4352 Flags |= llvm::DINode::FlagPrototyped;
4354 if (Name.starts_with(
"\01"))
4355 Name = Name.substr(1);
4357 assert((!D || !isa<VarDecl>(D) ||
4359 "Unexpected DynamicInitKind !");
4362 isa<VarDecl>(D) || isa<CapturedDecl>(D)) {
4363 Flags |= llvm::DINode::FlagArtificial;
4369 Flags |= llvm::DINode::FlagThunk;
4371 if (Fn->hasLocalLinkage())
4372 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4374 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4376 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4377 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4378 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4380 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4381 unsigned ScopeLine = getLineNumber(ScopeLoc);
4382 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4383 llvm::DISubprogram *
Decl =
nullptr;
4384 llvm::DINodeArray Annotations =
nullptr;
4386 Decl = isa<ObjCMethodDecl>(D)
4387 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4388 : getFunctionDeclaration(D);
4389 Annotations = CollectBTFDeclTagAnnotations(D);
4397 llvm::DISubprogram *SP = DBuilder.createFunction(
4398 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4399 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4401 Fn->setSubprogram(SP);
4405 if (HasDecl && isa<FunctionDecl>(D))
4409 LexicalBlockStack.emplace_back(SP);
4412 RegionMap[D].reset(SP);
4416 QualType FnType, llvm::Function *Fn) {
4418 StringRef LinkageName;
4424 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4425 return GetName(D,
true);
4428 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4429 llvm::DIFile *Unit = getOrCreateFile(Loc);
4430 bool IsDeclForCallSite = Fn ?
true :
false;
4431 llvm::DIScope *FDContext =
4432 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4433 llvm::DINodeArray TParamsArray;
4434 if (isa<FunctionDecl>(D)) {
4436 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4437 TParamsArray, Flags);
4438 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4439 Name = getObjCMethodName(OMD);
4440 Flags |= llvm::DINode::FlagPrototyped;
4442 llvm_unreachable(
"not a function or ObjC method");
4444 if (!Name.empty() && Name[0] ==
'\01')
4445 Name = Name.substr(1);
4448 Flags |= llvm::DINode::FlagArtificial;
4453 unsigned LineNo = getLineNumber(Loc);
4454 unsigned ScopeLine = 0;
4455 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4457 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4459 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4460 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4461 llvm::DISubprogram *SP = DBuilder.createFunction(
4462 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4463 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4469 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4470 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4473 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4474 DBuilder.createParameterVariable(
4475 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4476 llvm::DINode::FlagZero, ParamAnnotations);
4482 if (IsDeclForCallSite)
4483 Fn->setSubprogram(SP);
4485 DBuilder.finalizeSubprogram(SP);
4493 auto *
Func = CallOrInvoke->getCalledFunction();
4496 if (
Func->getSubprogram())
4501 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4502 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4513 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4515 auto FI = SPCache.find(FD->getCanonicalDecl());
4516 llvm::DISubprogram *SP =
nullptr;
4517 if (FI != SPCache.end())
4518 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4519 if (!SP || !SP->isDefinition())
4520 SP = getFunctionStub(GD);
4521 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4522 LexicalBlockStack.emplace_back(SP);
4528 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4537 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4540 llvm::MDNode *
Scope = LexicalBlockStack.back();
4541 Builder.SetCurrentDebugLocation(
4542 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4543 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4547 llvm::MDNode *Back =
nullptr;
4548 if (!LexicalBlockStack.empty())
4549 Back = LexicalBlockStack.back().get();
4550 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4551 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4552 getColumnNumber(CurLoc)));
4555void CGDebugInfo::AppendAddressSpaceXDeref(
4557 std::optional<unsigned> DWARFAddressSpace =
4559 if (!DWARFAddressSpace)
4562 Expr.push_back(llvm::dwarf::DW_OP_constu);
4563 Expr.push_back(*DWARFAddressSpace);
4564 Expr.push_back(llvm::dwarf::DW_OP_swap);
4565 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4574 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4576 LexicalBlockStack.back(), CurInlinedAt));
4578 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4582 CreateLexicalBlock(Loc);
4587 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4592 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4595 LexicalBlockStack.pop_back();
4599 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4600 unsigned RCount = FnBeginRegionCount.back();
4601 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4604 while (LexicalBlockStack.size() != RCount) {
4607 LexicalBlockStack.pop_back();
4609 FnBeginRegionCount.pop_back();
4611 if (Fn && Fn->getSubprogram())
4612 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4615CGDebugInfo::BlockByRefType
4616CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4617 uint64_t *XOffset) {
4620 uint64_t FieldSize, FieldOffset;
4621 uint32_t FieldAlign;
4623 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4628 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4629 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4631 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4632 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4635 if (HasCopyAndDispose) {
4638 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4640 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4642 bool HasByrefExtendedLayout;
4645 HasByrefExtendedLayout) &&
4646 HasByrefExtendedLayout) {
4649 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4658 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4661 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4664 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4669 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4673 *XOffset = FieldOffset;
4674 llvm::DIType *FieldTy = DBuilder.createMemberType(
4675 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4676 llvm::DINode::FlagZero, WrappedTy);
4677 EltTys.push_back(FieldTy);
4678 FieldOffset += FieldSize;
4680 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4681 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4682 llvm::DINode::FlagZero,
nullptr, Elements),
4686llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4687 llvm::Value *Storage,
4688 std::optional<unsigned> ArgNo,
4690 const bool UsePointerValue) {
4692 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4693 if (VD->
hasAttr<NoDebugAttr>())
4699 llvm::DIFile *Unit =
nullptr;
4704 if (VD->
hasAttr<BlocksAttr>())
4705 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4707 Ty = getOrCreateType(VD->
getType(), Unit);
4722 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4724 Flags |= llvm::DINode::FlagArtificial;
4729 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4733 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4736 Flags |= llvm::DINode::FlagObjectPointer;
4743 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4744 StringRef Name = VD->
getName();
4745 if (!Name.empty()) {
4751 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4756 Expr.push_back(llvm::dwarf::DW_OP_deref);
4757 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4762 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4774 for (
const auto *Field : RD->
fields()) {
4775 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4776 StringRef FieldName =
Field->getName();
4779 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4784 auto *D = DBuilder.createAutoVariable(
4786 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4789 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4793 Builder.GetInsertBlock());
4801 if (UsePointerValue) {
4802 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4803 "Debug info already contains DW_OP_deref.");
4804 Expr.push_back(llvm::dwarf::DW_OP_deref);
4808 llvm::DILocalVariable *D =
nullptr;
4810 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4811 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit,
Line, Ty,
4822 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4825 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4828 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4829 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4830 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4833 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4839 if (
Iter != CoroutineParameterMappings.end()) {
4841 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4842 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4844 if (Iter2 != ParamDbgMappings.end())
4845 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4851 D = RemapCoroArgToLocalVar();
4854 D = DBuilder.createAutoVariable(
Scope, Name, Unit,
Line, Ty,
4858 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4861 Builder.GetInsertBlock());
4866llvm::DIType *CGDebugInfo::CreateBindingDeclType(
const BindingDecl *BD) {
4867 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4872 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4873 if (FD->isBitField()) {
4890 llvm::DIType *Ty = getOrCreateType(FinalTy, Unit);
4897 return getOrCreateType(BD->
getType(), Unit);
4900llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4901 llvm::Value *Storage,
4902 std::optional<unsigned> ArgNo,
4904 const bool UsePointerValue) {
4906 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4907 if (BD->
hasAttr<NoDebugAttr>())
4914 llvm::DIType *Ty = CreateBindingDeclType(BD);
4925 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4930 if (UsePointerValue) {
4931 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4932 "Debug info already contains DW_OP_deref.");
4933 Expr.push_back(llvm::dwarf::DW_OP_deref);
4938 StringRef Name = BD->
getName();
4939 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4940 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4942 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
4944 llvm::DINode::FlagZero, Align);
4947 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4948 const unsigned fieldIndex = FD->getFieldIndex();
4955 if (fieldOffset != 0) {
4961 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4967 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
4968 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
4969 const uint64_t value = IL->getValue().getZExtValue();
4973 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4982 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(
Expr),
4985 Builder.GetInsertBlock());
4990llvm::DILocalVariable *
4993 const bool UsePointerValue) {
4996 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
4997 for (
auto *B : DD->bindings()) {
4998 EmitDeclare(B, Storage, std::nullopt, Builder,
5006 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5011 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5013 if (D->
hasAttr<NoDebugAttr>())
5016 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5017 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5023 StringRef Name = D->
getName();
5030 DBuilder.insertLabel(L,
5032 Scope, CurInlinedAt),
5033 Builder.GetInsertBlock());
5036llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5038 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5041 return DBuilder.createObjectPointerType(Ty);
5046 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5048 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5050 if (Builder.GetInsertBlock() ==
nullptr)
5052 if (VD->
hasAttr<NoDebugAttr>())
5055 bool isByRef = VD->
hasAttr<BlocksAttr>();
5057 uint64_t XOffset = 0;
5058 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5061 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5063 Ty = getOrCreateType(VD->
getType(), Unit);
5067 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5069 Ty = CreateSelfType(VD->
getType(), Ty);
5072 const unsigned Line =
5083 addr.push_back(llvm::dwarf::DW_OP_deref);
5084 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5087 addr.push_back(llvm::dwarf::DW_OP_deref);
5088 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5093 addr.push_back(llvm::dwarf::DW_OP_deref);
5094 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5102 auto *D = DBuilder.createAutoVariable(
5103 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5104 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5108 LexicalBlockStack.back(), CurInlinedAt);
5109 auto *
Expr = DBuilder.createExpression(addr);
5111 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint);
5113 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5116llvm::DILocalVariable *
5119 bool UsePointerValue) {
5121 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5125struct BlockLayoutChunk {
5126 uint64_t OffsetInBits;
5129bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5130 return l.OffsetInBits < r.OffsetInBits;
5134void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5136 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5142 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5143 BlockLayout.getElementOffsetInBits(0),
5145 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5146 BlockLayout.getElementOffsetInBits(1),
5150 BlockLayout.getElementOffsetInBits(0),
5152 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5153 BlockLayout.getElementOffsetInBits(1),
5157 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5158 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5160 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5161 BlockLayout.getElementOffsetInBits(3),
5163 Fields.push_back(createFieldType(
5168 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5175 llvm::AllocaInst *Alloca,
5183 llvm::DIFile *tunit = getOrCreateFile(loc);
5184 unsigned line = getLineNumber(loc);
5185 unsigned column = getColumnNumber(loc);
5190 const llvm::StructLayout *blockLayout =
5194 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5203 BlockLayoutChunk chunk;
5204 chunk.OffsetInBits =
5205 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5206 chunk.Capture =
nullptr;
5207 chunks.push_back(chunk);
5211 for (
const auto &capture :
blockDecl->captures()) {
5212 const VarDecl *variable = capture.getVariable();
5219 BlockLayoutChunk chunk;
5220 chunk.OffsetInBits =
5221 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5222 chunk.Capture = &capture;
5223 chunks.push_back(chunk);
5227 llvm::array_pod_sort(chunks.begin(), chunks.end());
5229 for (
const BlockLayoutChunk &Chunk : chunks) {
5230 uint64_t offsetInBits = Chunk.OffsetInBits;
5237 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5239 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5242 llvm_unreachable(
"unexpected block declcontext");
5244 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5245 offsetInBits, tunit, tunit));
5250 StringRef name = variable->
getName();
5252 llvm::DIType *fieldType;
5254 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5259 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5260 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5261 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5262 PtrInfo.
Width, Align, offsetInBits,
5263 llvm::DINode::FlagZero, fieldType);
5267 offsetInBits, Align, tunit, tunit);
5269 fields.push_back(fieldType);
5273 llvm::raw_svector_ostream(typeName)
5276 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5278 llvm::DIType *
type =
5279 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5281 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5285 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5286 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5289 auto *debugVar = DBuilder.createParameterVariable(
5290 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5293 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5295 column, scope, CurInlinedAt),
5296 Builder.GetInsertBlock());
5299llvm::DIDerivedType *
5300CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5305 if (MI != StaticDataMemberCache.end()) {
5306 assert(MI->second &&
"Static data member declaration should still exist");
5313 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
5314 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
5317llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5318 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5319 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5320 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5322 for (
const auto *Field : RD->
fields()) {
5323 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5324 StringRef FieldName = Field->getName();
5327 if (FieldName.empty()) {
5328 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5329 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5334 GVE = DBuilder.createGlobalVariableExpression(
5335 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5336 Var->hasLocalLinkage());
5337 Var->addDebugInfo(GVE);
5349 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5354 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5362 case TemplateArgument::Pack:
5363 return ReferencesAnonymousEntity(TA.getPackAsArray());
5364 case TemplateArgument::Type: {
5365 struct ReferencesAnonymous
5366 : public RecursiveASTVisitor<ReferencesAnonymous> {
5367 bool RefAnon = false;
5368 bool VisitRecordType(RecordType *RT) {
5369 if (ReferencesAnonymousEntity(RT)) {
5376 ReferencesAnonymous RT;
5377 RT.TraverseType(TA.getAsType());
5390 bool Reconstitutable =
true;
5392 Reconstitutable =
false;
5396 Reconstitutable =
false;
5399 bool VisitType(
Type *
T) {
5403 Reconstitutable =
false;
5408 bool TraverseEnumType(
EnumType *ET) {
5411 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5413 Reconstitutable =
false;
5417 Reconstitutable =
false;
5427 return Reconstitutable;
5431 Reconstitutable =
false;
5441 ReconstitutableType
T;
5443 return T.Reconstitutable;
5446bool CGDebugInfo::HasReconstitutableArgs(
5450 case TemplateArgument::Template:
5457 case TemplateArgument::Declaration:
5466 case TemplateArgument::NullPtr:
5470 case TemplateArgument::Pack:
5473 return HasReconstitutableArgs(TA.getPackAsArray());
5474 case TemplateArgument::Integral:
5479 return TA.getAsIntegral().getBitWidth() <= 64 &&
5480 IsReconstitutableType(TA.getIntegralType());
5481 case TemplateArgument::StructuralValue:
5483 case TemplateArgument::Type:
5484 return IsReconstitutableType(TA.getAsType());
5485 case TemplateArgument::Expression:
5486 return IsReconstitutableType(TA.getAsExpr()->getType());
5488 llvm_unreachable(
"Other, unresolved, template arguments should "
5489 "not be seen here");
5494std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5496 llvm::raw_string_ostream OS(Name);
5497 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5500 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5504 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5506 std::optional<TemplateArgs> Args;
5508 bool IsOperatorOverload =
false;
5509 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5510 Args = GetTemplateArgs(RD);
5511 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5512 Args = GetTemplateArgs(FD);
5514 IsOperatorOverload |=
5517 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5518 Args = GetTemplateArgs(VD);
5542 bool Reconstitutable =
5543 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5547 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5551 bool Mangled = TemplateNamesKind ==
5552 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5558 std::string EncodedOriginalName;
5559 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5567 std::string CanonicalOriginalName;
5568 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5570 assert(EncodedOriginalNameOS.str() == OriginalOS.str());
5580 if (D->
hasAttr<NoDebugAttr>())
5583 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5584 return GetName(D,
true);
5590 if (Cached != DeclCache.end())
5591 return Var->addDebugInfo(
5592 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5595 llvm::DIFile *Unit =
nullptr;
5596 llvm::DIScope *DContext =
nullptr;
5598 StringRef DeclName, LinkageName;
5600 llvm::MDTuple *TemplateParameters =
nullptr;
5601 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5602 TemplateParameters, DContext);
5606 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5614 "unnamed non-anonymous struct or union?");
5615 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5622 if (D->
hasAttr<CUDASharedAttr>())
5625 else if (D->
hasAttr<CUDAConstantAttr>())
5629 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5631 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5632 GVE = DBuilder.createGlobalVariableExpression(
5633 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5634 Var->hasLocalLinkage(),
true,
5635 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5636 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5637 Align, Annotations);
5638 Var->addDebugInfo(GVE);
5645 if (VD->
hasAttr<NoDebugAttr>())
5647 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5648 return GetName(VD,
true);
5653 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5654 StringRef Name = VD->
getName();
5655 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5657 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5658 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5659 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5672 llvm::DIType *EDTy =
5674 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5685 auto *VarD = dyn_cast<VarDecl>(VD);
5686 if (VarD && VarD->isStaticDataMember()) {
5687 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5688 getDeclContextDescriptor(VarD);
5693 RetainedTypes.push_back(
5698 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5700 auto &GV = DeclCache[VD];
5704 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
5705 llvm::MDTuple *TemplateParameters =
nullptr;
5707 if (isa<VarTemplateSpecializationDecl>(VD))
5709 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5710 TemplateParameters = parameterNodes.get();
5713 GV.reset(DBuilder.createGlobalVariableExpression(
5714 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5715 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5716 TemplateParameters, Align));
5722 if (D->
hasAttr<NoDebugAttr>())
5726 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5727 StringRef Name = D->
getName();
5728 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
5730 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5731 llvm::DIGlobalVariableExpression *GVE =
5732 DBuilder.createGlobalVariableExpression(
5733 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
5734 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5735 Var->addDebugInfo(GVE);
5746 const auto *D = cast<ValueDecl>(GD.
getDecl());
5747 if (D->
hasAttr<NoDebugAttr>())
5765 if (!(DI = getDeclarationOrDefinition(
5766 AliaseeDecl.getCanonicalDecl().getDecl())))
5769 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5772 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5773 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
5786 llvm::DIFile *
File = getOrCreateFile(Loc);
5787 llvm::DIGlobalVariableExpression *Debug =
5788 DBuilder.createGlobalVariableExpression(
5789 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
5790 getLineNumber(Loc), getOrCreateType(S->getType(),
File),
true);
5791 GV->addDebugInfo(Debug);
5794llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
5795 if (!LexicalBlockStack.empty())
5796 return LexicalBlockStack.back();
5797 llvm::DIScope *Mod = getParentModuleOrNull(D);
5798 return getContextDescriptor(D, Mod ? Mod : TheCU);
5810 DBuilder.createImportedModule(
5812 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
5817 if (llvm::DINode *
Target =
5820 DBuilder.createImportedDeclaration(
5822 getOrCreateFile(Loc), getLineNumber(Loc));
5830 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5832 for (
const auto *USD : UD.
shadows()) {
5837 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5838 if (
const auto *AT = FD->getType()
5841 if (AT->getDeducedType().isNull())
5855 "We shouldn't be codegening an invalid UsingEnumDecl"
5856 " containing no decls");
5858 for (
const auto *USD : UD.
shadows())
5863 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5865 if (
Module *M = ID.getImportedModule()) {
5867 auto Loc = ID.getLocation();
5868 DBuilder.createImportedDeclaration(
5869 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
5870 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
5871 getLineNumber(Loc));
5875llvm::DIImportedEntity *
5879 auto &VH = NamespaceAliasCache[&NA];
5881 return cast<llvm::DIImportedEntity>(VH);
5882 llvm::DIImportedEntity *R;
5884 if (
const auto *Underlying =
5887 R = DBuilder.createImportedDeclaration(
5890 getLineNumber(Loc), NA.
getName());
5892 R = DBuilder.createImportedDeclaration(
5895 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
5901CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
5905 auto I = NamespaceCache.find(NSDecl);
5906 if (I != NamespaceCache.end())
5907 return cast<llvm::DINamespace>(I->second);
5909 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
5911 llvm::DINamespace *NS =
5912 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
5913 NamespaceCache[NSDecl].reset(NS);
5918 assert(TheCU &&
"no main compile unit");
5919 TheCU->setDWOId(Signature);
5925 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
5926 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
5927 llvm::DIType *Ty = E.Type->getDecl()->getDefinition()
5928 ? CreateTypeDefinition(E.Type, E.Unit)
5930 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
5934 for (
const auto &
P : ObjCMethodCache) {
5935 if (
P.second.empty())
5938 QualType QTy(
P.first->getTypeForDecl(), 0);
5940 assert(It != TypeCache.end());
5942 llvm::DICompositeType *InterfaceDecl =
5943 cast<llvm::DICompositeType>(It->second);
5945 auto CurElts = InterfaceDecl->getElements();
5949 for (
auto &SubprogramDirect :
P.second)
5950 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
5951 EltTys.push_back(SubprogramDirect.getPointer());
5953 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5954 DBuilder.replaceArrays(InterfaceDecl, Elements);
5957 for (
const auto &
P : ReplaceMap) {
5959 auto *Ty = cast<llvm::DIType>(
P.second);
5960 assert(Ty->isForwardDecl());
5962 auto It = TypeCache.find(
P.first);
5963 assert(It != TypeCache.end());
5966 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
5967 cast<llvm::DIType>(It->second));
5970 for (
const auto &
P : FwdDeclReplaceMap) {
5972 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
5973 llvm::Metadata *Repl;
5975 auto It = DeclCache.find(
P.first);
5979 if (It == DeclCache.end())
5984 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
5985 Repl = GVE->getVariable();
5986 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
5991 for (
auto &RT : RetainedTypes)
5992 if (
auto MD = TypeCache[RT])
5993 DBuilder.retainType(cast<llvm::DIType>(MD));
5995 DBuilder.finalize();
6001 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6002 DBuilder.retainType(DieTy);
6007 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6008 DBuilder.retainType(DieTy);
6012 if (LexicalBlockStack.empty())
6013 return llvm::DebugLoc();
6015 llvm::MDNode *
Scope = LexicalBlockStack.back();
6016 return llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(Loc),
6017 getColumnNumber(Loc),
Scope);
6020llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6024 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6025 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6026 return llvm::DINode::FlagZero;
6031 bool SupportsDWARFv4Ext =
6033 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6034 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6036 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6037 return llvm::DINode::FlagZero;
6039 return llvm::DINode::FlagAllCallsDescribed;
6050 return DBuilder.createConstantValueExpression(
6051 Val.
getFloat().bitcastToAPInt().getZExtValue());
6056 llvm::APSInt
const &ValInt = Val.
getInt();
6057 std::optional<uint64_t> ValIntOpt;
6058 if (ValInt.isUnsigned())
6059 ValIntOpt = ValInt.tryZExtValue();
6060 else if (
auto tmp = ValInt.trySExtValue())
6063 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6066 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.