40#include "llvm/ADT/DenseSet.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/DerivedTypes.h"
46#include "llvm/IR/Instructions.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/Metadata.h"
49#include "llvm/IR/Module.h"
50#include "llvm/Support/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"
61 if (TI.isAlignRequired())
89 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
93 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
111 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
112 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
113 DBuilder(CGM.getModule()) {
118 assert(LexicalBlockStack.empty() &&
119 "Region stack mismatch, stack not empty!");
125 init(TemporaryLocation);
132 init(TemporaryLocation, DefaultToEmpty);
136 bool DefaultToEmpty) {
143 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
145 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
148 if (TemporaryLocation.
isValid()) {
149 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
153 if (DefaultToEmpty) {
154 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
159 assert(!DI->LexicalBlockStack.empty());
160 CGF->
Builder.SetCurrentDebugLocation(
161 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
162 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
176 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
178 CGF.
Builder.SetCurrentDebugLocation(std::move(
Loc));
185 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
196 SavedLocation = DI.getLocation();
197 assert((DI.getInlinedAt() ==
198 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
199 "CGDebugInfo and IRBuilder are out of sync");
201 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
209 DI.EmitLocation(CGF->
Builder, SavedLocation);
222 if (LexicalBlockStack.empty())
226 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
228 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
231 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
232 LexicalBlockStack.pop_back();
233 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
234 LBF->getScope(), getOrCreateFile(CurLoc)));
235 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
236 isa<llvm::DISubprogram>(
Scope)) {
237 LexicalBlockStack.pop_back();
238 LexicalBlockStack.emplace_back(
239 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
243llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *
D) {
244 llvm::DIScope *Mod = getParentModuleOrNull(
D);
249llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
254 auto I = RegionMap.find(Context);
255 if (I != RegionMap.end()) {
256 llvm::Metadata *
V = I->second;
257 return dyn_cast_or_null<llvm::DIScope>(
V);
261 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
262 return getOrCreateNamespace(NSDecl);
264 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
265 if (!RDecl->isDependentType())
300StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
301 return internString(GetName(FD));
304StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
306 llvm::raw_svector_ostream OS(MethodName);
309 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
310 OS << OID->getName();
311 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
312 OS << OID->getName();
313 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
314 if (OC->IsClassExtension()) {
315 OS << OC->getClassInterface()->getName();
317 OS << OC->getIdentifier()->getNameStart() <<
'('
318 << OC->getIdentifier()->getNameStart() <<
')';
320 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
321 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
325 return internString(OS.str());
328StringRef CGDebugInfo::getSelectorName(
Selector S) {
329 return internString(S.getAsString());
332StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
333 if (isa<ClassTemplateSpecializationDecl>(RD)) {
335 return internString(GetName(RD));
341 return II->getName();
349 "Typedef should not be in another decl context!");
350 assert(
D->getDeclName().getAsIdentifierInfo() &&
351 "Typedef was not named!");
352 return D->getDeclName().getAsIdentifierInfo()->getName();
362 Name = DD->getName();
367 Name = TND->getName();
370 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
371 if (CXXRD->isLambda())
379 return internString(UnnamedType);
387std::optional<llvm::DIFile::ChecksumKind>
396 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
400 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
403 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
404 return llvm::DIFile::CSK_MD5;
406 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
407 return llvm::DIFile::CSK_SHA1;
409 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
410 return llvm::DIFile::CSK_SHA256;
412 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
415std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
420 bool SourceInvalid =
false;
421 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
433 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
439 FileName = TheCU->getFile()->getFilename();
440 CSInfo = TheCU->getFile()->getChecksum();
446 FileName = TheCU->getFile()->getFilename();
454 auto It = DIFileCache.find(
FileName.data());
455 if (It != DIFileCache.end()) {
457 if (llvm::Metadata *
V = It->second)
458 return cast<llvm::DIFile>(
V);
464 std::optional<llvm::DIFile::ChecksumKind> CSKind =
465 computeChecksum(FID, Checksum);
467 CSInfo.emplace(*CSKind, Checksum);
472llvm::DIFile *CGDebugInfo::createFile(
474 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
475 std::optional<StringRef> Source) {
479 std::string CurDir =
remapDIPath(getCurrentDirname());
482 if (llvm::sys::path::is_absolute(RemappedFile)) {
485 auto FileIt = llvm::sys::path::begin(RemappedFile);
486 auto FileE = llvm::sys::path::end(RemappedFile);
487 auto CurDirIt = llvm::sys::path::begin(CurDir);
488 auto CurDirE = llvm::sys::path::end(CurDir);
489 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
490 llvm::sys::path::append(DirBuf, *CurDirIt);
491 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
497 for (; FileIt != FileE; ++FileIt)
498 llvm::sys::path::append(FileBuf, *FileIt);
503 if (!llvm::sys::path::is_absolute(
FileName))
507 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
508 DIFileCache[
FileName.data()].reset(F);
515 if (llvm::sys::path::replace_path_prefix(
P, From, To))
517 return P.str().str();
524 return SM.getPresumedLoc(
Loc).getLine();
540StringRef CGDebugInfo::getCurrentDirname() {
544 if (!CWDName.empty())
546 llvm::ErrorOr<std::string> CWD =
550 return CWDName = internString(*CWD);
553void CGDebugInfo::CreateCompileUnit() {
555 std::optional<llvm::DIFile::ChecksumKind> CSKind;
556 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
569 std::string MainFileName = CGO.MainFileName;
570 if (MainFileName.empty())
571 MainFileName =
"<stdin>";
577 std::string MainFileDir;
579 SM.getFileEntryRefForID(
SM.getMainFileID())) {
580 MainFileDir = std::string(MainFile->getDir().getName());
581 if (!llvm::sys::path::is_absolute(MainFileName)) {
583 llvm::sys::path::Style Style =
586 ? llvm::sys::path::Style::windows_backslash
587 : llvm::sys::path::Style::posix)
588 : llvm::sys::path::Style::native;
589 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
590 MainFileName = std::string(
591 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
598 if (MainFile->getName() == MainFileName &&
600 MainFile->getName().rsplit(
'.').second)
602 MainFileName = CGM.
getModule().getName().str();
604 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
608 llvm::dwarf::SourceLanguage LangTag;
611 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
612 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
613 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
614 else if (LO.CPlusPlus14)
615 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
616 else if (LO.CPlusPlus11)
617 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
619 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
620 }
else if (LO.ObjC) {
621 LangTag = llvm::dwarf::DW_LANG_ObjC;
622 }
else if (LO.OpenCL && (!CGM.
getCodeGenOpts().DebugStrictDwarf ||
624 LangTag = llvm::dwarf::DW_LANG_OpenCL;
625 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
626 LangTag = llvm::dwarf::DW_LANG_C11;
628 LangTag = llvm::dwarf::DW_LANG_C99;
630 LangTag = llvm::dwarf::DW_LANG_C89;
636 unsigned RuntimeVers = 0;
640 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
642 case llvm::codegenoptions::NoDebugInfo:
643 case llvm::codegenoptions::LocTrackingOnly:
644 EmissionKind = llvm::DICompileUnit::NoDebug;
646 case llvm::codegenoptions::DebugLineTablesOnly:
647 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
649 case llvm::codegenoptions::DebugDirectivesOnly:
650 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
652 case llvm::codegenoptions::DebugInfoConstructor:
653 case llvm::codegenoptions::LimitedDebugInfo:
654 case llvm::codegenoptions::FullDebugInfo:
655 case llvm::codegenoptions::UnusedTypeInfo:
656 EmissionKind = llvm::DICompileUnit::FullDebug;
667 CSInfo.emplace(*CSKind, Checksum);
668 llvm::DIFile *CUFile = DBuilder.createFile(
670 getSource(
SM,
SM.getMainFileID()));
672 StringRef Sysroot, SDK;
673 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
675 auto B = llvm::sys::path::rbegin(Sysroot);
676 auto E = llvm::sys::path::rend(Sysroot);
678 std::find_if(B,
E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
683 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
684 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
685 CGOpts.DebugNameTable);
687 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
689 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
692 TheCU = DBuilder.createCompileUnit(
693 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
694 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
695 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
696 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
697 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
700llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
704#define BUILTIN_TYPE(Id, SingletonId)
705#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
706#include "clang/AST/BuiltinTypes.def"
707 case BuiltinType::Dependent:
708 llvm_unreachable(
"Unexpected builtin type");
709 case BuiltinType::NullPtr:
710 return DBuilder.createNullPtrType();
711 case BuiltinType::Void:
713 case BuiltinType::ObjCClass:
716 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
717 "objc_class", TheCU, TheCU->getFile(), 0);
719 case BuiltinType::ObjCId: {
730 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
731 "objc_class", TheCU, TheCU->getFile(), 0);
735 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
737 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
738 0, 0, llvm::DINode::FlagZero,
nullptr,
739 llvm::DINodeArray());
741 DBuilder.replaceArrays(
742 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
743 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
744 llvm::DINode::FlagZero, ISATy)));
747 case BuiltinType::ObjCSel: {
749 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
750 "objc_selector", TheCU,
751 TheCU->getFile(), 0);
755#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
756 case BuiltinType::Id: \
757 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
759#include "clang/Basic/OpenCLImageTypes.def"
760 case BuiltinType::OCLSampler:
761 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
762 case BuiltinType::OCLEvent:
763 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
764 case BuiltinType::OCLClkEvent:
765 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
766 case BuiltinType::OCLQueue:
767 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
768 case BuiltinType::OCLReserveID:
769 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
770#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
771 case BuiltinType::Id: \
772 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
773#include "clang/Basic/OpenCLExtensionTypes.def"
774#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
775 case BuiltinType::Id: \
776 return getOrCreateStructPtrType(#Name, SingletonId);
777#include "clang/Basic/HLSLIntangibleTypes.def"
779#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
780#include "clang/Basic/AArch64SVEACLETypes.def"
782 if (BT->
getKind() == BuiltinType::MFloat8) {
783 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
787 return DBuilder.createBasicType(BTName, Size, Encoding);
791 BT->
getKind() == BuiltinType::SveCount
795 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
802 "Unsupported number of vectors for svcount_t");
806 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
812 llvm::Metadata *LowerBound, *UpperBound;
813 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
815 if (Info.
EC.isScalable()) {
816 unsigned NumElemsPerVG = NumElems / 2;
818 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
819 46, 0, llvm::dwarf::DW_OP_mul,
820 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
821 UpperBound = DBuilder.createExpression(
Expr);
823 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
826 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
827 nullptr, LowerBound, UpperBound,
nullptr);
828 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
829 llvm::DIType *ElemTy =
830 getOrCreateType(Info.
ElementType, TheCU->getFile());
832 return DBuilder.createVectorType( 0, Align, ElemTy,
837#define PPC_VECTOR_TYPE(Name, Id, size) \
838 case BuiltinType::Id:
839#include "clang/Basic/PPCTypes.def"
842#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
843#include "clang/Basic/RISCVVTypes.def"
848 unsigned ElementCount = Info.
EC.getKnownMinValue();
851 bool Fractional =
false;
853 unsigned FixedSize = ElementCount * SEW;
857 }
else if (FixedSize < 64) {
860 LMUL = 64 / FixedSize;
862 LMUL = FixedSize / 64;
870 {llvm::dwarf::DW_OP_bregx,
873 llvm::dwarf::DW_OP_constu,
875 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
877 Expr.push_back(llvm::dwarf::DW_OP_div);
879 Expr.push_back(llvm::dwarf::DW_OP_mul);
881 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
884 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
886 auto *UpperBound = DBuilder.createExpression(
Expr);
887 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
888 nullptr, LowerBound, UpperBound,
nullptr);
889 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
890 llvm::DIType *ElemTy =
891 getOrCreateType(Info.
ElementType, TheCU->getFile());
894 return DBuilder.createVectorType(0, Align, ElemTy,
898#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
899 case BuiltinType::Id: { \
902 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
903 MangledName, TheCU, TheCU->getFile(), 0); \
904 return SingletonId; \
906#include "clang/Basic/WebAssemblyReferenceTypes.def"
907#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
908 case BuiltinType::Id: { \
911 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
912 TheCU, TheCU->getFile(), 0); \
913 return SingletonId; \
915#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
916 case BuiltinType::Id: { \
919 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
920 return SingletonId; \
922#include "clang/Basic/AMDGPUTypes.def"
923 case BuiltinType::UChar:
924 case BuiltinType::Char_U:
925 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
927 case BuiltinType::Char_S:
928 case BuiltinType::SChar:
929 Encoding = llvm::dwarf::DW_ATE_signed_char;
931 case BuiltinType::Char8:
932 case BuiltinType::Char16:
933 case BuiltinType::Char32:
936 case BuiltinType::UShort:
937 case BuiltinType::UInt:
938 case BuiltinType::UInt128:
939 case BuiltinType::ULong:
940 case BuiltinType::WChar_U:
941 case BuiltinType::ULongLong:
942 Encoding = llvm::dwarf::DW_ATE_unsigned;
944 case BuiltinType::Short:
945 case BuiltinType::Int:
946 case BuiltinType::Int128:
947 case BuiltinType::Long:
948 case BuiltinType::WChar_S:
949 case BuiltinType::LongLong:
950 Encoding = llvm::dwarf::DW_ATE_signed;
952 case BuiltinType::Bool:
953 Encoding = llvm::dwarf::DW_ATE_boolean;
955 case BuiltinType::Half:
956 case BuiltinType::Float:
957 case BuiltinType::LongDouble:
958 case BuiltinType::Float16:
959 case BuiltinType::BFloat16:
960 case BuiltinType::Float128:
961 case BuiltinType::Double:
962 case BuiltinType::Ibm128:
968 Encoding = llvm::dwarf::DW_ATE_float;
970 case BuiltinType::ShortAccum:
971 case BuiltinType::Accum:
972 case BuiltinType::LongAccum:
973 case BuiltinType::ShortFract:
974 case BuiltinType::Fract:
975 case BuiltinType::LongFract:
976 case BuiltinType::SatShortFract:
977 case BuiltinType::SatFract:
978 case BuiltinType::SatLongFract:
979 case BuiltinType::SatShortAccum:
980 case BuiltinType::SatAccum:
981 case BuiltinType::SatLongAccum:
982 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
984 case BuiltinType::UShortAccum:
985 case BuiltinType::UAccum:
986 case BuiltinType::ULongAccum:
987 case BuiltinType::UShortFract:
988 case BuiltinType::UFract:
989 case BuiltinType::ULongFract:
990 case BuiltinType::SatUShortAccum:
991 case BuiltinType::SatUAccum:
992 case BuiltinType::SatULongAccum:
993 case BuiltinType::SatUShortFract:
994 case BuiltinType::SatUFract:
995 case BuiltinType::SatULongFract:
996 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1003 return DBuilder.createBasicType(BTName, Size, Encoding);
1006llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1008 StringRef Name = Ty->
isUnsigned() ?
"unsigned _BitInt" :
"_BitInt";
1010 ? llvm::dwarf::DW_ATE_unsigned
1011 : llvm::dwarf::DW_ATE_signed;
1017llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1019 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1021 Encoding = llvm::dwarf::DW_ATE_lo_user;
1024 return DBuilder.createBasicType(
"complex", Size, Encoding);
1038 return llvm::dwarf::DW_TAG_const_type;
1042 return llvm::dwarf::DW_TAG_volatile_type;
1046 return llvm::dwarf::DW_TAG_restrict_type;
1048 return (llvm::dwarf::Tag)0;
1051llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
1052 llvm::DIFile *Unit) {
1062 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1063 return getOrCreateType(
QualType(
T, 0), Unit);
1070 return DBuilder.createQualifiedType(Tag, FromTy);
1074 llvm::DIFile *Unit) {
1083 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1094 return DBuilder.createQualifiedType(Tag, FromTy);
1098 llvm::DIFile *Unit) {
1106 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1110llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1111 llvm::DIFile *Unit) {
1112 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1118 switch (TheCU->getSourceLanguage()) {
1119 case llvm::dwarf::DW_LANG_C_plus_plus:
1120 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1121 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1123 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1124 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
1152 llvm::DICompileUnit *TheCU) {
1170 llvm::DICompileUnit *TheCU) {
1176 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1178 if (RD->isDynamicClass() &&
1191 llvm::dwarf::Tag Tag;
1193 Tag = llvm::dwarf::DW_TAG_structure_type;
1195 Tag = llvm::dwarf::DW_TAG_union_type;
1200 Tag = llvm::dwarf::DW_TAG_class_type;
1205llvm::DICompositeType *
1206CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1207 llvm::DIScope *Ctx) {
1210 return cast<llvm::DICompositeType>(
T);
1211 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1212 const unsigned Line =
1214 StringRef RDName = getClassName(RD);
1220 if (
D &&
D->isCompleteDefinition())
1223 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1228 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1229 if (!CXXRD->hasDefinition() ||
1230 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1231 Flags |= llvm::DINode::FlagNonTrivial;
1238 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1242 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1243 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1244 CollectCXXTemplateParams(TSpecial, DefUnit));
1245 ReplaceMap.emplace_back(
1246 std::piecewise_construct, std::make_tuple(Ty),
1247 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1251llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1254 llvm::DIFile *Unit) {
1259 std::optional<unsigned> DWARFAddressSpace =
1265 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1267 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1270 StringRef
Tag = BTFAttrTy->
getAttr()->getBTFTypeTag();
1272 llvm::Metadata *Ops[2] = {
1273 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_type_tag")),
1275 Annots.insert(Annots.begin(),
1278 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->
getWrappedType());
1281 llvm::DINodeArray Annotations =
nullptr;
1282 if (Annots.size() > 0)
1283 Annotations = DBuilder.getOrCreateArray(Annots);
1285 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1286 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1287 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1288 Size, Align, DWARFAddressSpace);
1290 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1291 Align, DWARFAddressSpace, StringRef(),
1295llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1296 llvm::DIType *&
Cache) {
1299 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1300 TheCU, TheCU->getFile(), 0);
1302 Cache = DBuilder.createPointerType(
Cache, Size);
1306uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1307 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1320 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1321 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1324 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1326 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1327 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1329 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1333 EltTys.push_back(DBuilder.createMemberType(
1334 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1335 FieldOffset, llvm::DINode::FlagZero, DescTy));
1336 FieldOffset += FieldSize;
1343 llvm::DIFile *Unit) {
1347 llvm::DINodeArray Elements;
1351 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1352 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1354 Elements = DBuilder.getOrCreateArray(EltTys);
1357 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1360 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1361 FieldOffset, 0, Flags,
nullptr, Elements);
1366 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1368 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1371 Elements = DBuilder.getOrCreateArray(EltTys);
1377 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1378 Flags,
nullptr, Elements);
1380 return DBuilder.createPointerType(EltTy, Size);
1397 if (Param->isParameterPack()) {
1406 if (SubstArgs.empty()) {
1415 SpecArgs.push_back(SubstArgs.front());
1416 SubstArgs = SubstArgs.drop_front();
1422 llvm::DIFile *Unit) {
1427 if (isa<BuiltinTemplateDecl>(TD))
1430 const auto *
AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
1435 llvm::raw_svector_ostream OS(NS);
1437 auto PP = getPrintingPolicy();
1464 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1473 llvm::raw_string_ostream OS(Name);
1476 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1477 !HasReconstitutableArgs(Args.Args))
1480 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1481 Src, Name, getOrCreateFile(
Loc), getLineNumber(
Loc),
1482 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1488 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(
Loc),
1505 return llvm::DINode::FlagZero;
1509 return llvm::DINode::FlagPrivate;
1511 return llvm::DINode::FlagProtected;
1513 return llvm::DINode::FlagPublic;
1515 return llvm::DINode::FlagZero;
1517 llvm_unreachable(
"unexpected access enumerator");
1520llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1521 llvm::DIFile *Unit) {
1522 llvm::DIType *Underlying =
1534 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1536 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1538 if (isa<RecordDecl>(DC))
1541 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1542 getOrCreateFile(
Loc), getLineNumber(
Loc),
1543 getDeclContextDescriptor(Ty->
getDecl()), Align,
1544 Flags, Annotations);
1554 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1556 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1558 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1560 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1562 return llvm::dwarf::DW_CC_BORLAND_pascal;
1564 return llvm::dwarf::DW_CC_LLVM_Win64;
1566 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1570 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1572 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1574 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1576 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1579 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1581 return llvm::dwarf::DW_CC_LLVM_Swift;
1583 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1585 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1587 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1589 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1591 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1593 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1595 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1601 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1603 Flags |= llvm::DINode::FlagLValueReference;
1605 Flags |= llvm::DINode::FlagRValueReference;
1609llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1610 llvm::DIFile *Unit) {
1611 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1613 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1622 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1624 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1628 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1631 for (
const QualType &ParamType : FPT->param_types())
1632 EltTys.push_back(getOrCreateType(ParamType, Unit));
1633 if (FPT->isVariadic())
1634 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1637 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1638 llvm::DIType *F = DBuilder.createSubroutineType(
1643llvm::DIDerivedType *
1644CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1645 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1646 StringRef Name = BitFieldDecl->
getName();
1648 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1649 Ty = BitFieldDecl->
getAttr<PreferredTypeAttr>()->getType();
1651 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1652 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1655 llvm::DIFile *
File = getOrCreateFile(
Loc);
1656 unsigned Line = getLineNumber(
Loc);
1661 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1670 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1672 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1673 return DBuilder.createBitFieldMemberType(
1674 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1675 Flags, DebugType, Annotations);
1678llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1679 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1707 if (PreviousFieldsDI.empty())
1711 auto *PreviousMDEntry =
1712 PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
1713 auto *PreviousMDField =
1714 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1715 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1716 PreviousMDField->getSizeInBits() == 0)
1720 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1722 assert(PreviousBitfield->isBitField());
1725 if (!PreviousBitfield->isZeroLengthBitField(Context))
1728 QualType Ty = PreviousBitfield->getType();
1730 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1731 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1732 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1734 llvm::DIFile *
File = getOrCreateFile(
Loc);
1735 unsigned Line = getLineNumber(
Loc);
1738 cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
1741 llvm::DINode::DIFlags Flags =
1743 llvm::DINodeArray Annotations =
1744 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1745 return DBuilder.createBitFieldMemberType(
1746 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1747 Flags, DebugType, Annotations);
1750llvm::DIType *CGDebugInfo::createFieldType(
1752 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1753 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1754 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1757 llvm::DIFile *file = getOrCreateFile(loc);
1758 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
1761 auto Align = AlignInBits;
1762 if (!
type->isIncompleteArrayType()) {
1764 SizeInBits = TI.
Width;
1770 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1771 offsetInBits, flags, debugType, Annotations);
1775CGDebugInfo::createInlinedTrapSubprogram(StringRef FuncName,
1776 llvm::DIFile *FileScope) {
1780 llvm::DISubprogram *&SP = InlinedTrapFuncMap[FuncName];
1783 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
1784 SP = DBuilder.createFunction(
1785 FileScope, FuncName, StringRef(),
1786 FileScope, 0, DIFnTy,
1788 llvm::DINode::FlagArtificial,
1789 llvm::DISubprogram::SPFlagDefinition,
1790 nullptr,
nullptr,
nullptr);
1796void CGDebugInfo::CollectRecordLambdaFields(
1798 llvm::DIType *RecordTy) {
1804 unsigned fieldno = 0;
1807 I !=
E; ++I, ++Field, ++fieldno) {
1809 if (
C.capturesVariable()) {
1811 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
1813 StringRef VName =
V->getName();
1814 llvm::DIFile *VUnit = getOrCreateFile(
Loc);
1816 llvm::DIType *FieldType = createFieldType(
1818 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1819 elements.push_back(FieldType);
1820 }
else if (
C.capturesThis()) {
1826 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1828 StringRef ThisName =
1830 llvm::DIType *fieldType = createFieldType(
1834 elements.push_back(fieldType);
1839llvm::DIDerivedType *
1840CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1845 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1846 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1848 unsigned LineNumber = getLineNumber(Var->
getLocation());
1849 StringRef VName = Var->
getName();
1853 llvm::Constant *
C =
nullptr;
1859 if (
Value->isFloat())
1866 ? llvm::dwarf::DW_TAG_variable
1867 : llvm::dwarf::DW_TAG_member;
1869 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1870 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
1875void CGDebugInfo::CollectRecordNormalField(
1876 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1883 if (
name.empty() && !
type->isRecordType())
1886 llvm::DIType *FieldType;
1888 llvm::DIDerivedType *BitFieldType;
1889 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
1890 if (llvm::DIType *Separator =
1891 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
1892 elements.push_back(Separator);
1895 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
1898 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
1901 elements.push_back(FieldType);
1904void CGDebugInfo::CollectRecordNestedType(
1908 if (isa<InjectedClassNameType>(Ty))
1911 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(
Loc));
1912 elements.push_back(nestedType);
1915void CGDebugInfo::CollectRecordFields(
1916 const RecordDecl *record, llvm::DIFile *tunit,
1918 llvm::DICompositeType *RecordTy) {
1919 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
1921 if (CXXDecl && CXXDecl->
isLambda())
1922 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1927 unsigned fieldNo = 0;
1931 for (
const auto *I : record->
decls())
1932 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
1933 if (
V->hasAttr<NoDebugAttr>())
1939 isa<VarTemplateSpecializationDecl>(
V))
1942 if (isa<VarTemplatePartialSpecializationDecl>(
V))
1946 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
1947 if (MI != StaticDataMemberCache.end()) {
1948 assert(MI->second &&
1949 "Static data member declaration should still exist");
1950 elements.push_back(MI->second);
1952 auto Field = CreateRecordStaticField(
V, RecordTy, record);
1953 elements.push_back(Field);
1955 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1956 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1957 elements, RecordTy, record);
1964 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
1966 if (isa<RecordDecl>(I) &&
1967 cast<RecordDecl>(I)->isAnonymousStructOrUnion())
1969 if (!nestedType->isImplicit() &&
1970 nestedType->getDeclContext() == record)
1971 CollectRecordNestedType(nestedType, elements);
1977llvm::DISubroutineType *
1978CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1979 llvm::DIFile *Unit) {
1982 return cast_or_null<llvm::DISubroutineType>(
1989 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
1992llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
2008 const auto *OriginalFunc = cast<llvm::DISubroutineType>(
2010 Func->getReturnType(),
Func->getParamTypes(), EPI),
2012 llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
2013 assert(Args.size() &&
"Invalid number of arguments!");
2018 Elts.push_back(Args[0]);
2024 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2026 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
2027 Elts.push_back(ThisPtrType);
2031 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
2032 Elts.push_back(Args[i]);
2034 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2036 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2043 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2050llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2051 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2053 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
2055 StringRef MethodName = getFunctionName(Method);
2056 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
2060 StringRef MethodLinkageName;
2070 llvm::DIFile *MethodDefUnit =
nullptr;
2071 unsigned MethodLine = 0;
2073 MethodDefUnit = getOrCreateFile(Method->
getLocation());
2074 MethodLine = getLineNumber(Method->
getLocation());
2078 llvm::DIType *ContainingType =
nullptr;
2079 unsigned VIndex = 0;
2080 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2081 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2086 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2088 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2093 if (!isa<CXXDestructorDecl>(Method))
2098 const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
2110 Flags |= llvm::DINode::FlagIntroducedVirtual;
2119 ContainingType = RecordTy;
2123 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2126 Flags |= llvm::DINode::FlagNoReturn;
2129 Flags |= llvm::DINode::FlagStaticMember;
2131 Flags |= llvm::DINode::FlagArtificial;
2133 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
2134 if (CXXC->isExplicit())
2135 Flags |= llvm::DINode::FlagExplicit;
2136 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
2137 if (CXXC->isExplicit())
2138 Flags |= llvm::DINode::FlagExplicit;
2141 Flags |= llvm::DINode::FlagPrototyped;
2143 Flags |= llvm::DINode::FlagLValueReference;
2145 Flags |= llvm::DINode::FlagRValueReference;
2147 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2149 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2153 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2157 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
2158 llvm::DISubprogram *SP = DBuilder.createMethod(
2159 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2160 MethodTy, VIndex,
ThisAdjustment, ContainingType, Flags, SPFlags,
2161 TParamsArray.get());
2168void CGDebugInfo::CollectCXXMemberFunctions(
2175 for (
const auto *I : RD->
decls()) {
2176 const auto *Method = dyn_cast<CXXMethodDecl>(I);
2200 EltTys.push_back(MI == SPCache.end()
2201 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
2202 :
static_cast<llvm::Metadata *
>(MI->second));
2206void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2208 llvm::DIType *RecordTy) {
2209 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2210 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2211 llvm::DINode::FlagZero);
2216 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2217 llvm::DINode::FlagIndirectVirtualBase);
2221void CGDebugInfo::CollectCXXBasesAux(
2226 llvm::DINode::DIFlags StartingFlags) {
2228 for (
const auto &BI : Bases) {
2231 if (!SeenTypes.insert(
Base).second)
2233 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2234 llvm::DINode::DIFlags BFlags = StartingFlags;
2238 if (BI.isVirtual()) {
2255 BFlags |= llvm::DINode::FlagVirtual;
2262 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2263 VBPtrOffset, BFlags);
2264 EltTys.push_back(DTy);
2269CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2270 llvm::DIFile *Unit) {
2272 return llvm::DINodeArray();
2273 TemplateArgs &Args = *OArgs;
2275 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2280 Name = Args.TList->getParam(i)->getName();
2284 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2285 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2286 TheCU, Name, TTy, defaultParameter));
2291 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2292 TheCU, Name, TTy, defaultParameter,
2298 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2299 llvm::Constant *
V =
nullptr;
2306 if (
const auto *VD = dyn_cast<VarDecl>(
D))
2310 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D);
2311 MD && MD->isImplicitObjectMemberFunction())
2313 else if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
2317 else if (
const auto *MPT =
2318 dyn_cast<MemberPointerType>(
T.getTypePtr())) {
2326 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(
D)) {
2328 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
2335 assert(
V &&
"Failed to find template parameter pointer");
2336 V =
V->stripPointerCasts();
2338 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2339 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2343 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2344 llvm::Constant *
V =
nullptr;
2347 if (
const auto *MPT = dyn_cast<MemberPointerType>(
T.getTypePtr()))
2353 if (MPT->isMemberDataPointer())
2356 V = llvm::ConstantInt::get(CGM.
Int8Ty, 0);
2357 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2358 TheCU, Name, TTy, defaultParameter,
V));
2362 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2365 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2366 TheCU, Name, TTy, defaultParameter,
V));
2369 std::string QualName;
2370 llvm::raw_string_ostream OS(QualName);
2372 OS, getPrintingPolicy());
2373 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2374 TheCU, Name,
nullptr, QualName, defaultParameter));
2378 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2379 TheCU, Name,
nullptr,
2388 assert(
V &&
"Expression in template argument isn't constant");
2389 llvm::DIType *TTy = getOrCreateType(
T, Unit);
2390 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2391 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2397 "These argument types shouldn't exist in concrete types");
2400 return DBuilder.getOrCreateArray(TemplateParams);
2403std::optional<CGDebugInfo::TemplateArgs>
2404CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2412 return std::nullopt;
2414std::optional<CGDebugInfo::TemplateArgs>
2415CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2419 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2421 return std::nullopt;
2424 auto TA = TS->getTemplateArgs().asArray();
2425 return {{TList, TA}};
2427std::optional<CGDebugInfo::TemplateArgs>
2428CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2429 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2434 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2436 return {{TPList, TAList.
asArray()}};
2438 return std::nullopt;
2442CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2443 llvm::DIFile *Unit) {
2444 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2447llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2448 llvm::DIFile *Unit) {
2449 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2452llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2453 llvm::DIFile *Unit) {
2454 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2457llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *
D) {
2463 llvm::Metadata *Ops[2] = {
2464 llvm::MDString::get(CGM.
getLLVMContext(), StringRef(
"btf_decl_tag")),
2466 Annotations.push_back(llvm::MDNode::get(CGM.
getLLVMContext(), Ops));
2468 return DBuilder.getOrCreateArray(Annotations);
2471llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2473 return VTablePtrType;
2478 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2479 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
2480 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2483 std::optional<unsigned> DWARFAddressSpace =
2486 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2487 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2488 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2489 return VTablePtrType;
2492StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2497StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2499 llvm::Function *InitFn) {
2504 return InitFn->getName();
2514 llvm::raw_svector_ostream OS(QualifiedGV);
2516 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2518 std::swap(Quals, GVName);
2522 llvm::raw_svector_ostream OS(InitName);
2524 OS << Quals <<
"::";
2529 llvm_unreachable(
"not an initializer");
2531 OS <<
"`dynamic initializer for '";
2534 OS <<
"`dynamic atexit destructor for '";
2541 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2543 getPrintingPolicy());
2548 return internString(OS.str());
2551void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2568 llvm::DIType *VPtrTy =
nullptr;
2571 if (NeedVTableShape) {
2576 unsigned VSlotCount =
2578 unsigned VTableWidth = PtrWidth * VSlotCount;
2580 std::optional<unsigned> DWARFAddressSpace =
2584 llvm::DIType *VTableType = DBuilder.createPointerType(
2585 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2586 EltTys.push_back(VTableType);
2589 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
2597 VPtrTy = getOrCreateVTablePtrType(Unit);
2600 llvm::DIType *VPtrMember =
2601 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
2602 llvm::DINode::FlagArtificial, VPtrTy);
2603 EltTys.push_back(VPtrMember);
2609 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(
Loc));
2621 assert(!
D.isNull() &&
"null type");
2622 llvm::DIType *
T = getOrCreateType(
D, getOrCreateFile(
Loc));
2623 assert(
T &&
"could not create debug info for type");
2625 RetainedTypes.push_back(
D.getAsOpaquePtr());
2633 llvm::codegenoptions::DebugLineTablesOnly)
2639 node = getOrCreateType(AllocatedTy, getOrCreateFile(
Loc));
2641 CI->setMetadata(
"heapallocsite", node);
2645 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2649 auto I = TypeCache.find(TyPtr);
2650 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
2652 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
2653 assert(!Res->isForwardDecl());
2654 TypeCache[TyPtr].reset(Res);
2658 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2665 if (RD->
hasAttr<DLLImportAttr>())
2668 if (MD->hasAttr<DLLImportAttr>())
2681 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2691 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2692 Explicit = TD->isExplicitInstantiationOrSpecialization();
2706 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2707 if (CXXRD->isDynamicClass() &&
2709 llvm::GlobalValue::AvailableExternallyLinkage &&
2720 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2724 auto I = TypeCache.find(TyPtr);
2725 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2732 assert(!Res->isForwardDecl());
2733 TypeCache[TyPtr].reset(Res);
2740 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2741 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2764 if (Ctor->isCopyOrMoveConstructor())
2766 if (!Ctor->isDeleted())
2785 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
2788 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
2789 RD->
hasAttr<StandaloneDebugAttr>())
2792 if (!LangOpts.CPlusPlus)
2798 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2814 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2815 Spec = SD->getSpecializationKind();
2824 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
2836 llvm::DIType *
T = getTypeOrNull(Ty);
2837 if (
T &&
T->isForwardDecl())
2841llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2843 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2847 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2851 auto [Def, Pref] = CreateTypeDefinition(Ty);
2853 return Pref ? Pref : Def;
2856llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
2857 llvm::DIFile *Unit) {
2861 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
2865 return getOrCreateType(PNA->getTypedefType(), Unit);
2868std::pair<llvm::DIType *, llvm::DIType *>
2869CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2873 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2881 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
2884 if (!
D || !
D->isCompleteDefinition())
2885 return {FwdDecl,
nullptr};
2887 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2888 CollectContainingType(CXXDecl, FwdDecl);
2891 LexicalBlockStack.emplace_back(&*FwdDecl);
2892 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2902 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
2904 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2905 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
2909 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2910 if (CXXDecl && !CGM.
getCodeGenOpts().DebugOmitUnreferencedMethods)
2911 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2913 LexicalBlockStack.pop_back();
2914 RegionMap.erase(Ty->
getDecl());
2916 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2917 DBuilder.replaceArrays(FwdDecl, Elements);
2919 if (FwdDecl->isTemporary())
2921 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2923 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2925 if (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
2926 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
2927 return {FwdDecl, PrefDI};
2929 return {FwdDecl,
nullptr};
2933 llvm::DIFile *Unit) {
2939 llvm::DIFile *Unit) {
2944 return DBuilder.createTypedef(
2947 getDeclContextDescriptor(Ty->
getDecl()));
2975 llvm::DIFile *Unit) {
2981 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2986 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
2987 !
ID->getImplementation())
2988 return DBuilder.createForwardDecl(
2989 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
2990 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
2993 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
2994 unsigned Line = getLineNumber(
ID->getLocation());
3000 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3001 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3002 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3003 DefUnit,
Line, RuntimeLang);
3004 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3008 return CreateTypeDefinition(Ty, Unit);
3012 bool CreateSkeletonCU) {
3017 auto ModRef = ModuleCache.find(M);
3018 if (ModRef != ModuleCache.end())
3019 return cast<llvm::DIModule>(ModRef->second);
3024 llvm::raw_svector_ostream OS(ConfigMacros);
3028 for (
auto &M : PPOpts.Macros) {
3031 const std::string &
Macro = M.first;
3032 bool Undef = M.second;
3033 OS <<
"\"-" << (Undef ?
'U' :
'D');
3034 for (
char c : Macro)
3049 bool IsRootModule = M ? !M->
Parent :
true;
3053 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3055 "clang module without ASTFile must be specified by -fmodule-name");
3058 auto RemapPath = [
this](StringRef
Path) -> std::string {
3060 StringRef Relative(Remapped);
3061 StringRef CompDir = TheCU->getDirectory();
3062 if (Relative.consume_front(CompDir))
3063 Relative.consume_front(llvm::sys::path::get_separator());
3065 return Relative.str();
3068 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3075 Signature = ModSig.truncatedValue();
3081 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3083 PCM = getCurrentDirname();
3087 llvm::sys::path::append(PCM, Mod.
getASTFile());
3088 DIB.createCompileUnit(
3089 TheCU->getSourceLanguage(),
3092 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3093 llvm::DICompileUnit::FullDebug, Signature);
3098 IsRootModule ? nullptr
3101 std::string IncludePath = Mod.
getPath().str();
3102 llvm::DIModule *DIMod =
3104 RemapPath(IncludePath));
3105 ModuleCache[M].reset(DIMod);
3110 llvm::DIFile *Unit) {
3112 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3113 unsigned Line = getLineNumber(
ID->getLocation());
3114 unsigned RuntimeLang = TheCU->getSourceLanguage();
3120 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3121 if (
ID->getImplementation())
3122 Flags |= llvm::DINode::FlagObjcClassComplete;
3124 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3125 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3126 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3127 nullptr, llvm::DINodeArray(), RuntimeLang);
3130 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3133 LexicalBlockStack.emplace_back(RealDecl);
3134 RegionMap[Ty->
getDecl()].reset(RealDecl);
3141 llvm::DIType *SClassTy =
3146 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3147 llvm::DINode::FlagZero);
3148 EltTys.push_back(InhTag);
3154 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3155 unsigned PLine = getLineNumber(
Loc);
3158 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3159 PD->getName(), PUnit, PLine,
3161 : getSelectorName(PD->getGetterName()),
3163 : getSelectorName(PD->getSetterName()),
3164 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3165 EltTys.push_back(PropertyNode);
3170 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3174 llvm::DenseSet<IsClassAndIdent> PropertySet;
3177 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3180 for (
auto *PD : ClassExt->properties()) {
3181 PropertySet.insert(GetIsClassAndIdent(PD));
3184 for (
const auto *PD :
ID->properties()) {
3187 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3194 unsigned FieldNo = 0;
3196 Field =
Field->getNextIvar(), ++FieldNo) {
3197 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3201 StringRef FieldName =
Field->getName();
3204 if (FieldName.empty())
3208 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3209 unsigned FieldLine = getLineNumber(
Field->getLocation());
3217 FieldSize =
Field->isBitField()
3228 if (
Field->isBitField()) {
3239 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3241 Flags = llvm::DINode::FlagProtected;
3243 Flags = llvm::DINode::FlagPrivate;
3245 Flags = llvm::DINode::FlagPublic;
3247 if (
Field->isBitField())
3248 Flags |= llvm::DINode::FlagBitField;
3250 llvm::MDNode *PropertyNode =
nullptr;
3253 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3256 llvm::DIFile *PUnit = getOrCreateFile(
Loc);
3257 unsigned PLine = getLineNumber(
Loc);
3260 PropertyNode = DBuilder.createObjCProperty(
3261 PD->getName(), PUnit, PLine,
3264 : getSelectorName(PD->getGetterName()),
3267 : getSelectorName(PD->getSetterName()),
3268 PD->getPropertyAttributes(),
3269 getOrCreateType(PD->getType(), PUnit));
3273 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3274 FieldSize, FieldAlign, FieldOffset, Flags,
3275 FieldTy, PropertyNode);
3276 EltTys.push_back(FieldTy);
3279 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3280 DBuilder.replaceArrays(RealDecl, Elements);
3282 LexicalBlockStack.pop_back();
3286llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3287 llvm::DIFile *Unit) {
3305 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3308 llvm::Metadata *Subscript;
3310 auto SizeExpr = SizeExprCache.find(QTy);
3311 if (SizeExpr != SizeExprCache.end())
3312 Subscript = DBuilder.getOrCreateSubrange(
3313 SizeExpr->getSecond() ,
nullptr ,
3314 nullptr ,
nullptr );
3317 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3318 llvm::Type::getInt64Ty(CGM.
getLLVMContext()), Count ? Count : -1));
3319 Subscript = DBuilder.getOrCreateSubrange(
3320 CountNode ,
nullptr ,
nullptr ,
3323 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3328 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3332 llvm::DIFile *Unit) {
3336 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3342 auto *ColumnCountNode =
3343 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3345 auto *RowCountNode =
3346 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3348 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3349 ColumnCountNode ,
nullptr ,
nullptr ,
3351 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3352 RowCountNode ,
nullptr ,
nullptr ,
3354 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3355 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3358llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3363 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3387 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3396 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3397 Count = CAT->getZExtSize();
3398 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3399 if (
Expr *Size = VAT->getSizeExpr()) {
3402 Count =
Result.Val.getInt().getExtValue();
3406 auto SizeNode = SizeExprCache.find(EltTy);
3407 if (SizeNode != SizeExprCache.end())
3408 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3409 SizeNode->getSecond() ,
nullptr ,
3410 nullptr ,
nullptr ));
3413 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3415 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3416 CountNode ,
nullptr ,
nullptr ,
3422 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3424 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3429 llvm::DIFile *Unit) {
3430 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3435 llvm::DIFile *Unit) {
3436 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3440 Tag = llvm::dwarf::DW_TAG_reference_type;
3442 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3447 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3457 Flags |= llvm::DINode::FlagSingleInheritance;
3460 Flags |= llvm::DINode::FlagMultipleInheritance;
3463 Flags |= llvm::DINode::FlagVirtualInheritance;
3473 return DBuilder.createMemberPointerType(
3479 return DBuilder.createMemberPointerType(
3480 getOrCreateInstanceMethodType(
3483 ClassType,
Size, 0, Flags);
3486llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *
U) {
3488 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3491llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *
U) {
3495llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3507 bool isImportedFromModule =
3519 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3520 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3521 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3522 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3525 StringRef EDName = ED->
getName();
3526 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3527 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3528 0, Size, Align, llvm::DINode::FlagFwdDecl,
Identifier);
3530 ReplaceMap.emplace_back(
3531 std::piecewise_construct, std::make_tuple(Ty),
3532 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3536 return CreateTypeDefinition(Ty);
3539llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3552 assert(ED &&
"An enumeration definition is required");
3554 Enumerators.push_back(
3555 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3559 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
3561 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
3563 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
3564 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
3565 return DBuilder.createEnumerationType(
3566 EnumContext, ED->
getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
3572 StringRef Name, StringRef
Value) {
3573 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3580 llvm::DIFile *FName = getOrCreateFile(FileLoc);
3581 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
3582 return DBuilder.createTempMacroFile(
Parent,
Line, FName);
3586 llvm::DebugLoc TrapLocation, StringRef
Category, StringRef FailureMsg) {
3594 FuncName += FailureMsg;
3596 llvm::DISubprogram *TrapSP =
3597 createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());
3599 TrapSP, TrapLocation);
3609 Quals += InnerQuals;
3613 return C.getQualifiedType(
T.getTypePtr(), Quals);
3614 case Type::TemplateSpecialization: {
3615 const auto *Spec = cast<TemplateSpecializationType>(
T);
3616 if (Spec->isTypeAlias())
3617 return C.getQualifiedType(
T.getTypePtr(), Quals);
3621 case Type::TypeOfExpr:
3622 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
3625 T = cast<TypeOfType>(
T)->getUnmodifiedType();
3627 case Type::Decltype:
3628 T = cast<DecltypeType>(
T)->getUnderlyingType();
3630 case Type::UnaryTransform:
3631 T = cast<UnaryTransformType>(
T)->getUnderlyingType();
3633 case Type::Attributed:
3634 T = cast<AttributedType>(
T)->getEquivalentType();
3636 case Type::BTFTagAttributed:
3637 T = cast<BTFTagAttributedType>(
T)->getWrappedType();
3639 case Type::CountAttributed:
3640 T = cast<CountAttributedType>(
T)->
desugar();
3642 case Type::Elaborated:
3643 T = cast<ElaboratedType>(
T)->getNamedType();
3646 T = cast<UsingType>(
T)->getUnderlyingType();
3649 T = cast<ParenType>(
T)->getInnerType();
3651 case Type::MacroQualified:
3652 T = cast<MacroQualifiedType>(
T)->getUnderlyingType();
3654 case Type::SubstTemplateTypeParm:
3655 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
3658 case Type::DeducedTemplateSpecialization: {
3659 QualType DT = cast<DeducedType>(
T)->getDeducedType();
3660 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
3664 case Type::PackIndexing: {
3665 T = cast<PackIndexingType>(
T)->getSelectedType();
3668 case Type::Adjusted:
3671 T = cast<AdjustedType>(
T)->getAdjustedType();
3675 assert(
T != LastT &&
"Type unwrapping failed to unwrap!");
3680llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
3683 if (It != TypeCache.end()) {
3685 if (llvm::Metadata *
V = It->second)
3686 return cast<llvm::DIType>(
V);
3698 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
3708llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
3712 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
3714 llvm::raw_string_ostream OS(Name);
3715 Ty.
print(OS, getPrintingPolicy());
3722 if (
auto *
T = getTypeOrNull(Ty))
3725 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
3726 void *TyPtr = Ty.getAsOpaquePtr();
3729 TypeCache[TyPtr].reset(Res);
3734llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *
D) {
3742 auto Info = Reader->getSourceDescriptor(Idx);
3744 return getOrCreateModuleRef(*Info,
true);
3745 }
else if (ClangModuleMap) {
3759 return getOrCreateModuleRef(Info,
false);
3762 return getOrCreateModuleRef(PCHDescriptor,
false);
3769llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
3772 return CreateQualifiedType(Ty, Unit);
3776#define TYPE(Class, Base)
3777#define ABSTRACT_TYPE(Class, Base)
3778#define NON_CANONICAL_TYPE(Class, Base)
3779#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3780#include "clang/AST/TypeNodes.inc"
3781 llvm_unreachable(
"Dependent types cannot show up in debug information");
3783 case Type::ExtVector:
3785 return CreateType(cast<VectorType>(Ty), Unit);
3786 case Type::ConstantMatrix:
3787 return CreateType(cast<ConstantMatrixType>(Ty), Unit);
3788 case Type::ObjCObjectPointer:
3789 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
3790 case Type::ObjCObject:
3791 return CreateType(cast<ObjCObjectType>(Ty), Unit);
3792 case Type::ObjCTypeParam:
3793 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
3794 case Type::ObjCInterface:
3795 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
3797 return CreateType(cast<BuiltinType>(Ty));
3799 return CreateType(cast<ComplexType>(Ty));
3801 return CreateType(cast<PointerType>(Ty), Unit);
3802 case Type::BlockPointer:
3803 return CreateType(cast<BlockPointerType>(Ty), Unit);
3805 return CreateType(cast<TypedefType>(Ty), Unit);
3807 return CreateType(cast<RecordType>(Ty));
3809 return CreateEnumType(cast<EnumType>(Ty));
3810 case Type::FunctionProto:
3811 case Type::FunctionNoProto:
3812 return CreateType(cast<FunctionType>(Ty), Unit);
3813 case Type::ConstantArray:
3814 case Type::VariableArray:
3815 case Type::IncompleteArray:
3816 case Type::ArrayParameter:
3817 return CreateType(cast<ArrayType>(Ty), Unit);
3819 case Type::LValueReference:
3820 return CreateType(cast<LValueReferenceType>(Ty), Unit);
3821 case Type::RValueReference:
3822 return CreateType(cast<RValueReferenceType>(Ty), Unit);
3824 case Type::MemberPointer:
3825 return CreateType(cast<MemberPointerType>(Ty), Unit);
3828 return CreateType(cast<AtomicType>(Ty), Unit);
3831 return CreateType(cast<BitIntType>(Ty));
3833 return CreateType(cast<PipeType>(Ty), Unit);
3835 case Type::TemplateSpecialization:
3836 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
3838 case Type::CountAttributed:
3840 case Type::Attributed:
3841 case Type::BTFTagAttributed:
3842 case Type::HLSLAttributedResource:
3843 case Type::Adjusted:
3845 case Type::DeducedTemplateSpecialization:
3846 case Type::Elaborated:
3849 case Type::MacroQualified:
3850 case Type::SubstTemplateTypeParm:
3851 case Type::TypeOfExpr:
3853 case Type::Decltype:
3854 case Type::PackIndexing:
3855 case Type::UnaryTransform:
3859 llvm_unreachable(
"type should have been unwrapped!");
3862llvm::DICompositeType *
3863CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
3866 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
3871 if (
T && !
T->isForwardDecl())
3875 llvm::DICompositeType *Res = CreateLimitedType(Ty);
3880 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
3883 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
3888llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
3892 StringRef RDName = getClassName(RD);
3894 llvm::DIFile *DefUnit =
nullptr;
3897 DefUnit = getOrCreateFile(
Loc);
3901 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3905 auto *
T = cast_or_null<llvm::DICompositeType>(
3913 if (!
D || !
D->isCompleteDefinition())
3914 return getOrCreateRecordFwdDecl(Ty, RDContext);
3927 auto Flags = llvm::DINode::FlagZero;
3928 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3930 Flags |= llvm::DINode::FlagTypePassByReference;
3932 Flags |= llvm::DINode::FlagTypePassByValue;
3935 if (!CXXRD->isTrivial())
3936 Flags |= llvm::DINode::FlagNonTrivial;
3939 if (CXXRD->isAnonymousStructOrUnion())
3940 Flags |= llvm::DINode::FlagExportSymbols;
3943 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
3946 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
3947 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3953 switch (RealDecl->getTag()) {
3955 llvm_unreachable(
"invalid composite type tag");
3957 case llvm::dwarf::DW_TAG_array_type:
3958 case llvm::dwarf::DW_TAG_enumeration_type:
3967 case llvm::dwarf::DW_TAG_structure_type:
3968 case llvm::dwarf::DW_TAG_union_type:
3969 case llvm::dwarf::DW_TAG_class_type:
3972 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3976 RegionMap[Ty->
getDecl()].reset(RealDecl);
3979 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3980 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3981 CollectCXXTemplateParams(TSpecial, DefUnit));
3985void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3986 llvm::DICompositeType *RealDecl) {
3988 llvm::DIType *ContainingType =
nullptr;
4000 ContainingType = getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
4003 ContainingType = RealDecl;
4005 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4008llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
4009 StringRef Name, uint64_t *Offset) {
4010 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4014 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4015 *Offset, llvm::DINode::FlagZero, FieldTy);
4016 *Offset += FieldSize;
4020void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
4022 StringRef &LinkageName,
4023 llvm::DIScope *&FDContext,
4024 llvm::DINodeArray &TParamsArray,
4025 llvm::DINode::DIFlags &Flags) {
4027 Name = getFunctionName(FD);
4032 Flags |= llvm::DINode::FlagPrototyped;
4036 if (LinkageName == Name ||
4041 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4042 LinkageName = StringRef();
4047 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4051 FDContext = getOrCreateNamespace(NSDecl);
4054 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4055 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4061 Flags |= llvm::DINode::FlagNoReturn;
4063 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4067void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4069 StringRef &Name, StringRef &LinkageName,
4070 llvm::MDTuple *&TemplateParameters,
4071 llvm::DIScope *&VDContext) {
4080 llvm::APInt ConstVal(32, 1);
4091 if (LinkageName == Name)
4092 LinkageName = StringRef();
4094 if (isa<VarTemplateSpecializationDecl>(VD)) {
4095 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4096 TemplateParameters = parameterNodes.get();
4098 TemplateParameters =
nullptr;
4118 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4119 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
4122llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
4124 llvm::DINodeArray TParamsArray;
4125 StringRef Name, LinkageName;
4126 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4127 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4129 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4130 llvm::DIScope *DContext = Unit;
4131 unsigned Line = getLineNumber(
Loc);
4132 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4134 auto *FD = cast<FunctionDecl>(GD.
getDecl());
4139 ArgTypes.push_back(Parm->getType());
4145 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4147 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4150 Flags |= getCallSiteRelatedAttrs();
4151 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4152 return DBuilder.createFunction(
4153 DContext, Name, LinkageName, Unit,
Line,
4154 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4155 TParamsArray.get(), getFunctionDeclaration(FD));
4158 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4159 DContext, Name, LinkageName, Unit,
Line,
4160 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4161 TParamsArray.get(), getFunctionDeclaration(FD));
4163 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4164 std::make_tuple(CanonDecl),
4165 std::make_tuple(SP));
4169llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
4170 return getFunctionFwdDeclOrStub(GD,
false);
4173llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
4174 return getFunctionFwdDeclOrStub(GD,
true);
4177llvm::DIGlobalVariable *
4178CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4180 StringRef Name, LinkageName;
4182 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4183 llvm::DIScope *DContext = Unit;
4184 unsigned Line = getLineNumber(
Loc);
4185 llvm::MDTuple *TemplateParameters =
nullptr;
4187 collectVarDeclProps(VD, Unit,
Line,
T, Name, LinkageName, TemplateParameters,
4190 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4191 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(
T, Unit),
4193 FwdDeclReplaceMap.emplace_back(
4194 std::piecewise_construct,
4196 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4200llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *
D) {
4205 if (
const auto *TD = dyn_cast<TypeDecl>(
D))
4210 if (I != DeclCache.end()) {
4212 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4213 return GVE->getVariable();
4214 return cast<llvm::DINode>(N);
4221 if (IE != ImportedDeclCache.end()) {
4222 auto N = IE->second;
4223 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4224 return cast<llvm::DINode>(GVE);
4225 return dyn_cast_or_null<llvm::DINode>(N);
4230 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4231 return getFunctionForwardDeclaration(FD);
4232 else if (
const auto *VD = dyn_cast<VarDecl>(
D))
4233 return getGlobalVariableForwardDeclaration(VD);
4238llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *
D) {
4239 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4242 const auto *FD = dyn_cast<FunctionDecl>(
D);
4247 auto *S = getDeclContextDescriptor(
D);
4250 if (MI == SPCache.end()) {
4252 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4253 cast<llvm::DICompositeType>(S));
4256 if (MI != SPCache.end()) {
4257 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4258 if (SP && !SP->isDefinition())
4262 for (
auto *NextFD : FD->
redecls()) {
4263 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4264 if (MI != SPCache.end()) {
4265 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4266 if (SP && !SP->isDefinition())
4273llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4274 const Decl *
D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4275 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4276 if (!
D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4279 const auto *OMD = dyn_cast<ObjCMethodDecl>(
D);
4287 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4297 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4298 if (It == TypeCache.end())
4300 auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
4301 llvm::DISubprogram *FD = DBuilder.createFunction(
4302 InterfaceType, getObjCMethodName(OMD), StringRef(),
4303 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4304 DBuilder.finalizeSubprogram(FD);
4311llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *
D,
4316 if (!
D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4320 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4322 if (
const auto *Method = dyn_cast<CXXMethodDecl>(
D))
4323 return getOrCreateMethodType(Method, F);
4328 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(
D)) {
4333 QualType ResultTy = OMethod->getReturnType();
4338 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4340 Elts.push_back(getOrCreateType(ResultTy, F));
4343 if (
auto *SelfDecl = OMethod->getSelfDecl())
4344 SelfDeclTy = SelfDecl->getType();
4345 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4348 if (!SelfDeclTy.
isNull())
4350 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4352 Elts.push_back(DBuilder.createArtificialType(
4355 for (
const auto *PI : OMethod->parameters())
4356 Elts.push_back(getOrCreateType(PI->getType(), F));
4358 if (OMethod->isVariadic())
4359 Elts.push_back(DBuilder.createUnspecifiedParameter());
4361 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4362 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4368 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
4369 if (FD->isVariadic()) {
4371 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4372 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4374 EltTys.push_back(getOrCreateType(ParamType, F));
4375 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4376 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4377 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4381 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
4390 CC = SrcFnTy->getCallConv();
4392 for (
const VarDecl *VD : Args)
4393 ArgTypes.push_back(VD->
getType());
4400 llvm::Function *Fn,
bool CurFuncIsThunk) {
4402 StringRef LinkageName;
4404 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4407 bool HasDecl = (
D !=
nullptr);
4409 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4410 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4411 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4412 llvm::DIScope *FDContext = Unit;
4413 llvm::DINodeArray TParamsArray;
4416 LinkageName = Fn->getName();
4417 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
4419 auto FI = SPCache.find(FD->getCanonicalDecl());
4420 if (FI != SPCache.end()) {
4421 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4422 if (SP && SP->isDefinition()) {
4423 LexicalBlockStack.emplace_back(SP);
4424 RegionMap[
D].reset(SP);
4428 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4429 TParamsArray, Flags);
4430 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4431 Name = getObjCMethodName(OMD);
4432 Flags |= llvm::DINode::FlagPrototyped;
4433 }
else if (isa<VarDecl>(
D) &&
4439 Name = Fn->getName();
4441 if (isa<BlockDecl>(
D))
4444 Flags |= llvm::DINode::FlagPrototyped;
4446 if (Name.starts_with(
"\01"))
4447 Name = Name.substr(1);
4449 assert((!
D || !isa<VarDecl>(
D) ||
4451 "Unexpected DynamicInitKind !");
4454 isa<VarDecl>(
D) || isa<CapturedDecl>(
D)) {
4455 Flags |= llvm::DINode::FlagArtificial;
4461 Flags |= llvm::DINode::FlagThunk;
4463 if (Fn->hasLocalLinkage())
4464 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4466 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4468 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
4469 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4470 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4472 const unsigned LineNo = getLineNumber(
Loc.
isValid() ?
Loc : CurLoc);
4473 unsigned ScopeLine = getLineNumber(ScopeLoc);
4474 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(
D, FnType, Unit);
4475 llvm::DISubprogram *
Decl =
nullptr;
4476 llvm::DINodeArray Annotations =
nullptr;
4478 Decl = isa<ObjCMethodDecl>(
D)
4479 ? getObjCMethodDeclaration(
D, DIFnType, LineNo, Flags, SPFlags)
4480 : getFunctionDeclaration(
D);
4481 Annotations = CollectBTFDeclTagAnnotations(
D);
4489 llvm::DISubprogram *SP = DBuilder.createFunction(
4490 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4491 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4493 Fn->setSubprogram(SP);
4497 if (HasDecl && isa<FunctionDecl>(
D))
4501 LexicalBlockStack.emplace_back(SP);
4504 RegionMap[
D].reset(SP);
4508 QualType FnType, llvm::Function *Fn) {
4510 StringRef LinkageName;
4516 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
4517 return GetName(
D,
true);
4520 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4521 llvm::DIFile *Unit = getOrCreateFile(
Loc);
4522 bool IsDeclForCallSite = Fn ?
true :
false;
4523 llvm::DIScope *FDContext =
4524 IsDeclForCallSite ? Unit : getDeclContextDescriptor(
D);
4525 llvm::DINodeArray TParamsArray;
4526 if (isa<FunctionDecl>(
D)) {
4528 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4529 TParamsArray, Flags);
4530 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D)) {
4531 Name = getObjCMethodName(OMD);
4532 Flags |= llvm::DINode::FlagPrototyped;
4534 llvm_unreachable(
"not a function or ObjC method");
4536 if (!Name.empty() && Name[0] ==
'\01')
4537 Name = Name.substr(1);
4540 Flags |= llvm::DINode::FlagArtificial;
4545 unsigned LineNo = getLineNumber(
Loc);
4546 unsigned ScopeLine = 0;
4547 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4549 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4551 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
4552 llvm::DISubroutineType *STy = getOrCreateFunctionType(
D, FnType, Unit);
4553 llvm::DISubprogram *SP = DBuilder.createFunction(
4554 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
4555 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations);
4561 if (
auto *FD = dyn_cast<FunctionDecl>(
D)) {
4562 llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
4565 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
4566 DBuilder.createParameterVariable(
4567 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
4568 llvm::DINode::FlagZero, ParamAnnotations);
4574 if (IsDeclForCallSite)
4575 Fn->setSubprogram(SP);
4577 DBuilder.finalizeSubprogram(SP);
4585 auto *
Func = CallOrInvoke->getCalledFunction();
4588 if (
Func->getSubprogram())
4593 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
4594 getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
4605 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
4607 auto FI = SPCache.find(FD->getCanonicalDecl());
4608 llvm::DISubprogram *SP =
nullptr;
4609 if (FI != SPCache.end())
4610 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4611 if (!SP || !SP->isDefinition())
4612 SP = getFunctionStub(GD);
4613 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4614 LexicalBlockStack.emplace_back(SP);
4620 assert(CurInlinedAt &&
"unbalanced inline scope stack");
4629 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
4632 llvm::MDNode *
Scope = LexicalBlockStack.back();
4633 Builder.SetCurrentDebugLocation(
4634 llvm::DILocation::get(CGM.
getLLVMContext(), getLineNumber(CurLoc),
4635 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
4639 llvm::MDNode *Back =
nullptr;
4640 if (!LexicalBlockStack.empty())
4641 Back = LexicalBlockStack.back().get();
4642 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
4643 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
4644 getColumnNumber(CurLoc)));
4647void CGDebugInfo::AppendAddressSpaceXDeref(
4649 std::optional<unsigned> DWARFAddressSpace =
4651 if (!DWARFAddressSpace)
4654 Expr.push_back(llvm::dwarf::DW_OP_constu);
4655 Expr.push_back(*DWARFAddressSpace);
4656 Expr.push_back(llvm::dwarf::DW_OP_swap);
4657 Expr.push_back(llvm::dwarf::DW_OP_xderef);
4666 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
4668 LexicalBlockStack.back(), CurInlinedAt));
4670 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4674 CreateLexicalBlock(
Loc);
4679 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4684 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4687 LexicalBlockStack.pop_back();
4691 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4692 unsigned RCount = FnBeginRegionCount.back();
4693 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
4696 while (LexicalBlockStack.size() != RCount) {
4699 LexicalBlockStack.pop_back();
4701 FnBeginRegionCount.pop_back();
4703 if (Fn && Fn->getSubprogram())
4704 DBuilder.finalizeSubprogram(Fn->getSubprogram());
4707CGDebugInfo::BlockByRefType
4708CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
4709 uint64_t *XOffset) {
4712 uint64_t FieldSize, FieldOffset;
4713 uint32_t FieldAlign;
4715 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4720 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
4721 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
4723 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
4724 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
4727 if (HasCopyAndDispose) {
4730 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
4732 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
4734 bool HasByrefExtendedLayout;
4737 HasByrefExtendedLayout) &&
4738 HasByrefExtendedLayout) {
4741 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
4750 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
4753 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
4756 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
4761 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
4765 *XOffset = FieldOffset;
4766 llvm::DIType *FieldTy = DBuilder.createMemberType(
4767 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
4768 llvm::DINode::FlagZero, WrappedTy);
4769 EltTys.push_back(FieldTy);
4770 FieldOffset += FieldSize;
4772 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4773 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
4774 llvm::DINode::FlagZero,
nullptr, Elements),
4778llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
4779 llvm::Value *Storage,
4780 std::optional<unsigned> ArgNo,
4782 const bool UsePointerValue) {
4784 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4785 if (VD->
hasAttr<NoDebugAttr>())
4790 llvm::DIFile *Unit =
nullptr;
4791 if (!VarIsArtificial)
4795 if (VD->
hasAttr<BlocksAttr>())
4796 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
4798 Ty = getOrCreateType(VD->
getType(), Unit);
4808 if (!VarIsArtificial) {
4813 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4814 if (VarIsArtificial)
4815 Flags |= llvm::DINode::FlagArtificial;
4820 AppendAddressSpaceXDeref(AddressSpace,
Expr);
4824 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
4827 Flags |= llvm::DINode::FlagObjectPointer;
4834 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
4835 StringRef Name = VD->
getName();
4836 if (!Name.empty()) {
4842 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4847 Expr.push_back(llvm::dwarf::DW_OP_deref);
4848 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
4853 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
4865 for (
const auto *Field : RD->
fields()) {
4866 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
4867 StringRef FieldName =
Field->getName();
4870 if (FieldName.empty() && !isa<RecordType>(
Field->getType()))
4875 auto *
D = DBuilder.createAutoVariable(
4877 Flags | llvm::DINode::FlagArtificial, FieldAlign);
4880 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
4884 Builder.GetInsertBlock());
4892 if (UsePointerValue) {
4893 assert(!llvm::is_contained(
Expr, llvm::dwarf::DW_OP_deref) &&
4894 "Debug info already contains DW_OP_deref.");
4895 Expr.push_back(llvm::dwarf::DW_OP_deref);
4899 llvm::DILocalVariable *
D =
nullptr;
4901 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
4902 D = DBuilder.createParameterVariable(
Scope, Name, *ArgNo, Unit,
Line, Ty,
4913 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
4916 if (!isa<llvm::DISubprogram>(
Scope) || !
Scope->isDistinct())
4919 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
4920 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
4921 if (
DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
4924 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
4930 if (
Iter != CoroutineParameterMappings.end()) {
4932 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
4933 return DbgPair.first == PD && DbgPair.second->getScope() ==
Scope;
4935 if (Iter2 != ParamDbgMappings.end())
4936 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
4942 D = RemapCoroArgToLocalVar();
4945 D = DBuilder.createAutoVariable(
Scope, Name, Unit,
Line, Ty,
4949 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
4952 Builder.GetInsertBlock());
4957llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
4958 llvm::Value *Storage,
4959 std::optional<unsigned> ArgNo,
4961 const bool UsePointerValue) {
4963 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
4964 if (BD->
hasAttr<NoDebugAttr>())
4971 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
4972 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
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());
4999 llvm::DILocalVariable *
D = DBuilder.createAutoVariable(
5001 llvm::DINode::FlagZero, Align);
5004 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5005 const unsigned fieldIndex = FD->getFieldIndex();
5011 if (FD->isBitField()) {
5018 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5024 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5025 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5030 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5031 }
else if (fieldOffset != 0) {
5033 "Unexpected non-bitfield with non-byte-aligned offset");
5034 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5040 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5041 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5042 const uint64_t value = IL->getValue().getZExtValue();
5046 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5055 DBuilder.insertDeclare(Storage,
D, DBuilder.createExpression(
Expr),
5058 Builder.GetInsertBlock());
5063llvm::DILocalVariable *
5066 const bool UsePointerValue) {
5069 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5070 for (
auto *B : DD->bindings()) {
5071 EmitDeclare(B, Storage, std::nullopt, Builder,
5079 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5084 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5089 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
5090 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
5096 StringRef Name =
D->getName();
5103 DBuilder.insertLabel(L,
5105 Scope, CurInlinedAt),
5106 Builder.GetInsertBlock());
5109llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5111 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5114 return DBuilder.createObjectPointerType(Ty);
5119 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5121 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5123 if (Builder.GetInsertBlock() ==
nullptr)
5125 if (VD->
hasAttr<NoDebugAttr>())
5128 bool isByRef = VD->
hasAttr<BlocksAttr>();
5130 uint64_t XOffset = 0;
5131 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5134 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5136 Ty = getOrCreateType(VD->
getType(), Unit);
5140 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5142 Ty = CreateSelfType(VD->
getType(), Ty);
5145 const unsigned Line =
5156 addr.push_back(llvm::dwarf::DW_OP_deref);
5157 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5160 addr.push_back(llvm::dwarf::DW_OP_deref);
5161 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5166 addr.push_back(llvm::dwarf::DW_OP_deref);
5167 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5175 auto *
D = DBuilder.createAutoVariable(
5176 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
5177 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5181 LexicalBlockStack.back(), CurInlinedAt);
5182 auto *
Expr = DBuilder.createExpression(addr);
5184 DBuilder.insertDeclare(Storage,
D,
Expr, DL, InsertPoint);
5186 DBuilder.insertDeclare(Storage,
D,
Expr, DL, Builder.GetInsertBlock());
5189llvm::DILocalVariable *
5192 bool UsePointerValue) {
5194 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5198struct BlockLayoutChunk {
5199 uint64_t OffsetInBits;
5202bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5203 return l.OffsetInBits < r.OffsetInBits;
5207void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5209 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5216 BlockLayout.getElementOffsetInBits(0),
5219 BlockLayout.getElementOffsetInBits(1),
5223 BlockLayout.getElementOffsetInBits(0),
5226 BlockLayout.getElementOffsetInBits(1),
5230 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5231 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5233 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType,
Loc,
AS_public,
5234 BlockLayout.getElementOffsetInBits(3),
5236 Fields.push_back(createFieldType(
5241 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5248 llvm::AllocaInst *Alloca,
5256 llvm::DIFile *tunit = getOrCreateFile(loc);
5257 unsigned line = getLineNumber(loc);
5258 unsigned column = getColumnNumber(loc);
5263 const llvm::StructLayout *blockLayout =
5267 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5276 BlockLayoutChunk chunk;
5277 chunk.OffsetInBits =
5278 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5279 chunk.Capture =
nullptr;
5280 chunks.push_back(chunk);
5284 for (
const auto &capture :
blockDecl->captures()) {
5285 const VarDecl *variable = capture.getVariable();
5292 BlockLayoutChunk chunk;
5293 chunk.OffsetInBits =
5294 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5295 chunk.Capture = &capture;
5296 chunks.push_back(chunk);
5300 llvm::array_pod_sort(chunks.begin(), chunks.end());
5302 for (
const BlockLayoutChunk &Chunk : chunks) {
5303 uint64_t offsetInBits = Chunk.OffsetInBits;
5310 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5312 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5315 llvm_unreachable(
"unexpected block declcontext");
5317 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5318 offsetInBits, tunit, tunit));
5323 StringRef name = variable->
getName();
5325 llvm::DIType *fieldType;
5327 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5332 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5333 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5334 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5335 PtrInfo.
Width, Align, offsetInBits,
5336 llvm::DINode::FlagZero, fieldType);
5340 offsetInBits, Align, tunit, tunit);
5342 fields.push_back(fieldType);
5346 llvm::raw_svector_ostream(typeName)
5349 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5351 llvm::DIType *
type =
5352 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5354 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5358 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5359 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
5362 auto *debugVar = DBuilder.createParameterVariable(
5363 scope, Name, ArgNo, tunit, line,
type, CGM.
getLangOpts().Optimize, flags);
5366 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5368 column, scope, CurInlinedAt),
5369 Builder.GetInsertBlock());
5372llvm::DIDerivedType *
5373CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *
D) {
5374 if (!
D || !
D->isStaticDataMember())
5378 if (MI != StaticDataMemberCache.end()) {
5379 assert(MI->second &&
"Static data member declaration should still exist");
5386 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(
D));
5387 return CreateRecordStaticField(
D, Ctxt, cast<RecordDecl>(DC));
5390llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5391 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5392 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5393 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5395 for (
const auto *Field : RD->
fields()) {
5396 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5397 StringRef FieldName = Field->getName();
5400 if (FieldName.empty()) {
5401 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5402 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
5407 GVE = DBuilder.createGlobalVariableExpression(
5408 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5409 Var->hasLocalLinkage());
5410 Var->addDebugInfo(GVE);
5422 const auto *RD = dyn_cast<CXXRecordDecl>(RT->
getDecl());
5427 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5435 case TemplateArgument::Pack:
5436 return ReferencesAnonymousEntity(TA.getPackAsArray());
5437 case TemplateArgument::Type: {
5438 struct ReferencesAnonymous
5439 : public RecursiveASTVisitor<ReferencesAnonymous> {
5440 bool RefAnon = false;
5441 bool VisitRecordType(RecordType *RT) {
5442 if (ReferencesAnonymousEntity(RT)) {
5449 ReferencesAnonymous RT;
5450 RT.TraverseType(TA.getAsType());
5463 bool Reconstitutable =
true;
5465 Reconstitutable =
false;
5469 Reconstitutable =
false;
5472 bool VisitType(
Type *
T) {
5476 Reconstitutable =
false;
5481 bool TraverseEnumType(
EnumType *ET) {
5484 if (
const auto *ED = dyn_cast<EnumDecl>(ET->
getDecl())) {
5486 Reconstitutable =
false;
5490 Reconstitutable =
false;
5500 return Reconstitutable;
5504 Reconstitutable =
false;
5514 ReconstitutableType
T;
5516 return T.Reconstitutable;
5519bool CGDebugInfo::HasReconstitutableArgs(
5523 case TemplateArgument::Template:
5530 case TemplateArgument::Declaration:
5539 case TemplateArgument::NullPtr:
5543 case TemplateArgument::Pack:
5546 return HasReconstitutableArgs(TA.getPackAsArray());
5547 case TemplateArgument::Integral:
5552 return TA.getAsIntegral().getBitWidth() <= 64 &&
5553 IsReconstitutableType(TA.getIntegralType());
5554 case TemplateArgument::StructuralValue:
5556 case TemplateArgument::Type:
5557 return IsReconstitutableType(TA.getAsType());
5558 case TemplateArgument::Expression:
5559 return IsReconstitutableType(TA.getAsExpr()->getType());
5561 llvm_unreachable(
"Other, unresolved, template arguments should "
5562 "not be seen here");
5567std::string CGDebugInfo::GetName(
const Decl *
D,
bool Qualified)
const {
5569 llvm::raw_string_ostream OS(Name);
5570 const NamedDecl *ND = dyn_cast<NamedDecl>(
D);
5573 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
5577 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
5579 std::optional<TemplateArgs> Args;
5581 bool IsOperatorOverload =
false;
5582 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
5583 Args = GetTemplateArgs(RD);
5584 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
5585 Args = GetTemplateArgs(FD);
5587 IsOperatorOverload |=
5590 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
5591 Args = GetTemplateArgs(VD);
5615 bool Reconstitutable =
5616 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
5620 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
5624 bool Mangled = TemplateNamesKind ==
5625 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
5631 std::string EncodedOriginalName;
5632 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
5640 std::string CanonicalOriginalName;
5641 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
5643 assert(EncodedOriginalName == CanonicalOriginalName);
5656 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
5657 return GetName(
D,
true);
5663 if (Cached != DeclCache.end())
5664 return Var->addDebugInfo(
5665 cast<llvm::DIGlobalVariableExpression>(Cached->second));
5668 llvm::DIFile *Unit =
nullptr;
5669 llvm::DIScope *DContext =
nullptr;
5671 StringRef DeclName, LinkageName;
5673 llvm::MDTuple *TemplateParameters =
nullptr;
5674 collectVarDeclProps(
D, Unit, LineNo,
T, DeclName, LinkageName,
5675 TemplateParameters, DContext);
5679 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5687 "unnamed non-anonymous struct or union?");
5688 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
5698 else if (
D->
hasAttr<CUDAConstantAttr>())
5702 AppendAddressSpaceXDeref(AddressSpace,
Expr);
5704 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(
D);
5705 GVE = DBuilder.createGlobalVariableExpression(
5706 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(
T, Unit),
5707 Var->hasLocalLinkage(),
true,
5708 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
5709 getOrCreateStaticDataMemberDeclarationOrNull(
D), TemplateParameters,
5710 Align, Annotations);
5711 Var->addDebugInfo(GVE);
5718 if (VD->
hasAttr<NoDebugAttr>())
5720 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
5721 return GetName(VD,
true);
5726 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5727 StringRef Name = VD->
getName();
5728 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
5730 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
5731 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
5732 assert(isa<EnumType>(ED->
getTypeForDecl()) &&
"Enum without EnumType?");
5745 llvm::DIType *EDTy =
5747 assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
5758 auto *VarD = dyn_cast<VarDecl>(VD);
5759 if (VarD && VarD->isStaticDataMember()) {
5760 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
5761 getDeclContextDescriptor(VarD);
5766 RetainedTypes.push_back(
5771 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
5773 auto &GV = DeclCache[VD];
5777 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
5778 llvm::MDTuple *TemplateParameters =
nullptr;
5780 if (isa<VarTemplateSpecializationDecl>(VD))
5782 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
5783 TemplateParameters = parameterNodes.get();
5786 GV.reset(DBuilder.createGlobalVariableExpression(
5787 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
5788 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
5789 TemplateParameters, Align));
5799 llvm::DIFile *Unit = getOrCreateFile(
D->
getLocation());
5800 StringRef Name =
D->getName();
5801 llvm::DIType *Ty = getOrCreateType(
D->getType(), Unit);
5803 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
5804 llvm::DIGlobalVariableExpression *GVE =
5805 DBuilder.createGlobalVariableExpression(
5806 DContext, Name, StringRef(), Unit, getLineNumber(
D->
getLocation()),
5807 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
5808 Var->addDebugInfo(GVE);
5816 llvm::codegenoptions::DebugLineTablesOnly)
5819 llvm::DILocation *DIL =
Value->getDebugLoc().get();
5823 llvm::DIFile *Unit = DIL->getFile();
5824 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
5829 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
5830 llvm::Value *Var = Load->getPointerOperand();
5835 auto DeclareTypeMatches = [&](
auto *DbgDeclare) {
5836 return DbgDeclare->getVariable()->getType() ==
Type;
5838 if (any_of(llvm::findDbgDeclares(Var), DeclareTypeMatches) ||
5839 any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
5843 llvm::DILocalVariable *
D =
5844 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
5845 Type,
false, llvm::DINode::FlagArtificial);
5847 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
5848 DBuilder.insertDbgValueIntrinsic(
Value,
D, DBuilder.createExpression(), DIL,
5861 const auto *
D = cast<ValueDecl>(GD.
getDecl());
5880 if (!(DI = getDeclarationOrDefinition(
5881 AliaseeDecl.getCanonicalDecl().getDecl())))
5884 llvm::DIScope *DContext = getDeclContextDescriptor(
D);
5887 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
5888 DContext, DI, getOrCreateFile(
Loc), getLineNumber(
Loc),
D->getName());
5901 llvm::DIFile *
File = getOrCreateFile(
Loc);
5902 llvm::DIGlobalVariableExpression *Debug =
5903 DBuilder.createGlobalVariableExpression(
5904 nullptr, StringRef(), StringRef(), getOrCreateFile(
Loc),
5905 getLineNumber(
Loc), getOrCreateType(S->getType(),
File),
true);
5906 GV->addDebugInfo(Debug);
5909llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *
D) {
5910 if (!LexicalBlockStack.empty())
5911 return LexicalBlockStack.back();
5912 llvm::DIScope *Mod = getParentModuleOrNull(
D);
5913 return getContextDescriptor(
D, Mod ? Mod : TheCU);
5925 DBuilder.createImportedModule(
5927 getOrCreateNamespace(NSDecl), getOrCreateFile(
Loc), getLineNumber(
Loc));
5932 if (llvm::DINode *
Target =
5935 DBuilder.createImportedDeclaration(
5937 getOrCreateFile(
Loc), getLineNumber(
Loc));
5945 "We shouldn't be codegening an invalid UsingDecl containing no decls");
5947 for (
const auto *USD : UD.
shadows()) {
5952 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
5953 if (
const auto *AT = FD->getType()
5956 if (AT->getDeducedType().isNull())
5970 "We shouldn't be codegening an invalid UsingEnumDecl"
5971 " containing no decls");
5973 for (
const auto *USD : UD.
shadows())
5978 if (CGM.
getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
5980 if (
Module *M = ID.getImportedModule()) {
5982 auto Loc = ID.getLocation();
5983 DBuilder.createImportedDeclaration(
5984 getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
5985 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(
Loc),
5986 getLineNumber(
Loc));
5990llvm::DIImportedEntity *
5994 auto &VH = NamespaceAliasCache[&NA];
5996 return cast<llvm::DIImportedEntity>(VH);
5997 llvm::DIImportedEntity *R;
5999 if (
const auto *Underlying =
6002 R = DBuilder.createImportedDeclaration(
6007 R = DBuilder.createImportedDeclaration(
6016CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6020 auto I = NamespaceCache.find(NSDecl);
6021 if (I != NamespaceCache.end())
6022 return cast<llvm::DINamespace>(I->second);
6024 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6026 llvm::DINamespace *NS =
6027 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6028 NamespaceCache[NSDecl].reset(NS);
6033 assert(TheCU &&
"no main compile unit");
6034 TheCU->setDWOId(Signature);
6040 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6041 ObjCInterfaceCacheEntry
E = ObjCInterfaceCache[i];
6042 llvm::DIType *Ty =
E.Type->getDecl()->getDefinition()
6043 ? CreateTypeDefinition(
E.Type,
E.Unit)
6045 DBuilder.replaceTemporary(llvm::TempDIType(
E.Decl), Ty);
6049 for (
const auto &
P : ObjCMethodCache) {
6050 if (
P.second.empty())
6053 QualType QTy(
P.first->getTypeForDecl(), 0);
6055 assert(It != TypeCache.end());
6057 llvm::DICompositeType *InterfaceDecl =
6058 cast<llvm::DICompositeType>(It->second);
6060 auto CurElts = InterfaceDecl->getElements();
6064 for (
auto &SubprogramDirect :
P.second)
6065 if (CGM.
getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6066 EltTys.push_back(SubprogramDirect.getPointer());
6068 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6069 DBuilder.replaceArrays(InterfaceDecl, Elements);
6072 for (
const auto &
P : ReplaceMap) {
6074 auto *Ty = cast<llvm::DIType>(
P.second);
6075 assert(Ty->isForwardDecl());
6077 auto It = TypeCache.find(
P.first);
6078 assert(It != TypeCache.end());
6081 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6082 cast<llvm::DIType>(It->second));
6085 for (
const auto &
P : FwdDeclReplaceMap) {
6087 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
6088 llvm::Metadata *Repl;
6090 auto It = DeclCache.find(
P.first);
6094 if (It == DeclCache.end())
6099 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6100 Repl = GVE->getVariable();
6101 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
6106 for (
auto &RT : RetainedTypes)
6107 if (
auto MD = TypeCache[RT])
6108 DBuilder.retainType(cast<llvm::DIType>(MD));
6110 DBuilder.finalize();
6116 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6117 DBuilder.retainType(DieTy);
6122 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6123 DBuilder.retainType(DieTy);
6127 if (LexicalBlockStack.empty())
6128 return llvm::DebugLoc();
6130 llvm::MDNode *
Scope = LexicalBlockStack.back();
6135llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
6139 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6140 DebugKind == llvm::codegenoptions::LocTrackingOnly)
6141 return llvm::DINode::FlagZero;
6146 bool SupportsDWARFv4Ext =
6148 (CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6149 CGM.
getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6151 if (!SupportsDWARFv4Ext && CGM.
getCodeGenOpts().DwarfVersion < 5)
6152 return llvm::DINode::FlagZero;
6154 return llvm::DINode::FlagAllCallsDescribed;
6165 return DBuilder.createConstantValueExpression(
6166 Val.
getFloat().bitcastToAPInt().getZExtValue());
6171 llvm::APSInt
const &ValInt = Val.
getInt();
6172 std::optional<uint64_t> ValIntOpt;
6173 if (ValInt.isUnsigned())
6174 ValIntOpt = ValInt.tryZExtValue();
6175 else if (
auto tmp = ValInt.trySExtValue())
6178 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6181 return DBuilder.createConstantValueExpression(ValIntOpt.value());
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
static bool IsArtificial(VarDecl const *VD)
Returns true if VD is a compiler-generated variable and should be treated as artificial for the purpo...
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func)
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
static llvm::SmallVector< TemplateArgument > GetTemplateArgs(const TemplateDecl *TD, const TemplateSpecializationType *Ty)
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function.
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q)
static bool IsDecomposedVarDecl(VarDecl const *VD)
Returns true if VD is a a holding variable (aka a VarDecl retrieved using BindingDecl::getHoldingVar)...
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
static unsigned getDwarfCC(CallingConv CC)
static bool ReferencesAnonymousEntity(ArrayRef< TemplateArgument > Args)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Target Target
constexpr llvm::StringRef ClangTrapPrefix
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
__device__ __2f16 float c
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const
Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getEnumType(const EnumDecl *Decl) const
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType UnsignedLongTy
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedCharTy
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
unsigned getTargetAddressSpace(LangAS AS) const
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
Module * getModuleOrNull() const
ASTFileSignature getSignature() const
StringRef getASTFile() const
StringRef getPath() const
std::string getModuleName() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
const BTFTypeTagAttr * getAttr() const
QualType getWrappedType() const
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
A fixed int type of a specified bitwidth.
A class which contains all the information about a particular captured value.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
VarDecl * getVariable() const
The variable being captured.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
This class is used for builtin types like 'int'.
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
unsigned size_overridden_methods() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isLambda() const
Determine whether this class describes a lambda function object.
capture_const_iterator captures_end() const
method_range methods() const
bool hasConstexprNonCopyMoveConstructor() const
Determine whether this class has at least one constexpr constructor other than the copy or move const...
method_iterator method_begin() const
Method begin iterator.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool hasDefinition() const
method_iterator method_end() const
Method past-the-end iterator.
capture_const_iterator captures_begin() const
llvm::iterator_range< base_class_const_iterator > base_class_const_range
A wrapper class around a pointer that always points to its canonical declaration.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
bool hasMaybeUnusedDebugInfo() const
Check if maybe unused type info should be emitted.
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn.
~ApplyInlineDebugLocation()
Restore everything back to the original state.
unsigned getIndex() const
CGBlockInfo - Information to generate a block literal.
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
const Capture & getCapture(const VarDecl *var) const
virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.
@ RAA_Indirect
Pass it as a pointer to temporary memory.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::MDNode * getInlinedAt() const
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file.
void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl)
Emit information about global variable alias.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder)
Emit call to llvm.dbg.label for an label.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
void completeUnusedClass(const CXXRecordDecl &D)
void EmitUsingShadowDecl(const UsingShadowDecl &USD)
Emit a shadow decl brought in by a using or using-enum.
void EmitUsingEnumDecl(const UsingEnumDecl &UD)
Emit C++ using-enum declaration.
void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)
Constructs the debug code for exiting a function.
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, const FunctionDecl *CalleeDecl)
Emit debug info for an extern function being called.
void EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an #include directive.
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about an external variable.
void emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void completeRequiredType(const RecordDecl *RD)
void EmitAndRetainType(QualType Ty)
Emit the type even if it might not be used.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
void AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S)
DebugInfo isn't attached to string literals by default.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void completeClassData(const RecordDecl *RD)
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
void EmitImportDecl(const ImportDecl &ID)
Emit an @import declaration.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, StringRef Name, unsigned ArgNo, llvm::AllocaInst *LocalAddr, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for the block-literal argument to a block invocation function.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
CGDebugInfo(CodeGenModule &CGM)
void completeClass(const RecordDecl *RD)
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
void setLocation(SourceLocation Loc)
Update the current source location.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a #define directive or a macro undefined by a #undef directi...
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
QualType getFunctionType(const FunctionDecl *FD, QualType RetTy, const SmallVectorImpl< const VarDecl * > &Args)
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
void completeType(const EnumDecl *ED)
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint=nullptr)
Emit call to llvm.dbg.declare for an imported variable declaration in a block.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar)
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
This class organizes the cross-function state that is used while generating LLVM code.
const PreprocessorOptions & getPreprocessorOpts() const
ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)
Get the address of a GUID.
llvm::Module & getModule() const
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
const IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const
const LangOptions & getLangOpts() const
int getUniqueBlockCount()
Fetches the global unique block count.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)
Get the address of a template parameter object.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
MicrosoftVTableContext & getMicrosoftVTableContext()
const HeaderSearchOptions & getHeaderSearchOpts() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::LLVMContext & getLLVMContext()
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const GlobalDecl getMangledNameDecl(StringRef)
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
unsigned getTargetAddressSpace(QualType T) const
llvm::Constant * getPointer() const
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
virtual bool shouldEmitDWARFBitFieldSeparators() const
Complex values, per C99 6.2.5p11.
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isObjCZeroArgSelector() const
@ CXXConversionFunctionName
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
bool isObjCOneArgSelector() const
NameKind getNameKind() const
Determine what kind of name this is.
Represents a ValueDecl that came out of a declarator.
enumerator_range enumerators() const
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
EnumDecl * getDefinition() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool hasCXXExplicitFunctionObjectParameter() const
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDeleted() const
Whether this function has been deleted.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > param_types() const
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
DynamicInitKind getDynamicInitKind() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
An lvalue reference type, per C++11 [dcl.ref].
Represents the declaration of a label.
Describes the capture of a variable or of this, or of a C++1y init-capture.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
virtual std::string getLambdaString(const CXXRecordDecl *Lambda)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
QualType getPointeeType() const
const Type * getClass() const
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
Describes a module or submodule.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExternallyVisible() const
Represents a C++ namespace alias.
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isInline() const
Returns true if this is an inline namespace declaration.
ObjCCategoryDecl - Represents a category declaration.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCImplementationDecl * getImplementation() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents a class type in Objective C.
QualType getBaseType() const
Gets the base type of this object type.
Represents one property declaration in an Objective-C interface.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a type parameter type in Objective C.
ObjCTypeParamDecl * getDecl() const
Represents a parameter to a function.
QualType getElementType() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
A qualifier set is used to build a set of qualifiers.
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void removeObjCLifetime()
void removeAddressSpace()
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
field_iterator field_end() const
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
TagDecl * getDecl() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual unsigned getVtblPtrAddressSpace() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
ArrayRef< NamedDecl * > asArray()
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
Represents a declaration of a type.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
bool isIncompleteArrayType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isExtVectorBoolType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isMemberDataPointerType() const
bool isBitIntType() const
bool isComplexIntegerType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Represents a C++ using-declaration.
Represents C++ using-directive.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
const Expr * getInit() const
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
Declaration of a variable template.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
The JSON file list parser is used to communicate input to InstallAPI.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Result
The result type of a method or function.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_Deleting
Deleting dtor.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ CXXThis
Parameter for C++ 'this' argument.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
unsigned char PointerWidthInBits
The width of a pointer into the generic address space.
EvalResult is a struct with detailed info about an evaluated expression.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
Describes how types, statements, expressions, and declarations should be printed.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
A this pointer adjustment.