40#include "llvm/ADT/DenseSet.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/DerivedTypes.h"
46#include "llvm/IR/Instructions.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/Metadata.h"
49#include "llvm/IR/Module.h"
50#include "llvm/Support/FileSystem.h"
51#include "llvm/Support/MD5.h"
52#include "llvm/Support/Path.h"
53#include "llvm/Support/SHA1.h"
54#include "llvm/Support/SHA256.h"
55#include "llvm/Support/TimeProfiler.h"
62 if (TI.isAlignRequired())
83 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
84 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
85 DBuilder(CGM.getModule()) {
90 assert(LexicalBlockStack.empty() &&
91 "Region stack mismatch, stack not empty!");
97 init(TemporaryLocation);
104 init(TemporaryLocation, DefaultToEmpty);
108 bool DefaultToEmpty) {
115 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
117 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
120 if (TemporaryLocation.
isValid()) {
121 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
125 if (DefaultToEmpty) {
126 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
131 assert(!DI->LexicalBlockStack.empty());
132 CGF->
Builder.SetCurrentDebugLocation(
133 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
134 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
148 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
150 CGF.
Builder.SetCurrentDebugLocation(std::move(
Loc));
157 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
168 SavedLocation = DI.getLocation();
169 assert((DI.getInlinedAt() ==
170 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
171 "CGDebugInfo and IRBuilder are out of sync");
173 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
181 DI.EmitLocation(CGF->
Builder, SavedLocation);
194 if (LexicalBlockStack.empty())
198 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
200 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
203 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
204 LexicalBlockStack.pop_back();
205 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
206 LBF->getScope(), getOrCreateFile(CurLoc)));
207 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
208 isa<llvm::DISubprogram>(
Scope)) {
209 LexicalBlockStack.pop_back();
210 LexicalBlockStack.emplace_back(
211 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
215llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *
D) {
216 llvm::DIScope *Mod = getParentModuleOrNull(
D);
221llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
226 auto I = RegionMap.find(Context);
227 if (I != RegionMap.end()) {
228 llvm::Metadata *
V = I->second;
229 return dyn_cast_or_null<llvm::DIScope>(
V);
233 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
234 return getOrCreateNamespace(NSDecl);
236 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
237 if (!RDecl->isDependentType())
271StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
272 return internString(GetName(FD));
275StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
277 llvm::raw_svector_ostream OS(MethodName);
280 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
281 OS << OID->getName();
282 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
283 OS << OID->getName();
284 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
285 if (OC->IsClassExtension()) {
286 OS << OC->getClassInterface()->getName();
288 OS << OC->getIdentifier()->getNameStart() <<
'('
289 << OC->getIdentifier()->getNameStart() <<
')';
291 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
292 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
296 return internString(OS.str());
299StringRef CGDebugInfo::getSelectorName(
Selector S) {
300 return internString(S.getAsString());
303StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
304 if (isa<ClassTemplateSpecializationDecl>(RD)) {
306 return internString(GetName(RD));
312 return II->getName();
320 "Typedef should not be in another decl context!");
321 assert(
D->getDeclName().getAsIdentifierInfo() &&
322 "Typedef was not named!");
323 return D->getDeclName().getAsIdentifierInfo()->getName();
333 Name = DD->getName();
338 Name = TND->getName();
341 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
342 if (CXXRD->isLambda())
350 return internString(UnnamedType);
358std::optional<llvm::DIFile::ChecksumKind>
367 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
371 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
374 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
375 return llvm::DIFile::CSK_MD5;
377 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
378 return llvm::DIFile::CSK_SHA1;
380 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
381 return llvm::DIFile::CSK_SHA256;
383 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
386std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
391 bool SourceInvalid =
false;
392 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
404 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
410 FileName = TheCU->getFile()->getFilename();
411 CSInfo = TheCU->getFile()->getChecksum();
417 FileName = TheCU->getFile()->getFilename();
425 auto It = DIFileCache.find(
FileName.data());
426 if (It != DIFileCache.end()) {
428 if (llvm::Metadata *
V = It->second)
429 return cast<llvm::DIFile>(
V);
435 std::optional<llvm::DIFile::ChecksumKind> CSKind =
436 computeChecksum(FID, Checksum);
438 CSInfo.emplace(*CSKind, Checksum);
443llvm::DIFile *CGDebugInfo::createFile(
445 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
446 std::optional<StringRef> Source) {
450 std::string CurDir =
remapDIPath(getCurrentDirname());
453 if (llvm::sys::path::is_absolute(RemappedFile)) {
456 auto FileIt = llvm::sys::path::begin(RemappedFile);
457 auto FileE = llvm::sys::path::end(RemappedFile);
458 auto CurDirIt = llvm::sys::path::begin(CurDir);
459 auto CurDirE = llvm::sys::path::end(CurDir);
460 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
461 llvm::sys::path::append(DirBuf, *CurDirIt);
462 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
468 for (; FileIt != FileE; ++FileIt)
469 llvm::sys::path::append(FileBuf, *FileIt);
474 if (!llvm::sys::path::is_absolute(
FileName))
478 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
479 DIFileCache[
FileName.data()].reset(F);
486 if (llvm::sys::path::replace_path_prefix(
P, From, To))
488 return P.str().str();
495 return SM.getPresumedLoc(
Loc).getLine();
511StringRef CGDebugInfo::getCurrentDirname() {
515 if (!CWDName.empty())
517 llvm::ErrorOr<std::string> CWD =
521 return CWDName = internString(*CWD);
524void CGDebugInfo::CreateCompileUnit() {
526 std::optional<llvm::DIFile::ChecksumKind> CSKind;
527 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
540 std::string MainFileName = CGO.MainFileName;
541 if (MainFileName.empty())
542 MainFileName =
"<stdin>";
548 std::string MainFileDir;
550 SM.getFileEntryRefForID(
SM.getMainFileID())) {
551 MainFileDir = std::string(MainFile->getDir().getName());
552 if (!llvm::sys::path::is_absolute(MainFileName)) {
554 llvm::sys::path::Style Style =
557 ? llvm::sys::path::Style::windows_backslash
558 : llvm::sys::path::Style::posix)
559 : llvm::sys::path::Style::native;
560 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
561 MainFileName = std::string(
562 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
569 if (MainFile->getName() == MainFileName &&
571 MainFile->getName().rsplit(
'.').second)
573 MainFileName = CGM.
getModule().getName().str();
575 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
579 llvm::dwarf::SourceLanguage LangTag;
582 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
583 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
584 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
585 else if (LO.CPlusPlus14)
586 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
587 else if (LO.CPlusPlus11)
588 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
590 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
591 }
else if (LO.ObjC) {
592 LangTag = llvm::dwarf::DW_LANG_ObjC;
593 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
595 LangTag = llvm::dwarf::DW_LANG_OpenCL;
596 }
else if (LO.RenderScript) {
597 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
598 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
599 LangTag = llvm::dwarf::DW_LANG_C11;
601 LangTag = llvm::dwarf::DW_LANG_C99;
603 LangTag = llvm::dwarf::DW_LANG_C89;
609 unsigned RuntimeVers = 0;
613 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
615 case llvm::codegenoptions::NoDebugInfo:
616 case llvm::codegenoptions::LocTrackingOnly:
617 EmissionKind = llvm::DICompileUnit::NoDebug;
619 case llvm::codegenoptions::DebugLineTablesOnly:
620 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
622 case llvm::codegenoptions::DebugDirectivesOnly:
623 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
625 case llvm::codegenoptions::DebugInfoConstructor:
626 case llvm::codegenoptions::LimitedDebugInfo:
627 case llvm::codegenoptions::FullDebugInfo:
628 case llvm::codegenoptions::UnusedTypeInfo:
629 EmissionKind = llvm::DICompileUnit::FullDebug;
640 CSInfo.emplace(*CSKind, Checksum);
641 llvm::DIFile *CUFile = DBuilder.createFile(
643 getSource(
SM,
SM.getMainFileID()));
645 StringRef Sysroot, SDK;
646 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
648 auto B = llvm::sys::path::rbegin(Sysroot);
649 auto E = llvm::sys::path::rend(Sysroot);
651 std::find_if(B,
E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
656 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
657 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
658 CGOpts.DebugNameTable);
660 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
662 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
665 TheCU = DBuilder.createCompileUnit(
666 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
667 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
668 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
669 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
670 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
673llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
677#define BUILTIN_TYPE(Id, SingletonId)
678#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
679#include "clang/AST/BuiltinTypes.def"
680 case BuiltinType::Dependent:
681 llvm_unreachable(
"Unexpected builtin type");
682 case BuiltinType::NullPtr:
683 return DBuilder.createNullPtrType();
684 case BuiltinType::Void:
686 case BuiltinType::ObjCClass:
689 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
690 "objc_class", TheCU, TheCU->getFile(), 0);
692 case BuiltinType::ObjCId: {
703 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
704 "objc_class", TheCU, TheCU->getFile(), 0);
708 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
710 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
711 0, 0, llvm::DINode::FlagZero,
nullptr,
712 llvm::DINodeArray());
714 DBuilder.replaceArrays(
715 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
716 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
717 llvm::DINode::FlagZero, ISATy)));
720 case BuiltinType::ObjCSel: {
722 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
723 "objc_selector", TheCU,
724 TheCU->getFile(), 0);
728#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
729 case BuiltinType::Id: \
730 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
732#include "clang/Basic/OpenCLImageTypes.def"
733 case BuiltinType::OCLSampler:
734 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
735 case BuiltinType::OCLEvent:
736 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
737 case BuiltinType::OCLClkEvent:
738 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
739 case BuiltinType::OCLQueue:
740 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
741 case BuiltinType::OCLReserveID:
742 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
743#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
744 case BuiltinType::Id: \
745 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
746#include "clang/Basic/OpenCLExtensionTypes.def"
748#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
749#include "clang/Basic/AArch64SVEACLETypes.def"
753 BT->
getKind() == BuiltinType::SveCount
757 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
764 "Unsupported number of vectors for svcount_t");
768 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
774 llvm::Metadata *LowerBound, *UpperBound;
775 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
777 if (Info.
EC.isScalable()) {
778 unsigned NumElemsPerVG = NumElems / 2;
780 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
781 46, 0, llvm::dwarf::DW_OP_mul,
782 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
783 UpperBound = DBuilder.createExpression(
Expr);
785 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
788 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
789 nullptr, LowerBound, UpperBound,
nullptr);
790 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
791 llvm::DIType *ElemTy =
792 getOrCreateType(Info.
ElementType, TheCU->getFile());
794 return DBuilder.createVectorType( 0, Align, ElemTy,
799#define PPC_VECTOR_TYPE(Name, Id, size) \
800 case BuiltinType::Id:
801#include "clang/Basic/PPCTypes.def"
804#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
805#include "clang/Basic/RISCVVTypes.def"
810 unsigned ElementCount = Info.
EC.getKnownMinValue();
813 bool Fractional =
false;
815 unsigned FixedSize = ElementCount * SEW;
819 }
else if (FixedSize < 64) {
822 LMUL = 64 / FixedSize;
824 LMUL = FixedSize / 64;
832 {llvm::dwarf::DW_OP_bregx,
835 llvm::dwarf::DW_OP_constu,
837 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
839 Expr.push_back(llvm::dwarf::DW_OP_div);
841 Expr.push_back(llvm::dwarf::DW_OP_mul);
843 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
846 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
848 auto *UpperBound = DBuilder.createExpression(
Expr);
849 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
850 nullptr, LowerBound, UpperBound,
nullptr);
851 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
852 llvm::DIType *ElemTy =
853 getOrCreateType(Info.
ElementType, TheCU->getFile());
856 return DBuilder.createVectorType(0, Align, ElemTy,
860#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
861 case BuiltinType::Id: { \
864 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
865 MangledName, TheCU, TheCU->getFile(), 0); \
866 return SingletonId; \
868#include "clang/Basic/WebAssemblyReferenceTypes.def"
869#define AMDGPU_OPAQUE_PTR_TYPE(Name, MangledName, AS, Width, Align, Id, \
871 case BuiltinType::Id: { \
874 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
875 MangledName, TheCU, TheCU->getFile(), 0); \
876 return SingletonId; \
878#include "clang/Basic/AMDGPUTypes.def"
879 case BuiltinType::UChar:
880 case BuiltinType::Char_U:
881 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
883 case BuiltinType::Char_S:
884 case BuiltinType::SChar:
885 Encoding = llvm::dwarf::DW_ATE_signed_char;
887 case BuiltinType::Char8:
888 case BuiltinType::Char16:
889 case BuiltinType::Char32:
892 case BuiltinType::UShort:
893 case BuiltinType::UInt:
894 case BuiltinType::UInt128:
895 case BuiltinType::ULong:
896 case BuiltinType::WChar_U:
897 case BuiltinType::ULongLong:
898 Encoding = llvm::dwarf::DW_ATE_unsigned;
900 case BuiltinType::Short:
901 case BuiltinType::Int:
902 case BuiltinType::Int128:
903 case BuiltinType::Long:
904 case BuiltinType::WChar_S:
905 case BuiltinType::LongLong:
906 Encoding = llvm::dwarf::DW_ATE_signed;
908 case BuiltinType::Bool:
909 Encoding = llvm::dwarf::DW_ATE_boolean;
911 case BuiltinType::Half:
912 case BuiltinType::Float:
913 case BuiltinType::LongDouble:
914 case BuiltinType::Float16:
915 case BuiltinType::BFloat16:
916 case BuiltinType::Float128:
917 case BuiltinType::Double:
918 case BuiltinType::Ibm128:
924 Encoding = llvm::dwarf::DW_ATE_float;
926 case BuiltinType::ShortAccum:
927 case BuiltinType::Accum:
928 case BuiltinType::LongAccum:
929 case BuiltinType::ShortFract:
930 case BuiltinType::Fract:
931 case BuiltinType::LongFract:
932 case BuiltinType::SatShortFract:
933 case BuiltinType::SatFract:
934 case BuiltinType::SatLongFract:
935 case BuiltinType::SatShortAccum:
936 case BuiltinType::SatAccum:
937 case BuiltinType::SatLongAccum:
938 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
940 case BuiltinType::UShortAccum:
941 case BuiltinType::UAccum:
942 case BuiltinType::ULongAccum:
943 case BuiltinType::UShortFract:
944 case BuiltinType::UFract:
945 case BuiltinType::ULongFract:
946 case BuiltinType::SatUShortAccum:
947 case BuiltinType::SatUAccum:
948 case BuiltinType::SatULongAccum:
949 case BuiltinType::SatUShortFract:
950 case BuiltinType::SatUFract:
951 case BuiltinType::SatULongFract:
952 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
959 return DBuilder.createBasicType(BTName, Size, Encoding);
962llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
964 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
966 ? llvm::dwarf::DW_ATE_unsigned
967 : llvm::dwarf::DW_ATE_signed;
973llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
975 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
977 Encoding = llvm::dwarf::DW_ATE_lo_user;
980 return DBuilder.createBasicType(
"complex", Size, Encoding);
994 return llvm::dwarf::DW_TAG_const_type;
998 return llvm::dwarf::DW_TAG_volatile_type;
1002 return llvm::dwarf::DW_TAG_restrict_type;
1004 return (llvm::dwarf::Tag)0;
1007llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
1008 llvm::DIFile *Unit) {
1018 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1019 return getOrCreateType(
QualType(
T, 0), Unit);
1026 return DBuilder.createQualifiedType(Tag, FromTy);
1030 llvm::DIFile *Unit) {
1039 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1050 return DBuilder.createQualifiedType(Tag, FromTy);
1054 llvm::DIFile *Unit) {
1062 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1066llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1067 llvm::DIFile *Unit) {
1068 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1074 switch (TheCU->getSourceLanguage()) {
1075 case llvm::dwarf::DW_LANG_C_plus_plus:
1076 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1077 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1079 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1080 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1108 llvm::DICompileUnit *TheCU) {
1126 llvm::DICompileUnit *TheCU) {
1132 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1134 if (RD->isDynamicClass() &&
1147 llvm::dwarf::Tag Tag;
1149 Tag = llvm::dwarf::DW_TAG_structure_type;
1151 Tag = llvm::dwarf::DW_TAG_union_type;
1156 Tag = llvm::dwarf::DW_TAG_class_type;
1161llvm::DICompositeType *
1162CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1163 llvm::DIScope *Ctx) {
1166 return cast<llvm::DICompositeType>(
T);
1167 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1168 const unsigned Line =
1170 StringRef RDName = getClassName(RD);
1176 if (
D &&
D->isCompleteDefinition())
1179 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1184 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1185 if (!CXXRD->hasDefinition() ||
1186 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1187 Flags |= llvm::DINode::FlagNonTrivial;
1194 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1198 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1199 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1200 CollectCXXTemplateParams(TSpecial, DefUnit));
1201 ReplaceMap.emplace_back(
1202 std::piecewise_construct, std::make_tuple(Ty),
1203 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1207llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1210 llvm::DIFile *Unit) {
1215 std::optional<unsigned> DWARFAddressSpace =
1220 auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1222 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1224 llvm::Metadata *Ops[2] = {
1225 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1227 Annots.insert(Annots.begin(),
1230 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1233 llvm::DINodeArray Annotations =
nullptr;
1234 if (Annots.size() > 0)
1235 Annotations = DBuilder.getOrCreateArray(Annots);
1237 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1238 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1239 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1240 Size, Align, DWARFAddressSpace);
1242 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1243 Align, DWARFAddressSpace, StringRef(),
1247llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1248 llvm::DIType *&
Cache) {
1251 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1252 TheCU, TheCU->getFile(), 0);
1254 Cache = DBuilder.createPointerType(
Cache, Size);
1258uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1259 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1272 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1273 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1276 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1278 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1279 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1281 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1285 EltTys.push_back(DBuilder.createMemberType(
1286 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1287 FieldOffset, llvm::DINode::FlagZero, DescTy));
1288 FieldOffset += FieldSize;
1295 llvm::DIFile *Unit) {
1299 llvm::DINodeArray Elements;
1303 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1304 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1306 Elements = DBuilder.getOrCreateArray(EltTys);
1309 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1312 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1313 FieldOffset, 0, Flags,
nullptr, Elements);
1318 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1320 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1323 Elements = DBuilder.getOrCreateArray(EltTys);
1329 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1330 Flags,
nullptr, Elements);
1332 return DBuilder.createPointerType(EltTy, Size);
1349 if (Param->isParameterPack()) {
1358 if (SubstArgs.empty()) {
1367 SpecArgs.push_back(SubstArgs.front());
1368 SubstArgs = SubstArgs.drop_front();
1374 llvm::DIFile *Unit) {
1379 if (isa<BuiltinTemplateDecl>(TD))
1382 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1387 llvm::raw_svector_ostream OS(NS);
1389 auto PP = getPrintingPolicy();
1416 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1425 llvm::raw_string_ostream OS(Name);
1428 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1429 !HasReconstitutableArgs(Args.Args))
1432 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1433 Src, Name, getOrCreateFile(
Loc), getLineNumber(
Loc),
1434 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1449 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(
Loc),
1466 return llvm::DINode::FlagZero;
1470 return llvm::DINode::FlagPrivate;
1472 return llvm::DINode::FlagProtected;
1474 return llvm::DINode::FlagPublic;
1476 return llvm::DINode::FlagZero;
1478 llvm_unreachable(
"unexpected access enumerator");
1481llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1482 llvm::DIFile *Unit) {
1483 llvm::DIType *Underlying =
1495 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1497 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1499 if (isa<RecordDecl>(DC))
1502 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1503 getOrCreateFile(
Loc), getLineNumber(
Loc),
1504 getDeclContextDescriptor(Ty->
getDecl()), Align,
1505 Flags, Annotations);
1515 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1517 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1519 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1521 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1523 return llvm::dwarf::DW_CC_BORLAND_pascal;
1525 return llvm::dwarf::DW_CC_LLVM_Win64;
1527 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1531 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1533 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1535 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1537 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1540 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1542 return llvm::dwarf::DW_CC_LLVM_Swift;
1544 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1546 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1548 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1550 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1552 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1554 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1556 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1562 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1564 Flags |= llvm::DINode::FlagLValueReference;
1566 Flags |= llvm::DINode::FlagRValueReference;
1570llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1571 llvm::DIFile *Unit) {
1572 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1574 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1583 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1585 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1589 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1592 for (
const QualType &ParamType : FPT->param_types())
1593 EltTys.push_back(getOrCreateType(ParamType, Unit));
1594 if (FPT->isVariadic())
1595 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1598 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1599 llvm::DIType *F = DBuilder.createSubroutineType(
1604llvm::DIDerivedType *
1605CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1606 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1607 StringRef Name = BitFieldDecl->
getName();
1609 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1610 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1612 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1613 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1616 llvm::DIFile *
File = getOrCreateFile(
Loc);
1617 unsigned Line = getLineNumber(
Loc);
1622 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1631 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1633 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1634 return DBuilder.createBitFieldMemberType(
1635 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1636 Flags, DebugType, Annotations);
1639llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1640 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1668 if (PreviousFieldsDI.empty())
1672 auto *PreviousMDEntry =
1673 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1674 auto *PreviousMDField =
1675 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1676 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1677 PreviousMDField->getSizeInBits() == 0)
1681 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1683 assert(PreviousBitfield->isBitField());
1686 if (!PreviousBitfield->isZeroLengthBitField(Context))
1689 QualType Ty = PreviousBitfield->getType();
1691 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1692 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1693 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1695 llvm::DIFile *
File = getOrCreateFile(
Loc);
1696 unsigned Line = getLineNumber(
Loc);
1699 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1702 llvm::DINode::DIFlags Flags =
1704 llvm::DINodeArray Annotations =
1705 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1706 return DBuilder.createBitFieldMemberType(
1707 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1708 Flags, DebugType, Annotations);
1711llvm::DIType *CGDebugInfo::createFieldType(
1713 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1714 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1715 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1718 llvm::DIFile *file = getOrCreateFile(loc);
1719 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1722 auto Align = AlignInBits;
1723 if (!
type->isIncompleteArrayType()) {
1725 SizeInBits = TI.
Width;
1731 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1732 offsetInBits, flags, debugType, Annotations);
1736CGDebugInfo::createInlinedTrapSubprogram(StringRef FuncName,
1737 llvm::DIFile *FileScope) {
1741 llvm::DISubprogram *&SP = InlinedTrapFuncMap[FuncName];
1744 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1745 SP = DBuilder.createFunction(
1746 FileScope, FuncName, StringRef(),
1747 FileScope, 0, DIFnTy,
1749 llvm::DINode::FlagArtificial,
1750 llvm::DISubprogram::SPFlagDefinition,
1751 nullptr,
nullptr,
nullptr);
1757void CGDebugInfo::CollectRecordLambdaFields(
1759 llvm::DIType *RecordTy) {
1765 unsigned fieldno = 0;
1768 I !=
E; ++I, ++Field, ++fieldno) {
1770 if (
C.capturesVariable()) {
1772 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1774 StringRef VName =
V->getName();
1775 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1777 llvm::DIType *FieldType = createFieldType(
1779 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1780 elements.push_back(FieldType);
1781 }
else if (
C.capturesThis()) {
1787 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1789 StringRef ThisName =
1791 llvm::DIType *fieldType = createFieldType(
1795 elements.push_back(fieldType);
1800llvm::DIDerivedType *
1801CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1806 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1807 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1809 unsigned LineNumber = getLineNumber(Var->
getLocation());
1810 StringRef VName = Var->
getName();
1814 llvm::Constant *
C =
nullptr;
1820 if (
Value->isFloat())
1827 ? llvm::dwarf::DW_TAG_variable
1828 : llvm::dwarf::DW_TAG_member;
1830 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1831 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1836void CGDebugInfo::CollectRecordNormalField(
1837 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1844 if (
name.empty() && !
type->isRecordType())
1847 llvm::DIType *FieldType;
1849 llvm::DIDerivedType *BitFieldType;
1850 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1851 if (llvm::DIType *Separator =
1852 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1853 elements.push_back(Separator);
1856 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1859 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1862 elements.push_back(FieldType);
1865void CGDebugInfo::CollectRecordNestedType(
1869 if (isa<InjectedClassNameType>(Ty))
1872 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(
Loc));
1873 elements.push_back(nestedType);
1876void CGDebugInfo::CollectRecordFields(
1877 const RecordDecl *record, llvm::DIFile *tunit,
1879 llvm::DICompositeType *RecordTy) {
1880 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1882 if (CXXDecl && CXXDecl->
isLambda())
1883 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1888 unsigned fieldNo = 0;
1892 for (
const auto *I : record->
decls())
1893 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1894 if (
V->hasAttr<NoDebugAttr>())
1900 isa<VarTemplateSpecializationDecl>(
V))
1903 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1907 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1908 if (MI != StaticDataMemberCache.end()) {
1909 assert(MI->second &&
1910 "Static data member declaration should still exist");
1911 elements.push_back(MI->second);
1913 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1914 elements.push_back(Field);
1916 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1917 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1918 elements, RecordTy, record);
1925 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1927 if (isa<RecordDecl>(I) &&
1928 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1930 if (!nestedType->isImplicit() &&
1931 nestedType->getDeclContext() == record)
1932 CollectRecordNestedType(nestedType, elements);
1938llvm::DISubroutineType *
1939CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1940 llvm::DIFile *Unit) {
1943 return cast_or_null<llvm::DISubroutineType>(
1945 return getOrCreateInstanceMethodType(Method->
getThisType(),
Func, Unit);
1948llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1964 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
1966 Func->getReturnType(),
Func->getParamTypes(), EPI),
1968 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
1969 assert(Args.size() &&
"Invalid number of arguments!");
1974 Elts.push_back(Args[0]);
1978 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1980 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1983 llvm::DIType *PointeeType =
1985 llvm::DIType *ThisPtrType =
1986 DBuilder.createPointerType(PointeeType, Size, Align);
1991 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1992 Elts.push_back(ThisPtrType);
1994 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1996 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1997 Elts.push_back(ThisPtrType);
2001 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
2002 Elts.push_back(Args[i]);
2004 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2006 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2013 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2020llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2021 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2023 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
2025 StringRef MethodName = getFunctionName(Method);
2026 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
2030 StringRef MethodLinkageName;
2040 llvm::DIFile *MethodDefUnit =
nullptr;
2041 unsigned MethodLine = 0;
2043 MethodDefUnit = getOrCreateFile(Method->
getLocation());
2044 MethodLine = getLineNumber(Method->
getLocation());
2048 llvm::DIType *ContainingType =
nullptr;
2049 unsigned VIndex = 0;
2050 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2051 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2056 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2058 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2063 if (!isa<CXXDestructorDecl>(Method))
2068 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
2080 Flags |= llvm::DINode::FlagIntroducedVirtual;
2089 ContainingType = RecordTy;
2093 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2096 Flags |= llvm::DINode::FlagNoReturn;
2099 Flags |= llvm::DINode::FlagStaticMember;
2101 Flags |= llvm::DINode::FlagArtificial;
2103 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
2104 if (CXXC->isExplicit())
2105 Flags |= llvm::DINode::FlagExplicit;
2106 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
2107 if (CXXC->isExplicit())
2108 Flags |= llvm::DINode::FlagExplicit;
2111 Flags |= llvm::DINode::FlagPrototyped;
2113 Flags |= llvm::DINode::FlagLValueReference;
2115 Flags |= llvm::DINode::FlagRValueReference;
2117 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2119 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2123 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2127 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2128 llvm::DISubprogram *SP = DBuilder.createMethod(
2129 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2130 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2131 TParamsArray.get());
2138void CGDebugInfo::CollectCXXMemberFunctions(
2145 for (
const auto *I : RD->
decls()) {
2146 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2170 EltTys.push_back(MI == SPCache.end()
2171 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2172 :
static_cast<llvm::Metadata *
>(MI->second));
2176void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2178 llvm::DIType *RecordTy) {
2180 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2181 llvm::DINode::FlagZero);
2186 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2187 llvm::DINode::FlagIndirectVirtualBase);
2191void CGDebugInfo::CollectCXXBasesAux(
2196 llvm::DINode::DIFlags StartingFlags) {
2198 for (
const auto &BI : Bases) {
2201 if (!SeenTypes.insert(
Base).second)
2203 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2204 llvm::DINode::DIFlags BFlags = StartingFlags;
2206 uint32_t VBPtrOffset = 0;
2208 if (BI.isVirtual()) {
2225 BFlags |= llvm::DINode::FlagVirtual;
2232 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2233 VBPtrOffset, BFlags);
2234 EltTys.push_back(DTy);
2239CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2240 llvm::DIFile *Unit) {
2242 return llvm::DINodeArray();
2243 TemplateArgs &Args = *OArgs;
2245 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2250 Name = Args.TList->getParam(i)->getName();
2254 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2255 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2256 TheCU, Name, TTy, defaultParameter));
2261 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2262 TheCU, Name, TTy, defaultParameter,
2268 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2269 llvm::Constant *
V =
nullptr;
2276 if (
const auto *VD = dyn_cast<VarDecl>(
D))
2280 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D);
2281 MD && MD->isImplicitObjectMemberFunction())
2283 else if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
2287 else if (
const auto *MPT =
2288 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2296 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(
D)) {
2298 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
2305 assert(
V &&
"Failed to find template parameter pointer");
2306 V =
V->stripPointerCasts();
2308 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2309 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2313 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2314 llvm::Constant *
V =
nullptr;
2317 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2323 if (MPT->isMemberDataPointer())
2326 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2327 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2328 TheCU, Name, TTy, defaultParameter,
V));
2332 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2335 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2336 TheCU, Name, TTy, defaultParameter,
V));
2339 std::string QualName;
2340 llvm::raw_string_ostream OS(QualName);
2342 OS, getPrintingPolicy());
2343 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2344 TheCU, Name,
nullptr, OS.str(), defaultParameter));
2348 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2349 TheCU, Name,
nullptr,
2358 assert(
V &&
"Expression in template argument isn't constant");
2359 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2360 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2361 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2367 "These argument types shouldn't exist in concrete types");
2370 return DBuilder.getOrCreateArray(TemplateParams);
2373std::optional<CGDebugInfo::TemplateArgs>
2374CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2382 return std::nullopt;
2384std::optional<CGDebugInfo::TemplateArgs>
2385CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2389 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2391 return std::nullopt;
2394 auto TA = TS->getTemplateArgs().asArray();
2395 return {{TList, TA}};
2397std::optional<CGDebugInfo::TemplateArgs>
2398CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2399 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2404 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2406 return {{TPList, TAList.
asArray()}};
2408 return std::nullopt;
2412CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2413 llvm::DIFile *Unit) {
2414 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2417llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2418 llvm::DIFile *Unit) {
2419 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2422llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2423 llvm::DIFile *Unit) {
2424 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2427llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *
D) {
2433 llvm::Metadata *Ops[2] = {
2434 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2436 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2438 return DBuilder.getOrCreateArray(Annotations);
2441llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2443 return VTablePtrType;
2448 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2449 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2450 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2453 std::optional<unsigned> DWARFAddressSpace =
2456 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2457 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2458 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2459 return VTablePtrType;
2462StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2467StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2469 llvm::Function *InitFn) {
2474 return InitFn->getName();
2484 llvm::raw_svector_ostream OS(QualifiedGV);
2486 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2488 std::swap(Quals, GVName);
2492 llvm::raw_svector_ostream OS(InitName);
2494 OS << Quals <<
"::";
2499 llvm_unreachable(
"not an initializer");
2501 OS <<
"`dynamic initializer for '";
2504 OS <<
"`dynamic atexit destructor for '";
2511 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2513 getPrintingPolicy());
2518 return internString(OS.str());
2521void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2538 llvm::DIType *VPtrTy =
nullptr;
2541 if (NeedVTableShape) {
2546 unsigned VSlotCount =
2548 unsigned VTableWidth = PtrWidth * VSlotCount;
2550 std::optional<unsigned> DWARFAddressSpace =
2554 llvm::DIType *VTableType = DBuilder.createPointerType(
2555 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2556 EltTys.push_back(VTableType);
2559 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2567 VPtrTy = getOrCreateVTablePtrType(Unit);
2570 llvm::DIType *VPtrMember =
2571 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2572 llvm::DINode::FlagArtificial, VPtrTy);
2573 EltTys.push_back(VPtrMember);
2579 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(
Loc));
2591 assert(!
D.isNull() &&
"null type");
2592 llvm::DIType *
T = getOrCreateType(
D, getOrCreateFile(
Loc));
2593 assert(
T &&
"could not create debug info for type");
2595 RetainedTypes.push_back(
D.getAsOpaquePtr());
2603 llvm::codegenoptions::DebugLineTablesOnly)
2609 node = getOrCreateType(AllocatedTy, getOrCreateFile(
Loc));
2611 CI->setMetadata(
"heapallocsite", node);
2615 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2619 auto I = TypeCache.find(TyPtr);
2620 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2622 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2623 assert(!Res->isForwardDecl());
2624 TypeCache[TyPtr].reset(Res);
2628 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2635 if (RD->
hasAttr<DLLImportAttr>())
2638 if (MD->hasAttr<DLLImportAttr>())
2651 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2660 bool Explicit =
false;
2661 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2662 Explicit = TD->isExplicitInstantiationOrSpecialization();
2676 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2677 if (CXXRD->isDynamicClass() &&
2679 llvm::GlobalValue::AvailableExternallyLinkage &&
2690 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2694 auto I = TypeCache.find(TyPtr);
2695 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2702 assert(!Res->isForwardDecl());
2703 TypeCache[TyPtr].reset(Res);
2710 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2711 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2734 if (Ctor->isCopyOrMoveConstructor())
2736 if (!Ctor->isDeleted())
2755 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2758 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2759 RD->
hasAttr<StandaloneDebugAttr>())
2762 if (!LangOpts.CPlusPlus)
2768 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2784 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2785 Spec = SD->getSpecializationKind();
2794 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2806 llvm::DIType *
T = getTypeOrNull(Ty);
2807 if (
T &&
T->isForwardDecl())
2811llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2813 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2817 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2821 auto [Def, Pref] = CreateTypeDefinition(Ty);
2823 return Pref ? Pref : Def;
2826llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2827 llvm::DIFile *Unit) {
2831 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2835 return getOrCreateType(PNA->getTypedefType(), Unit);
2838std::pair<llvm::DIType *, llvm::DIType *>
2839CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2843 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2851 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2854 if (!
D || !
D->isCompleteDefinition())
2855 return {FwdDecl,
nullptr};
2857 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2858 CollectContainingType(CXXDecl, FwdDecl);
2861 LexicalBlockStack.emplace_back(&*FwdDecl);
2862 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2872 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2874 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2875 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2879 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2880 if (CXXDecl && !CGM.
getCodeGenOpts().DebugOmitUnreferencedMethods)
2881 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2883 LexicalBlockStack.pop_back();
2884 RegionMap.erase(Ty->
getDecl());
2886 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2887 DBuilder.replaceArrays(FwdDecl, Elements);
2889 if (FwdDecl->isTemporary())
2891 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2893 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2895 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2896 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2897 return {FwdDecl, PrefDI};
2899 return {FwdDecl,
nullptr};
2903 llvm::DIFile *Unit) {
2909 llvm::DIFile *Unit) {
2914 return DBuilder.createTypedef(
2917 getDeclContextDescriptor(Ty->
getDecl()));
2945 llvm::DIFile *Unit) {
2953 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2954 !
ID->getImplementation())
2955 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2957 getDeclContextDescriptor(ID), Unit, 0);
2960 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2961 unsigned Line = getLineNumber(
ID->getLocation());
2963 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2969 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2970 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2971 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
2972 DefUnit,
Line, RuntimeLang);
2973 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2977 return CreateTypeDefinition(Ty, Unit);
2981 bool CreateSkeletonCU) {
2986 auto ModRef = ModuleCache.find(M);
2987 if (ModRef != ModuleCache.end())
2988 return cast<llvm::DIModule>(ModRef->second);
2993 llvm::raw_svector_ostream OS(ConfigMacros);
2997 for (
auto &M : PPOpts.Macros) {
3000 const std::string &
Macro = M.first;
3001 bool Undef = M.second;
3002 OS <<
"\"-" << (Undef ?
'U' :
'D');
3003 for (
char c : Macro)
3018 bool IsRootModule = M ? !M->
Parent :
true;
3022 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3024 "clang module without ASTFile must be specified by -fmodule-name");
3027 auto RemapPath = [
this](StringRef
Path) -> std::string {
3029 StringRef Relative(Remapped);
3030 StringRef CompDir = TheCU->getDirectory();
3031 if (Relative.consume_front(CompDir))
3032 Relative.consume_front(llvm::sys::path::get_separator());
3034 return Relative.str();
3037 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3044 Signature = ModSig.truncatedValue();
3050 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3052 PCM = getCurrentDirname();
3056 llvm::sys::path::append(PCM, Mod.
getASTFile());
3057 DIB.createCompileUnit(
3058 TheCU->getSourceLanguage(),
3061 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3062 llvm::DICompileUnit::FullDebug, Signature);
3067 IsRootModule ? nullptr
3070 std::string IncludePath = Mod.
getPath().str();
3071 llvm::DIModule *DIMod =
3073 RemapPath(IncludePath));
3074 ModuleCache[M].reset(DIMod);
3079 llvm::DIFile *Unit) {
3081 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3082 unsigned Line = getLineNumber(
ID->getLocation());
3083 unsigned RuntimeLang = TheCU->getSourceLanguage();
3089 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3090 if (
ID->getImplementation())
3091 Flags |= llvm::DINode::FlagObjcClassComplete;
3093 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3094 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3095 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3096 nullptr, llvm::DINodeArray(), RuntimeLang);
3099 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3102 LexicalBlockStack.emplace_back(RealDecl);
3103 RegionMap[Ty->
getDecl()].reset(RealDecl);
3110 llvm::DIType *SClassTy =
3115 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3116 llvm::DINode::FlagZero);
3117 EltTys.push_back(InhTag);
3123 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3124 unsigned PLine = getLineNumber(
Loc);
3127 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3128 PD->getName(), PUnit, PLine,
3130 : getSelectorName(PD->getGetterName()),
3132 : getSelectorName(PD->getSetterName()),
3133 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3134 EltTys.push_back(PropertyNode);
3139 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3146 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3149 for (
auto *PD : ClassExt->properties()) {
3150 PropertySet.insert(GetIsClassAndIdent(PD));
3153 for (
const auto *PD :
ID->properties()) {
3156 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3163 unsigned FieldNo = 0;
3165 Field =
Field->getNextIvar(), ++FieldNo) {
3166 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3170 StringRef FieldName =
Field->getName();
3173 if (FieldName.empty())
3177 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3178 unsigned FieldLine = getLineNumber(
Field->getLocation());
3181 uint32_t FieldAlign = 0;
3186 FieldSize =
Field->isBitField()
3197 if (
Field->isBitField()) {
3208 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3210 Flags = llvm::DINode::FlagProtected;
3212 Flags = llvm::DINode::FlagPrivate;
3214 Flags = llvm::DINode::FlagPublic;
3216 if (
Field->isBitField())
3217 Flags |= llvm::DINode::FlagBitField;
3219 llvm::MDNode *PropertyNode =
nullptr;
3222 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3225 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3226 unsigned PLine = getLineNumber(
Loc);
3229 PropertyNode = DBuilder.createObjCProperty(
3230 PD->getName(), PUnit, PLine,
3233 : getSelectorName(PD->getGetterName()),
3236 : getSelectorName(PD->getSetterName()),
3237 PD->getPropertyAttributes(),
3238 getOrCreateType(PD->getType(), PUnit));
3242 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3243 FieldSize, FieldAlign, FieldOffset, Flags,
3244 FieldTy, PropertyNode);
3245 EltTys.push_back(FieldTy);
3248 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3249 DBuilder.replaceArrays(RealDecl, Elements);
3251 LexicalBlockStack.pop_back();
3255llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3256 llvm::DIFile *Unit) {
3274 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3277 llvm::Metadata *Subscript;
3279 auto SizeExpr = SizeExprCache.find(QTy);
3280 if (SizeExpr != SizeExprCache.end())
3281 Subscript = DBuilder.getOrCreateSubrange(
3282 SizeExpr->getSecond() ,
nullptr ,
3283 nullptr ,
nullptr );
3286 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3287 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3288 Subscript = DBuilder.getOrCreateSubrange(
3289 CountNode ,
nullptr ,
nullptr ,
3292 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3297 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3301 llvm::DIFile *Unit) {
3305 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3311 auto *ColumnCountNode =
3312 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3314 auto *RowCountNode =
3315 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3317 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3318 ColumnCountNode ,
nullptr ,
nullptr ,
3320 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3321 RowCountNode ,
nullptr ,
nullptr ,
3323 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3324 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3327llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3332 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3356 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3365 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3366 Count = CAT->getZExtSize();
3367 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3368 if (
Expr *Size = VAT->getSizeExpr()) {
3371 Count =
Result.Val.getInt().getExtValue();
3375 auto SizeNode = SizeExprCache.find(EltTy);
3376 if (SizeNode != SizeExprCache.end())
3377 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3378 SizeNode->getSecond() ,
nullptr ,
3379 nullptr ,
nullptr ));
3382 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3384 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3385 CountNode ,
nullptr ,
nullptr ,
3391 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3393 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3398 llvm::DIFile *Unit) {
3399 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3404 llvm::DIFile *Unit) {
3405 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3409 Tag = llvm::dwarf::DW_TAG_reference_type;
3411 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3416 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3426 Flags |= llvm::DINode::FlagSingleInheritance;
3429 Flags |= llvm::DINode::FlagMultipleInheritance;
3432 Flags |= llvm::DINode::FlagVirtualInheritance;
3442 return DBuilder.createMemberPointerType(
3448 return DBuilder.createMemberPointerType(
3449 getOrCreateInstanceMethodType(
3452 ClassType,
Size, 0, Flags);
3455llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3457 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3460llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3464llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3476 bool isImportedFromModule =
3488 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3489 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3490 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3491 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3494 StringRef EDName = ED->
getName();
3495 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3496 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3497 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3499 ReplaceMap.emplace_back(
3500 std::piecewise_construct, std::make_tuple(Ty),
3501 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3505 return CreateTypeDefinition(Ty);
3508llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3522 Enumerators.push_back(
3523 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3527 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3529 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3531 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3532 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3533 return DBuilder.createEnumerationType(
3534 EnumContext, ED->
getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3540 StringRef Name, StringRef
Value) {
3541 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3548 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3549 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3550 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3554 llvm::DebugLoc TrapLocation, StringRef
Category, StringRef FailureMsg) {
3562 FuncName += FailureMsg;
3564 llvm::DISubprogram *TrapSP =
3565 createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());
3567 TrapSP, TrapLocation);
3577 Quals += InnerQuals;
3581 return C.getQualifiedType(
T.getTypePtr(), Quals);
3582 case Type::TemplateSpecialization: {
3583 const auto *Spec = cast<TemplateSpecializationType>(
T);
3584 if (Spec->isTypeAlias())
3585 return C.getQualifiedType(
T.getTypePtr(), Quals);
3589 case Type::TypeOfExpr:
3590 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3593 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3595 case Type::Decltype:
3596 T = cast<DecltypeType>(
T)->getUnderlyingType();
3598 case Type::UnaryTransform:
3599 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3601 case Type::Attributed:
3602 T = cast<AttributedType>(
T)->getEquivalentType();
3604 case Type::BTFTagAttributed:
3605 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3607 case Type::CountAttributed:
3608 T = cast<CountAttributedType>(
T)->
desugar();
3610 case Type::Elaborated:
3611 T = cast<ElaboratedType>(
T)->getNamedType();
3614 T = cast<UsingType>(
T)->getUnderlyingType();
3617 T = cast<ParenType>(
T)->getInnerType();
3619 case Type::MacroQualified:
3620 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3622 case Type::SubstTemplateTypeParm:
3623 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3626 case Type::DeducedTemplateSpecialization: {
3627 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3628 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3632 case Type::PackIndexing: {
3633 T = cast<PackIndexingType>(
T)->getSelectedType();
3636 case Type::Adjusted:
3639 T = cast<AdjustedType>(
T)->getAdjustedType();
3643 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3648llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3651 if (It != TypeCache.end()) {
3653 if (llvm::Metadata *
V = It->second)
3654 return cast<llvm::DIType>(
V);
3666 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3676llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3680 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3682 llvm::raw_string_ostream OS(Name);
3683 Ty.
print(OS, getPrintingPolicy());
3690 if (
auto *
T = getTypeOrNull(Ty))
3693 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3694 void *TyPtr = Ty.getAsOpaquePtr();
3697 TypeCache[TyPtr].reset(Res);
3702llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *
D) {
3710 auto Info = Reader->getSourceDescriptor(Idx);
3712 return getOrCreateModuleRef(*Info,
true);
3713 }
else if (ClangModuleMap) {
3727 return getOrCreateModuleRef(Info,
false);
3730 return getOrCreateModuleRef(PCHDescriptor,
false);
3737llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3740 return CreateQualifiedType(Ty, Unit);
3744#define TYPE(Class, Base)
3745#define ABSTRACT_TYPE(Class, Base)
3746#define NON_CANONICAL_TYPE(Class, Base)
3747#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3748#include "clang/AST/TypeNodes.inc"
3749 llvm_unreachable(
"Dependent types cannot show up in debug information");
3751 case Type::ExtVector:
3753 return CreateType(cast<VectorType>(Ty), Unit);
3754 case Type::ConstantMatrix:
3755 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3756 case Type::ObjCObjectPointer:
3757 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3758 case Type::ObjCObject:
3759 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3760 case Type::ObjCTypeParam:
3761 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3762 case Type::ObjCInterface:
3763 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3765 return CreateType(cast<BuiltinType>(Ty));
3767 return CreateType(cast<ComplexType>(Ty));
3769 return CreateType(cast<PointerType>(Ty), Unit);
3770 case Type::BlockPointer:
3771 return CreateType(cast<BlockPointerType>(Ty), Unit);
3773 return CreateType(cast<TypedefType>(Ty), Unit);
3775 return CreateType(cast<RecordType>(Ty));
3777 return CreateEnumType(cast<EnumType>(Ty));
3778 case Type::FunctionProto:
3779 case Type::FunctionNoProto:
3780 return CreateType(cast<FunctionType>(Ty), Unit);
3781 case Type::ConstantArray:
3782 case Type::VariableArray:
3783 case Type::IncompleteArray:
3784 case Type::ArrayParameter:
3785 return CreateType(cast<ArrayType>(Ty), Unit);
3787 case Type::LValueReference:
3788 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3789 case Type::RValueReference:
3790 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3792 case Type::MemberPointer:
3793 return CreateType(cast<MemberPointerType>(Ty), Unit);
3796 return CreateType(cast<AtomicType>(Ty), Unit);
3799 return CreateType(cast<BitIntType>(Ty));
3801 return CreateType(cast<PipeType>(Ty), Unit);
3803 case Type::TemplateSpecialization:
3804 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3806 case Type::CountAttributed:
3808 case Type::Attributed:
3809 case Type::BTFTagAttributed:
3810 case Type::Adjusted:
3812 case Type::DeducedTemplateSpecialization:
3813 case Type::Elaborated:
3816 case Type::MacroQualified:
3817 case Type::SubstTemplateTypeParm:
3818 case Type::TypeOfExpr:
3820 case Type::Decltype:
3821 case Type::PackIndexing:
3822 case Type::UnaryTransform:
3826 llvm_unreachable(
"type should have been unwrapped!");
3829llvm::DICompositeType *
3830CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3833 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3838 if (
T && !
T->isForwardDecl())
3842 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3847 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
3850 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3855llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3859 StringRef RDName = getClassName(RD);
3861 llvm::DIFile *DefUnit =
nullptr;
3864 DefUnit = getOrCreateFile(
Loc);
3868 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3872 auto *
T = cast_or_null<llvm::DICompositeType>(
3880 if (!
D || !
D->isCompleteDefinition())
3881 return getOrCreateRecordFwdDecl(Ty, RDContext);
3894 auto Flags = llvm::DINode::FlagZero;
3895 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3897 Flags |= llvm::DINode::FlagTypePassByReference;
3899 Flags |= llvm::DINode::FlagTypePassByValue;
3902 if (!CXXRD->isTrivial())
3903 Flags |= llvm::DINode::FlagNonTrivial;
3906 if (CXXRD->isAnonymousStructOrUnion())
3907 Flags |= llvm::DINode::FlagExportSymbols;
3910 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3913 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
3914 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3920 switch (RealDecl->getTag()) {
3922 llvm_unreachable(
"invalid composite type tag");
3924 case llvm::dwarf::DW_TAG_array_type:
3925 case llvm::dwarf::DW_TAG_enumeration_type:
3934 case llvm::dwarf::DW_TAG_structure_type:
3935 case llvm::dwarf::DW_TAG_union_type:
3936 case llvm::dwarf::DW_TAG_class_type:
3939 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3943 RegionMap[Ty->
getDecl()].reset(RealDecl);
3946 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3947 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3948 CollectCXXTemplateParams(TSpecial, DefUnit));
3952void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3953 llvm::DICompositeType *RealDecl) {
3955 llvm::DIType *ContainingType =
nullptr;
3967 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3970 ContainingType = RealDecl;
3972 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3975llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3976 StringRef Name, uint64_t *Offset) {
3977 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3981 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3982 *Offset, llvm::DINode::FlagZero, FieldTy);
3983 *Offset += FieldSize;
3987void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3989 StringRef &LinkageName,
3990 llvm::DIScope *&FDContext,
3991 llvm::DINodeArray &TParamsArray,
3992 llvm::DINode::DIFlags &Flags) {
3994 Name = getFunctionName(FD);
3999 Flags |= llvm::DINode::FlagPrototyped;
4003 if (LinkageName == Name ||
4008 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4009 LinkageName = StringRef();
4014 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4018 FDContext = getOrCreateNamespace(NSDecl);
4021 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4022 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4028 Flags |= llvm::DINode::FlagNoReturn;
4030 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4034void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4036 StringRef &Name, StringRef &LinkageName,
4037 llvm::MDTuple *&TemplateParameters,
4038 llvm::DIScope *&VDContext) {
4047 llvm::APInt ConstVal(32, 1);
4058 if (LinkageName == Name)
4059 LinkageName = StringRef();
4061 if (isa<VarTemplateSpecializationDecl>(VD)) {
4062 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4063 TemplateParameters = parameterNodes.get();
4065 TemplateParameters =
nullptr;
4085 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4086 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4089llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4091 llvm::DINodeArray TParamsArray;
4092 StringRef Name, LinkageName;
4093 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4094 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4096 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4097 llvm::DIScope *DContext = Unit;
4098 unsigned Line = getLineNumber(
Loc);
4099 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4101 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4106 ArgTypes.push_back(Parm->getType());
4112 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4114 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4117 Flags |= getCallSiteRelatedAttrs();
4118 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4119 return DBuilder.createFunction(
4120 DContext, Name, LinkageName, Unit,
Line,
4121 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4122 TParamsArray.get(), getFunctionDeclaration(FD));
4125 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4126 DContext, Name, LinkageName, Unit,
Line,
4127 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4128 TParamsArray.get(), getFunctionDeclaration(FD));
4130 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4131 std::make_tuple(CanonDecl),
4132 std::make_tuple(SP));
4136llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4137 return getFunctionFwdDeclOrStub(GD,
false);
4140llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4141 return getFunctionFwdDeclOrStub(GD,
true);
4144llvm::DIGlobalVariable *
4145CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4147 StringRef Name, LinkageName;
4149 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4150 llvm::DIScope *DContext = Unit;
4151 unsigned Line = getLineNumber(
Loc);
4152 llvm::MDTuple *TemplateParameters =
nullptr;
4154 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4157 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4158 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4160 FwdDeclReplaceMap.emplace_back(
4161 std::piecewise_construct,
4163 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4167llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *
D) {
4172 if (
const auto *TD = dyn_cast<TypeDecl>(
D))
4177 if (I != DeclCache.end()) {
4179 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4180 return GVE->getVariable();
4181 return cast<llvm::DINode>(N);
4188 if (IE != ImportedDeclCache.end()) {
4189 auto N = IE->second;
4190 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4191 return cast<llvm::DINode>(GVE);
4192 return dyn_cast_or_null<llvm::DINode>(N);
4197 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4198 return getFunctionForwardDeclaration(FD);
4199 else if (
const auto *VD = dyn_cast<VarDecl>(
D))
4200 return getGlobalVariableForwardDeclaration(VD);
4205llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *
D) {
4206 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4209 const auto *FD = dyn_cast<FunctionDecl>(
D);
4214 auto *S = getDeclContextDescriptor(
D);
4217 if (MI == SPCache.end()) {
4219 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4220 cast<llvm::DICompositeType>(S));
4223 if (MI != SPCache.end()) {
4224 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4225 if (SP && !SP->isDefinition())
4229 for (
auto *NextFD : FD->
redecls()) {
4230 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4231 if (MI != SPCache.end()) {
4232 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4233 if (SP && !SP->isDefinition())
4240llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4241 const Decl *
D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4242 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4243 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4246 const auto *OMD = dyn_cast<ObjCMethodDecl>(
D);
4254 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4264 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4265 if (It == TypeCache.end())
4267 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4268 llvm::DISubprogram *FD = DBuilder.createFunction(
4269 InterfaceType, getObjCMethodName(OMD), StringRef(),
4270 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4271 DBuilder.finalizeSubprogram(FD);
4278llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *
D,
4283 if (!
D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4287 return DBuilder.createSubroutineType(
4288 DBuilder.getOrCreateTypeArray(std::nullopt));
4290 if (
const auto *Method = dyn_cast<CXXMethodDecl>(
D))
4291 return getOrCreateMethodType(Method, F);
4296 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(
D)) {
4301 QualType ResultTy = OMethod->getReturnType();
4306 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4308 Elts.push_back(getOrCreateType(ResultTy, F));
4311 if (
auto *SelfDecl = OMethod->getSelfDecl())
4312 SelfDeclTy = SelfDecl->getType();
4313 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4316 if (!SelfDeclTy.
isNull())
4318 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4320 Elts.push_back(DBuilder.createArtificialType(
4323 for (
const auto *PI : OMethod->parameters())
4324 Elts.push_back(getOrCreateType(PI->getType(), F));
4326 if (OMethod->isVariadic())
4327 Elts.push_back(DBuilder.createUnspecifiedParameter());
4329 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4330 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4336 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4337 if (FD->isVariadic()) {
4339 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4340 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4342 EltTys.push_back(getOrCreateType(ParamType, F));
4343 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4344 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4345 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4349 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4358 CC = SrcFnTy->getCallConv();
4360 for (
const VarDecl *VD : Args)
4361 ArgTypes.push_back(VD->
getType());
4368 llvm::Function *Fn,
bool CurFuncIsThunk) {
4370 StringRef LinkageName;
4372 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4375 bool HasDecl = (
D !=
nullptr);
4377 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4378 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4379 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4380 llvm::DIScope *FDContext = Unit;
4381 llvm::DINodeArray TParamsArray;
4384 LinkageName = Fn->getName();
4385 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
4387 auto FI = SPCache.find(FD->getCanonicalDecl());
4388 if (FI != SPCache.end()) {
4389 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4390 if (SP && SP->isDefinition()) {
4391 LexicalBlockStack.emplace_back(SP);
4392 RegionMap[
D].reset(SP);
4396 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4397 TParamsArray, Flags);
4398 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4399 Name = getObjCMethodName(OMD);
4400 Flags |= llvm::DINode::FlagPrototyped;
4401 }
else if (isa<VarDecl>(
D) &&
4407 Name = Fn->getName();
4409 if (isa<BlockDecl>(
D))
4412 Flags |= llvm::DINode::FlagPrototyped;
4414 if (Name.starts_with(
"\01"))
4415 Name = Name.substr(1);
4417 assert((!
D || !isa<VarDecl>(
D) ||
4419 "Unexpected DynamicInitKind !");
4422 isa<VarDecl>(
D) || isa<CapturedDecl>(
D)) {
4423 Flags |= llvm::DINode::FlagArtificial;
4429 Flags |= llvm::DINode::FlagThunk;
4431 if (Fn->hasLocalLinkage())
4432 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4434 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4436 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4437 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4438 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4440 const unsigned LineNo = getLineNumber(
Loc.
isValid() ?
Loc : CurLoc);
4441 unsigned ScopeLine = getLineNumber(ScopeLoc);
4442 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(
D, FnType, Unit);
4443 llvm::DISubprogram *
Decl =
nullptr;
4444 llvm::DINodeArray Annotations =
nullptr;
4446 Decl = isa<ObjCMethodDecl>(
D)
4447 ? getObjCMethodDeclaration(
D, DIFnType, LineNo, Flags, SPFlags)
4448 : getFunctionDeclaration(
D);
4449 Annotations = CollectBTFDeclTagAnnotations(
D);
4457 llvm::DISubprogram *SP = DBuilder.createFunction(
4458 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4459 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4461 Fn->setSubprogram(SP);
4465 if (HasDecl && isa<FunctionDecl>(
D))
4469 LexicalBlockStack.emplace_back(SP);
4472 RegionMap[
D].reset(SP);
4476 QualType FnType, llvm::Function *Fn) {
4478 StringRef LinkageName;
4484 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4485 return GetName(
D,
true);
4488 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4489 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4490 bool IsDeclForCallSite = Fn ?
true :
false;
4491 llvm::DIScope *FDContext =
4492 IsDeclForCallSite ? Unit : getDeclContextDescriptor(
D);
4493 llvm::DINodeArray TParamsArray;
4494 if (isa<FunctionDecl>(
D)) {
4496 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4497 TParamsArray, Flags);
4498 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4499 Name = getObjCMethodName(OMD);
4500 Flags |= llvm::DINode::FlagPrototyped;
4502 llvm_unreachable(
"not a function or ObjC method");
4504 if (!Name.empty() && Name[0] ==
'\01')
4505 Name = Name.substr(1);
4508 Flags |= llvm::DINode::FlagArtificial;
4513 unsigned LineNo = getLineNumber(
Loc);
4514 unsigned ScopeLine = 0;
4515 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4517 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4519 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
4520 llvm::DISubroutineType *STy = getOrCreateFunctionType(
D, FnType, Unit);
4521 llvm::DISubprogram *SP = DBuilder.createFunction(
4522 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4523 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4529 if (
auto *FD = dyn_cast<FunctionDecl>(
D)) {
4530 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4533 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4534 DBuilder.createParameterVariable(
4535 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4536 llvm::DINode::FlagZero, ParamAnnotations);
4542 if (IsDeclForCallSite)
4543 Fn->setSubprogram(SP);
4545 DBuilder.finalizeSubprogram(SP);
4553 auto *
Func = CallOrInvoke->getCalledFunction();
4556 if (
Func->getSubprogram())
4561 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4562 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4573 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4575 auto FI = SPCache.find(FD->getCanonicalDecl());
4576 llvm::DISubprogram *SP =
nullptr;
4577 if (FI != SPCache.end())
4578 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4579 if (!SP || !SP->isDefinition())
4580 SP = getFunctionStub(GD);
4581 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4582 LexicalBlockStack.emplace_back(SP);
4588 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4597 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4600 llvm::MDNode *
Scope = LexicalBlockStack.back();
4601 Builder.SetCurrentDebugLocation(
4602 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4603 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4607 llvm::MDNode *Back =
nullptr;
4608 if (!LexicalBlockStack.empty())
4609 Back = LexicalBlockStack.back().get();
4610 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4611 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4612 getColumnNumber(CurLoc)));
4615void CGDebugInfo::AppendAddressSpaceXDeref(
4617 std::optional<unsigned> DWARFAddressSpace =
4619 if (!DWARFAddressSpace)
4622 Expr.push_back(llvm::dwarf::DW_OP_constu);
4623 Expr.push_back(*DWARFAddressSpace);
4624 Expr.push_back(llvm::dwarf::DW_OP_swap);
4625 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4634 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4636 LexicalBlockStack.back(), CurInlinedAt));
4638 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4642 CreateLexicalBlock(
Loc);
4647 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4652 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4655 LexicalBlockStack.pop_back();
4659 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4660 unsigned RCount = FnBeginRegionCount.back();
4661 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4664 while (LexicalBlockStack.size() != RCount) {
4667 LexicalBlockStack.pop_back();
4669 FnBeginRegionCount.pop_back();
4671 if (Fn && Fn->getSubprogram())
4672 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4675CGDebugInfo::BlockByRefType
4676CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4677 uint64_t *XOffset) {
4680 uint64_t FieldSize, FieldOffset;
4681 uint32_t FieldAlign;
4683 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4688 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4689 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4691 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4692 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4695 if (HasCopyAndDispose) {
4698 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4700 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4702 bool HasByrefExtendedLayout;
4705 HasByrefExtendedLayout) &&
4706 HasByrefExtendedLayout) {
4709 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4718 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4721 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4724 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4729 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4733 *XOffset = FieldOffset;
4734 llvm::DIType *FieldTy = DBuilder.createMemberType(
4735 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4736 llvm::DINode::FlagZero, WrappedTy);
4737 EltTys.push_back(FieldTy);
4738 FieldOffset += FieldSize;
4740 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4741 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4742 llvm::DINode::FlagZero,
nullptr, Elements),
4746llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4747 llvm::Value *Storage,
4748 std::optional<unsigned> ArgNo,
4750 const bool UsePointerValue) {
4752 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4753 if (VD->
hasAttr<NoDebugAttr>())
4759 llvm::DIFile *Unit =
nullptr;
4764 if (VD->
hasAttr<BlocksAttr>())
4765 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4767 Ty = getOrCreateType(VD->
getType(), Unit);
4782 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4784 Flags |= llvm::DINode::FlagArtificial;
4789 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4793 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4796 Flags |= llvm::DINode::FlagObjectPointer;
4803 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4804 StringRef Name = VD->
getName();
4805 if (!Name.empty()) {
4811 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4816 Expr.push_back(llvm::dwarf::DW_OP_deref);
4817 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4822 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4834 for (
const auto *Field : RD->
fields()) {
4835 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4836 StringRef FieldName =
Field->getName();
4839 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4844 auto *
D = DBuilder.createAutoVariable(
4846 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4849 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
4853 Builder.GetInsertBlock());
4861 if (UsePointerValue) {
4862 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4863 "Debug info already contains DW_OP_deref.");
4864 Expr.push_back(llvm::dwarf::DW_OP_deref);
4868 llvm::DILocalVariable *
D =
nullptr;
4870 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4871 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit,
Line, Ty,
4882 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4885 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4888 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4889 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4890 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4893 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4899 if (
Iter != CoroutineParameterMappings.end()) {
4901 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4902 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4904 if (Iter2 != ParamDbgMappings.end())
4905 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4911 D = RemapCoroArgToLocalVar();
4914 D = DBuilder.createAutoVariable(
Scope, Name, Unit,
Line, Ty,
4918 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
4921 Builder.GetInsertBlock());
4926llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4927 llvm::Value *Storage,
4928 std::optional<unsigned> ArgNo,
4930 const bool UsePointerValue) {
4932 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4933 if (BD->
hasAttr<NoDebugAttr>())
4940 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4941 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
4952 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4957 if (UsePointerValue) {
4958 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4959 "Debug info already contains DW_OP_deref.");
4960 Expr.push_back(llvm::dwarf::DW_OP_deref);
4965 StringRef Name = BD->
getName();
4966 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4968 llvm::DILocalVariable *
D = DBuilder.createAutoVariable(
4970 llvm::DINode::FlagZero, Align);
4973 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4974 const unsigned fieldIndex = FD->getFieldIndex();
4980 if (FD->isBitField()) {
4987 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4993 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
4994 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
4999 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5000 }
else if (fieldOffset != 0) {
5002 "Unexpected non-bitfield with non-byte-aligned offset");
5003 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5009 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5010 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5011 const uint64_t value = IL->getValue().getZExtValue();
5015 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5024 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
5027 Builder.GetInsertBlock());
5032llvm::DILocalVariable *
5035 const bool UsePointerValue) {
5038 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5039 for (
auto *B : DD->bindings()) {
5040 EmitDeclare(B, Storage, std::nullopt, Builder,
5048 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5053 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5058 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5059 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
5065 StringRef Name =
D->getName();
5072 DBuilder.insertLabel(L,
5074 Scope, CurInlinedAt),
5075 Builder.GetInsertBlock());
5078llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5080 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5083 return DBuilder.createObjectPointerType(Ty);
5088 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5090 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5092 if (Builder.GetInsertBlock() ==
nullptr)
5094 if (VD->
hasAttr<NoDebugAttr>())
5097 bool isByRef = VD->
hasAttr<BlocksAttr>();
5099 uint64_t XOffset = 0;
5100 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5103 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5105 Ty = getOrCreateType(VD->
getType(), Unit);
5109 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5111 Ty = CreateSelfType(VD->
getType(), Ty);
5114 const unsigned Line =
5125 addr.push_back(llvm::dwarf::DW_OP_deref);
5126 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5129 addr.push_back(llvm::dwarf::DW_OP_deref);
5130 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5135 addr.push_back(llvm::dwarf::DW_OP_deref);
5136 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5144 auto *
D = DBuilder.createAutoVariable(
5145 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5146 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5150 LexicalBlockStack.back(), CurInlinedAt);
5151 auto *
Expr = DBuilder.createExpression(addr);
5153 DBuilder.insertDeclare(Storage,
D,
Expr, DL, InsertPoint);
5155 DBuilder.insertDeclare(Storage,
D,
Expr, DL, Builder.GetInsertBlock());
5158llvm::DILocalVariable *
5161 bool UsePointerValue) {
5163 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5167struct BlockLayoutChunk {
5168 uint64_t OffsetInBits;
5171bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5172 return l.OffsetInBits < r.OffsetInBits;
5176void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5178 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5185 BlockLayout.getElementOffsetInBits(0),
5188 BlockLayout.getElementOffsetInBits(1),
5192 BlockLayout.getElementOffsetInBits(0),
5195 BlockLayout.getElementOffsetInBits(1),
5199 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5200 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5202 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType,
Loc,
AS_public,
5203 BlockLayout.getElementOffsetInBits(3),
5205 Fields.push_back(createFieldType(
5210 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5217 llvm::AllocaInst *Alloca,
5225 llvm::DIFile *tunit = getOrCreateFile(loc);
5226 unsigned line = getLineNumber(loc);
5227 unsigned column = getColumnNumber(loc);
5232 const llvm::StructLayout *blockLayout =
5236 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5245 BlockLayoutChunk chunk;
5246 chunk.OffsetInBits =
5247 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5248 chunk.Capture =
nullptr;
5249 chunks.push_back(chunk);
5253 for (
const auto &capture :
blockDecl->captures()) {
5254 const VarDecl *variable = capture.getVariable();
5261 BlockLayoutChunk chunk;
5262 chunk.OffsetInBits =
5263 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5264 chunk.Capture = &capture;
5265 chunks.push_back(chunk);
5269 llvm::array_pod_sort(chunks.begin(), chunks.end());
5271 for (
const BlockLayoutChunk &Chunk : chunks) {
5272 uint64_t offsetInBits = Chunk.OffsetInBits;
5279 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5281 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5284 llvm_unreachable(
"unexpected block declcontext");
5286 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5287 offsetInBits, tunit, tunit));
5292 StringRef name = variable->
getName();
5294 llvm::DIType *fieldType;
5296 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5301 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5302 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5303 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5304 PtrInfo.
Width, Align, offsetInBits,
5305 llvm::DINode::FlagZero, fieldType);
5309 offsetInBits, Align, tunit, tunit);
5311 fields.push_back(fieldType);
5315 llvm::raw_svector_ostream(typeName)
5318 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5320 llvm::DIType *
type =
5321 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5323 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5327 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5328 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5331 auto *debugVar = DBuilder.createParameterVariable(
5332 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5335 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5337 column, scope, CurInlinedAt),
5338 Builder.GetInsertBlock());
5341llvm::DIDerivedType *
5342CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *
D) {
5343 if (!
D || !
D->isStaticDataMember())
5347 if (MI != StaticDataMemberCache.end()) {
5348 assert(MI->second &&
"Static data member declaration should still exist");
5355 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(
D));
5356 return CreateRecordStaticField(
D, Ctxt, cast<RecordDecl>(DC));
5359llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5360 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5361 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5362 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5364 for (
const auto *Field : RD->
fields()) {
5365 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5366 StringRef FieldName = Field->getName();
5369 if (FieldName.empty()) {
5370 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5371 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5376 GVE = DBuilder.createGlobalVariableExpression(
5377 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5378 Var->hasLocalLinkage());
5379 Var->addDebugInfo(GVE);
5391 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5396 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5404 case TemplateArgument::Pack:
5405 return ReferencesAnonymousEntity(TA.getPackAsArray());
5406 case TemplateArgument::Type: {
5407 struct ReferencesAnonymous
5408 : public RecursiveASTVisitor<ReferencesAnonymous> {
5409 bool RefAnon = false;
5410 bool VisitRecordType(RecordType *RT) {
5411 if (ReferencesAnonymousEntity(RT)) {
5418 ReferencesAnonymous RT;
5419 RT.TraverseType(TA.getAsType());
5432 bool Reconstitutable =
true;
5434 Reconstitutable =
false;
5438 Reconstitutable =
false;
5441 bool VisitType(
Type *
T) {
5445 Reconstitutable =
false;
5450 bool TraverseEnumType(
EnumType *ET) {
5453 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5455 Reconstitutable =
false;
5459 Reconstitutable =
false;
5469 return Reconstitutable;
5473 Reconstitutable =
false;
5483 ReconstitutableType
T;
5485 return T.Reconstitutable;
5488bool CGDebugInfo::HasReconstitutableArgs(
5492 case TemplateArgument::Template:
5499 case TemplateArgument::Declaration:
5508 case TemplateArgument::NullPtr:
5512 case TemplateArgument::Pack:
5515 return HasReconstitutableArgs(TA.getPackAsArray());
5516 case TemplateArgument::Integral:
5521 return TA.getAsIntegral().getBitWidth() <= 64 &&
5522 IsReconstitutableType(TA.getIntegralType());
5523 case TemplateArgument::StructuralValue:
5525 case TemplateArgument::Type:
5526 return IsReconstitutableType(TA.getAsType());
5527 case TemplateArgument::Expression:
5528 return IsReconstitutableType(TA.getAsExpr()->getType());
5530 llvm_unreachable(
"Other, unresolved, template arguments should "
5531 "not be seen here");
5536std::string CGDebugInfo::GetName(
const Decl *
D,
bool Qualified)
const {
5538 llvm::raw_string_ostream OS(Name);
5539 const NamedDecl *ND = dyn_cast<NamedDecl>(
D);
5542 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5546 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5548 std::optional<TemplateArgs> Args;
5550 bool IsOperatorOverload =
false;
5551 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5552 Args = GetTemplateArgs(RD);
5553 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5554 Args = GetTemplateArgs(FD);
5556 IsOperatorOverload |=
5559 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5560 Args = GetTemplateArgs(VD);
5584 bool Reconstitutable =
5585 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5589 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5593 bool Mangled = TemplateNamesKind ==
5594 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5600 std::string EncodedOriginalName;
5601 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5609 std::string CanonicalOriginalName;
5610 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5612 assert(EncodedOriginalNameOS.str() == OriginalOS.str());
5625 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5626 return GetName(
D,
true);
5632 if (Cached != DeclCache.end())
5633 return Var->addDebugInfo(
5634 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5637 llvm::DIFile *Unit =
nullptr;
5638 llvm::DIScope *DContext =
nullptr;
5640 StringRef DeclName, LinkageName;
5642 llvm::MDTuple *TemplateParameters =
nullptr;
5643 collectVarDeclProps(
D, Unit, LineNo,
T, DeclName, LinkageName,
5644 TemplateParameters, DContext);
5648 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5656 "unnamed non-anonymous struct or union?");
5657 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5667 else if (
D->
hasAttr<CUDAConstantAttr>())
5671 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5673 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
5674 GVE = DBuilder.createGlobalVariableExpression(
5675 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5676 Var->hasLocalLinkage(),
true,
5677 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5678 getOrCreateStaticDataMemberDeclarationOrNull(
D), TemplateParameters,
5679 Align, Annotations);
5680 Var->addDebugInfo(GVE);
5687 if (VD->
hasAttr<NoDebugAttr>())
5689 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5690 return GetName(VD,
true);
5695 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5696 StringRef Name = VD->
getName();
5697 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5699 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5700 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5701 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5714 llvm::DIType *EDTy =
5716 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5727 auto *VarD = dyn_cast<VarDecl>(VD);
5728 if (VarD && VarD->isStaticDataMember()) {
5729 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5730 getDeclContextDescriptor(VarD);
5735 RetainedTypes.push_back(
5740 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5742 auto &GV = DeclCache[VD];
5746 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
5747 llvm::MDTuple *TemplateParameters =
nullptr;
5749 if (isa<VarTemplateSpecializationDecl>(VD))
5751 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5752 TemplateParameters = parameterNodes.get();
5755 GV.reset(DBuilder.createGlobalVariableExpression(
5756 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5757 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5758 TemplateParameters, Align));
5768 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
5769 StringRef Name =
D->getName();
5770 llvm::DIType *Ty = getOrCreateType(
D->getType(), Unit);
5772 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
5773 llvm::DIGlobalVariableExpression *GVE =
5774 DBuilder.createGlobalVariableExpression(
5775 DContext, Name, StringRef(), Unit, getLineNumber(
D->
getLocation()),
5776 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5777 Var->addDebugInfo(GVE);
5785 llvm::codegenoptions::DebugLineTablesOnly)
5788 llvm::DILocation *DIL =
Value->getDebugLoc().get();
5792 llvm::DIFile *Unit = DIL->getFile();
5793 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
5798 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
5799 llvm::Value *Var = Load->getPointerOperand();
5804 auto DeclareTypeMatches = [&](
auto *DbgDeclare) {
5805 return DbgDeclare->getVariable()->getType() ==
Type;
5807 if (any_of(llvm::findDbgDeclares(Var), DeclareTypeMatches) ||
5808 any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
5812 llvm::DILocalVariable *
D =
5813 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
5814 Type,
false, llvm::DINode::FlagArtificial);
5816 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
5817 DBuilder.insertDbgValueIntrinsic(
Value,
D, DBuilder.createExpression(), DIL,
5830 const auto *
D = cast<ValueDecl>(GD.
getDecl());
5849 if (!(DI = getDeclarationOrDefinition(
5850 AliaseeDecl.getCanonicalDecl().getDecl())))
5853 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
5856 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5857 DContext, DI, getOrCreateFile(
Loc), getLineNumber(
Loc),
D->getName());
5870 llvm::DIFile *
File = getOrCreateFile(
Loc);
5871 llvm::DIGlobalVariableExpression *Debug =
5872 DBuilder.createGlobalVariableExpression(
5873 nullptr, StringRef(), StringRef(), getOrCreateFile(
Loc),
5874 getLineNumber(
Loc), getOrCreateType(S->getType(),
File),
true);
5875 GV->addDebugInfo(Debug);
5878llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *
D) {
5879 if (!LexicalBlockStack.empty())
5880 return LexicalBlockStack.back();
5881 llvm::DIScope *Mod = getParentModuleOrNull(
D);
5882 return getContextDescriptor(
D, Mod ? Mod : TheCU);
5894 DBuilder.createImportedModule(
5896 getOrCreateNamespace(NSDecl), getOrCreateFile(
Loc), getLineNumber(
Loc));
5901 if (llvm::DINode *
Target =
5904 DBuilder.createImportedDeclaration(
5906 getOrCreateFile(
Loc), getLineNumber(
Loc));
5914 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5916 for (
const auto *USD : UD.
shadows()) {
5921 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5922 if (
const auto *AT = FD->getType()
5925 if (AT->getDeducedType().isNull())
5939 "We shouldn't be codegening an invalid UsingEnumDecl"
5940 " containing no decls");
5942 for (
const auto *USD : UD.
shadows())
5947 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5949 if (
Module *M = ID.getImportedModule()) {
5951 auto Loc = ID.getLocation();
5952 DBuilder.createImportedDeclaration(
5953 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
5954 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(
Loc),
5955 getLineNumber(
Loc));
5959llvm::DIImportedEntity *
5963 auto &VH = NamespaceAliasCache[&NA];
5965 return cast<llvm::DIImportedEntity>(VH);
5966 llvm::DIImportedEntity *R;
5968 if (
const auto *Underlying =
5971 R = DBuilder.createImportedDeclaration(
5976 R = DBuilder.createImportedDeclaration(
5985CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
5989 auto I = NamespaceCache.find(NSDecl);
5990 if (I != NamespaceCache.end())
5991 return cast<llvm::DINamespace>(I->second);
5993 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
5995 llvm::DINamespace *NS =
5996 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
5997 NamespaceCache[NSDecl].reset(NS);
6002 assert(TheCU &&
"no main compile unit");
6003 TheCU->setDWOId(Signature);
6009 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6010 ObjCInterfaceCacheEntry
E = ObjCInterfaceCache[i];
6011 llvm::DIType *Ty =
E.Type->getDecl()->getDefinition()
6012 ? CreateTypeDefinition(
E.Type,
E.Unit)
6014 DBuilder.replaceTemporary(llvm::TempDIType(
E.Decl), Ty);
6018 for (
const auto &
P : ObjCMethodCache) {
6019 if (
P.second.empty())
6022 QualType QTy(
P.first->getTypeForDecl(), 0);
6024 assert(It != TypeCache.end());
6026 llvm::DICompositeType *InterfaceDecl =
6027 cast<llvm::DICompositeType>(It->second);
6029 auto CurElts = InterfaceDecl->getElements();
6033 for (
auto &SubprogramDirect :
P.second)
6034 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6035 EltTys.push_back(SubprogramDirect.getPointer());
6037 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6038 DBuilder.replaceArrays(InterfaceDecl, Elements);
6041 for (
const auto &
P : ReplaceMap) {
6043 auto *Ty = cast<llvm::DIType>(
P.second);
6044 assert(Ty->isForwardDecl());
6046 auto It = TypeCache.find(
P.first);
6047 assert(It != TypeCache.end());
6050 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6051 cast<llvm::DIType>(It->second));
6054 for (
const auto &
P : FwdDeclReplaceMap) {
6056 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
6057 llvm::Metadata *Repl;
6059 auto It = DeclCache.find(
P.first);
6063 if (It == DeclCache.end())
6068 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6069 Repl = GVE->getVariable();
6070 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
6075 for (
auto &RT : RetainedTypes)
6076 if (
auto MD = TypeCache[RT])
6077 DBuilder.retainType(cast<llvm::DIType>(MD));
6079 DBuilder.finalize();
6085 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6086 DBuilder.retainType(DieTy);
6091 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6092 DBuilder.retainType(DieTy);
6096 if (LexicalBlockStack.empty())
6097 return llvm::DebugLoc();
6099 llvm::MDNode *
Scope = LexicalBlockStack.back();
6104llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6108 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6109 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6110 return llvm::DINode::FlagZero;
6115 bool SupportsDWARFv4Ext =
6117 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6118 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6120 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6121 return llvm::DINode::FlagZero;
6123 return llvm::DINode::FlagAllCallsDescribed;
6134 return DBuilder.createConstantValueExpression(
6135 Val.
getFloat().bitcastToAPInt().getZExtValue());
6140 llvm::APSInt
const &ValInt = Val.
getInt();
6141 std::optional<uint64_t> ValIntOpt;
6142 if (ValInt.isUnsigned())
6143 ValIntOpt = ValInt.tryZExtValue();
6144 else if (
auto tmp = ValInt.trySExtValue())
6147 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6150 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
constexpr llvm::StringRef ClangTrapPrefix
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 getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType UnsignedLongTy
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
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
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
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.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
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::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
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.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
Represents a ValueDecl that came out of a declarator.
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.
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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.