39 #include "llvm/ADT/DenseSet.h"
40 #include "llvm/ADT/SmallVector.h"
41 #include "llvm/ADT/StringExtras.h"
42 #include "llvm/IR/Constants.h"
43 #include "llvm/IR/DataLayout.h"
44 #include "llvm/IR/DerivedTypes.h"
45 #include "llvm/IR/Instructions.h"
46 #include "llvm/IR/Intrinsics.h"
47 #include "llvm/IR/Metadata.h"
48 #include "llvm/IR/Module.h"
49 #include "llvm/Support/FileSystem.h"
50 #include "llvm/Support/MD5.h"
51 #include "llvm/Support/Path.h"
52 #include "llvm/Support/SHA1.h"
53 #include "llvm/Support/SHA256.h"
54 #include "llvm/Support/TimeProfiler.h"
56 using namespace clang;
73 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
74 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
75 DBuilder(CGM.getModule()) {
80 assert(LexicalBlockStack.empty() &&
81 "Region stack mismatch, stack not empty!");
87 init(TemporaryLocation);
94 init(TemporaryLocation, DefaultToEmpty);
98 bool DefaultToEmpty) {
105 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
107 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
110 if (TemporaryLocation.
isValid()) {
111 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
115 if (DefaultToEmpty) {
116 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
121 assert(!DI->LexicalBlockStack.empty());
122 CGF->
Builder.SetCurrentDebugLocation(
123 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
124 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
138 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
140 CGF.
Builder.SetCurrentDebugLocation(std::move(
Loc));
147 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
158 SavedLocation = DI.getLocation();
159 assert((DI.getInlinedAt() ==
160 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
161 "CGDebugInfo and IRBuilder are out of sync");
163 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
171 DI.EmitLocation(CGF->
Builder, SavedLocation);
184 if (LexicalBlockStack.empty())
188 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
190 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
193 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
194 LexicalBlockStack.pop_back();
195 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
196 LBF->getScope(), getOrCreateFile(CurLoc)));
197 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
198 isa<llvm::DISubprogram>(
Scope)) {
199 LexicalBlockStack.pop_back();
200 LexicalBlockStack.emplace_back(
201 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
205 llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
206 llvm::DIScope *Mod = getParentModuleOrNull(D);
211 llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
212 llvm::DIScope *Default) {
216 auto I = RegionMap.find(Context);
217 if (I != RegionMap.end()) {
218 llvm::Metadata *
V = I->second;
219 return dyn_cast_or_null<llvm::DIScope>(
V);
223 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
224 return getOrCreateNamespace(NSDecl);
226 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
227 if (!RDecl->isDependentType())
261 StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
262 return internString(GetName(FD));
265 StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
267 llvm::raw_svector_ostream OS(MethodName);
270 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
271 OS << OID->getName();
272 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
273 OS << OID->getName();
274 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
275 if (OC->IsClassExtension()) {
276 OS << OC->getClassInterface()->getName();
278 OS << OC->getIdentifier()->getNameStart() <<
'('
279 << OC->getIdentifier()->getNameStart() <<
')';
281 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
282 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
286 return internString(OS.str());
289 StringRef CGDebugInfo::getSelectorName(
Selector S) {
290 return internString(S.getAsString());
293 StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
294 if (isa<ClassTemplateSpecializationDecl>(RD)) {
296 return internString(GetName(RD));
302 return II->getName();
310 "Typedef should not be in another decl context!");
311 assert(D->getDeclName().getAsIdentifierInfo() &&
312 "Typedef was not named!");
313 return D->getDeclName().getAsIdentifierInfo()->getName();
323 Name = DD->getName();
328 Name = TND->getName();
331 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
332 if (CXXRD->isLambda())
340 return internString(UnnamedType);
348 std::optional<llvm::DIFile::ChecksumKind>
357 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
361 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
364 llvm::toHex(llvm::MD5::hash(Data),
true, Checksum);
365 return llvm::DIFile::CSK_MD5;
367 llvm::toHex(llvm::SHA1::hash(Data),
true, Checksum);
368 return llvm::DIFile::CSK_SHA1;
370 llvm::toHex(llvm::SHA256::hash(Data),
true, Checksum);
371 return llvm::DIFile::CSK_SHA256;
373 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
376 std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
381 bool SourceInvalid =
false;
382 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
392 FileID MainFileID =
SM.getMainFileID();
396 if (ExpectedFileRef) {
397 MainFileID =
SM.getOrCreateFileID(ExpectedFileRef.get(),
407 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
421 FileName = TheCU->getFile()->getFilename();
422 CSInfo = TheCU->getFile()->getChecksum();
429 FileName = TheCU->getFile()->getFilename();
435 auto It = DIFileCache.find(
FileName.data());
436 if (It != DIFileCache.end()) {
438 if (llvm::Metadata *
V = It->second)
439 return cast<llvm::DIFile>(
V);
442 if (
SM.getFileEntryForID(
SM.getMainFileID()) &&
452 std::optional<llvm::DIFile::ChecksumKind> CSKind =
453 computeChecksum(FID, Checksum);
455 CSInfo.emplace(*CSKind, Checksum);
457 return createFile(FileName, CSInfo, getSource(
SM,
SM.getFileID(
Loc)));
460 llvm::DIFile *CGDebugInfo::createFile(
462 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
463 std::optional<StringRef> Source) {
467 std::string CurDir =
remapDIPath(getCurrentDirname());
470 if (llvm::sys::path::is_absolute(RemappedFile)) {
473 auto FileIt = llvm::sys::path::begin(RemappedFile);
474 auto FileE = llvm::sys::path::end(RemappedFile);
475 auto CurDirIt = llvm::sys::path::begin(CurDir);
476 auto CurDirE = llvm::sys::path::end(CurDir);
477 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
478 llvm::sys::path::append(DirBuf, *CurDirIt);
479 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
485 for (; FileIt != FileE; ++FileIt)
486 llvm::sys::path::append(FileBuf, *FileIt);
491 if (!llvm::sys::path::is_absolute(FileName))
495 llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source);
496 DIFileCache[
FileName.data()].reset(F);
503 if (llvm::sys::path::replace_path_prefix(
P, From, To))
505 return P.str().str();
512 return SM.getPresumedLoc(
Loc).getLine();
528 StringRef CGDebugInfo::getCurrentDirname() {
532 if (!CWDName.empty())
534 llvm::ErrorOr<std::string> CWD =
538 return CWDName = internString(*CWD);
541 void CGDebugInfo::CreateCompileUnit() {
543 std::optional<llvm::DIFile::ChecksumKind> CSKind;
544 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
557 std::string MainFileName = CGO.MainFileName;
558 std::string FullMainFileName = CGO.FullMainFileName;
559 if (MainFileName.empty())
560 MainFileName =
"<stdin>";
570 std::string MainFileDir;
572 SM.getFileEntryRefForID(
SM.getMainFileID())) {
573 MainFileDir = std::string(MainFile->getDir().getName());
574 FileID MainFileID =
SM.getMainFileID();
575 if (!llvm::sys::path::is_absolute(MainFileName) &&
578 llvm::sys::path::Style Style =
581 ? llvm::sys::path::Style::windows_backslash
582 : llvm::sys::path::Style::posix)
583 : llvm::sys::path::Style::native;
584 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
585 MainFileName = std::string(
586 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
594 MainFileName = FullMainFileName;
601 if (MainFile->getName() == MainFileName &&
603 MainFile->getName().rsplit(
'.').second)
605 MainFileName = CGM.
getModule().getName().str();
607 CSKind = computeChecksum(MainFileID, Checksum);
611 llvm::dwarf::SourceLanguage LangTag;
614 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
615 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
616 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
617 else if (LO.CPlusPlus14)
618 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
619 else if (LO.CPlusPlus11)
620 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
622 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
623 }
else if (LO.ObjC) {
624 LangTag = llvm::dwarf::DW_LANG_ObjC;
625 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
627 LangTag = llvm::dwarf::DW_LANG_OpenCL;
628 }
else if (LO.RenderScript) {
629 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
630 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
631 LangTag = llvm::dwarf::DW_LANG_C11;
633 LangTag = llvm::dwarf::DW_LANG_C99;
635 LangTag = llvm::dwarf::DW_LANG_C89;
641 unsigned RuntimeVers = 0;
645 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
647 case llvm::codegenoptions::NoDebugInfo:
648 case llvm::codegenoptions::LocTrackingOnly:
649 EmissionKind = llvm::DICompileUnit::NoDebug;
651 case llvm::codegenoptions::DebugLineTablesOnly:
652 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
654 case llvm::codegenoptions::DebugDirectivesOnly:
655 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
657 case llvm::codegenoptions::DebugInfoConstructor:
658 case llvm::codegenoptions::LimitedDebugInfo:
659 case llvm::codegenoptions::FullDebugInfo:
660 case llvm::codegenoptions::UnusedTypeInfo:
661 EmissionKind = llvm::DICompileUnit::FullDebug;
675 CSInfo.emplace(*CSKind, Checksum);
677 llvm::DIFile *CUFile =
679 CSInfo, getSource(
SM,
SM.getMainFileID()));
681 StringRef Sysroot, SDK;
682 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
684 auto B = llvm::sys::path::rbegin(Sysroot);
685 auto E = llvm::sys::path::rend(Sysroot);
687 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
692 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
693 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
694 CGOpts.DebugNameTable);
698 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
701 TheCU = DBuilder.createCompileUnit(
702 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
703 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
704 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
705 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
706 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
709 llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
713 #define BUILTIN_TYPE(Id, SingletonId)
714 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
715 #include "clang/AST/BuiltinTypes.def"
716 case BuiltinType::Dependent:
717 llvm_unreachable(
"Unexpected builtin type");
718 case BuiltinType::NullPtr:
719 return DBuilder.createNullPtrType();
720 case BuiltinType::Void:
722 case BuiltinType::ObjCClass:
725 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
726 "objc_class", TheCU, TheCU->getFile(), 0);
728 case BuiltinType::ObjCId: {
739 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
740 "objc_class", TheCU, TheCU->getFile(), 0);
744 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
746 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
747 0, 0, llvm::DINode::FlagZero,
nullptr,
748 llvm::DINodeArray());
750 DBuilder.replaceArrays(
751 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
752 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
753 llvm::DINode::FlagZero, ISATy)));
756 case BuiltinType::ObjCSel: {
758 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
759 "objc_selector", TheCU,
760 TheCU->getFile(), 0);
764 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
765 case BuiltinType::Id: \
766 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
768 #include "clang/Basic/OpenCLImageTypes.def"
769 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
770 case BuiltinType::Sampled##Id: \
771 return getOrCreateStructPtrType( \
772 "spirv_sampled_" #ImgType "_" #Suffix "_t", Sampled##SingletonId);
773 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
774 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
775 #include "clang/Basic/OpenCLImageTypes.def"
776 case BuiltinType::OCLSampler:
777 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
778 case BuiltinType::OCLEvent:
779 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
780 case BuiltinType::OCLClkEvent:
781 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
782 case BuiltinType::OCLQueue:
783 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
784 case BuiltinType::OCLReserveID:
785 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
786 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
787 case BuiltinType::Id: \
788 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
789 #include "clang/Basic/OpenCLExtensionTypes.def"
791 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
792 #include "clang/Basic/AArch64SVEACLETypes.def"
796 BT->
getKind() == BuiltinType::SveCount
800 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
807 "Unsupported number of vectors for svcount_t");
811 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
817 llvm::Metadata *LowerBound, *UpperBound;
818 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
820 if (Info.
EC.isScalable()) {
821 unsigned NumElemsPerVG = NumElems / 2;
823 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
824 46, 0, llvm::dwarf::DW_OP_mul,
825 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
826 UpperBound = DBuilder.createExpression(
Expr);
828 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
831 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
832 nullptr, LowerBound, UpperBound,
nullptr);
833 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
834 llvm::DIType *ElemTy =
835 getOrCreateType(Info.
ElementType, TheCU->getFile());
837 return DBuilder.createVectorType( 0, Align, ElemTy,
842 #define PPC_VECTOR_TYPE(Name, Id, size) \
843 case BuiltinType::Id:
844 #include "clang/Basic/PPCTypes.def"
847 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
848 #include "clang/Basic/RISCVVTypes.def"
853 unsigned ElementCount = Info.
EC.getKnownMinValue();
856 bool Fractional =
false;
858 unsigned FixedSize = ElementCount * SEW;
862 }
else if (FixedSize < 64) {
865 LMUL = 64 / FixedSize;
867 LMUL = FixedSize / 64;
875 {llvm::dwarf::DW_OP_bregx,
878 llvm::dwarf::DW_OP_constu,
880 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
882 Expr.push_back(llvm::dwarf::DW_OP_div);
884 Expr.push_back(llvm::dwarf::DW_OP_mul);
886 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
889 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
891 auto *UpperBound = DBuilder.createExpression(
Expr);
892 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
893 nullptr, LowerBound, UpperBound,
nullptr);
894 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
895 llvm::DIType *ElemTy =
896 getOrCreateType(Info.
ElementType, TheCU->getFile());
899 return DBuilder.createVectorType(0, Align, ElemTy,
903 #define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
904 case BuiltinType::Id: { \
907 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
908 MangledName, TheCU, TheCU->getFile(), 0); \
909 return SingletonId; \
911 #include "clang/Basic/WebAssemblyReferenceTypes.def"
913 case BuiltinType::UChar:
914 case BuiltinType::Char_U:
915 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
917 case BuiltinType::Char_S:
918 case BuiltinType::SChar:
919 Encoding = llvm::dwarf::DW_ATE_signed_char;
921 case BuiltinType::Char8:
922 case BuiltinType::Char16:
923 case BuiltinType::Char32:
926 case BuiltinType::UShort:
927 case BuiltinType::UInt:
928 case BuiltinType::UInt128:
929 case BuiltinType::ULong:
930 case BuiltinType::WChar_U:
931 case BuiltinType::ULongLong:
932 Encoding = llvm::dwarf::DW_ATE_unsigned;
934 case BuiltinType::Short:
935 case BuiltinType::Int:
936 case BuiltinType::Int128:
937 case BuiltinType::Long:
938 case BuiltinType::WChar_S:
939 case BuiltinType::LongLong:
940 Encoding = llvm::dwarf::DW_ATE_signed;
942 case BuiltinType::Bool:
943 Encoding = llvm::dwarf::DW_ATE_boolean;
945 case BuiltinType::Half:
947 case BuiltinType::LongDouble:
948 case BuiltinType::Float16:
949 case BuiltinType::BFloat16:
950 case BuiltinType::Float128:
951 case BuiltinType::Double:
952 case BuiltinType::Ibm128:
958 Encoding = llvm::dwarf::DW_ATE_float;
960 case BuiltinType::ShortAccum:
961 case BuiltinType::Accum:
962 case BuiltinType::LongAccum:
963 case BuiltinType::ShortFract:
964 case BuiltinType::Fract:
965 case BuiltinType::LongFract:
966 case BuiltinType::SatShortFract:
967 case BuiltinType::SatFract:
968 case BuiltinType::SatLongFract:
969 case BuiltinType::SatShortAccum:
970 case BuiltinType::SatAccum:
971 case BuiltinType::SatLongAccum:
972 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
974 case BuiltinType::UShortAccum:
975 case BuiltinType::UAccum:
976 case BuiltinType::ULongAccum:
977 case BuiltinType::UShortFract:
978 case BuiltinType::UFract:
979 case BuiltinType::ULongFract:
980 case BuiltinType::SatUShortAccum:
981 case BuiltinType::SatUAccum:
982 case BuiltinType::SatULongAccum:
983 case BuiltinType::SatUShortFract:
984 case BuiltinType::SatUFract:
985 case BuiltinType::SatULongFract:
986 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
993 return DBuilder.createBasicType(BTName, Size,
Encoding);
996 llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
998 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1000 ? llvm::dwarf::DW_ATE_unsigned
1001 : llvm::dwarf::DW_ATE_signed;
1007 llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1009 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1011 Encoding = llvm::dwarf::DW_ATE_lo_user;
1014 return DBuilder.createBasicType(
"complex", Size,
Encoding);
1028 return llvm::dwarf::DW_TAG_const_type;
1032 return llvm::dwarf::DW_TAG_volatile_type;
1036 return llvm::dwarf::DW_TAG_restrict_type;
1038 return (llvm::dwarf::Tag)0;
1041 llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
1042 llvm::DIFile *Unit) {
1052 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1053 return getOrCreateType(
QualType(
T, 0), Unit);
1060 return DBuilder.createQualifiedType(Tag, FromTy);
1064 llvm::DIFile *Unit) {
1073 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1084 return DBuilder.createQualifiedType(Tag, FromTy);
1088 llvm::DIFile *Unit) {
1096 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1100 llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1101 llvm::DIFile *Unit) {
1102 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1108 switch (TheCU->getSourceLanguage()) {
1109 case llvm::dwarf::DW_LANG_C_plus_plus:
1110 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1111 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1113 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1114 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1142 llvm::DICompileUnit *TheCU) {
1160 llvm::DICompileUnit *TheCU) {
1166 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1168 if (RD->isDynamicClass() &&
1181 llvm::dwarf::Tag Tag;
1183 Tag = llvm::dwarf::DW_TAG_structure_type;
1185 Tag = llvm::dwarf::DW_TAG_union_type;
1190 Tag = llvm::dwarf::DW_TAG_class_type;
1195 llvm::DICompositeType *
1196 CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1197 llvm::DIScope *Ctx) {
1200 return cast<llvm::DICompositeType>(
T);
1201 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1202 const unsigned Line =
1204 StringRef RDName = getClassName(RD);
1213 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1218 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1219 if (!CXXRD->hasDefinition() ||
1220 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1221 Flags |= llvm::DINode::FlagNonTrivial;
1228 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1229 getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align, Flags,
1232 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1233 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1234 CollectCXXTemplateParams(TSpecial, DefUnit));
1235 ReplaceMap.emplace_back(
1236 std::piecewise_construct, std::make_tuple(Ty),
1237 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1241 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1244 llvm::DIFile *Unit) {
1249 std::optional<unsigned> DWARFAddressSpace =
1254 auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1256 StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1258 llvm::Metadata *Ops[2] = {
1259 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1261 Annots.insert(Annots.begin(),
1264 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1267 llvm::DINodeArray Annotations =
nullptr;
1268 if (Annots.size() > 0)
1269 Annotations = DBuilder.getOrCreateArray(Annots);
1271 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1272 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1273 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1274 Size, Align, DWARFAddressSpace);
1276 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1277 Align, DWARFAddressSpace, StringRef(),
1281 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1282 llvm::DIType *&
Cache) {
1285 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1286 TheCU, TheCU->getFile(), 0);
1288 Cache = DBuilder.createPointerType(
Cache, Size);
1292 uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1293 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1306 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1307 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1310 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1312 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1313 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1315 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1319 EltTys.push_back(DBuilder.createMemberType(
1320 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1321 FieldOffset, llvm::DINode::FlagZero, DescTy));
1322 FieldOffset += FieldSize;
1329 llvm::DIFile *Unit) {
1333 llvm::DINodeArray Elements;
1337 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1338 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1340 Elements = DBuilder.getOrCreateArray(EltTys);
1343 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1346 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1347 FieldOffset, 0, Flags,
nullptr, Elements);
1352 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1354 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1357 Elements = DBuilder.getOrCreateArray(EltTys);
1363 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1364 Flags,
nullptr, Elements);
1366 return DBuilder.createPointerType(EltTy, Size);
1383 if (Param->isParameterPack()) {
1392 if (SubstArgs.empty()) {
1401 SpecArgs.push_back(SubstArgs.front());
1402 SubstArgs = SubstArgs.drop_front();
1408 llvm::DIFile *Unit) {
1413 if (isa<BuiltinTemplateDecl>(TD))
1416 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1421 llvm::raw_svector_ostream OS(NS);
1423 auto PP = getPrintingPolicy();
1450 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1459 llvm::raw_string_ostream OS(Name);
1462 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1463 !HasReconstitutableArgs(Args.Args))
1466 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1467 Src, Name, getOrCreateFile(
Loc), getLineNumber(
Loc),
1468 getDeclContextDescriptor(AliasDecl), CollectTemplateParams(Args, Unit));
1483 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(
Loc),
1485 getDeclContextDescriptor(AliasDecl));
1500 return llvm::DINode::FlagZero;
1504 return llvm::DINode::FlagPrivate;
1506 return llvm::DINode::FlagProtected;
1508 return llvm::DINode::FlagPublic;
1510 return llvm::DINode::FlagZero;
1512 llvm_unreachable(
"unexpected access enumerator");
1515 llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1516 llvm::DIFile *Unit) {
1517 llvm::DIType *Underlying =
1530 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1532 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1534 if (isa<RecordDecl>(DC))
1537 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1538 getOrCreateFile(
Loc), getLineNumber(
Loc),
1539 getDeclContextDescriptor(Ty->
getDecl()), Align,
1540 Flags, Annotations);
1550 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1552 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1554 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1556 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1558 return llvm::dwarf::DW_CC_BORLAND_pascal;
1560 return llvm::dwarf::DW_CC_LLVM_Win64;
1562 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1566 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1568 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1570 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1572 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1575 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1577 return llvm::dwarf::DW_CC_LLVM_Swift;
1579 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1581 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1583 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1585 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1587 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1589 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1591 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1597 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1599 Flags |= llvm::DINode::FlagLValueReference;
1601 Flags |= llvm::DINode::FlagRValueReference;
1605 llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1606 llvm::DIFile *Unit) {
1607 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1609 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1618 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1620 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1624 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1627 for (
const QualType &ParamType : FPT->param_types())
1628 EltTys.push_back(getOrCreateType(ParamType, Unit));
1629 if (FPT->isVariadic())
1630 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1633 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1634 llvm::DIType *F = DBuilder.createSubroutineType(
1639 llvm::DIDerivedType *
1640 CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1641 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1642 StringRef Name = BitFieldDecl->
getName();
1644 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1645 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1647 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1648 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1651 llvm::DIFile *
File = getOrCreateFile(
Loc);
1652 unsigned Line = getLineNumber(
Loc);
1657 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1668 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1669 return DBuilder.createBitFieldMemberType(
1670 RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1671 Flags, DebugType, Annotations);
1674 llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1675 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1703 if (PreviousFieldsDI.empty())
1707 auto *PreviousMDEntry =
1708 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1709 auto *PreviousMDField =
1710 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1711 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1712 PreviousMDField->getSizeInBits() == 0)
1718 assert(PreviousBitfield->isBitField());
1721 if (!PreviousBitfield->isZeroLengthBitField(Context))
1724 QualType Ty = PreviousBitfield->getType();
1726 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1727 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1728 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1730 llvm::DIFile *
File = getOrCreateFile(
Loc);
1731 unsigned Line = getLineNumber(
Loc);
1734 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1737 llvm::DINode::DIFlags Flags =
1739 llvm::DINodeArray Annotations =
1740 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1741 return DBuilder.createBitFieldMemberType(
1742 RecordTy,
"", File, Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1743 Flags, DebugType, Annotations);
1746 llvm::DIType *CGDebugInfo::createFieldType(
1748 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1749 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1750 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1753 llvm::DIFile *file = getOrCreateFile(loc);
1754 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1757 auto Align = AlignInBits;
1758 if (!
type->isIncompleteArrayType()) {
1760 SizeInBits = TI.
Width;
1766 return DBuilder.createMemberType(scope,
name, file, line, SizeInBits, Align,
1767 offsetInBits, flags, debugType, Annotations);
1770 void CGDebugInfo::CollectRecordLambdaFields(
1772 llvm::DIType *RecordTy) {
1778 unsigned fieldno = 0;
1781 I != E; ++I, ++Field, ++fieldno) {
1783 if (
C.capturesVariable()) {
1785 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1787 StringRef VName =
V->getName();
1788 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1790 llvm::DIType *FieldType = createFieldType(
1792 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1793 elements.push_back(FieldType);
1794 }
else if (
C.capturesThis()) {
1800 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1802 StringRef ThisName =
1804 llvm::DIType *fieldType = createFieldType(
1808 elements.push_back(fieldType);
1813 llvm::DIDerivedType *
1814 CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1819 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1820 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1822 unsigned LineNumber = getLineNumber(Var->
getLocation());
1823 StringRef VName = Var->
getName();
1827 llvm::Constant *
C =
nullptr;
1833 if (
Value->isFloat())
1840 ? llvm::dwarf::DW_TAG_variable
1841 : llvm::dwarf::DW_TAG_member;
1843 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1844 RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Tag, Align);
1849 void CGDebugInfo::CollectRecordNormalField(
1857 if (
name.empty() && !
type->isRecordType())
1860 llvm::DIType *FieldType;
1862 llvm::DIDerivedType *BitFieldType;
1863 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1864 if (llvm::DIType *Separator =
1865 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1866 elements.push_back(Separator);
1869 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1872 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1875 elements.push_back(FieldType);
1878 void CGDebugInfo::CollectRecordNestedType(
1882 if (isa<InjectedClassNameType>(Ty))
1885 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(
Loc));
1886 elements.push_back(nestedType);
1889 void CGDebugInfo::CollectRecordFields(
1890 const RecordDecl *record, llvm::DIFile *tunit,
1892 llvm::DICompositeType *RecordTy) {
1893 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1895 if (CXXDecl && CXXDecl->
isLambda())
1896 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1901 unsigned fieldNo = 0;
1905 for (
const auto *I : record->
decls())
1906 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1913 isa<VarTemplateSpecializationDecl>(
V))
1916 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1920 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1921 if (MI != StaticDataMemberCache.end()) {
1922 assert(MI->second &&
1923 "Static data member declaration should still exist");
1924 elements.push_back(MI->second);
1926 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1927 elements.push_back(Field);
1929 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1930 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1931 elements, RecordTy, record);
1938 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1940 if (isa<RecordDecl>(I) &&
1941 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1943 if (!nestedType->isImplicit() &&
1944 nestedType->getDeclContext() == record)
1945 CollectRecordNestedType(nestedType, elements);
1951 llvm::DISubroutineType *
1952 CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1953 llvm::DIFile *Unit) {
1956 return cast_or_null<llvm::DISubroutineType>(
1957 getOrCreateType(
QualType(Func, 0), Unit));
1958 return getOrCreateInstanceMethodType(Method->
getThisType(), Func, Unit);
1961 llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1977 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
1979 Func->getReturnType(),
Func->getParamTypes(), EPI),
1981 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
1982 assert(Args.size() &&
"Invalid number of arguments!");
1987 Elts.push_back(Args[0]);
1991 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1993 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1996 llvm::DIType *PointeeType =
1998 llvm::DIType *ThisPtrType =
1999 DBuilder.createPointerType(PointeeType, Size, Align);
2004 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
2005 Elts.push_back(ThisPtrType);
2007 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2009 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
2010 Elts.push_back(ThisPtrType);
2014 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
2015 Elts.push_back(Args[i]);
2017 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2019 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2026 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2033 llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2034 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2036 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
2038 StringRef MethodName = getFunctionName(Method);
2039 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
2043 StringRef MethodLinkageName;
2053 llvm::DIFile *MethodDefUnit =
nullptr;
2054 unsigned MethodLine = 0;
2056 MethodDefUnit = getOrCreateFile(Method->
getLocation());
2057 MethodLine = getLineNumber(Method->
getLocation());
2061 llvm::DIType *ContainingType =
nullptr;
2062 unsigned VIndex = 0;
2063 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2064 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2069 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2071 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2076 if (!isa<CXXDestructorDecl>(Method))
2081 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
2093 Flags |= llvm::DINode::FlagIntroducedVirtual;
2102 ContainingType = RecordTy;
2106 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2109 Flags |= llvm::DINode::FlagNoReturn;
2112 Flags |= llvm::DINode::FlagStaticMember;
2114 Flags |= llvm::DINode::FlagArtificial;
2116 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
2117 if (CXXC->isExplicit())
2118 Flags |= llvm::DINode::FlagExplicit;
2119 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
2120 if (CXXC->isExplicit())
2121 Flags |= llvm::DINode::FlagExplicit;
2124 Flags |= llvm::DINode::FlagPrototyped;
2126 Flags |= llvm::DINode::FlagLValueReference;
2128 Flags |= llvm::DINode::FlagRValueReference;
2130 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2132 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2136 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2140 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2141 llvm::DISubprogram *SP = DBuilder.createMethod(
2142 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2143 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2144 TParamsArray.get());
2151 void CGDebugInfo::CollectCXXMemberFunctions(
2158 for (
const auto *I : RD->
decls()) {
2159 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2184 EltTys.push_back(MI == SPCache.end()
2185 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2186 :
static_cast<llvm::Metadata *
>(MI->second));
2190 void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2192 llvm::DIType *RecordTy) {
2194 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2195 llvm::DINode::FlagZero);
2200 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2201 llvm::DINode::FlagIndirectVirtualBase);
2205 void CGDebugInfo::CollectCXXBasesAux(
2210 llvm::DINode::DIFlags StartingFlags) {
2212 for (
const auto &BI : Bases) {
2215 if (!SeenTypes.insert(
Base).second)
2217 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2218 llvm::DINode::DIFlags BFlags = StartingFlags;
2220 uint32_t VBPtrOffset = 0;
2222 if (BI.isVirtual()) {
2239 BFlags |= llvm::DINode::FlagVirtual;
2246 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2247 VBPtrOffset, BFlags);
2248 EltTys.push_back(DTy);
2253 CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2254 llvm::DIFile *Unit) {
2256 return llvm::DINodeArray();
2257 TemplateArgs &Args = *OArgs;
2259 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2264 Name = Args.TList->getParam(i)->getName();
2268 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2269 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2270 TheCU, Name, TTy, defaultParameter));
2275 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2276 TheCU, Name, TTy, defaultParameter,
2282 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2283 llvm::Constant *
V =
nullptr;
2287 !D->
hasAttr<CUDADeviceAttr>()) {
2290 if (
const auto *VD = dyn_cast<VarDecl>(D))
2294 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2295 MD && MD->isImplicitObjectMemberFunction())
2297 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2301 else if (
const auto *MPT =
2302 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2310 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2312 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2319 assert(
V &&
"Failed to find template parameter pointer");
2320 V =
V->stripPointerCasts();
2322 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2323 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2327 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2328 llvm::Constant *
V =
nullptr;
2331 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2337 if (MPT->isMemberDataPointer())
2340 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2341 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2342 TheCU, Name, TTy, defaultParameter,
V));
2346 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2349 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2350 TheCU, Name, TTy, defaultParameter,
V));
2353 std::string QualName;
2354 llvm::raw_string_ostream OS(QualName);
2356 OS, getPrintingPolicy());
2357 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2358 TheCU, Name,
nullptr, OS.str(), defaultParameter));
2362 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2363 TheCU, Name,
nullptr,
2372 assert(
V &&
"Expression in template argument isn't constant");
2373 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2374 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2375 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2381 "These argument types shouldn't exist in concrete types");
2384 return DBuilder.getOrCreateArray(TemplateParams);
2387 std::optional<CGDebugInfo::TemplateArgs>
2388 CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2396 return std::nullopt;
2398 std::optional<CGDebugInfo::TemplateArgs>
2399 CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2403 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2405 return std::nullopt;
2408 auto TA = TS->getTemplateArgs().asArray();
2409 return {{TList, TA}};
2411 std::optional<CGDebugInfo::TemplateArgs>
2412 CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2413 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2418 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2420 return {{TPList, TAList.
asArray()}};
2422 return std::nullopt;
2426 CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2427 llvm::DIFile *Unit) {
2428 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2431 llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2432 llvm::DIFile *Unit) {
2433 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2436 llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2437 llvm::DIFile *Unit) {
2438 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2441 llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2442 if (!D->
hasAttr<BTFDeclTagAttr>())
2447 llvm::Metadata *Ops[2] = {
2448 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2450 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2452 return DBuilder.getOrCreateArray(Annotations);
2455 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2457 return VTablePtrType;
2462 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2463 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2464 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2467 std::optional<unsigned> DWARFAddressSpace =
2470 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2471 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2472 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2473 return VTablePtrType;
2476 StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2481 StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2483 llvm::Function *InitFn) {
2488 return InitFn->getName();
2498 llvm::raw_svector_ostream OS(QualifiedGV);
2500 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2502 std::swap(Quals, GVName);
2506 llvm::raw_svector_ostream OS(InitName);
2508 OS << Quals <<
"::";
2513 llvm_unreachable(
"not an initializer");
2515 OS <<
"`dynamic initializer for '";
2518 OS <<
"`dynamic atexit destructor for '";
2525 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2527 getPrintingPolicy());
2532 return internString(OS.str());
2535 void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2552 llvm::DIType *VPtrTy =
nullptr;
2555 if (NeedVTableShape) {
2560 unsigned VSlotCount =
2562 unsigned VTableWidth = PtrWidth * VSlotCount;
2564 std::optional<unsigned> DWARFAddressSpace =
2568 llvm::DIType *VTableType = DBuilder.createPointerType(
2569 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2570 EltTys.push_back(VTableType);
2573 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2581 VPtrTy = getOrCreateVTablePtrType(Unit);
2584 llvm::DIType *VPtrMember =
2585 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2586 llvm::DINode::FlagArtificial, VPtrTy);
2587 EltTys.push_back(VPtrMember);
2593 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(
Loc));
2605 assert(!D.
isNull() &&
"null type");
2606 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(
Loc));
2607 assert(
T &&
"could not create debug info for type");
2617 llvm::codegenoptions::DebugLineTablesOnly)
2623 node = getOrCreateType(AllocatedTy, getOrCreateFile(
Loc));
2625 CI->setMetadata(
"heapallocsite",
node);
2629 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2633 auto I = TypeCache.find(TyPtr);
2634 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2636 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2637 assert(!Res->isForwardDecl());
2638 TypeCache[TyPtr].reset(Res);
2642 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2649 if (RD->
hasAttr<DLLImportAttr>())
2652 if (MD->hasAttr<DLLImportAttr>())
2665 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2674 bool Explicit =
false;
2675 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2676 Explicit = TD->isExplicitInstantiationOrSpecialization();
2690 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2691 if (CXXRD->isDynamicClass() &&
2693 llvm::GlobalValue::AvailableExternallyLinkage &&
2704 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2708 auto I = TypeCache.find(TyPtr);
2709 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2716 assert(!Res->isForwardDecl());
2717 TypeCache[TyPtr].reset(Res);
2724 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2725 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2748 if (Ctor->isCopyOrMoveConstructor())
2750 if (!Ctor->isDeleted())
2769 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2772 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2773 RD->
hasAttr<StandaloneDebugAttr>())
2776 if (!LangOpts.CPlusPlus)
2782 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2798 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2799 Spec = SD->getSpecializationKind();
2808 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2820 llvm::DIType *
T = getTypeOrNull(Ty);
2821 if (
T &&
T->isForwardDecl())
2825 llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2827 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2831 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2835 auto [Def, Pref] = CreateTypeDefinition(Ty);
2837 return Pref ? Pref : Def;
2840 llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2841 llvm::DIFile *Unit) {
2845 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2849 return getOrCreateType(PNA->getTypedefType(), Unit);
2852 std::pair<llvm::DIType *, llvm::DIType *>
2853 CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2857 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2865 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2869 return {FwdDecl,
nullptr};
2871 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2872 CollectContainingType(CXXDecl, FwdDecl);
2875 LexicalBlockStack.emplace_back(&*FwdDecl);
2876 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2886 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2888 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2889 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2893 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2895 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2897 LexicalBlockStack.pop_back();
2898 RegionMap.erase(Ty->
getDecl());
2900 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2901 DBuilder.replaceArrays(FwdDecl, Elements);
2903 if (FwdDecl->isTemporary())
2905 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2907 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2909 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2910 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2911 return {FwdDecl, PrefDI};
2913 return {FwdDecl,
nullptr};
2917 llvm::DIFile *Unit) {
2923 llvm::DIFile *Unit) {
2928 return DBuilder.createTypedef(
2931 getDeclContextDescriptor(Ty->
getDecl()));
2959 llvm::DIFile *Unit) {
2967 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2968 !
ID->getImplementation())
2969 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2971 getDeclContextDescriptor(
ID), Unit, 0);
2974 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2975 unsigned Line = getLineNumber(
ID->getLocation());
2977 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2983 llvm::DIScope *Mod = getParentModuleOrNull(
ID);
2984 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2985 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
2986 DefUnit, Line, RuntimeLang);
2987 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2991 return CreateTypeDefinition(Ty, Unit);
2995 bool CreateSkeletonCU) {
3000 auto ModRef = ModuleCache.find(M);
3001 if (ModRef != ModuleCache.end())
3002 return cast<llvm::DIModule>(ModRef->second);
3007 llvm::raw_svector_ostream OS(ConfigMacros);
3011 for (
auto &M : PPOpts.Macros) {
3014 const std::string &
Macro = M.first;
3015 bool Undef = M.second;
3016 OS <<
"\"-" << (Undef ?
'U' :
'D');
3017 for (
char c : Macro)
3032 bool IsRootModule = M ? !M->
Parent :
true;
3036 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3038 "clang module without ASTFile must be specified by -fmodule-name");
3041 auto RemapPath = [
this](StringRef Path) -> std::string {
3043 StringRef Relative(Remapped);
3044 StringRef CompDir = TheCU->getDirectory();
3045 if (Relative.consume_front(CompDir))
3046 Relative.consume_front(llvm::sys::path::get_separator());
3048 return Relative.str();
3051 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3058 Signature = ModSig.truncatedValue();
3064 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3066 PCM = getCurrentDirname();
3070 llvm::sys::path::append(PCM, Mod.
getASTFile());
3071 DIB.createCompileUnit(
3072 TheCU->getSourceLanguage(),
3075 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3076 llvm::DICompileUnit::FullDebug, Signature);
3081 IsRootModule ? nullptr
3084 std::string IncludePath = Mod.
getPath().str();
3085 llvm::DIModule *DIMod =
3087 RemapPath(IncludePath));
3088 ModuleCache[M].reset(DIMod);
3093 llvm::DIFile *Unit) {
3095 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3096 unsigned Line = getLineNumber(
ID->getLocation());
3097 unsigned RuntimeLang = TheCU->getSourceLanguage();
3103 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3104 if (
ID->getImplementation())
3105 Flags |= llvm::DINode::FlagObjcClassComplete;
3107 llvm::DIScope *Mod = getParentModuleOrNull(
ID);
3108 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3109 Mod ? Mod : Unit,
ID->getName(), DefUnit, Line, Size, Align, Flags,
3110 nullptr, llvm::DINodeArray(), RuntimeLang);
3113 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3116 LexicalBlockStack.emplace_back(RealDecl);
3117 RegionMap[Ty->
getDecl()].reset(RealDecl);
3124 llvm::DIType *SClassTy =
3129 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3130 llvm::DINode::FlagZero);
3131 EltTys.push_back(InhTag);
3137 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3138 unsigned PLine = getLineNumber(
Loc);
3141 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3142 PD->getName(), PUnit, PLine,
3144 : getSelectorName(PD->getGetterName()),
3146 : getSelectorName(PD->getSetterName()),
3147 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3148 EltTys.push_back(PropertyNode);
3153 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3160 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3163 for (
auto *PD : ClassExt->properties()) {
3164 PropertySet.insert(GetIsClassAndIdent(PD));
3167 for (
const auto *PD :
ID->properties()) {
3170 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3177 unsigned FieldNo = 0;
3179 Field =
Field->getNextIvar(), ++FieldNo) {
3180 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3184 StringRef FieldName =
Field->getName();
3187 if (FieldName.empty())
3191 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3192 unsigned FieldLine = getLineNumber(
Field->getLocation());
3195 uint32_t FieldAlign = 0;
3200 FieldSize =
Field->isBitField()
3211 if (
Field->isBitField()) {
3222 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3224 Flags = llvm::DINode::FlagProtected;
3226 Flags = llvm::DINode::FlagPrivate;
3228 Flags = llvm::DINode::FlagPublic;
3230 if (
Field->isBitField())
3231 Flags |= llvm::DINode::FlagBitField;
3233 llvm::MDNode *PropertyNode =
nullptr;
3236 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3239 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3240 unsigned PLine = getLineNumber(
Loc);
3243 PropertyNode = DBuilder.createObjCProperty(
3244 PD->getName(), PUnit, PLine,
3247 : getSelectorName(PD->getGetterName()),
3250 : getSelectorName(PD->getSetterName()),
3251 PD->getPropertyAttributes(),
3252 getOrCreateType(PD->getType(), PUnit));
3256 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3257 FieldSize, FieldAlign, FieldOffset, Flags,
3258 FieldTy, PropertyNode);
3259 EltTys.push_back(FieldTy);
3262 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3263 DBuilder.replaceArrays(RealDecl, Elements);
3265 LexicalBlockStack.pop_back();
3269 llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3270 llvm::DIFile *Unit) {
3288 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3291 llvm::Metadata *Subscript;
3293 auto SizeExpr = SizeExprCache.find(QTy);
3294 if (SizeExpr != SizeExprCache.end())
3295 Subscript = DBuilder.getOrCreateSubrange(
3296 SizeExpr->getSecond() ,
nullptr ,
3297 nullptr ,
nullptr );
3300 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3301 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3302 Subscript = DBuilder.getOrCreateSubrange(
3303 CountNode ,
nullptr ,
nullptr ,
3306 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3311 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3315 llvm::DIFile *Unit) {
3319 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3325 auto *ColumnCountNode =
3326 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3328 auto *RowCountNode =
3329 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3331 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3332 ColumnCountNode ,
nullptr ,
nullptr ,
3334 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3335 RowCountNode ,
nullptr ,
nullptr ,
3337 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3338 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3341 llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3346 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3370 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3379 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3380 Count = CAT->getZExtSize();
3381 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3382 if (
Expr *Size = VAT->getSizeExpr()) {
3385 Count = Result.Val.getInt().getExtValue();
3389 auto SizeNode = SizeExprCache.find(EltTy);
3390 if (SizeNode != SizeExprCache.end())
3391 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3392 SizeNode->getSecond() ,
nullptr ,
3393 nullptr ,
nullptr ));
3396 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3398 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3399 CountNode ,
nullptr ,
nullptr ,
3405 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3407 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3412 llvm::DIFile *Unit) {
3413 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3418 llvm::DIFile *Unit) {
3419 llvm::dwarf::Tag Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3423 Tag = llvm::dwarf::DW_TAG_reference_type;
3425 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3430 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3440 Flags |= llvm::DINode::FlagSingleInheritance;
3443 Flags |= llvm::DINode::FlagMultipleInheritance;
3446 Flags |= llvm::DINode::FlagVirtualInheritance;
3456 return DBuilder.createMemberPointerType(
3462 return DBuilder.createMemberPointerType(
3463 getOrCreateInstanceMethodType(
3466 ClassType,
Size, 0, Flags);
3469 llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3471 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3474 llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3478 llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3490 bool isImportedFromModule =
3502 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3503 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3504 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3505 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3508 StringRef EDName = ED->
getName();
3509 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3510 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
3511 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3513 ReplaceMap.emplace_back(
3514 std::piecewise_construct, std::make_tuple(Ty),
3515 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3519 return CreateTypeDefinition(Ty);
3522 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3536 Enumerators.push_back(
3537 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3541 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3543 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3545 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3546 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3547 return DBuilder.createEnumerationType(
3548 EnumContext, ED->
getName(), DefUnit, Line, Size, Align, EltArray, ClassTy,
3554 StringRef Name, StringRef
Value) {
3555 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3556 return DBuilder.createMacro(
Parent, Line, MType, Name,
Value);
3562 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3563 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3564 return DBuilder.createTempMacroFile(
Parent, Line, FName);
3574 Quals += InnerQuals;
3578 return C.getQualifiedType(
T.getTypePtr(), Quals);
3579 case Type::TemplateSpecialization: {
3580 const auto *Spec = cast<TemplateSpecializationType>(
T);
3581 if (Spec->isTypeAlias())
3582 return C.getQualifiedType(
T.getTypePtr(), Quals);
3586 case Type::TypeOfExpr:
3587 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3590 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3592 case Type::Decltype:
3593 T = cast<DecltypeType>(
T)->getUnderlyingType();
3595 case Type::UnaryTransform:
3596 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3598 case Type::Attributed:
3599 T = cast<AttributedType>(
T)->getEquivalentType();
3601 case Type::BTFTagAttributed:
3602 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3604 case Type::CountAttributed:
3605 T = cast<CountAttributedType>(
T)->
desugar();
3607 case Type::Elaborated:
3608 T = cast<ElaboratedType>(
T)->getNamedType();
3611 T = cast<UsingType>(
T)->getUnderlyingType();
3614 T = cast<ParenType>(
T)->getInnerType();
3616 case Type::MacroQualified:
3617 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3619 case Type::SubstTemplateTypeParm:
3620 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3623 case Type::DeducedTemplateSpecialization: {
3624 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3625 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3629 case Type::PackIndexing: {
3630 T = cast<PackIndexingType>(
T)->getSelectedType();
3633 case Type::Adjusted:
3636 T = cast<AdjustedType>(
T)->getAdjustedType();
3640 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3645 llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3648 if (It != TypeCache.end()) {
3650 if (llvm::Metadata *
V = It->second)
3651 return cast<llvm::DIType>(
V);
3663 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3673 llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3677 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3679 llvm::raw_string_ostream OS(Name);
3680 Ty.
print(OS, getPrintingPolicy());
3687 if (
auto *
T = getTypeOrNull(Ty))
3690 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3691 void *TyPtr = Ty.getAsOpaquePtr();
3694 TypeCache[TyPtr].reset(Res);
3699 llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
3701 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
3707 auto Info = Reader->getSourceDescriptor(Idx);
3709 return getOrCreateModuleRef(*Info,
true);
3710 }
else if (ClangModuleMap) {
3724 return getOrCreateModuleRef(Info,
false);
3727 return getOrCreateModuleRef(PCHDescriptor,
false);
3734 llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3737 return CreateQualifiedType(Ty, Unit);
3741 #define TYPE(Class, Base)
3742 #define ABSTRACT_TYPE(Class, Base)
3743 #define NON_CANONICAL_TYPE(Class, Base)
3744 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
3745 #include "clang/AST/TypeNodes.inc"
3746 llvm_unreachable(
"Dependent types cannot show up in debug information");
3748 case Type::ExtVector:
3750 return CreateType(cast<VectorType>(Ty), Unit);
3751 case Type::ConstantMatrix:
3752 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3753 case Type::ObjCObjectPointer:
3754 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3755 case Type::ObjCObject:
3756 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3757 case Type::ObjCTypeParam:
3758 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3759 case Type::ObjCInterface:
3760 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3762 return CreateType(cast<BuiltinType>(Ty));
3764 return CreateType(cast<ComplexType>(Ty));
3766 return CreateType(cast<PointerType>(Ty), Unit);
3767 case Type::BlockPointer:
3768 return CreateType(cast<BlockPointerType>(Ty), Unit);
3770 return CreateType(cast<TypedefType>(Ty), Unit);
3772 return CreateType(cast<RecordType>(Ty));
3774 return CreateEnumType(cast<EnumType>(Ty));
3775 case Type::FunctionProto:
3776 case Type::FunctionNoProto:
3777 return CreateType(cast<FunctionType>(Ty), Unit);
3778 case Type::ConstantArray:
3779 case Type::VariableArray:
3780 case Type::IncompleteArray:
3781 case Type::ArrayParameter:
3782 return CreateType(cast<ArrayType>(Ty), Unit);
3784 case Type::LValueReference:
3785 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3786 case Type::RValueReference:
3787 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3789 case Type::MemberPointer:
3790 return CreateType(cast<MemberPointerType>(Ty), Unit);
3793 return CreateType(cast<AtomicType>(Ty), Unit);
3796 return CreateType(cast<BitIntType>(Ty));
3798 return CreateType(cast<PipeType>(Ty), Unit);
3800 case Type::TemplateSpecialization:
3801 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3803 case Type::CountAttributed:
3805 case Type::Attributed:
3806 case Type::BTFTagAttributed:
3807 case Type::Adjusted:
3809 case Type::DeducedTemplateSpecialization:
3810 case Type::Elaborated:
3813 case Type::MacroQualified:
3814 case Type::SubstTemplateTypeParm:
3815 case Type::TypeOfExpr:
3817 case Type::Decltype:
3818 case Type::PackIndexing:
3819 case Type::UnaryTransform:
3823 llvm_unreachable(
"type should have been unwrapped!");
3826 llvm::DICompositeType *
3827 CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3830 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3835 if (
T && !
T->isForwardDecl())
3839 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3844 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
3847 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3852 llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3856 StringRef RDName = getClassName(RD);
3858 llvm::DIFile *DefUnit =
nullptr;
3861 DefUnit = getOrCreateFile(
Loc);
3862 Line = getLineNumber(
Loc);
3865 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3869 auto *
T = cast_or_null<llvm::DICompositeType>(
3878 return getOrCreateRecordFwdDecl(Ty, RDContext);
3891 auto Flags = llvm::DINode::FlagZero;
3892 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3894 Flags |= llvm::DINode::FlagTypePassByReference;
3896 Flags |= llvm::DINode::FlagTypePassByValue;
3899 if (!CXXRD->isTrivial())
3900 Flags |= llvm::DINode::FlagNonTrivial;
3903 if (CXXRD->isAnonymousStructOrUnion())
3904 Flags |= llvm::DINode::FlagExportSymbols;
3907 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3910 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
3911 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3912 getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
3917 switch (RealDecl->getTag()) {
3919 llvm_unreachable(
"invalid composite type tag");
3921 case llvm::dwarf::DW_TAG_array_type:
3922 case llvm::dwarf::DW_TAG_enumeration_type:
3931 case llvm::dwarf::DW_TAG_structure_type:
3932 case llvm::dwarf::DW_TAG_union_type:
3933 case llvm::dwarf::DW_TAG_class_type:
3936 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3940 RegionMap[Ty->
getDecl()].reset(RealDecl);
3943 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3944 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3945 CollectCXXTemplateParams(TSpecial, DefUnit));
3949 void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3950 llvm::DICompositeType *RealDecl) {
3952 llvm::DIType *ContainingType =
nullptr;
3964 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3967 ContainingType = RealDecl;
3969 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3972 llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3974 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3978 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3979 *
Offset, llvm::DINode::FlagZero, FieldTy);
3984 void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3986 StringRef &LinkageName,
3987 llvm::DIScope *&FDContext,
3988 llvm::DINodeArray &TParamsArray,
3989 llvm::DINode::DIFlags &Flags) {
3991 Name = getFunctionName(FD);
3996 Flags |= llvm::DINode::FlagPrototyped;
4000 if (LinkageName == Name ||
4005 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4006 LinkageName = StringRef();
4011 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4015 FDContext = getOrCreateNamespace(NSDecl);
4018 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4019 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4025 Flags |= llvm::DINode::FlagNoReturn;
4027 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4031 void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4033 StringRef &Name, StringRef &LinkageName,
4034 llvm::MDTuple *&TemplateParameters,
4035 llvm::DIScope *&VDContext) {
4055 if (LinkageName == Name)
4056 LinkageName = StringRef();
4058 if (isa<VarTemplateSpecializationDecl>(VD)) {
4059 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4060 TemplateParameters = parameterNodes.get();
4062 TemplateParameters =
nullptr;
4082 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4083 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4086 llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4088 llvm::DINodeArray TParamsArray;
4089 StringRef Name, LinkageName;
4090 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4091 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4093 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4094 llvm::DIScope *DContext = Unit;
4095 unsigned Line = getLineNumber(
Loc);
4096 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4098 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4103 ArgTypes.push_back(Parm->getType());
4109 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4111 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4114 Flags |= getCallSiteRelatedAttrs();
4115 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4116 return DBuilder.createFunction(
4117 DContext, Name, LinkageName, Unit, Line,
4118 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4119 TParamsArray.get(), getFunctionDeclaration(FD));
4122 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4123 DContext, Name, LinkageName, Unit, Line,
4124 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4125 TParamsArray.get(), getFunctionDeclaration(FD));
4127 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4128 std::make_tuple(CanonDecl),
4129 std::make_tuple(SP));
4133 llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4134 return getFunctionFwdDeclOrStub(GD,
false);
4137 llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4138 return getFunctionFwdDeclOrStub(GD,
true);
4141 llvm::DIGlobalVariable *
4142 CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4144 StringRef Name, LinkageName;
4146 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4147 llvm::DIScope *DContext = Unit;
4148 unsigned Line = getLineNumber(
Loc);
4149 llvm::MDTuple *TemplateParameters =
nullptr;
4151 collectVarDeclProps(VD, Unit, Line,
T, Name, LinkageName, TemplateParameters,
4154 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4155 DContext, Name, LinkageName, Unit, Line, getOrCreateType(
T, Unit),
4157 FwdDeclReplaceMap.emplace_back(
4158 std::piecewise_construct,
4160 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4164 llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4169 if (
const auto *TD = dyn_cast<TypeDecl>(D))
4174 if (I != DeclCache.end()) {
4176 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4177 return GVE->getVariable();
4178 return cast<llvm::DINode>(N);
4185 if (IE != ImportedDeclCache.end()) {
4186 auto N = IE->second;
4187 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4188 return cast<llvm::DINode>(GVE);
4189 return dyn_cast_or_null<llvm::DINode>(N);
4194 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4195 return getFunctionForwardDeclaration(FD);
4196 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4197 return getGlobalVariableForwardDeclaration(VD);
4202 llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4203 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4206 const auto *FD = dyn_cast<FunctionDecl>(D);
4211 auto *S = getDeclContextDescriptor(D);
4214 if (MI == SPCache.end()) {
4216 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4217 cast<llvm::DICompositeType>(S));
4220 if (MI != SPCache.end()) {
4221 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4222 if (SP && !SP->isDefinition())
4226 for (
auto *NextFD : FD->
redecls()) {
4227 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4228 if (MI != SPCache.end()) {
4229 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4230 if (SP && !SP->isDefinition())
4237 llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4238 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4239 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4240 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4243 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4251 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4261 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4262 if (It == TypeCache.end())
4264 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4265 llvm::DISubprogram *FD = DBuilder.createFunction(
4266 InterfaceType, getObjCMethodName(OMD), StringRef(),
4267 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4268 DBuilder.finalizeSubprogram(FD);
4275 llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4280 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4284 return DBuilder.createSubroutineType(
4285 DBuilder.getOrCreateTypeArray(std::nullopt));
4287 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
4288 return getOrCreateMethodType(Method, F);
4293 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4298 QualType ResultTy = OMethod->getReturnType();
4303 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4305 Elts.push_back(getOrCreateType(ResultTy, F));
4308 if (
auto *SelfDecl = OMethod->getSelfDecl())
4309 SelfDeclTy = SelfDecl->getType();
4310 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4313 if (!SelfDeclTy.
isNull())
4315 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4317 Elts.push_back(DBuilder.createArtificialType(
4320 for (
const auto *PI : OMethod->parameters())
4321 Elts.push_back(getOrCreateType(PI->getType(), F));
4323 if (OMethod->isVariadic())
4324 Elts.push_back(DBuilder.createUnspecifiedParameter());
4326 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4327 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4333 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4334 if (FD->isVariadic()) {
4336 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4337 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4339 EltTys.push_back(getOrCreateType(ParamType, F));
4340 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4341 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4342 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4346 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4355 CC = SrcFnTy->getCallConv();
4357 for (
const VarDecl *VD : Args)
4358 ArgTypes.push_back(VD->
getType());
4365 llvm::Function *Fn,
bool CurFuncIsThunk) {
4367 StringRef LinkageName;
4369 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4372 bool HasDecl = (D !=
nullptr);
4374 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4375 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4376 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4377 llvm::DIScope *FDContext = Unit;
4378 llvm::DINodeArray TParamsArray;
4381 LinkageName = Fn->getName();
4382 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4384 auto FI = SPCache.find(FD->getCanonicalDecl());
4385 if (FI != SPCache.end()) {
4386 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4387 if (SP && SP->isDefinition()) {
4388 LexicalBlockStack.emplace_back(SP);
4389 RegionMap[D].reset(SP);
4393 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4394 TParamsArray, Flags);
4395 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4396 Name = getObjCMethodName(OMD);
4397 Flags |= llvm::DINode::FlagPrototyped;
4398 }
else if (isa<VarDecl>(D) &&
4404 Name = Fn->getName();
4406 if (isa<BlockDecl>(D))
4409 Flags |= llvm::DINode::FlagPrototyped;
4411 if (Name.starts_with(
"\01"))
4412 Name = Name.substr(1);
4414 assert((!D || !isa<VarDecl>(D) ||
4416 "Unexpected DynamicInitKind !");
4419 isa<VarDecl>(D) || isa<CapturedDecl>(D)) {
4420 Flags |= llvm::DINode::FlagArtificial;
4426 Flags |= llvm::DINode::FlagThunk;
4428 if (Fn->hasLocalLinkage())
4429 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4431 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4433 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4434 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4435 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4437 const unsigned LineNo = getLineNumber(
Loc.
isValid() ?
Loc : CurLoc);
4438 unsigned ScopeLine = getLineNumber(ScopeLoc);
4439 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4440 llvm::DISubprogram *
Decl =
nullptr;
4441 llvm::DINodeArray Annotations =
nullptr;
4443 Decl = isa<ObjCMethodDecl>(D)
4444 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4445 : getFunctionDeclaration(D);
4446 Annotations = CollectBTFDeclTagAnnotations(D);
4454 llvm::DISubprogram *SP = DBuilder.createFunction(
4455 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4456 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4458 Fn->setSubprogram(SP);
4462 if (HasDecl && isa<FunctionDecl>(D))
4466 LexicalBlockStack.emplace_back(SP);
4469 RegionMap[D].reset(SP);
4473 QualType FnType, llvm::Function *Fn) {
4475 StringRef LinkageName;
4481 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4482 return GetName(D,
true);
4485 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4486 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4487 bool IsDeclForCallSite = Fn ?
true :
false;
4488 llvm::DIScope *FDContext =
4489 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
4490 llvm::DINodeArray TParamsArray;
4491 if (isa<FunctionDecl>(D)) {
4493 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4494 TParamsArray, Flags);
4495 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4496 Name = getObjCMethodName(OMD);
4497 Flags |= llvm::DINode::FlagPrototyped;
4499 llvm_unreachable(
"not a function or ObjC method");
4501 if (!Name.empty() && Name[0] ==
'\01')
4502 Name = Name.substr(1);
4505 Flags |= llvm::DINode::FlagArtificial;
4510 unsigned LineNo = getLineNumber(
Loc);
4511 unsigned ScopeLine = 0;
4512 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4514 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4516 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4517 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4518 llvm::DISubprogram *SP = DBuilder.createFunction(
4519 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4520 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4526 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
4527 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4530 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4531 DBuilder.createParameterVariable(
4532 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4533 llvm::DINode::FlagZero, ParamAnnotations);
4539 if (IsDeclForCallSite)
4540 Fn->setSubprogram(SP);
4542 DBuilder.finalizeSubprogram(SP);
4550 auto *
Func = CallOrInvoke->getCalledFunction();
4553 if (
Func->getSubprogram())
4558 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4560 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4571 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4573 auto FI = SPCache.find(FD->getCanonicalDecl());
4574 llvm::DISubprogram *SP =
nullptr;
4575 if (FI != SPCache.end())
4576 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4577 if (!SP || !SP->isDefinition())
4578 SP = getFunctionStub(GD);
4579 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4580 LexicalBlockStack.emplace_back(SP);
4586 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4595 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4598 llvm::MDNode *
Scope = LexicalBlockStack.back();
4599 Builder.SetCurrentDebugLocation(
4600 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4601 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4605 llvm::MDNode *Back =
nullptr;
4606 if (!LexicalBlockStack.empty())
4607 Back = LexicalBlockStack.back().get();
4608 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4609 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4610 getColumnNumber(CurLoc)));
4613 void CGDebugInfo::AppendAddressSpaceXDeref(
4615 std::optional<unsigned> DWARFAddressSpace =
4617 if (!DWARFAddressSpace)
4620 Expr.push_back(llvm::dwarf::DW_OP_constu);
4621 Expr.push_back(*DWARFAddressSpace);
4622 Expr.push_back(llvm::dwarf::DW_OP_swap);
4623 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4632 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4634 LexicalBlockStack.back(), CurInlinedAt));
4636 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4640 CreateLexicalBlock(
Loc);
4645 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4650 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4653 LexicalBlockStack.pop_back();
4657 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4658 unsigned RCount = FnBeginRegionCount.back();
4659 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4662 while (LexicalBlockStack.size() != RCount) {
4665 LexicalBlockStack.pop_back();
4667 FnBeginRegionCount.pop_back();
4669 if (Fn && Fn->getSubprogram())
4670 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4673 CGDebugInfo::BlockByRefType
4674 CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4679 uint32_t FieldAlign;
4681 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4686 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4687 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4689 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4690 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4693 if (HasCopyAndDispose) {
4696 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4698 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4700 bool HasByrefExtendedLayout;
4703 HasByrefExtendedLayout) &&
4704 HasByrefExtendedLayout) {
4707 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4716 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4722 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4727 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4731 *XOffset = FieldOffset;
4732 llvm::DIType *FieldTy = DBuilder.createMemberType(
4733 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4734 llvm::DINode::FlagZero, WrappedTy);
4735 EltTys.push_back(FieldTy);
4736 FieldOffset += FieldSize;
4738 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4739 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4740 llvm::DINode::FlagZero,
nullptr, Elements),
4744 llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4746 std::optional<unsigned> ArgNo,
4748 const bool UsePointerValue) {
4750 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4757 llvm::DIFile *Unit =
nullptr;
4762 if (VD->
hasAttr<BlocksAttr>())
4763 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4765 Ty = getOrCreateType(VD->
getType(), Unit);
4780 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4782 Flags |= llvm::DINode::FlagArtificial;
4787 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4791 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4794 Flags |= llvm::DINode::FlagObjectPointer;
4801 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4802 StringRef Name = VD->
getName();
4803 if (!Name.empty()) {
4809 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4814 Expr.push_back(llvm::dwarf::DW_OP_deref);
4815 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4820 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4832 for (
const auto *Field : RD->
fields()) {
4833 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4834 StringRef FieldName =
Field->getName();
4837 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4842 auto *D = DBuilder.createAutoVariable(
4844 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4847 DBuilder.insertDeclare(
Storage, D, DBuilder.createExpression(
Expr),
4851 Builder.GetInsertBlock());
4859 if (UsePointerValue) {
4860 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4861 "Debug info already contains DW_OP_deref.");
4862 Expr.push_back(llvm::dwarf::DW_OP_deref);
4866 llvm::DILocalVariable *D =
nullptr;
4868 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4869 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit, Line, Ty,
4880 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4883 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4886 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4887 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4888 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4891 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4897 if (
Iter != CoroutineParameterMappings.end()) {
4899 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4900 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4902 if (Iter2 != ParamDbgMappings.end())
4903 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4909 D = RemapCoroArgToLocalVar();
4912 D = DBuilder.createAutoVariable(
Scope, Name, Unit, Line, Ty,
4916 DBuilder.insertDeclare(
Storage, D, DBuilder.createExpression(
Expr),
4918 Column,
Scope, CurInlinedAt),
4919 Builder.GetInsertBlock());
4924 llvm::DIType *CGDebugInfo::CreateBindingDeclType(
const BindingDecl *BD) {
4925 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4930 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
4931 if (FD->isBitField()) {
4948 llvm::DIType *Ty = getOrCreateType(FinalTy, Unit);
4955 return getOrCreateType(BD->
getType(), Unit);
4958 llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4960 std::optional<unsigned> ArgNo,
4962 const bool UsePointerValue) {
4964 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4972 llvm::DIType *Ty = CreateBindingDeclType(BD);
4983 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4988 if (UsePointerValue) {
4989 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4990 "Debug info already contains DW_OP_deref.");
4991 Expr.push_back(llvm::dwarf::DW_OP_deref);
4996 StringRef Name = BD->
getName();
4997 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4998 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5000 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5002 llvm::DINode::FlagZero, Align);
5005 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5006 const unsigned fieldIndex = FD->getFieldIndex();
5013 if (fieldOffset != 0) {
5019 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5025 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5026 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5027 const uint64_t value = IL->getValue().getZExtValue();
5031 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5040 DBuilder.insertDeclare(
Storage, D, DBuilder.createExpression(
Expr),
5042 Column,
Scope, CurInlinedAt),
5043 Builder.GetInsertBlock());
5048 llvm::DILocalVariable *
5051 const bool UsePointerValue) {
5054 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5055 for (
auto *B : DD->bindings()) {
5056 EmitDeclare(B,
Storage, std::nullopt, Builder,
5064 return EmitDeclare(VD,
Storage, std::nullopt, Builder, UsePointerValue);
5069 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5074 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5075 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5081 StringRef Name = D->
getName();
5088 DBuilder.insertLabel(L,
5090 Scope, CurInlinedAt),
5091 Builder.GetInsertBlock());
5094 llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5096 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5099 return DBuilder.createObjectPointerType(Ty);
5104 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5106 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5108 if (Builder.GetInsertBlock() ==
nullptr)
5113 bool isByRef = VD->
hasAttr<BlocksAttr>();
5116 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5119 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5121 Ty = getOrCreateType(VD->
getType(), Unit);
5125 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5127 Ty = CreateSelfType(VD->
getType(), Ty);
5130 const unsigned Line =
5141 addr.push_back(llvm::dwarf::DW_OP_deref);
5142 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5145 addr.push_back(llvm::dwarf::DW_OP_deref);
5146 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5151 addr.push_back(llvm::dwarf::DW_OP_deref);
5152 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5160 auto *D = DBuilder.createAutoVariable(
5161 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5162 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5166 LexicalBlockStack.back(), CurInlinedAt);
5167 auto *
Expr = DBuilder.createExpression(addr);
5169 DBuilder.insertDeclare(
Storage, D,
Expr, DL, InsertPoint);
5171 DBuilder.insertDeclare(
Storage, D,
Expr, DL, Builder.GetInsertBlock());
5174 llvm::DILocalVariable *
5177 bool UsePointerValue) {
5179 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5183 struct BlockLayoutChunk {
5187 bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5188 return l.OffsetInBits < r.OffsetInBits;
5192 void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5194 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5201 BlockLayout.getElementOffsetInBits(0),
5204 BlockLayout.getElementOffsetInBits(1),
5208 BlockLayout.getElementOffsetInBits(0),
5211 BlockLayout.getElementOffsetInBits(1),
5215 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5216 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5218 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType,
Loc,
AS_public,
5219 BlockLayout.getElementOffsetInBits(3),
5221 Fields.push_back(createFieldType(
5226 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5233 llvm::AllocaInst *Alloca,
5241 llvm::DIFile *tunit = getOrCreateFile(loc);
5242 unsigned line = getLineNumber(loc);
5243 unsigned column = getColumnNumber(loc);
5248 const llvm::StructLayout *blockLayout =
5252 collectDefaultFieldsForBlockLiteralDeclare(block, C, loc, *blockLayout, tunit,
5261 BlockLayoutChunk chunk;
5262 chunk.OffsetInBits =
5263 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5264 chunk.Capture =
nullptr;
5265 chunks.push_back(chunk);
5269 for (
const auto &capture :
blockDecl->captures()) {
5270 const VarDecl *variable = capture.getVariable();
5277 BlockLayoutChunk chunk;
5278 chunk.OffsetInBits =
5279 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5280 chunk.Capture = &capture;
5281 chunks.push_back(chunk);
5285 llvm::array_pod_sort(chunks.begin(), chunks.end());
5287 for (
const BlockLayoutChunk &Chunk : chunks) {
5288 uint64_t offsetInBits = Chunk.OffsetInBits;
5295 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5297 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5300 llvm_unreachable(
"unexpected block declcontext");
5302 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5303 offsetInBits, tunit, tunit));
5310 llvm::DIType *fieldType;
5312 TypeInfo PtrInfo = C.getTypeInfo(C.VoidPtrTy);
5317 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5318 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5319 fieldType = DBuilder.createMemberType(tunit,
name, tunit, line,
5320 PtrInfo.
Width, Align, offsetInBits,
5321 llvm::DINode::FlagZero, fieldType);
5325 offsetInBits, Align, tunit, tunit);
5327 fields.push_back(fieldType);
5331 llvm::raw_svector_ostream(typeName)
5334 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5336 llvm::DIType *
type =
5337 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5339 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5343 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5344 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5347 auto *debugVar = DBuilder.createParameterVariable(
5348 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5351 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5353 column, scope, CurInlinedAt),
5354 Builder.GetInsertBlock());
5357 llvm::DIDerivedType *
5358 CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5363 if (MI != StaticDataMemberCache.end()) {
5364 assert(MI->second &&
"Static data member declaration should still exist");
5371 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
5372 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
5375 llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5376 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5377 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5378 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5380 for (
const auto *Field : RD->
fields()) {
5381 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5382 StringRef FieldName = Field->getName();
5385 if (FieldName.empty()) {
5386 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5387 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5392 GVE = DBuilder.createGlobalVariableExpression(
5393 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5394 Var->hasLocalLinkage());
5395 Var->addDebugInfo(GVE);
5407 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5412 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5420 case TemplateArgument::Pack:
5421 return ReferencesAnonymousEntity(TA.getPackAsArray());
5422 case TemplateArgument::Type: {
5423 struct ReferencesAnonymous
5424 : public RecursiveASTVisitor<ReferencesAnonymous> {
5425 bool RefAnon = false;
5426 bool VisitRecordType(RecordType *RT) {
5427 if (ReferencesAnonymousEntity(RT)) {
5434 ReferencesAnonymous RT;
5435 RT.TraverseType(TA.getAsType());
5448 bool Reconstitutable =
true;
5450 Reconstitutable =
false;
5454 Reconstitutable =
false;
5457 bool VisitType(
Type *
T) {
5461 Reconstitutable =
false;
5466 bool TraverseEnumType(
EnumType *ET) {
5469 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5471 Reconstitutable =
false;
5475 Reconstitutable =
false;
5485 return Reconstitutable;
5489 Reconstitutable =
false;
5499 ReconstitutableType
T;
5501 return T.Reconstitutable;
5504 bool CGDebugInfo::HasReconstitutableArgs(
5508 case TemplateArgument::Template:
5515 case TemplateArgument::Declaration:
5524 case TemplateArgument::NullPtr:
5528 case TemplateArgument::Pack:
5531 return HasReconstitutableArgs(TA.getPackAsArray());
5532 case TemplateArgument::Integral:
5537 return TA.getAsIntegral().getBitWidth() <= 64 &&
5538 IsReconstitutableType(TA.getIntegralType());
5539 case TemplateArgument::StructuralValue:
5541 case TemplateArgument::Type:
5542 return IsReconstitutableType(TA.getAsType());
5543 case TemplateArgument::Expression:
5544 return IsReconstitutableType(TA.getAsExpr()->getType());
5546 llvm_unreachable(
"Other, unresolved, template arguments should "
5547 "not be seen here");
5552 std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified)
const {
5554 llvm::raw_string_ostream OS(Name);
5555 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5558 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5559 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
5561 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5562 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5564 std::optional<TemplateArgs> Args;
5566 bool IsOperatorOverload =
false;
5567 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5569 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5572 IsOperatorOverload |=
5575 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5600 bool Reconstitutable =
5601 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5605 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5609 bool Mangled = TemplateNamesKind ==
5610 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5616 std::string EncodedOriginalName;
5617 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5625 std::string CanonicalOriginalName;
5626 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5628 assert(EncodedOriginalNameOS.str() == OriginalOS.str());
5635 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
5637 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5641 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5642 return GetName(D,
true);
5648 if (Cached != DeclCache.end())
5649 return Var->addDebugInfo(
5650 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5653 llvm::DIFile *Unit =
nullptr;
5654 llvm::DIScope *DContext =
nullptr;
5656 StringRef DeclName, LinkageName;
5658 llvm::MDTuple *TemplateParameters =
nullptr;
5659 collectVarDeclProps(D, Unit, LineNo,
T, DeclName, LinkageName,
5660 TemplateParameters, DContext);
5664 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5672 "unnamed non-anonymous struct or union?");
5673 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5678 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
5679 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
5680 if (D->
hasAttr<CUDASharedAttr>())
5683 else if (D->
hasAttr<CUDAConstantAttr>())
5687 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5689 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5690 GVE = DBuilder.createGlobalVariableExpression(
5691 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5692 Var->hasLocalLinkage(),
true,
5693 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5694 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
5695 Align, Annotations);
5696 Var->addDebugInfo(GVE);
5702 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5705 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5706 return GetName(VD,
true);
5711 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5712 StringRef Name = VD->
getName();
5713 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5715 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5716 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5717 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5719 if (CGM.getCodeGenOpts().EmitCodeView) {
5730 llvm::DIType *EDTy =
5732 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5743 auto *VarD = dyn_cast<VarDecl>(VD);
5744 if (VarD && VarD->isStaticDataMember()) {
5745 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5746 getDeclContextDescriptor(VarD);
5751 RetainedTypes.push_back(
5752 CGM.getContext().getRecordType(RD).getAsOpaquePtr());
5756 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5758 auto &GV = DeclCache[VD];
5762 llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init);
5763 llvm::MDTuple *TemplateParameters =
nullptr;
5765 if (isa<VarTemplateSpecializationDecl>(VD))
5767 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5768 TemplateParameters = parameterNodes.get();
5771 GV.reset(DBuilder.createGlobalVariableExpression(
5772 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5773 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5774 TemplateParameters, Align));
5777 void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
5779 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5784 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5785 StringRef Name = D->
getName();
5786 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
5788 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5789 llvm::DIGlobalVariableExpression *GVE =
5790 DBuilder.createGlobalVariableExpression(
5791 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
5792 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5793 Var->addDebugInfo(GVE);
5796 void CGDebugInfo::EmitGlobalAlias(
const llvm::GlobalValue *GV,
5801 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5804 const auto *D = cast<ValueDecl>(GD.
getDecl());
5808 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
5823 if (!(DI = getDeclarationOrDefinition(
5824 AliaseeDecl.getCanonicalDecl().getDecl())))
5827 llvm::DIScope *DContext = getDeclContextDescriptor(D);
5830 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5831 DContext, DI, getOrCreateFile(
Loc), getLineNumber(
Loc), D->getName());
5837 void CGDebugInfo::AddStringLiteralDebugInfo(llvm::GlobalVariable *GV,
5840 PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(
Loc);
5844 llvm::DIFile *
File = getOrCreateFile(
Loc);
5845 llvm::DIGlobalVariableExpression *Debug =
5846 DBuilder.createGlobalVariableExpression(
5847 nullptr, StringRef(), StringRef(), getOrCreateFile(
Loc),
5848 getLineNumber(
Loc), getOrCreateType(S->getType(),
File),
true);
5849 GV->addDebugInfo(Debug);
5852 llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
5853 if (!LexicalBlockStack.empty())
5854 return LexicalBlockStack.back();
5855 llvm::DIScope *Mod = getParentModuleOrNull(D);
5856 return getContextDescriptor(D, Mod ? Mod : TheCU);
5860 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5866 CGM.getCodeGenOpts().DebugExplicitImport) {
5870 DBuilder.createImportedModule(
5872 getOrCreateNamespace(NSDecl), getOrCreateFile(
Loc), getLineNumber(
Loc));
5877 if (llvm::DINode *
Target =
5880 DBuilder.createImportedDeclaration(
5882 getOrCreateFile(
Loc), getLineNumber(
Loc));
5887 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5892 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5894 for (
const auto *USD : UD.
shadows()) {
5899 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5900 if (
const auto *AT = FD->getType()
5903 if (AT->getDeducedType().isNull())
5906 EmitUsingShadowDecl(*USD);
5914 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5919 "We shouldn't be codegening an invalid UsingEnumDecl"
5920 " containing no decls");
5922 for (
const auto *USD : UD.
shadows())
5923 EmitUsingShadowDecl(*USD);
5927 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5929 if (
Module *M =
ID.getImportedModule()) {
5931 auto Loc =
ID.getLocation();
5932 DBuilder.createImportedDeclaration(
5933 getCurrentContextDescriptor(cast<Decl>(
ID.getDeclContext())),
5934 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(
Loc),
5935 getLineNumber(
Loc));
5939 llvm::DIImportedEntity *
5941 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
5945 auto &VH = NamespaceAliasCache[&NA];
5947 return cast<llvm::DIImportedEntity>(VH);
5948 llvm::DIImportedEntity *R;
5950 if (
const auto *Underlying =
5953 R = DBuilder.createImportedDeclaration(
5955 EmitNamespaceAlias(*Underlying), getOrCreateFile(
Loc),
5958 R = DBuilder.createImportedDeclaration(
5967 CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
5971 auto I = NamespaceCache.find(NSDecl);
5972 if (I != NamespaceCache.end())
5973 return cast<llvm::DINamespace>(I->second);
5975 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
5977 llvm::DINamespace *NS =
5978 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
5979 NamespaceCache[NSDecl].reset(NS);
5984 assert(TheCU &&
"no main compile unit");
5985 TheCU->setDWOId(Signature);
5991 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
5992 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
5993 llvm::DIType *Ty = E.Type->getDecl()->getDefinition()
5994 ? CreateTypeDefinition(E.Type, E.Unit)
5996 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6000 for (
const auto &
P : ObjCMethodCache) {
6001 if (
P.second.empty())
6004 QualType QTy(
P.first->getTypeForDecl(), 0);
6006 assert(It != TypeCache.end());
6008 llvm::DICompositeType *InterfaceDecl =
6009 cast<llvm::DICompositeType>(It->second);
6011 auto CurElts = InterfaceDecl->getElements();
6015 for (
auto &SubprogramDirect :
P.second)
6016 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6017 EltTys.push_back(SubprogramDirect.getPointer());
6019 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6020 DBuilder.replaceArrays(InterfaceDecl, Elements);
6023 for (
const auto &
P : ReplaceMap) {
6025 auto *Ty = cast<llvm::DIType>(
P.second);
6026 assert(Ty->isForwardDecl());
6028 auto It = TypeCache.find(
P.first);
6029 assert(It != TypeCache.end());
6032 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6033 cast<llvm::DIType>(It->second));
6036 for (
const auto &
P : FwdDeclReplaceMap) {
6038 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
6039 llvm::Metadata *Repl;
6041 auto It = DeclCache.find(
P.first);
6045 if (It == DeclCache.end())
6050 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6051 Repl = GVE->getVariable();
6052 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
6057 for (
auto &RT : RetainedTypes)
6058 if (
auto MD = TypeCache[RT])
6059 DBuilder.retainType(cast<llvm::DIType>(MD));
6061 DBuilder.finalize();
6066 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6067 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6068 DBuilder.retainType(DieTy);
6072 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6073 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6074 DBuilder.retainType(DieTy);
6078 if (LexicalBlockStack.empty())
6079 return llvm::DebugLoc();
6081 llvm::MDNode *
Scope = LexicalBlockStack.back();
6082 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(
Loc),
6086 llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6089 if (!CGM.getLangOpts().Optimize ||
6090 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6091 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6092 return llvm::DINode::FlagZero;
6097 bool SupportsDWARFv4Ext =
6098 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6099 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6100 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6102 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6103 return llvm::DINode::FlagZero;
6105 return llvm::DINode::FlagAllCallsDescribed;
6108 llvm::DIExpression *
6112 if (CGM.getContext().getTypeSize(VD->
getType()) > 64)
6116 return DBuilder.createConstantValueExpression(
6117 Val.
getFloat().bitcastToAPInt().getZExtValue());
6123 std::optional<uint64_t> ValIntOpt;
6124 if (ValInt.isUnsigned())
6125 ValIntOpt = ValInt.tryZExtValue();
6126 else if (
auto tmp = ValInt.trySExtValue())
6129 ValIntOpt =
static_cast<uint64_t>(*tmp);
6132 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6150 if (isa<TypedefDecl>(D))
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
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 llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
FileID ComputeValidFileID(SourceManager &SM, StringRef FileName)
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
llvm::MachO::Record Record
static ParseState advance(ParseState S, size_t N)
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...
const clang::PrintingPolicy & getPrintingPolicy() const
SourceManager & getSourceManager()
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getEnumType(const EnumDecl *Decl) const
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType UnsignedLongTy
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
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.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TranslationUnitDecl * getTranslationUnitDecl() 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/...
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
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.
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...
ASTFileSignature getSignature() const
std::string getModuleName() const
StringRef getASTFile() const
Module * getModuleOrNull() const
StringRef getPath() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
A fixed int type of a specified bitwidth.
A class which contains all the information about a particular captured value.
VarDecl * getVariable() const
The variable being captured.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
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.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
unsigned size_overridden_methods() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
QualType getThisType() const
Return the type of the this pointer.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
llvm::iterator_range< base_class_const_iterator > base_class_const_range
A wrapper class around a pointer that always points to its canonical declaration.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
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.
MangleContext & getMangleContext()
Gets the mangle context.
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.
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
llvm::MDNode * getInlinedAt() const
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)
Emit call to llvm.dbg.label for an label.
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
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.
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 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 completeRequiredType(const RecordDecl *RD)
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.
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 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.
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a #define directive or a macro undefined by a #undef directi...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
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.
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.
ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)
Get the address of a GUID.
const TargetInfo & getTarget() const
CodeGenTypes & getTypes()
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
const llvm::DataLayout & getDataLayout() 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.
llvm::Module & getModule() const
int getUniqueBlockCount()
Fetches the global unique block count.
const LangOptions & getLangOpts() const
llvm::LLVMContext & getLLVMContext()
CGCXXABI & getCXXABI() const
ItaniumVTableContext & getItaniumVTableContext()
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.
const TargetCodeGenInfo & getTargetCodeGenInfo()
StringRef getMangledName(GlobalDecl GD)
const IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
MicrosoftVTableContext & getMicrosoftVTableContext()
const HeaderSearchOptions & getHeaderSearchOpts() const
const PreprocessorOptions & getPreprocessorOpts() const
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
unsigned getTargetAddressSpace(QualType T) const
llvm::Constant * getPointer() const
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
virtual bool shouldEmitDWARFBitFieldSeparators() const
Complex values, per C99 6.2.5p11.
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getLocation() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
AccessSpecifier getAccess() const
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
DeclContext * getDeclContext()
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.
EnumDecl * getDefinition() const
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
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
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.
ArrayRef< ParmVarDecl * > parameters() const
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.
ArrayRef< QualType > getParamTypes() const
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
ArrayRef< QualType > param_types() const
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() 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...
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
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.
const Type * getClass() const
CXXRecordDecl * getMostRecentCXXRecordDecl() const
QualType getPointeeType() const
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
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.
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...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
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.
void * getAsOpaquePtr() const
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
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.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
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.
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TypedefNameDecl * getTypedefNameForAnonDecl() const
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
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
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
QualType getAsType() const
Retrieve the type for a type template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template 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.
@ 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.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
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
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
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
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isMemberDataPointerType() const
bool isBitIntType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
Declaration of a variable template.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
bool noSystemDebugInfo(const Decl *D, const CodeGenModule &CGM)
constexpr XRayInstrMask None
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.
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.
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
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
@ 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.