41#include "llvm/ADT/DenseSet.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DerivedTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/Metadata.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/MD5.h"
53#include "llvm/Support/Path.h"
54#include "llvm/Support/SHA1.h"
55#include "llvm/Support/SHA256.h"
56#include "llvm/Support/TimeProfiler.h"
71 if (TI.isAlignRequired())
99 llvm::dyn_cast_or_null<DeclRefExpr>(
Init->IgnoreUnlessSpelledInSource());
103 return llvm::dyn_cast_or_null<DecompositionDecl>(RefExpr->getDecl());
127 if (!llvm::isa<ParmVarDecl>(VD))
137 if (!Method->isImplicit() || !Method->isPropertyAccessor())
148 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
149 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
150 DBuilder(CGM.getModule()) {
155 assert(LexicalBlockStack.empty() &&
156 "Region stack mismatch, stack not empty!");
159void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
160 uint64_t Group, uint8_t Rank) {
161 if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
165 Rank = std::min<uint8_t>(Rank, 7);
167 const llvm::DebugLoc &DL = I->getDebugLoc();
172 if (DL->getAtomGroup() && DL->getAtomRank() && DL->getAtomRank() < Rank) {
173 Group = DL->getAtomGroup();
174 Rank = DL->getAtomRank();
179 KeyInstructionsInfo.HighestEmittedAtom =
180 std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
183 llvm::DILocation *NewDL = llvm::DILocation::get(
184 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
185 DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
186 I->setDebugLoc(NewDL);
190 llvm::Value *Backup) {
192 KeyInstructionsInfo.CurrentAtom);
198 if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
201 llvm::DISubprogram *SP = KeyInstruction->getFunction()->getSubprogram();
202 if (!SP || !SP->getKeyInstructionsEnabled())
205 addInstSourceAtomMetadata(KeyInstruction, Group, 1);
207 llvm::Instruction *BackupI =
208 llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
213 addInstSourceAtomMetadata(BackupI, Group, 2);
219 while (
auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
220 BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
223 addInstSourceAtomMetadata(BackupI, Group, Rank++);
229 KeyInstructionsInfo.NextAtom = 1;
230 KeyInstructionsInfo.HighestEmittedAtom = 0;
231 KeyInstructionsInfo.CurrentAtom = 0;
237 OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
238 DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
246 DI->KeyInstructionsInfo.NextAtom =
247 std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
248 DI->KeyInstructionsInfo.NextAtom);
250 DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
256 init(TemporaryLocation);
263 init(TemporaryLocation, DefaultToEmpty);
267 bool DefaultToEmpty) {
274 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
276 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
279 if (TemporaryLocation.
isValid()) {
280 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
284 if (DefaultToEmpty) {
285 CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc());
290 assert(!DI->LexicalBlockStack.empty());
291 CGF->Builder.SetCurrentDebugLocation(
292 llvm::DILocation::get(DI->LexicalBlockStack.back()->getContext(), 0, 0,
293 DI->LexicalBlockStack.back(), DI->getInlinedAt()));
303 if (!CGF.getDebugInfo()) {
307 OriginalLocation = CGF.Builder.getCurrentDebugLocation();
311 if (Loc->getAtomGroup())
312 Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
313 Loc->getColumn(), Loc->getScope(),
314 Loc->getInlinedAt(), Loc.isImplicitCode());
315 CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
323 CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
329 if (!CGF.getDebugInfo()) {
333 auto &DI = *CGF.getDebugInfo();
334 SavedLocation = DI.getLocation();
335 assert((DI.getInlinedAt() ==
336 CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
337 "CGDebugInfo and IRBuilder are out of sync");
339 DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
345 auto &DI = *CGF->getDebugInfo();
346 DI.EmitInlineFunctionEnd(CGF->Builder);
347 DI.EmitLocation(CGF->Builder, SavedLocation);
355 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(
361 if (LexicalBlockStack.empty())
367 if (PCLoc.
isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
370 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
371 LexicalBlockStack.pop_back();
372 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
373 LBF->getScope(), getOrCreateFile(CurLoc)));
376 LexicalBlockStack.pop_back();
377 LexicalBlockStack.emplace_back(
378 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
382llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
383 llvm::DIScope *Mod = getParentModuleOrNull(D);
388llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
393 auto I = RegionMap.find(Context);
394 if (I != RegionMap.end()) {
395 llvm::Metadata *
V = I->second;
396 return dyn_cast_or_null<llvm::DIScope>(
V);
400 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
401 return getOrCreateNamespace(NSDecl);
403 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
404 if (!RDecl->isDependentType())
410PrintingPolicy CGDebugInfo::getPrintingPolicy()
const {
411 PrintingPolicy PP = CGM.getContext().getPrintingPolicy();
418 if (CGM.getCodeGenOpts().EmitCodeView) {
439StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD,
440 bool *NameIsSimplified) {
441 return internString(GetName(FD,
false, NameIsSimplified));
444StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
445 SmallString<256> MethodName;
446 llvm::raw_svector_ostream
OS(MethodName);
449 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
450 OS << OID->getName();
451 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
452 OS << OID->getName();
453 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
454 if (OC->IsClassExtension()) {
455 OS << OC->getClassInterface()->getName();
457 OS << OC->getIdentifier()->getNameStart() <<
'('
458 << OC->getIdentifier()->getNameStart() <<
')';
460 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
461 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
465 return internString(
OS.str());
468StringRef CGDebugInfo::getSelectorName(Selector S) {
472StringRef CGDebugInfo::getClassName(
const RecordDecl *RD,
473 bool *NameIsSimplified) {
476 return internString(GetName(RD,
false, NameIsSimplified));
482 return II->getName();
487 if (CGM.getCodeGenOpts().EmitCodeView) {
490 "Typedef should not be in another decl context!");
491 assert(D->getDeclName().getAsIdentifierInfo() &&
492 "Typedef was not named!");
493 return D->getDeclName().getAsIdentifierInfo()->getName();
496 if (CGM.getLangOpts().CPlusPlus) {
499 ASTContext &Context = CGM.getContext();
503 Name = DD->getName();
504 else if (
const TypedefNameDecl *TND =
508 Name = TND->getName();
511 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
512 if (CXXRD->isLambda())
514 CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
517 SmallString<256> UnnamedType(
"<unnamed-type-");
520 return internString(UnnamedType);
528std::optional<llvm::DIFile::ChecksumKind>
529CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum)
const {
532 if (!CGM.getCodeGenOpts().EmitCodeView &&
533 CGM.getCodeGenOpts().DwarfVersion < 5)
536 SourceManager &
SM = CGM.getContext().getSourceManager();
537 std::optional<llvm::MemoryBufferRef> MemBuffer =
SM.getBufferOrNone(FID);
541 auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer());
542 switch (CGM.getCodeGenOpts().getDebugSrcHash()) {
544 llvm::toHex(llvm::MD5::hash(
Data),
true, Checksum);
545 return llvm::DIFile::CSK_MD5;
547 llvm::toHex(llvm::SHA1::hash(
Data),
true, Checksum);
548 return llvm::DIFile::CSK_SHA1;
550 llvm::toHex(llvm::SHA256::hash(
Data),
true, Checksum);
551 return llvm::DIFile::CSK_SHA256;
555 llvm_unreachable(
"Unhandled DebugSrcHashKind enum");
558std::optional<StringRef> CGDebugInfo::getSource(
const SourceManager &
SM,
560 if (!CGM.getCodeGenOpts().EmbedSource)
563 bool SourceInvalid =
false;
564 StringRef Source =
SM.getBufferData(FID, &SourceInvalid);
572llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
573 SourceManager &
SM = CGM.getContext().getSourceManager();
576 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
582 FileName = TheCU->getFile()->getFilename();
583 CSInfo = TheCU->getFile()->getChecksum();
589 FileName = TheCU->getFile()->getFilename();
597 auto It = DIFileCache.find(
FileName.data());
598 if (It != DIFileCache.end()) {
600 if (llvm::Metadata *
V = It->second)
605 SmallString<64> Checksum;
607 std::optional<llvm::DIFile::ChecksumKind> CSKind =
608 computeChecksum(FID, Checksum);
610 CSInfo.emplace(*CSKind, Checksum);
616llvm::DIFile *CGDebugInfo::createFile(
618 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
619 std::optional<StringRef> Source) {
623 std::string CurDir =
remapDIPath(getCurrentDirname());
624 SmallString<128> DirBuf;
625 SmallString<128> FileBuf;
626 if (llvm::sys::path::is_absolute(RemappedFile)) {
629 auto FileIt = llvm::sys::path::begin(RemappedFile);
630 auto FileE = llvm::sys::path::end(RemappedFile);
631 auto CurDirIt = llvm::sys::path::begin(CurDir);
632 auto CurDirE = llvm::sys::path::end(CurDir);
633 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
634 llvm::sys::path::append(DirBuf, *CurDirIt);
635 if (llvm::sys::path::root_path(DirBuf) == DirBuf) {
641 for (; FileIt != FileE; ++FileIt)
642 llvm::sys::path::append(FileBuf, *FileIt);
647 if (!llvm::sys::path::is_absolute(
FileName))
651 llvm::DIFile *F = DBuilder.createFile(
File, Dir, CSInfo, Source);
652 DIFileCache[
FileName.data()].reset(F);
658 for (
auto &[From, To] : llvm::reverse(CGM.getCodeGenOpts().DebugPrefixMap))
659 if (llvm::sys::path::replace_path_prefix(P, From, To))
661 return P.str().str();
671unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
685StringRef CGDebugInfo::getCurrentDirname() {
693 assert(CGO.DwarfVersion <= 5);
695 llvm::dwarf::SourceLanguage LangTag;
698 LangTag = llvm::dwarf::DW_LANG_HLSL;
700 LangTag = llvm::dwarf::DW_LANG_HIP;
702 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
703 else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
704 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
705 else if (LO.CPlusPlus14)
706 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
707 else if (LO.CPlusPlus11)
708 LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
710 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
711 }
else if (LO.ObjC) {
712 LangTag = llvm::dwarf::DW_LANG_ObjC;
713 }
else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
714 LangTag = llvm::dwarf::DW_LANG_OpenCL;
715 }
else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
716 LangTag = llvm::dwarf::DW_LANG_C11;
718 LangTag = llvm::dwarf::DW_LANG_C99;
720 LangTag = llvm::dwarf::DW_LANG_C89;
726static llvm::DISourceLanguageName
734 uint32_t LangVersion = 0;
735 llvm::dwarf::SourceLanguageName LangTag;
738 LangTag = llvm::dwarf::DW_LNAME_HLSL;
740 LangTag = llvm::dwarf::DW_LNAME_HIP;
741 }
else if (LO.ObjC) {
742 LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
744 LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
747 }
else if (LO.ObjC) {
748 LangTag = llvm::dwarf::DW_LNAME_ObjC;
749 }
else if (LO.OpenCL) {
750 LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
752 LangTag = llvm::dwarf::DW_LNAME_C;
756 return llvm::DISourceLanguageName(LangTag, LangVersion);
759void CGDebugInfo::CreateCompileUnit() {
760 SmallString<64> Checksum;
761 std::optional<llvm::DIFile::ChecksumKind> CSKind;
762 std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
772 SourceManager &
SM = CGM.getContext().getSourceManager();
773 auto &CGO = CGM.getCodeGenOpts();
774 const LangOptions &LO = CGM.getLangOpts();
775 std::string MainFileName = CGO.MainFileName;
776 if (MainFileName.empty())
777 MainFileName =
"<stdin>";
783 std::string MainFileDir;
785 SM.getFileEntryRefForID(
SM.getMainFileID())) {
786 MainFileDir = std::string(MainFile->getDir().getName());
787 if (!llvm::sys::path::is_absolute(MainFileName)) {
788 llvm::SmallString<1024> MainFileDirSS(MainFileDir);
789 llvm::sys::path::Style Style =
791 ? (CGM.getTarget().
getTriple().isOSWindows()
792 ? llvm::sys::path::Style::windows_backslash
793 : llvm::sys::path::Style::posix)
794 : llvm::sys::path::Style::native;
795 llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
796 MainFileName = std::string(
797 llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
804 if (MainFile->getName() == MainFileName &&
806 MainFile->getName().rsplit(
'.').second)
808 MainFileName = CGM.getModule().getName().str();
810 CSKind = computeChecksum(
SM.getMainFileID(), Checksum);
817 unsigned RuntimeVers = 0;
821 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
823 case llvm::codegenoptions::NoDebugInfo:
824 case llvm::codegenoptions::LocTrackingOnly:
825 EmissionKind = llvm::DICompileUnit::NoDebug;
827 case llvm::codegenoptions::DebugLineTablesOnly:
828 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
830 case llvm::codegenoptions::DebugDirectivesOnly:
831 EmissionKind = llvm::DICompileUnit::DebugDirectivesOnly;
833 case llvm::codegenoptions::DebugInfoConstructor:
834 case llvm::codegenoptions::LimitedDebugInfo:
835 case llvm::codegenoptions::FullDebugInfo:
836 case llvm::codegenoptions::UnusedTypeInfo:
837 EmissionKind = llvm::DICompileUnit::FullDebug;
842 auto &CGOpts = CGM.getCodeGenOpts();
848 CSInfo.emplace(*CSKind, Checksum);
849 llvm::DIFile *CUFile = DBuilder.createFile(
851 getSource(
SM,
SM.getMainFileID()));
853 StringRef Sysroot, SDK;
854 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) {
855 Sysroot = CGM.getHeaderSearchOpts().Sysroot;
856 auto B = llvm::sys::path::rbegin(Sysroot);
857 auto E = llvm::sys::path::rend(Sysroot);
859 std::find_if(B, E, [](
auto SDK) {
return SDK.ends_with(
".sdk"); });
864 llvm::DICompileUnit::DebugNameTableKind NameTableKind =
865 static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
866 CGOpts.DebugNameTable);
867 if (CGM.getTarget().getTriple().isNVPTX())
868 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::None;
869 else if (CGM.getTarget().getTriple().getVendor() == llvm::Triple::Apple)
870 NameTableKind = llvm::DICompileUnit::DebugNameTableKind::Apple;
873 TheCU = DBuilder.createCompileUnit(
875 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
876 CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
877 CGOpts.PrepareForThinLTO,
878 CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
879 DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
880 NameTableKind, CGOpts.DebugRangesBaseAddress,
remapDIPath(Sysroot), SDK);
883llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
887#define BUILTIN_TYPE(Id, SingletonId)
888#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
889#include "clang/AST/BuiltinTypes.def"
890 case BuiltinType::Dependent:
891 llvm_unreachable(
"Unexpected builtin type");
892 case BuiltinType::NullPtr:
893 return DBuilder.createNullPtrType();
894 case BuiltinType::Void:
896 case BuiltinType::ObjCClass:
899 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
900 "objc_class", TheCU, TheCU->getFile(), 0);
902 case BuiltinType::ObjCId: {
913 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
914 "objc_class", TheCU, TheCU->getFile(), 0);
916 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
918 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
920 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
921 (uint64_t)0, 0, llvm::DINode::FlagZero,
922 nullptr, llvm::DINodeArray());
924 DBuilder.replaceArrays(
925 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
926 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
927 llvm::DINode::FlagZero, ISATy)));
930 case BuiltinType::ObjCSel: {
932 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
933 "objc_selector", TheCU,
934 TheCU->getFile(), 0);
938#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
939 case BuiltinType::Id: \
940 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \
942#include "clang/Basic/OpenCLImageTypes.def"
943 case BuiltinType::OCLSampler:
944 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
945 case BuiltinType::OCLEvent:
946 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
947 case BuiltinType::OCLClkEvent:
948 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
949 case BuiltinType::OCLQueue:
950 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
951 case BuiltinType::OCLReserveID:
952 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
953#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
954 case BuiltinType::Id: \
955 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
956#include "clang/Basic/OpenCLExtensionTypes.def"
957#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
958 case BuiltinType::Id: \
959 return getOrCreateStructPtrType(#Name, SingletonId);
960#include "clang/Basic/HLSLIntangibleTypes.def"
962#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
963#include "clang/Basic/AArch64ACLETypes.def"
965 if (BT->
getKind() == BuiltinType::MFloat8) {
966 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
967 BTName = BT->
getName(CGM.getLangOpts());
970 return DBuilder.createBasicType(BTName, Size, Encoding);
972 ASTContext::BuiltinVectorTypeInfo Info =
974 BT->
getKind() == BuiltinType::SveCount
975 ? ASTContext::BuiltinVectorTypeInfo(
976 CGM.getContext().BoolTy, llvm::ElementCount::getFixed(16),
978 : CGM.getContext().getBuiltinVectorTypeInfo(BT);
985 "Unsupported number of vectors for svcount_t");
987 unsigned NumElems = Info.
EC.getKnownMinValue() * Info.
NumVectors;
988 llvm::Metadata *BitStride =
nullptr;
989 if (BT->
getKind() == BuiltinType::SveBool) {
990 Info.
ElementType = CGM.getContext().UnsignedCharTy;
991 BitStride = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
992 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 1));
993 }
else if (BT->
getKind() == BuiltinType::SveCount) {
995 Info.
ElementType = CGM.getContext().UnsignedCharTy;
998 llvm::Metadata *LowerBound, *UpperBound;
999 LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1000 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1001 if (Info.
EC.isScalable()) {
1002 unsigned NumElemsPerVG = NumElems / 2;
1003 SmallVector<uint64_t, 9> Expr(
1004 {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
1005 46, 0, llvm::dwarf::DW_OP_mul,
1006 llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1007 UpperBound = DBuilder.createExpression(Expr);
1009 UpperBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1010 llvm::Type::getInt64Ty(CGM.getLLVMContext()), NumElems - 1));
1012 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1013 nullptr, LowerBound, UpperBound,
nullptr);
1014 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1015 llvm::DIType *ElemTy =
1016 getOrCreateType(Info.
ElementType, TheCU->getFile());
1018 return DBuilder.createVectorType( 0, Align, ElemTy,
1019 SubscriptArray, BitStride);
1023#define PPC_VECTOR_TYPE(Name, Id, size) \
1024 case BuiltinType::Id:
1025#include "clang/Basic/PPCTypes.def"
1028#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1029#include "clang/Basic/RISCVVTypes.def"
1031 ASTContext::BuiltinVectorTypeInfo Info =
1032 CGM.getContext().getBuiltinVectorTypeInfo(BT);
1034 unsigned ElementCount = Info.
EC.getKnownMinValue();
1035 unsigned SEW = CGM.getContext().getTypeSize(Info.
ElementType);
1037 bool Fractional =
false;
1040 unsigned FixedSize = ElementCount * SEW;
1041 if (Info.
ElementType == CGM.getContext().BoolTy) {
1044 }
else if (FixedSize < 64) {
1047 LMUL = 64 / FixedSize;
1049 LMUL = FixedSize / 64;
1053 SmallVector<uint64_t, 12> Expr(
1057 {llvm::dwarf::DW_OP_bregx,
1060 llvm::dwarf::DW_OP_constu,
1062 llvm::dwarf::DW_OP_div, llvm::dwarf::DW_OP_constu, LMUL});
1064 Expr.push_back(llvm::dwarf::DW_OP_div);
1066 Expr.push_back(llvm::dwarf::DW_OP_mul);
1069 Expr.append({llvm::dwarf::DW_OP_constu, NFIELDS, llvm::dwarf::DW_OP_mul});
1071 Expr.append({llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
1074 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
1075 llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
1076 auto *UpperBound = DBuilder.createExpression(Expr);
1077 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
1078 nullptr, LowerBound, UpperBound,
nullptr);
1079 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
1080 llvm::DIType *ElemTy =
1081 getOrCreateType(Info.
ElementType, TheCU->getFile());
1084 return DBuilder.createVectorType(0, Align, ElemTy,
1088#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
1089 case BuiltinType::Id: { \
1092 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
1093 MangledName, TheCU, TheCU->getFile(), 0); \
1094 return SingletonId; \
1096#include "clang/Basic/WebAssemblyReferenceTypes.def"
1097#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
1098 case BuiltinType::Id: { \
1101 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
1102 TheCU, TheCU->getFile(), 0); \
1103 return SingletonId; \
1105#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
1106 case BuiltinType::Id: { \
1109 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_unsigned); \
1110 return SingletonId; \
1112#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
1113 case BuiltinType::Id: { \
1116 DBuilder.createBasicType(Name, Width, llvm::dwarf::DW_ATE_boolean); \
1117 return SingletonId; \
1119#include "clang/Basic/AMDGPUTypes.def"
1120 case BuiltinType::UChar:
1121 case BuiltinType::Char_U:
1122 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
1124 case BuiltinType::Char_S:
1125 case BuiltinType::SChar:
1126 Encoding = llvm::dwarf::DW_ATE_signed_char;
1128 case BuiltinType::Char8:
1129 case BuiltinType::Char16:
1130 case BuiltinType::Char32:
1131 Encoding = llvm::dwarf::DW_ATE_UTF;
1133 case BuiltinType::UShort:
1134 case BuiltinType::UInt:
1135 case BuiltinType::UInt128:
1136 case BuiltinType::ULong:
1137 case BuiltinType::WChar_U:
1138 case BuiltinType::ULongLong:
1139 Encoding = llvm::dwarf::DW_ATE_unsigned;
1141 case BuiltinType::Short:
1142 case BuiltinType::Int:
1143 case BuiltinType::Int128:
1144 case BuiltinType::Long:
1145 case BuiltinType::WChar_S:
1146 case BuiltinType::LongLong:
1147 Encoding = llvm::dwarf::DW_ATE_signed;
1149 case BuiltinType::Bool:
1150 Encoding = llvm::dwarf::DW_ATE_boolean;
1152 case BuiltinType::Half:
1153 case BuiltinType::Float:
1154 case BuiltinType::LongDouble:
1155 case BuiltinType::Float16:
1156 case BuiltinType::BFloat16:
1157 case BuiltinType::Float128:
1158 case BuiltinType::Double:
1159 case BuiltinType::Ibm128:
1165 Encoding = llvm::dwarf::DW_ATE_float;
1167 case BuiltinType::ShortAccum:
1168 case BuiltinType::Accum:
1169 case BuiltinType::LongAccum:
1170 case BuiltinType::ShortFract:
1171 case BuiltinType::Fract:
1172 case BuiltinType::LongFract:
1173 case BuiltinType::SatShortFract:
1174 case BuiltinType::SatFract:
1175 case BuiltinType::SatLongFract:
1176 case BuiltinType::SatShortAccum:
1177 case BuiltinType::SatAccum:
1178 case BuiltinType::SatLongAccum:
1179 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
1181 case BuiltinType::UShortAccum:
1182 case BuiltinType::UAccum:
1183 case BuiltinType::ULongAccum:
1184 case BuiltinType::UShortFract:
1185 case BuiltinType::UFract:
1186 case BuiltinType::ULongFract:
1187 case BuiltinType::SatUShortAccum:
1188 case BuiltinType::SatUAccum:
1189 case BuiltinType::SatULongAccum:
1190 case BuiltinType::SatUShortFract:
1191 case BuiltinType::SatUFract:
1192 case BuiltinType::SatULongFract:
1193 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
1197 BTName = BT->
getName(CGM.getLangOpts());
1200 return DBuilder.createBasicType(BTName, Size, Encoding);
1203llvm::DIType *CGDebugInfo::CreateType(
const BitIntType *Ty) {
1204 SmallString<32> Name;
1205 llvm::raw_svector_ostream
OS(Name);
1206 OS << (Ty->
isUnsigned() ?
"unsigned _BitInt(" :
"_BitInt(")
1209 ? llvm::dwarf::DW_ATE_unsigned
1210 : llvm::dwarf::DW_ATE_signed;
1211 return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
1212 Encoding, llvm::DINode::FlagZero, 0,
1216llvm::DIType *CGDebugInfo::CreateType(
const OverflowBehaviorType *Ty,
1218 return getOrCreateType(Ty->getUnderlyingType(), U);
1221llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
1223 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
1225 Encoding = llvm::dwarf::DW_ATE_lo_user;
1228 return DBuilder.createBasicType(
"complex", Size, Encoding);
1242 return llvm::dwarf::DW_TAG_const_type;
1246 return llvm::dwarf::DW_TAG_volatile_type;
1250 return llvm::dwarf::DW_TAG_restrict_type;
1252 return (llvm::dwarf::Tag)0;
1255llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
1256 llvm::DIFile *Unit) {
1257 QualifierCollector Qc;
1271 bool AuthenticatesNullValues =
1274 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1275 llvm::DIType *FromTy = getOrCreateType(QualType(T, 0), Unit);
1276 return DBuilder.createPtrAuthQualifiedType(FromTy, Key, IsDiscr,
1277 ExtraDiscr, IsaPointer,
1278 AuthenticatesNullValues);
1280 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
1281 return getOrCreateType(QualType(T, 0), Unit);
1285 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
1289 return DBuilder.createQualifiedType(Tag, FromTy);
1292llvm::DIType *CGDebugInfo::CreateQualifiedType(
const FunctionProtoType *F,
1293 llvm::DIFile *Unit) {
1302 assert(Q.
empty() &&
"Unknown type qualifier for debug info");
1307 getOrCreateType(CGM.getContext().getFunctionType(F->
getReturnType(),
1313 return DBuilder.createQualifiedType(Tag, FromTy);
1316llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectPointerType *Ty,
1317 llvm::DIFile *Unit) {
1323 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
1325 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1329llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
1330 llvm::DIFile *Unit) {
1331 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1337 case llvm::dwarf::DW_LANG_C_plus_plus:
1338 case llvm::dwarf::DW_LANG_C_plus_plus_11:
1339 case llvm::dwarf::DW_LANG_C_plus_plus_14:
1340 case llvm::dwarf::DW_LANG_HIP:
1342 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
1352 case llvm::dwarf::DW_LNAME_C_plus_plus:
1353 case llvm::dwarf::DW_LNAME_HIP:
1355 case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
1366 if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
1367 SourceLang.hasVersionedName())
1369 static_cast<llvm::dwarf::SourceLanguageName
>(SourceLang.getName()),
1373 static_cast<llvm::dwarf::SourceLanguage
>(SourceLang.getName()),
1399 llvm::DICompileUnit *TheCU) {
1417 llvm::DICompileUnit *TheCU) {
1423 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD))
1425 if (RD->isDynamicClass() &&
1431 llvm::raw_svector_ostream Out(Identifier);
1438 llvm::dwarf::Tag Tag;
1440 Tag = llvm::dwarf::DW_TAG_structure_type;
1442 Tag = llvm::dwarf::DW_TAG_union_type;
1447 Tag = llvm::dwarf::DW_TAG_class_type;
1452llvm::DICompositeType *
1453CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
1454 llvm::DIScope *Ctx) {
1455 const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
1456 if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
1458 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1459 const unsigned Line =
1461 StringRef RDName = getClassName(RD);
1468 Size = CGM.getContext().getTypeSize(Ty);
1470 llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl;
1475 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1476 if (!CXXRD->hasDefinition() ||
1477 (CXXRD->hasDefinition() && !CXXRD->isTrivial()))
1478 Flags |= llvm::DINode::FlagNonTrivial;
1481 SmallString<256> Identifier;
1483 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1485 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
1488 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
1489 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1490 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
1491 CollectCXXTemplateParams(TSpecial, DefUnit));
1492 ReplaceMap.emplace_back(
1493 std::piecewise_construct, std::make_tuple(Ty),
1494 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
1498llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
1501 llvm::DIFile *Unit) {
1506 std::optional<unsigned> DWARFAddressSpace =
1507 CGM.getTarget().getDWARFAddressSpace(
1508 CGM.getTypes().getTargetAddressSpace(PointeeTy));
1510 const BTFTagAttributedType *BTFAttrTy;
1511 if (
auto *
Atomic = PointeeTy->
getAs<AtomicType>())
1512 BTFAttrTy = dyn_cast<BTFTagAttributedType>(
Atomic->getValueType());
1514 BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
1515 SmallVector<llvm::Metadata *, 4> Annots;
1517 StringRef
Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
1519 llvm::Metadata *Ops[2] = {
1520 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_type_tag")),
1521 llvm::MDString::get(CGM.getLLVMContext(), Tag)};
1522 Annots.insert(Annots.begin(),
1523 llvm::MDNode::get(CGM.getLLVMContext(), Ops));
1525 BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
1528 llvm::DINodeArray Annotations =
nullptr;
1529 if (Annots.size() > 0)
1530 Annotations = DBuilder.getOrCreateArray(Annots);
1532 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
1533 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
1534 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
1535 Size, Align, DWARFAddressSpace);
1537 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
1538 Align, DWARFAddressSpace, StringRef(),
1542llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
1543 llvm::DIType *&
Cache) {
1546 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
1547 TheCU, TheCU->getFile(), 0);
1548 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1549 Cache = DBuilder.createPointerType(
Cache, Size);
1553uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1554 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1555 unsigned LineNo, SmallVectorImpl<llvm::Metadata *> &EltTys) {
1565 if (CGM.getLangOpts().OpenCL) {
1566 FType = CGM.getContext().IntTy;
1567 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1568 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1570 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1571 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1572 FType = CGM.getContext().IntTy;
1573 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1574 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1576 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1577 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1578 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1579 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1580 EltTys.push_back(DBuilder.createMemberType(
1581 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1582 FieldOffset, llvm::DINode::FlagZero, DescTy));
1583 FieldOffset += FieldSize;
1589llvm::DIType *CGDebugInfo::CreateType(
const BlockPointerType *Ty,
1590 llvm::DIFile *Unit) {
1591 SmallVector<llvm::Metadata *, 8> EltTys;
1594 llvm::DINodeArray Elements;
1597 FType = CGM.getContext().UnsignedLongTy;
1598 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1599 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1601 Elements = DBuilder.getOrCreateArray(EltTys);
1604 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1607 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1608 FieldOffset, 0, Flags,
nullptr, Elements);
1613 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1615 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1618 Elements = DBuilder.getOrCreateArray(EltTys);
1624 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1625 Flags,
nullptr, Elements);
1627 return DBuilder.createPointerType(EltTy, Size);
1630static llvm::SmallVector<TemplateArgument>
1632 assert(Ty->isTypeAlias());
1641 ArrayRef SubstArgs = Ty->template_arguments();
1644 if (Param->isParameterPack()) {
1653 if (SubstArgs.empty()) {
1662 SpecArgs.push_back(SubstArgs.front());
1663 SubstArgs = SubstArgs.drop_front();
1668llvm::DIType *CGDebugInfo::CreateType(
const TemplateSpecializationType *Ty,
1669 llvm::DIFile *Unit) {
1670 assert(Ty->isTypeAlias());
1671 llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
1673 const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
1681 SmallString<128> NS;
1682 llvm::raw_svector_ostream
OS(NS);
1684 auto PP = getPrintingPolicy();
1687 SourceLocation Loc =
AliasDecl->getLocation();
1689 if (CGM.getCodeGenOpts().DebugTemplateAlias) {
1690 auto ArgVector = ::GetTemplateArgs(TD, Ty);
1699 llvm::raw_string_ostream
OS(Name);
1701 if (CGM.getCodeGenOpts().getDebugSimpleTemplateNames() !=
1702 llvm::codegenoptions::DebugTemplateNamesKind::Simple ||
1703 !HasReconstitutableArgs(Args.Args))
1704 printTemplateArgumentList(OS, Args.Args, PP);
1706 llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
1707 Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
1708 getDeclContextDescriptor(
AliasDecl), CollectTemplateParams(Args, Unit));
1712 printTemplateArgumentList(OS, Ty->template_arguments(), PP,
1714 return DBuilder.createTypedef(Src,
OS.str(), getOrCreateFile(Loc),
1731 return llvm::DINode::FlagZero;
1735 return llvm::DINode::FlagPrivate;
1737 return llvm::DINode::FlagProtected;
1739 return llvm::DINode::FlagPublic;
1741 return llvm::DINode::FlagZero;
1743 llvm_unreachable(
"unexpected access enumerator");
1746llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1747 llvm::DIFile *Unit) {
1748 llvm::DIType *Underlying =
1760 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->
getDecl());
1762 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1767 return DBuilder.createTypedef(Underlying, Ty->
getDecl()->
getName(),
1768 getOrCreateFile(Loc), getLineNumber(Loc),
1769 getDeclContextDescriptor(Ty->
getDecl()), Align,
1770 Flags, Annotations);
1780 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1782 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1784 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1786 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1788 return llvm::dwarf::DW_CC_BORLAND_pascal;
1790 return llvm::dwarf::DW_CC_LLVM_Win64;
1792 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1796 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1798 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1800 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1802 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1804 return llvm::dwarf::DW_CC_LLVM_DeviceKernel;
1806 return llvm::dwarf::DW_CC_LLVM_Swift;
1808 return llvm::dwarf::DW_CC_LLVM_SwiftTail;
1810 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1812 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1814 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1816 return llvm::dwarf::DW_CC_LLVM_M68kRTD;
1818 return llvm::dwarf::DW_CC_LLVM_PreserveNone;
1820 return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
1821#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:
1835 return llvm::dwarf::DW_CC_LLVM_RISCVVLSCall;
1841 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1843 Flags |= llvm::DINode::FlagLValueReference;
1845 Flags |= llvm::DINode::FlagRValueReference;
1849llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1850 llvm::DIFile *Unit) {
1851 const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
1853 if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
1859 SmallVector<llvm::Metadata *, 16> EltTys;
1862 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1864 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1868 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1871 for (
const QualType &ParamType : FPT->param_types())
1872 EltTys.push_back(getOrCreateType(ParamType, Unit));
1873 if (FPT->isVariadic())
1874 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1877 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1878 llvm::DIType *F = DBuilder.createSubroutineType(
1883llvm::DIDerivedType *
1884CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1885 llvm::DIScope *RecordTy,
const RecordDecl *RD) {
1886 StringRef Name = BitFieldDecl->
getName();
1887 QualType Ty = BitFieldDecl->
getType();
1888 if (BitFieldDecl->
hasAttr<PreferredTypeAttr>())
1891 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1892 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1895 llvm::DIFile *
File = getOrCreateFile(Loc);
1896 unsigned Line = getLineNumber(Loc);
1898 const CGBitFieldInfo &BitFieldInfo =
1899 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1901 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1908 if (CGM.getDataLayout().isBigEndian())
1910 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1912 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
1913 return DBuilder.createBitFieldMemberType(
1914 RecordTy, Name,
File,
Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1915 Flags, DebugType, Annotations);
1918llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
1919 const FieldDecl *BitFieldDecl,
const llvm::DIDerivedType *BitFieldDI,
1920 llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI,
const RecordDecl *RD) {
1922 if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
1947 if (PreviousFieldsDI.empty())
1951 auto *PreviousMDEntry =
1952 PreviousFieldsDI.empty() ?
nullptr : PreviousFieldsDI.back();
1953 auto *PreviousMDField =
1954 dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
1955 if (!PreviousMDField || !PreviousMDField->isBitField() ||
1956 PreviousMDField->getSizeInBits() == 0)
1960 std::advance(PreviousBitfield, BitFieldDecl->
getFieldIndex() - 1);
1962 assert(PreviousBitfield->isBitField());
1964 if (!PreviousBitfield->isZeroLengthBitField())
1967 QualType Ty = PreviousBitfield->getType();
1968 SourceLocation Loc = PreviousBitfield->getLocation();
1969 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1970 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1971 llvm::DIScope *RecordTy = BitFieldDI->getScope();
1973 llvm::DIFile *
File = getOrCreateFile(Loc);
1974 unsigned Line = getLineNumber(Loc);
1980 llvm::DINode::DIFlags Flags =
1982 llvm::DINodeArray Annotations =
1983 CollectBTFDeclTagAnnotations(*PreviousBitfield);
1984 return DBuilder.createBitFieldMemberType(
1985 RecordTy,
"",
File,
Line, 0, StorageOffsetInBits, StorageOffsetInBits,
1986 Flags, DebugType, Annotations);
1989llvm::DIType *CGDebugInfo::createFieldType(
1991 uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
1992 llvm::DIScope *scope,
const RecordDecl *RD, llvm::DINodeArray Annotations) {
1993 llvm::DIType *debugType = getOrCreateType(
type, tunit);
1996 llvm::DIFile *file = getOrCreateFile(loc);
1997 const unsigned line = getLineNumber(loc.
isValid() ? loc : CurLoc);
2000 auto Align = AlignInBits;
2001 if (!
type->isIncompleteArrayType()) {
2002 TypeInfo TI = CGM.getContext().getTypeInfo(
type);
2003 SizeInBits = TI.
Width;
2009 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
2010 offsetInBits, flags, debugType, Annotations);
2014CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
2015 llvm::DIFile *FileScope) {
2019 llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
2022 llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(
nullptr);
2023 SP = DBuilder.createFunction(
2024 FileScope, FuncName, StringRef(),
2025 FileScope, 0, DIFnTy,
2027 llvm::DINode::FlagArtificial,
2028 llvm::DISubprogram::SPFlagDefinition,
2029 nullptr,
nullptr,
nullptr,
2030 nullptr, StringRef(),
2031 CGM.getCodeGenOpts().DebugKeyInstructions);
2038CGDebugInfo::GetLambdaCaptureName(
const LambdaCapture &
Capture) {
2040 return CGM.getCodeGenOpts().EmitCodeView ?
"__this" :
"this";
2042 assert(
Capture.capturesVariable());
2044 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2045 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2047 return CaptureDecl->
getName();
2050void CGDebugInfo::CollectRecordLambdaFields(
2051 const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
2052 llvm::DIType *RecordTy) {
2057 unsigned fieldno = 0;
2060 I != E; ++I, ++Field, ++fieldno) {
2061 const LambdaCapture &
Capture = *I;
2063 CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
2065 assert(!
Field->isBitField() &&
"lambdas don't have bitfield members!");
2075 Loc =
Field->getLocation();
2076 }
else if (
Capture.capturesVariable()) {
2079 const ValueDecl *CaptureDecl =
Capture.getCapturedVar();
2080 assert(CaptureDecl &&
"Expected valid decl for captured variable.");
2087 llvm::DIFile *VUnit = getOrCreateFile(Loc);
2089 elements.push_back(createFieldType(
2091 Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
2097template <
typename T>
2098static llvm::Constant *
2109 return llvm::ConstantDataArray::get(Ctx, Vals);
2122 const QualType ElemQTy = ArrayTy->getElementType();
2129 switch (ElemBitWidth) {
2145llvm::DIDerivedType *
2146CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
2147 const RecordDecl *RD) {
2151 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
2152 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
2154 unsigned LineNumber = getLineNumber(Var->
getLocation());
2155 StringRef VName = Var->
getName();
2159 llvm::Constant *
C =
nullptr;
2164 C = llvm::ConstantInt::get(CGM.getLLVMContext(),
Value->getInt());
2165 if (
Value->isFloat())
2166 C = llvm::ConstantFP::get(CGM.getLLVMContext(),
Value->getFloat());
2167 if (
Value->isArray())
2173 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2174 ? llvm::dwarf::DW_TAG_variable
2175 : llvm::dwarf::DW_TAG_member;
2177 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
2178 RecordTy, VName, VUnit, LineNumber, VTy, Flags,
C, Tag, Align);
2183void CGDebugInfo::CollectRecordNormalField(
2184 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
2185 SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
2186 const RecordDecl *RD) {
2191 if (
name.empty() && !
type->isRecordType())
2194 llvm::DIType *FieldType;
2196 llvm::DIDerivedType *BitFieldType;
2197 FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
2198 if (llvm::DIType *Separator =
2199 createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
2200 elements.push_back(Separator);
2203 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
2206 OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
2209 elements.push_back(FieldType);
2212void CGDebugInfo::CollectRecordNestedType(
2213 const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
2214 QualType Ty = CGM.getContext().getTypeDeclType(TD);
2221 if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
2222 elements.push_back(nestedType);
2225void CGDebugInfo::CollectRecordFields(
2226 const RecordDecl *record, llvm::DIFile *tunit,
2227 SmallVectorImpl<llvm::Metadata *> &elements,
2228 llvm::DICompositeType *RecordTy) {
2229 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record);
2231 if (CXXDecl && CXXDecl->
isLambda())
2232 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
2234 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
2237 unsigned fieldNo = 0;
2241 for (
const auto *I : record->
decls())
2242 if (
const auto *
V = dyn_cast<VarDecl>(I)) {
2243 if (
V->hasAttr<NoDebugAttr>())
2248 if (CGM.getCodeGenOpts().EmitCodeView &&
2256 auto MI = StaticDataMemberCache.find(
V->getCanonicalDecl());
2257 if (MI != StaticDataMemberCache.end()) {
2258 assert(MI->second &&
2259 "Static data member declaration should still exist");
2260 elements.push_back(MI->second);
2262 auto Field = CreateRecordStaticField(
V, RecordTy, record);
2263 elements.push_back(Field);
2265 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
2266 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
2267 elements, RecordTy, record);
2271 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
2274 if (
const auto *nestedType = dyn_cast<TypeDecl>(I)) {
2279 if (!nestedType->isImplicit() &&
2280 nestedType->getDeclContext() == record)
2281 CollectRecordNestedType(nestedType, elements);
2287llvm::DISubroutineType *
2288CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *
Method,
2289 llvm::DIFile *Unit) {
2290 const FunctionProtoType *
Func =
Method->getType()->getAs<FunctionProtoType>();
2292 return cast_or_null<llvm::DISubroutineType>(
2293 getOrCreateType(QualType(
Func, 0), Unit));
2296 if (!
Method->hasCXXExplicitFunctionObjectParameter())
2297 ThisType =
Method->getThisType();
2299 return getOrCreateInstanceMethodType(ThisType,
Func, Unit);
2302llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2303 const CXXMethodDecl *
Method, llvm::DIFile *Unit, QualType FNType) {
2304 const FunctionProtoType *
Func = FNType->
getAs<FunctionProtoType>();
2306 return getOrCreateInstanceMethodType(
Method->getThisType(),
Func, Unit,
true);
2309llvm::DISubroutineType *
2310CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2311 const FunctionProtoType *
Func,
2312 llvm::DIFile *Unit,
bool SkipFirst) {
2313 FunctionProtoType::ExtProtoInfo EPI =
Func->getExtProtoInfo();
2328 getOrCreateType(CGM.getContext().getFunctionType(
2329 Func->getReturnType(),
Func->getParamTypes(), EPI),
2331 llvm::DITypeArray Args = OriginalFunc->getTypeArray();
2332 assert(Args.size() &&
"Invalid number of arguments!");
2334 SmallVector<llvm::Metadata *, 16> Elts;
2337 Elts.push_back(Args[0]);
2339 const bool HasExplicitObjectParameter = ThisPtr.
isNull();
2343 if (!HasExplicitObjectParameter) {
2344 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2347 DBuilder.createObjectPointerType(ThisPtrType,
true);
2348 Elts.push_back(ThisPtrType);
2352 for (
unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i < e; ++i)
2353 Elts.push_back(Args[i]);
2356 if (HasExplicitObjectParameter) {
2357 assert(Elts.size() >= 2 && Args.size() >= 2 &&
2358 "Expected at least return type and object parameter.");
2359 Elts[1] = DBuilder.createObjectPointerType(Args[1],
false);
2362 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
2364 return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
2371 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
2379CGDebugInfo::GetMethodLinkageName(
const CXXMethodDecl *
Method)
const {
2382 const bool IsCtorOrDtor =
2385 if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
2392 if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
2395 if (
const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(
Method))
2398 if (
const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(
Method))
2401 return CGM.getMangledName(
Method);
2404bool CGDebugInfo::shouldGenerateVirtualCallSite()
const {
2407 (CGM.getCodeGenOpts().DwarfVersion >= 5));
2410llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
2411 const CXXMethodDecl *
Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2414 StringRef MethodName = getFunctionName(
Method);
2415 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(
Method, Unit);
2417 StringRef MethodLinkageName;
2424 MethodLinkageName = GetMethodLinkageName(
Method);
2427 llvm::DIFile *MethodDefUnit =
nullptr;
2428 unsigned MethodLine = 0;
2429 if (!
Method->isImplicit()) {
2430 MethodDefUnit = getOrCreateFile(
Method->getLocation());
2431 MethodLine = getLineNumber(
Method->getLocation());
2435 llvm::DIType *ContainingType =
nullptr;
2436 unsigned VIndex = 0;
2437 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2438 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
2439 int ThisAdjustment = 0;
2442 if (
Method->isPureVirtual())
2443 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
2445 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
2447 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2451 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(
Method);
2455 const auto *DD = dyn_cast<CXXDestructorDecl>(
Method);
2458 DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2459 CGM.getContext().getLangOpts())
2463 MethodVFTableLocation ML =
2464 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
2472 if (
Method->size_overridden_methods() == 0)
2473 Flags |= llvm::DINode::FlagIntroducedVirtual;
2478 ThisAdjustment = CGM.getCXXABI()
2479 .getVirtualFunctionPrologueThisAdjustment(GD)
2482 ContainingType = RecordTy;
2485 if (
Method->getCanonicalDecl()->isDeleted())
2486 SPFlags |= llvm::DISubprogram::SPFlagDeleted;
2488 if (
Method->isNoReturn())
2489 Flags |= llvm::DINode::FlagNoReturn;
2492 Flags |= llvm::DINode::FlagStaticMember;
2493 if (
Method->isImplicit())
2494 Flags |= llvm::DINode::FlagArtificial;
2496 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(
Method)) {
2497 if (CXXC->isExplicit())
2498 Flags |= llvm::DINode::FlagExplicit;
2499 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(
Method)) {
2500 if (CXXC->isExplicit())
2501 Flags |= llvm::DINode::FlagExplicit;
2503 if (
Method->hasPrototype())
2504 Flags |= llvm::DINode::FlagPrototyped;
2506 Flags |= llvm::DINode::FlagLValueReference;
2508 Flags |= llvm::DINode::FlagRValueReference;
2509 if (!
Method->isExternallyVisible())
2510 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
2511 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2512 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
2516 if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
2517 if (
const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
Method))
2520 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(
Method, Unit);
2521 llvm::DISubprogram *SP = DBuilder.createMethod(
2522 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
2523 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
2524 TParamsArray.get(),
nullptr,
2525 CGM.getCodeGenOpts().DebugKeyInstructions);
2527 SPCache[
Method->getCanonicalDecl()].reset(SP);
2532void CGDebugInfo::CollectCXXMemberFunctions(
2533 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2534 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
2539 for (
const auto *I : RD->
decls()) {
2540 const auto *
Method = dyn_cast<CXXMethodDecl>(I);
2554 if (
Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType())
2563 auto MI = SPCache.find(
Method->getCanonicalDecl());
2564 EltTys.push_back(MI == SPCache.end()
2565 ? CreateCXXMemberFunction(
Method, Unit, RecordTy)
2566 :
static_cast<llvm::Metadata *
>(MI->second));
2570void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2571 SmallVectorImpl<llvm::Metadata *> &EltTys,
2572 llvm::DIType *RecordTy) {
2573 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
2574 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
2575 llvm::DINode::FlagZero);
2579 if (CGM.getCodeGenOpts().EmitCodeView) {
2580 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
2581 llvm::DINode::FlagIndirectVirtualBase);
2585void CGDebugInfo::CollectCXXBasesAux(
2586 const CXXRecordDecl *RD, llvm::DIFile *Unit,
2587 SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
2589 llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
2590 llvm::DINode::DIFlags StartingFlags) {
2591 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2592 for (
const auto &BI : Bases) {
2595 BI.getType()->castAsCanonical<RecordType>()->getDecl())
2597 if (!SeenTypes.insert(Base).second)
2599 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
2600 llvm::DINode::DIFlags BFlags = StartingFlags;
2604 if (BI.isVirtual()) {
2605 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
2608 BaseOffset = 0 - CGM.getItaniumVTableContext()
2609 .getVirtualBaseOffsetOffset(RD, Base)
2615 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
2616 VBPtrOffset = CGM.getContext()
2617 .getASTRecordLayout(RD)
2621 BFlags |= llvm::DINode::FlagVirtual;
2628 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
2629 VBPtrOffset, BFlags);
2630 EltTys.push_back(DTy);
2635CGDebugInfo::CollectTemplateParams(std::optional<TemplateArgs> OArgs,
2636 llvm::DIFile *Unit) {
2638 return llvm::DINodeArray();
2639 TemplateArgs &Args = *OArgs;
2640 SmallVector<llvm::Metadata *, 16> TemplateParams;
2641 for (
unsigned i = 0, e = Args.Args.size(); i != e; ++i) {
2642 const TemplateArgument &TA = Args.Args[i];
2646 Name = Args.TList->getParam(i)->getName();
2650 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
2651 TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
2652 TheCU, Name, TTy, defaultParameter));
2657 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2658 TheCU, Name, TTy, defaultParameter,
2659 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
2664 llvm::DIType *TTy = getOrCreateType(T, Unit);
2665 llvm::Constant *
V =
nullptr;
2668 if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
2669 !D->
hasAttr<CUDADeviceAttr>()) {
2672 if (
const auto *VD = dyn_cast<VarDecl>(D))
2673 V = CGM.GetAddrOfGlobalVar(VD);
2676 else if (
const auto *MD = dyn_cast<CXXMethodDecl>(D);
2677 MD && MD->isImplicitObjectMemberFunction())
2678 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
2679 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
2680 V = CGM.GetAddrOfFunction(FD);
2683 else if (
const auto *MPT =
2684 dyn_cast<MemberPointerType>(T.
getTypePtr())) {
2688 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
2690 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
2691 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
2692 }
else if (
const auto *GD = dyn_cast<MSGuidDecl>(D)) {
2693 V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
2694 }
else if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
2696 V = ConstantEmitter(CGM).emitAbstract(
2697 SourceLocation(), TPO->getValue(), TPO->getType());
2699 V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
2701 assert(
V &&
"Failed to find template parameter pointer");
2702 V =
V->stripPointerCasts();
2704 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2705 TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(
V)));
2709 llvm::DIType *TTy = getOrCreateType(T, Unit);
2710 llvm::Constant *
V =
nullptr;
2713 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
2719 if (MPT->isMemberDataPointer())
2720 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
2722 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
2723 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2724 TheCU, Name, TTy, defaultParameter,
V));
2728 llvm::DIType *TTy = getOrCreateType(T, Unit);
2729 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(
2731 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2732 TheCU, Name, TTy, defaultParameter,
V));
2735 std::string QualName;
2736 llvm::raw_string_ostream
OS(QualName);
2738 OS, getPrintingPolicy());
2739 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
2740 TheCU, Name,
nullptr, QualName, defaultParameter));
2744 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
2745 TheCU, Name,
nullptr,
2752 T = CGM.getContext().getLValueReferenceType(T);
2753 llvm::Constant *
V = ConstantEmitter(CGM).emitAbstract(E, T);
2754 assert(
V &&
"Expression in template argument isn't constant");
2755 llvm::DIType *TTy = getOrCreateType(T, Unit);
2756 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
2757 TheCU, Name, TTy, defaultParameter,
V->stripPointerCasts()));
2763 "These argument types shouldn't exist in concrete types");
2766 return DBuilder.getOrCreateArray(TemplateParams);
2769std::optional<CGDebugInfo::TemplateArgs>
2770CGDebugInfo::GetTemplateArgs(
const FunctionDecl *FD)
const {
2778 return std::nullopt;
2780std::optional<CGDebugInfo::TemplateArgs>
2781CGDebugInfo::GetTemplateArgs(
const VarDecl *VD)
const {
2785 auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VD);
2787 return std::nullopt;
2788 VarTemplateDecl *T = TS->getSpecializedTemplate();
2790 auto TA = TS->getTemplateArgs().asArray();
2791 return {{TList, TA}};
2793std::optional<CGDebugInfo::TemplateArgs>
2794CGDebugInfo::GetTemplateArgs(
const RecordDecl *RD)
const {
2795 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2799 TemplateParameterList *TPList =
2800 TSpecial->getSpecializedTemplate()->getTemplateParameters();
2801 const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
2802 return {{TPList, TAList.
asArray()}};
2804 return std::nullopt;
2808CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
2809 llvm::DIFile *Unit) {
2810 return CollectTemplateParams(GetTemplateArgs(FD), Unit);
2813llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
2814 llvm::DIFile *Unit) {
2815 return CollectTemplateParams(GetTemplateArgs(VL), Unit);
2818llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const RecordDecl *RD,
2819 llvm::DIFile *Unit) {
2820 return CollectTemplateParams(GetTemplateArgs(RD), Unit);
2823llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(
const Decl *D) {
2824 if (!D->
hasAttr<BTFDeclTagAttr>())
2827 SmallVector<llvm::Metadata *, 4> Annotations;
2829 llvm::Metadata *Ops[2] = {
2830 llvm::MDString::get(CGM.getLLVMContext(), StringRef(
"btf_decl_tag")),
2831 llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
2832 Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
2834 return DBuilder.getOrCreateArray(Annotations);
2837llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
2839 return VTablePtrType;
2841 ASTContext &Context = CGM.getContext();
2844 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
2845 llvm::DITypeArray SElements = DBuilder.getOrCreateTypeArray(STy);
2846 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
2848 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
2849 std::optional<unsigned> DWARFAddressSpace =
2850 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
2852 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
2853 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
2854 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
2855 return VTablePtrType;
2858StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
2870 if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2872 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
2882 if (CGM.getTarget().getTriple().isOSBinFormatCOFF() &&
2883 VTable->isDeclarationForLinker())
2887 StringRef SymbolName =
"__clang_vtable";
2889 QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2898 llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2900 llvm::DIFile *Unit = getOrCreateFile(Loc);
2901 llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2903 llvm::DINode::FlagArtificial;
2904 auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2905 ? llvm::dwarf::DW_TAG_variable
2906 : llvm::dwarf::DW_TAG_member;
2907 llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2908 Ctxt, SymbolName, Unit, 0, VTy, Flags,
2912 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2916 llvm::DIGlobalVariableExpression *GVE =
2917 DBuilder.createGlobalVariableExpression(
2918 TheCU, SymbolName, VTable->getName(), Unit, 0,
2919 getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2920 true,
nullptr, DT,
nullptr,
2922 VTable->addDebugInfo(GVE);
2925StringRef CGDebugInfo::getDynamicInitializerName(
const VarDecl *VD,
2927 llvm::Function *InitFn) {
2932 return InitFn->getName();
2942 llvm::raw_svector_ostream OS(QualifiedGV);
2944 std::tie(Quals, GVName) = OS.str().rsplit(
"::");
2946 std::swap(Quals, GVName);
2950 llvm::raw_svector_ostream OS(InitName);
2952 OS << Quals <<
"::";
2957 llvm_unreachable(
"not an initializer");
2959 OS <<
"`dynamic initializer for '";
2962 OS <<
"`dynamic atexit destructor for '";
2969 if (
const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
2970 printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
2971 getPrintingPolicy());
2976 return internString(
OS.str());
2979void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
2980 SmallVectorImpl<llvm::Metadata *> &EltTys) {
2989 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2996 llvm::DIType *VPtrTy =
nullptr;
2997 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
2998 CGM.getTarget().getCXXABI().isMicrosoft();
2999 if (NeedVTableShape) {
3001 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3002 const VTableLayout &VFTLayout =
3003 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
3004 unsigned VSlotCount =
3006 unsigned VTableWidth = PtrWidth * VSlotCount;
3007 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
3008 std::optional<unsigned> DWARFAddressSpace =
3009 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
3012 llvm::DIType *VTableType = DBuilder.createPointerType(
3013 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
3014 EltTys.push_back(VTableType);
3017 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
3025 VPtrTy = getOrCreateVTablePtrType(Unit);
3027 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
3028 llvm::DIType *VPtrMember =
3029 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
3030 llvm::DINode::FlagArtificial, VPtrTy);
3031 EltTys.push_back(VPtrMember);
3036 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3037 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
3048 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
3049 assert(!D.
isNull() &&
"null type");
3050 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
3051 assert(T &&
"could not create debug info for type");
3060 if (CGM.getCodeGenOpts().getDebugInfo() <=
3061 llvm::codegenoptions::DebugLineTablesOnly)
3065 node = llvm::MDNode::get(CGM.getLLVMContext(), {});
3067 node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
3069 CI->setMetadata(
"heapallocsite", node);
3073 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3075 CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
3077 auto I = TypeCache.find(TyPtr);
3080 llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
3081 assert(!Res->isForwardDecl());
3082 TypeCache[TyPtr].reset(Res);
3086 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3087 !CGM.getLangOpts().CPlusPlus)
3093 if (RD->
hasAttr<DLLImportAttr>())
3096 if (MD->hasAttr<DLLImportAttr>())
3109 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
3119 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
3120 Explicit = TD->isExplicitInstantiationOrSpecialization();
3124 if (CXXDecl->
fields().empty())
3134 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3135 if (CXXRD->isDynamicClass() &&
3136 CGM.getVTableLinkage(CXXRD) ==
3137 llvm::GlobalValue::AvailableExternallyLinkage &&
3148 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
3150 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3152 auto I = TypeCache.find(TyPtr);
3159 auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
3160 assert(!Res->isForwardDecl());
3161 TypeCache[TyPtr].reset(Res);
3168 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
3169 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
3192 if (Ctor->isCopyOrMoveConstructor())
3194 if (!Ctor->isDeleted())
3213 if (DebugKind == llvm::codegenoptions::DebugLineTablesOnly)
3216 if (DebugKind > llvm::codegenoptions::LimitedDebugInfo ||
3217 RD->
hasAttr<StandaloneDebugAttr>())
3220 if (!LangOpts.CPlusPlus)
3226 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3242 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3243 Spec = SD->getSpecializationKind();
3252 if ((DebugKind == llvm::codegenoptions::DebugInfoConstructor) &&
3263 CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
3264 llvm::DIType *T = getTypeOrNull(Ty);
3265 if (T && T->isForwardDecl())
3269llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
3270 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3271 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
3275 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
3279 auto [Def, Pref] = CreateTypeDefinition(Ty);
3281 return Pref ? Pref : Def;
3284llvm::DIType *CGDebugInfo::GetPreferredNameType(
const CXXRecordDecl *RD,
3285 llvm::DIFile *Unit) {
3289 auto const *PNA = RD->
getAttr<PreferredNameAttr>();
3293 return getOrCreateType(PNA->getTypedefType(), Unit);
3296std::pair<llvm::DIType *, llvm::DIType *>
3297CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
3298 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
3301 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
3309 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty);
3313 return {FwdDecl,
nullptr};
3315 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
3316 CollectContainingType(CXXDecl, FwdDecl);
3319 LexicalBlockStack.emplace_back(&*FwdDecl);
3320 RegionMap[RD].reset(FwdDecl);
3323 SmallVector<llvm::Metadata *, 16> EltTys;
3330 const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
3332 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
3333 CollectVTableInfo(CXXDecl, DefUnit, EltTys);
3337 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
3338 if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
3339 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
3341 LexicalBlockStack.pop_back();
3342 RegionMap.erase(RD);
3344 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3345 DBuilder.replaceArrays(FwdDecl, Elements);
3347 if (FwdDecl->isTemporary())
3349 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
3351 RegionMap[RD].reset(FwdDecl);
3353 if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
3354 if (
auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
3355 return {FwdDecl, PrefDI};
3357 return {FwdDecl,
nullptr};
3360llvm::DIType *CGDebugInfo::CreateType(
const ObjCObjectType *Ty,
3361 llvm::DIFile *Unit) {
3363 return getOrCreateType(Ty->getBaseType(), Unit);
3366llvm::DIType *CGDebugInfo::CreateType(
const ObjCTypeParamType *Ty,
3367 llvm::DIFile *Unit) {
3369 SourceLocation Loc = Ty->getDecl()->getLocation();
3372 return DBuilder.createTypedef(
3373 getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
3374 Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
3375 getDeclContextDescriptor(Ty->getDecl()));
3402llvm::DIType *CGDebugInfo::CreateType(
const ObjCInterfaceType *Ty,
3403 llvm::DIFile *Unit) {
3408 auto RuntimeLang =
static_cast<llvm::dwarf::SourceLanguage
>(
3409 TheCU->getSourceLanguage().getUnversionedName());
3414 if (DebugTypeExtRefs &&
ID->isFromASTFile() &&
ID->getDefinition() &&
3415 !
ID->getImplementation())
3416 return DBuilder.createForwardDecl(
3417 llvm::dwarf::DW_TAG_structure_type,
ID->getName(),
3418 getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
3421 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3422 unsigned Line = getLineNumber(
ID->getLocation());
3426 ObjCInterfaceDecl *Def =
ID->getDefinition();
3428 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3429 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
3430 llvm::dwarf::DW_TAG_structure_type,
ID->getName(), Mod ? Mod : TheCU,
3431 DefUnit,
Line, RuntimeLang);
3432 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
3436 return CreateTypeDefinition(Ty, Unit);
3439llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
3440 bool CreateSkeletonCU) {
3445 auto ModRef = ModuleCache.find(M);
3446 if (ModRef != ModuleCache.end())
3450 SmallString<128> ConfigMacros;
3452 llvm::raw_svector_ostream
OS(ConfigMacros);
3453 const auto &PPOpts = CGM.getPreprocessorOpts();
3456 for (
auto &M : PPOpts.Macros) {
3459 const std::string &
Macro = M.first;
3460 bool Undef = M.second;
3461 OS <<
"\"-" << (Undef ?
'U' :
'D');
3477 bool IsRootModule = M ? !M->
Parent :
true;
3481 if (CreateSkeletonCU && IsRootModule && Mod.
getASTFile().empty() && M)
3482 assert(StringRef(M->
Name).starts_with(CGM.getLangOpts().ModuleName) &&
3483 "clang module without ASTFile must be specified by -fmodule-name");
3486 auto RemapPath = [
this](StringRef Path) -> std::string {
3488 StringRef Relative(Remapped);
3489 StringRef CompDir = TheCU->getDirectory();
3490 if (CompDir.empty())
3493 if (Relative.consume_front(CompDir))
3494 Relative.consume_front(llvm::sys::path::get_separator());
3496 return Relative.str();
3499 if (CreateSkeletonCU && IsRootModule && !Mod.
getASTFile().empty()) {
3506 Signature = ModSig.truncatedValue();
3510 llvm::DIBuilder DIB(CGM.getModule());
3512 if (!llvm::sys::path::is_absolute(Mod.
getASTFile())) {
3513 if (CGM.getHeaderSearchOpts().ModuleFileHomeIsCwd)
3514 PCM = getCurrentDirname();
3518 llvm::sys::path::append(PCM, Mod.
getASTFile());
3519 DIB.createCompileUnit(
3520 TheCU->getSourceLanguage(),
3523 TheCU->getProducer(),
false, StringRef(), 0, RemapPath(PCM),
3524 llvm::DICompileUnit::FullDebug, Signature);
3528 llvm::DIModule *Parent =
3530 : getOrCreateModuleRef(ASTSourceDescriptor(*M->
Parent),
3532 std::string IncludePath = Mod.
getPath().str();
3533 llvm::DIModule *DIMod =
3534 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
3535 RemapPath(IncludePath));
3536 ModuleCache[M].reset(DIMod);
3540llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const ObjCInterfaceType *Ty,
3541 llvm::DIFile *Unit) {
3543 llvm::DIFile *DefUnit = getOrCreateFile(
ID->getLocation());
3544 unsigned Line = getLineNumber(
ID->getLocation());
3546 unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
3552 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3553 if (
ID->getImplementation())
3554 Flags |= llvm::DINode::FlagObjcClassComplete;
3556 llvm::DIScope *Mod = getParentModuleOrNull(ID);
3557 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
3558 Mod ? Mod : Unit,
ID->getName(), DefUnit,
Line, Size, Align, Flags,
3559 nullptr, llvm::DINodeArray(), RuntimeLang);
3561 QualType QTy(Ty, 0);
3562 TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
3565 LexicalBlockStack.emplace_back(RealDecl);
3566 RegionMap[Ty->
getDecl()].reset(RealDecl);
3569 SmallVector<llvm::Metadata *, 16> EltTys;
3571 ObjCInterfaceDecl *SClass =
ID->getSuperClass();
3573 llvm::DIType *SClassTy =
3574 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
3578 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
3579 llvm::DINode::FlagZero);
3580 EltTys.push_back(InhTag);
3584 auto AddProperty = [&](
const ObjCPropertyDecl *PD) {
3585 SourceLocation Loc = PD->getLocation();
3586 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3587 unsigned PLine = getLineNumber(Loc);
3588 ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
3589 ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
3590 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
3591 PD->getName(), PUnit, PLine,
3593 : getSelectorName(PD->getGetterName()),
3595 : getSelectorName(PD->getSetterName()),
3596 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
3597 EltTys.push_back(PropertyNode);
3602 typedef std::pair<char, const IdentifierInfo *> IsClassAndIdent;
3606 llvm::DenseSet<IsClassAndIdent> PropertySet;
3608 auto GetIsClassAndIdent = [](
const ObjCPropertyDecl *PD) {
3609 return std::make_pair(PD->isClassProperty(), PD->getIdentifier());
3611 for (
const ObjCCategoryDecl *ClassExt :
ID->known_extensions())
3612 for (
auto *PD : ClassExt->properties()) {
3613 PropertySet.insert(GetIsClassAndIdent(PD));
3616 for (
const auto *PD :
ID->properties()) {
3619 if (!PropertySet.insert(GetIsClassAndIdent(PD)).second)
3625 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
3626 unsigned FieldNo = 0;
3627 for (ObjCIvarDecl *Field =
ID->all_declared_ivar_begin(); Field;
3628 Field =
Field->getNextIvar(), ++FieldNo) {
3629 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
3633 StringRef FieldName =
Field->getName();
3636 if (FieldName.empty())
3640 llvm::DIFile *FieldDefUnit = getOrCreateFile(
Field->getLocation());
3641 unsigned FieldLine = getLineNumber(
Field->getLocation());
3642 QualType FType =
Field->getType();
3649 FieldSize =
Field->isBitField() ?
Field->getBitWidthValue()
3650 : CGM.getContext().getTypeSize(FType);
3655 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
3659 if (
Field->isBitField()) {
3661 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
3662 FieldOffset %= CGM.getContext().getCharWidth();
3670 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3672 Flags = llvm::DINode::FlagProtected;
3674 Flags = llvm::DINode::FlagPrivate;
3676 Flags = llvm::DINode::FlagPublic;
3678 if (
Field->isBitField())
3679 Flags |= llvm::DINode::FlagBitField;
3681 llvm::MDNode *PropertyNode =
nullptr;
3682 if (ObjCImplementationDecl *ImpD =
ID->getImplementation()) {
3683 if (ObjCPropertyImplDecl *PImpD =
3684 ImpD->FindPropertyImplIvarDecl(
Field->getIdentifier())) {
3685 if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
3686 SourceLocation Loc = PD->getLocation();
3687 llvm::DIFile *PUnit = getOrCreateFile(Loc);
3688 unsigned PLine = getLineNumber(Loc);
3689 ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
3690 ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
3691 PropertyNode = DBuilder.createObjCProperty(
3692 PD->getName(), PUnit, PLine,
3695 : getSelectorName(PD->getGetterName()),
3698 : getSelectorName(PD->getSetterName()),
3699 PD->getPropertyAttributes(),
3700 getOrCreateType(PD->getType(), PUnit));
3704 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
3705 FieldSize, FieldAlign, FieldOffset, Flags,
3706 FieldTy, PropertyNode);
3707 EltTys.push_back(FieldTy);
3710 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3711 DBuilder.replaceArrays(RealDecl, Elements);
3713 LexicalBlockStack.pop_back();
3717llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
3718 llvm::DIFile *Unit) {
3726 auto &Ctx = CGM.getContext();
3731 QualType CharVecTy =
3733 return CreateType(CharVecTy->
getAs<VectorType>(), Unit);
3736 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3739 llvm::Metadata *Subscript;
3740 QualType QTy(Ty, 0);
3741 auto SizeExpr = SizeExprCache.find(QTy);
3742 if (SizeExpr != SizeExprCache.end())
3743 Subscript = DBuilder.getOrCreateSubrange(
3744 SizeExpr->getSecond() ,
nullptr ,
3745 nullptr ,
nullptr );
3748 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3749 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count ? Count : -1));
3750 Subscript = DBuilder.getOrCreateSubrange(
3751 CountNode ,
nullptr ,
nullptr ,
3754 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
3759 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
3762llvm::DIType *CGDebugInfo::CreateType(
const ConstantMatrixType *Ty,
3763 llvm::DIFile *Unit) {
3767 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
3772 llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
3773 auto *ColumnCountNode =
3774 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3775 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumColumns()));
3776 auto *RowCountNode =
3777 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3778 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Ty->
getNumRows()));
3779 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3780 ColumnCountNode ,
nullptr ,
nullptr ,
3782 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3783 RowCountNode ,
nullptr ,
nullptr ,
3785 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3786 return DBuilder.createArrayType(Size, Align, ElementTy, SubscriptArray);
3789llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
3794 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3809 Size = CGM.getContext().getTypeSize(Ty);
3816 SmallVector<llvm::Metadata *, 8> Subscripts;
3817 QualType EltTy(Ty, 0);
3818 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
3827 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
3828 Count = CAT->getZExtSize();
3829 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
3830 if (Expr *Size = VAT->getSizeExpr()) {
3832 if (
Size->EvaluateAsInt(
Result, CGM.getContext()))
3833 Count =
Result.Val.getInt().getExtValue();
3837 auto SizeNode = SizeExprCache.find(EltTy);
3838 if (SizeNode != SizeExprCache.end())
3839 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3840 SizeNode->getSecond() ,
nullptr ,
3841 nullptr ,
nullptr ));
3844 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
3845 llvm::Type::getInt64Ty(CGM.getLLVMContext()), Count));
3846 Subscripts.push_back(DBuilder.getOrCreateSubrange(
3847 CountNode ,
nullptr ,
nullptr ,
3853 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
3855 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
3859llvm::DIType *CGDebugInfo::CreateType(
const LValueReferenceType *Ty,
3860 llvm::DIFile *Unit) {
3861 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
3865llvm::DIType *CGDebugInfo::CreateType(
const RValueReferenceType *Ty,
3866 llvm::DIFile *Unit) {
3867 llvm::dwarf::Tag
Tag = llvm::dwarf::DW_TAG_rvalue_reference_type;
3869 if (CGM.getCodeGenOpts().DebugStrictDwarf &&
3870 CGM.getCodeGenOpts().DwarfVersion < 4)
3871 Tag = llvm::dwarf::DW_TAG_reference_type;
3873 return CreatePointerLikeType(Tag, Ty, Ty->
getPointeeType(), Unit);
3876llvm::DIType *CGDebugInfo::CreateType(
const MemberPointerType *Ty,
3878 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3882 Size = CGM.getContext().getTypeSize(Ty);
3885 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
3888 Flags |= llvm::DINode::FlagSingleInheritance;
3891 Flags |= llvm::DINode::FlagMultipleInheritance;
3894 Flags |= llvm::DINode::FlagVirtualInheritance;
3904 llvm::DIType *ClassType = getOrCreateType(T, U);
3906 return DBuilder.createMemberPointerType(
3910 const FunctionProtoType *FPT =
3912 return DBuilder.createMemberPointerType(
3913 getOrCreateInstanceMethodType(
3916 ClassType, Size, 0, Flags);
3919llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
3921 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
3924llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
3928llvm::DIType *CGDebugInfo::CreateType(
const HLSLAttributedResourceType *Ty,
3930 return getOrCreateType(Ty->getWrappedType(), U);
3933llvm::DIType *CGDebugInfo::CreateType(
const HLSLInlineSpirvType *Ty,
3940 const EnumType *Ty) {
3952llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
3955 bool isImportedFromModule =
3956 DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
3960 if (isImportedFromModule || !ED->getDefinition()) {
3967 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
3968 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
3969 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
3970 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
3972 unsigned Line = getLineNumber(ED->getLocation());
3973 StringRef EDName = ED->getName();
3974 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
3975 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit,
Line,
3976 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
3978 ReplaceMap.emplace_back(
3979 std::piecewise_construct, std::make_tuple(Ty),
3980 std::make_tuple(
static_cast<llvm::Metadata *
>(RetTy)));
3984 return CreateTypeDefinition(Ty);
3987llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
3990 SmallVector<llvm::Metadata *, 16> Enumerators;
3991 ED = ED->getDefinition();
3992 assert(ED &&
"An enumeration definition is required");
3993 for (
const auto *
Enum : ED->enumerators()) {
3994 Enumerators.push_back(
3995 DBuilder.createEnumerator(
Enum->getName(),
Enum->getInitVal()));
3998 std::optional<EnumExtensibilityAttr::Kind> EnumKind;
3999 if (
auto *Attr = ED->getAttr<EnumExtensibilityAttr>())
4000 EnumKind = Attr->getExtensibility();
4003 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
4005 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
4006 unsigned Line = getLineNumber(ED->getLocation());
4007 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
4008 llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
4009 return DBuilder.createEnumerationType(
4010 EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
4011 0, Identifier, ED->isScoped(), EnumKind);
4016 StringRef Name, StringRef
Value) {
4017 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4018 return DBuilder.createMacro(Parent,
Line, MType, Name,
Value);
4024 llvm::DIFile *FName = getOrCreateFile(FileLoc);
4025 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
4026 return DBuilder.createTempMacroFile(Parent,
Line, FName);
4031 llvm::DISubprogram *SynthSubprogram) {
4032 return llvm::DILocation::get(CGM.getLLVMContext(), 0, 0,
4033 SynthSubprogram, ParentLocation);
4038 StringRef SynthFuncName,
4039 llvm::DIFile *SynthFile) {
4040 llvm::DISubprogram *SP = createInlinedSubprogram(SynthFuncName, SynthFile);
4045 llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
4051 FuncName += Category;
4053 FuncName += FailureMsg;
4056 TrapLocation->getFile());
4062 Qualifiers InnerQuals = T.getLocalQualifiers();
4066 Quals += InnerQuals;
4068 switch (T->getTypeClass()) {
4070 return C.getQualifiedType(T.getTypePtr(), Quals);
4073 case Type::InjectedClassName:
4074 return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
4076 case Type::TemplateSpecialization: {
4078 if (Spec->isTypeAlias())
4079 return C.getQualifiedType(T.getTypePtr(), Quals);
4080 T = Spec->desugar();
4083 case Type::TypeOfExpr:
4089 case Type::Decltype:
4092 case Type::UnaryTransform:
4095 case Type::Attributed:
4098 case Type::BTFTagAttributed:
4101 case Type::CountAttributed:
4110 case Type::MacroQualified:
4113 case Type::SubstTemplateTypeParm:
4117 case Type::DeducedTemplateSpecialization: {
4119 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
4123 case Type::PackIndexing: {
4127 case Type::Adjusted:
4134 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
4139llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
4142 if (It != TypeCache.end()) {
4144 if (llvm::Metadata *
V = It->second)
4157 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly ||
4164 RetainedTypes.push_back(
4165 CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
4168llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
4172 llvm::TimeTraceScope TimeScope(
"DebugType", [&]() {
4174 llvm::raw_string_ostream OS(Name);
4175 Ty.
print(OS, getPrintingPolicy());
4182 if (
auto *T = getTypeOrNull(Ty))
4185 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
4186 void *TyPtr = Ty.getAsOpaquePtr();
4189 TypeCache[TyPtr].reset(Res);
4194llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
4202 auto Info = Reader->getSourceDescriptor(Idx);
4204 return getOrCreateModuleRef(*Info,
true);
4205 }
else if (ClangModuleMap) {
4218 auto Info = ASTSourceDescriptor(*M);
4219 return getOrCreateModuleRef(Info,
false);
4222 return getOrCreateModuleRef(PCHDescriptor,
false);
4229llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
4232 return CreateQualifiedType(Ty, Unit);
4236#define TYPE(Class, Base)
4237#define ABSTRACT_TYPE(Class, Base)
4238#define NON_CANONICAL_TYPE(Class, Base)
4239#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4240#include "clang/AST/TypeNodes.inc"
4241 llvm_unreachable(
"Dependent types cannot show up in debug information");
4243 case Type::ExtVector:
4246 case Type::ConstantMatrix:
4248 case Type::ObjCObjectPointer:
4250 case Type::ObjCObject:
4252 case Type::ObjCTypeParam:
4254 case Type::ObjCInterface:
4262 case Type::BlockPointer:
4270 case Type::FunctionProto:
4271 case Type::FunctionNoProto:
4273 case Type::ConstantArray:
4274 case Type::VariableArray:
4275 case Type::IncompleteArray:
4276 case Type::ArrayParameter:
4279 case Type::LValueReference:
4281 case Type::RValueReference:
4284 case Type::MemberPointer:
4292 case Type::OverflowBehavior:
4297 case Type::TemplateSpecialization:
4299 case Type::HLSLAttributedResource:
4301 case Type::HLSLInlineSpirv:
4303 case Type::PredefinedSugar:
4305 case Type::CountAttributed:
4307 case Type::Attributed:
4308 case Type::BTFTagAttributed:
4309 case Type::Adjusted:
4311 case Type::DeducedTemplateSpecialization:
4314 case Type::MacroQualified:
4315 case Type::SubstTemplateTypeParm:
4316 case Type::TypeOfExpr:
4318 case Type::Decltype:
4319 case Type::PackIndexing:
4320 case Type::UnaryTransform:
4324 llvm_unreachable(
"type should have been unwrapped!");
4327llvm::DICompositeType *
4328CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty) {
4329 QualType QTy(Ty, 0);
4331 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
4336 if (T && !T->isForwardDecl())
4340 llvm::DICompositeType *Res = CreateLimitedType(Ty);
4345 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
4348 TypeCache[QTy.getAsOpaquePtr()].reset(Res);
4353llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
4354 RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
4355 bool NameIsSimplified =
false;
4358 StringRef RDName = getClassName(RD, &NameIsSimplified);
4360 llvm::DIFile *DefUnit =
nullptr;
4363 DefUnit = getOrCreateFile(Loc);
4364 Line = getLineNumber(Loc);
4367 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
4371 auto *T = cast_or_null<llvm::DICompositeType>(
4372 getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
4380 return getOrCreateRecordFwdDecl(Ty, RDContext);
4393 auto Flags = llvm::DINode::FlagZero;
4394 if (NameIsSimplified)
4395 Flags |= llvm::DINode::FlagNameIsSimplified;
4396 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4398 Flags |= llvm::DINode::FlagTypePassByReference;
4400 Flags |= llvm::DINode::FlagTypePassByValue;
4403 if (!CXXRD->isTrivial())
4404 Flags |= llvm::DINode::FlagNonTrivial;
4407 if (CXXRD->isAnonymousStructOrUnion())
4408 Flags |= llvm::DINode::FlagExportSymbols;
4411 dyn_cast<CXXRecordDecl>(CXXRD->getDeclContext()));
4414 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
4415 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
4417 Flags, Identifier, Annotations);
4421 switch (RealDecl->getTag()) {
4423 llvm_unreachable(
"invalid composite type tag");
4425 case llvm::dwarf::DW_TAG_array_type:
4426 case llvm::dwarf::DW_TAG_enumeration_type:
4431 if (Identifier.empty())
4435 case llvm::dwarf::DW_TAG_structure_type:
4436 case llvm::dwarf::DW_TAG_union_type:
4437 case llvm::dwarf::DW_TAG_class_type:
4440 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
4444 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
4445 CXXRecordDecl *TemplateDecl =
4446 CTSD->getSpecializedTemplate()->getTemplatedDecl();
4447 RegionMap[TemplateDecl].reset(RealDecl);
4449 RegionMap[RD].reset(RealDecl);
4451 TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
4453 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4454 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
4455 CollectCXXTemplateParams(TSpecial, DefUnit));
4459void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
4460 llvm::DICompositeType *RealDecl) {
4462 llvm::DIType *ContainingType =
nullptr;
4463 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4467 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
4474 CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
4475 ContainingType = getOrCreateType(T, getOrCreateFile(RD->
getLocation()));
4477 ContainingType = RealDecl;
4479 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
4482llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
4483 StringRef Name, uint64_t *Offset) {
4484 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
4485 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
4488 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
4489 *Offset, llvm::DINode::FlagZero, FieldTy);
4490 *Offset += FieldSize;
4494void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
4496 StringRef &LinkageName,
4497 llvm::DIScope *&FDContext,
4498 llvm::DINodeArray &TParamsArray,
4499 llvm::DINode::DIFlags &Flags) {
4501 bool NameIsSimplified =
false;
4502 Name = getFunctionName(FD, &NameIsSimplified);
4503 if (NameIsSimplified)
4504 Flags |= llvm::DINode::FlagNameIsSimplified;
4505 Name = getFunctionName(FD);
4508 LinkageName = CGM.getMangledName(GD);
4510 Flags |= llvm::DINode::FlagPrototyped;
4514 if (LinkageName == Name ||
4515 (CGM.getCodeGenOpts().CoverageNotesFile.empty() &&
4516 CGM.getCodeGenOpts().CoverageDataFile.empty() &&
4517 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
4518 !CGM.getCodeGenOpts().PseudoProbeForProfiling &&
4519 DebugKind <= llvm::codegenoptions::DebugLineTablesOnly))
4520 LinkageName = StringRef();
4524 if (CGM.getCodeGenOpts().hasReducedDebugInfo() ||
4525 (DebugKind == llvm::codegenoptions::DebugLineTablesOnly &&
4526 CGM.getCodeGenOpts().EmitCodeView)) {
4527 if (
const NamespaceDecl *NSDecl =
4529 FDContext = getOrCreateNamespace(NSDecl);
4530 else if (
const RecordDecl *RDecl =
4532 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
4533 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
4536 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
4539 Flags |= llvm::DINode::FlagNoReturn;
4541 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
4545void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
4546 unsigned &LineNo, QualType &T,
4547 StringRef &Name, StringRef &LinkageName,
4548 llvm::MDTuple *&TemplateParameters,
4549 llvm::DIScope *&VDContext) {
4558 llvm::APInt ConstVal(32, 1);
4559 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
4561 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
nullptr,
4568 LinkageName = CGM.getMangledName(VD);
4569 if (LinkageName == Name)
4570 LinkageName = StringRef();
4573 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
4574 TemplateParameters = parameterNodes.get();
4576 TemplateParameters =
nullptr;
4594 DC = CGM.getContext().getTranslationUnitDecl();
4596 llvm::DIScope *Mod = getParentModuleOrNull(VD);
4597 VDContext = getContextDescriptor(
cast<Decl>(DC), Mod ? Mod : TheCU);
4600llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
4602 llvm::DINodeArray TParamsArray;
4603 StringRef Name, LinkageName;
4604 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4605 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4607 llvm::DIFile *Unit = getOrCreateFile(Loc);
4608 llvm::DIScope *DContext = Unit;
4609 unsigned Line = getLineNumber(Loc);
4610 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
4615 SmallVector<QualType, 16> ArgTypes;
4616 for (
const ParmVarDecl *Parm : FD->
parameters())
4617 ArgTypes.push_back(Parm->getType());
4620 QualType FnType = CGM.getContext().getFunctionType(
4621 FD->
getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
4623 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4624 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4625 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4629 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
4630 return DBuilder.createFunction(
4631 DContext, Name, LinkageName, Unit,
Line,
4632 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4633 TParamsArray.get(), getFunctionDeclaration(FD),
nullptr,
4635 CGM.getCodeGenOpts().DebugKeyInstructions);
4638 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
4639 DContext, Name, LinkageName, Unit,
Line,
4640 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
4641 TParamsArray.get(), getFunctionDeclaration(FD));
4643 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
4644 std::make_tuple(CanonDecl),
4645 std::make_tuple(SP));
4649llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
4650 return getFunctionFwdDeclOrStub(GD,
false);
4653llvm::DISubprogram *CGDebugInfo::getFunctionStub(GlobalDecl GD) {
4654 return getFunctionFwdDeclOrStub(GD,
true);
4657llvm::DIGlobalVariable *
4658CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
4660 StringRef Name, LinkageName;
4662 llvm::DIFile *Unit = getOrCreateFile(Loc);
4663 llvm::DIScope *DContext = Unit;
4664 unsigned Line = getLineNumber(Loc);
4665 llvm::MDTuple *TemplateParameters =
nullptr;
4667 collectVarDeclProps(VD, Unit,
Line, T, Name, LinkageName, TemplateParameters,
4670 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
4671 DContext, Name, LinkageName, Unit,
Line, getOrCreateType(T, Unit),
4673 FwdDeclReplaceMap.emplace_back(
4674 std::piecewise_construct,
4676 std::make_tuple(
static_cast<llvm::Metadata *
>(GV)));
4680llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
4685 if (
const auto *TD = dyn_cast<TypeDecl>(D)) {
4686 QualType Ty = CGM.getContext().getTypeDeclType(TD);
4687 return getOrCreateType(Ty, getOrCreateFile(TD->
getLocation()));
4691 if (I != DeclCache.end()) {
4693 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
4694 return GVE->getVariable();
4702 if (IE != ImportedDeclCache.end()) {
4703 auto N = IE->second;
4704 if (
auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
4706 return dyn_cast_or_null<llvm::DINode>(N);
4711 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4712 return getFunctionForwardDeclaration(FD);
4713 else if (
const auto *VD = dyn_cast<VarDecl>(D))
4714 return getGlobalVariableForwardDeclaration(VD);
4719llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
4720 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4723 const auto *FD = dyn_cast<FunctionDecl>(D);
4728 auto *S = getDeclContextDescriptor(D);
4731 if (MI == SPCache.end()) {
4733 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
4737 if (MI != SPCache.end()) {
4738 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4739 if (SP && !SP->isDefinition())
4743 for (
auto *NextFD : FD->
redecls()) {
4744 auto MI = SPCache.find(NextFD->getCanonicalDecl());
4745 if (MI != SPCache.end()) {
4746 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
4747 if (SP && !SP->isDefinition())
4754llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
4755 const Decl *D, llvm::DISubroutineType *FnType,
unsigned LineNo,
4756 llvm::DINode::DIFlags Flags, llvm::DISubprogram::DISPFlags SPFlags) {
4757 if (!D || DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
4760 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
4764 if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->
isDirectMethod())
4768 SPFlags |= llvm::DISubprogram::SPFlagObjCDirect;
4777 QualType QTy(
ID->getTypeForDecl(), 0);
4778 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4779 if (It == TypeCache.end())
4782 llvm::DISubprogram *FD = DBuilder.createFunction(
4783 InterfaceType, getObjCMethodName(OMD), StringRef(),
4784 InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
4785 DBuilder.finalizeSubprogram(FD);
4792llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
4797 if (!D || (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly &&
4798 !CGM.getCodeGenOpts().EmitCodeView))
4801 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
4803 if (
const auto *
Method = dyn_cast<CXXDestructorDecl>(D)) {
4806 return getOrCreateMethodTypeForDestructor(
Method, F, FnType);
4809 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(D))
4810 return getOrCreateMethodType(
Method, F);
4812 const auto *FTy = FnType->
getAs<FunctionType>();
4815 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
4817 SmallVector<llvm::Metadata *, 16> Elts;
4820 QualType ResultTy = OMethod->getReturnType();
4823 if (ResultTy == CGM.getContext().getObjCInstanceType())
4824 ResultTy = CGM.getContext().getPointerType(
4825 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
4827 Elts.push_back(getOrCreateType(ResultTy, F));
4829 QualType SelfDeclTy;
4830 if (
auto *SelfDecl = OMethod->getSelfDecl())
4831 SelfDeclTy = SelfDecl->getType();
4832 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4835 if (!SelfDeclTy.
isNull())
4837 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
4839 Elts.push_back(DBuilder.createArtificialType(
4840 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
4842 for (
const auto *PI : OMethod->parameters())
4843 Elts.push_back(getOrCreateType(PI->getType(), F));
4845 if (OMethod->isVariadic())
4846 Elts.push_back(DBuilder.createUnspecifiedParameter());
4848 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
4849 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4855 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
4856 if (FD->isVariadic()) {
4857 SmallVector<llvm::Metadata *, 16> EltTys;
4858 EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
4859 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
4861 EltTys.push_back(getOrCreateType(ParamType, F));
4862 EltTys.push_back(DBuilder.createUnspecifiedParameter());
4863 llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
4864 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
4877 CC = SrcFnTy->getCallConv();
4879 for (
const VarDecl *VD : Args)
4880 ArgTypes.push_back(VD->
getType());
4881 return CGM.getContext().getFunctionType(RetTy, ArgTypes,
4887 llvm::Function *Fn,
bool CurFuncIsThunk) {
4889 StringRef LinkageName;
4891 FnBeginRegionCount.push_back(LexicalBlockStack.size());
4894 bool HasDecl = (D !=
nullptr);
4896 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
4897 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
4898 llvm::DIFile *Unit = getOrCreateFile(Loc);
4899 llvm::DIScope *FDContext = Unit;
4900 llvm::DINodeArray TParamsArray;
4901 bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
4904 LinkageName = Fn->getName();
4905 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
4907 auto FI = SPCache.find(FD->getCanonicalDecl());
4908 if (FI != SPCache.end()) {
4909 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
4910 if (SP && SP->isDefinition()) {
4911 LexicalBlockStack.emplace_back(SP);
4912 RegionMap[D].reset(SP);
4916 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
4917 TParamsArray, Flags);
4920 KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
4921 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
4922 Name = getObjCMethodName(OMD);
4923 Flags |= llvm::DINode::FlagPrototyped;
4929 if (Name != Fn->getName())
4930 LinkageName = Fn->getName();
4932 Name = Fn->getName();
4937 Flags |= llvm::DINode::FlagPrototyped;
4939 Name.consume_front(
"\01");
4943 "Unexpected DynamicInitKind !");
4947 Flags |= llvm::DINode::FlagArtificial;
4953 Flags |= llvm::DINode::FlagThunk;
4955 if (Fn->hasLocalLinkage())
4956 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
4957 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
4958 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4961 llvm::DISubprogram::DISPFlags SPFlagsForDef =
4962 SPFlags | llvm::DISubprogram::SPFlagDefinition;
4964 const unsigned LineNo = getLineNumber(Loc.
isValid() ? Loc : CurLoc);
4965 unsigned ScopeLine = getLineNumber(ScopeLoc);
4966 llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
4967 llvm::DISubprogram *
Decl =
nullptr;
4968 llvm::DINodeArray Annotations =
nullptr;
4971 ? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
4972 : getFunctionDeclaration(D);
4973 Annotations = CollectBTFDeclTagAnnotations(D);
4981 llvm::DISubprogram *SP = DBuilder.createFunction(
4982 FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
4983 FlagsForDef, SPFlagsForDef, TParamsArray.get(),
Decl,
nullptr,
4984 Annotations,
"", KeyInstructions);
4985 Fn->setSubprogram(SP);
4994 LexicalBlockStack.emplace_back(SP);
4997 RegionMap[D].reset(SP);
5001 QualType FnType, llvm::Function *Fn) {
5003 StringRef LinkageName;
5009 llvm::TimeTraceScope TimeScope(
"DebugFunction", [&]() {
5010 return GetName(D,
true);
5013 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5014 llvm::DIFile *Unit = getOrCreateFile(Loc);
5015 bool IsDeclForCallSite = Fn ?
true :
false;
5016 llvm::DIScope *FDContext =
5017 IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
5018 llvm::DINodeArray TParamsArray;
5021 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
5022 TParamsArray, Flags);
5023 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
5024 Name = getObjCMethodName(OMD);
5025 Flags |= llvm::DINode::FlagPrototyped;
5027 llvm_unreachable(
"not a function or ObjC method");
5029 Name.consume_front(
"\01");
5032 Flags |= llvm::DINode::FlagArtificial;
5037 unsigned LineNo = getLineNumber(Loc);
5038 unsigned ScopeLine = 0;
5039 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
5040 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
5041 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
5043 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
5044 llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
5046 assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
5047 llvm::DISubprogram *SP = DBuilder.createFunction(
5048 FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
5049 SPFlags, TParamsArray.get(),
nullptr,
nullptr, Annotations,
5055 if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
5056 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
5057 llvm::DITypeArray ParamTypes = STy->getTypeArray();
5060 llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
5061 DBuilder.createParameterVariable(
5062 SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo],
true,
5063 llvm::DINode::FlagZero, ParamAnnotations);
5069 if (IsDeclForCallSite)
5070 Fn->setSubprogram(SP);
5074 llvm::CallBase *CI) {
5075 if (!shouldGenerateVirtualCallSite())
5081 assert(CI &&
"Invalid Call Instruction.");
5082 if (!CI->isIndirectCall())
5086 if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
5087 CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
5095 auto *
Func = dyn_cast<llvm::Function>(CallOrInvoke->getCalledOperand());
5098 if (
Func->getSubprogram())
5106 if (CalleeDecl->
hasAttr<NoDebugAttr>() ||
5121 auto FI = SPCache.find(FD->getCanonicalDecl());
5122 llvm::DISubprogram *SP =
nullptr;
5123 if (FI != SPCache.end())
5124 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
5125 if (!SP || !SP->isDefinition())
5126 SP = getFunctionStub(GD);
5127 FnBeginRegionCount.push_back(LexicalBlockStack.size());
5128 LexicalBlockStack.emplace_back(SP);
5134 assert(CurInlinedAt &&
"unbalanced inline scope stack");
5143 if (CurLoc.isInvalid() ||
5144 (CGM.getCodeGenOpts().DebugInfoMacroExpansionLoc && CurLoc.isMacroID()) ||
5145 LexicalBlockStack.empty())
5148 llvm::MDNode *
Scope = LexicalBlockStack.back();
5149 Builder.SetCurrentDebugLocation(
5150 llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
5151 getColumnNumber(CurLoc),
Scope, CurInlinedAt));
5155 llvm::MDNode *Back =
nullptr;
5156 if (!LexicalBlockStack.empty())
5157 Back = LexicalBlockStack.back().get();
5158 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
5160 getColumnNumber(CurLoc)));
5163void CGDebugInfo::AppendAddressSpaceXDeref(
5165 std::optional<unsigned> DWARFAddressSpace =
5167 if (!DWARFAddressSpace)
5170 Expr.push_back(llvm::dwarf::DW_OP_constu);
5171 Expr.push_back(*DWARFAddressSpace);
5172 Expr.push_back(llvm::dwarf::DW_OP_swap);
5173 Expr.push_back(llvm::dwarf::DW_OP_xderef);
5182 Builder.SetCurrentDebugLocation(llvm::DILocation::get(
5183 CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
5184 LexicalBlockStack.back(), CurInlinedAt));
5186 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5190 CreateLexicalBlock(Loc);
5195 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5200 if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
5203 LexicalBlockStack.pop_back();
5207 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5208 unsigned RCount = FnBeginRegionCount.back();
5209 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
5212 while (LexicalBlockStack.size() != RCount) {
5215 LexicalBlockStack.pop_back();
5217 FnBeginRegionCount.pop_back();
5219 if (Fn && Fn->getSubprogram())
5220 DBuilder.finalizeSubprogram(Fn->getSubprogram());
5223CGDebugInfo::BlockByRefType
5224CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
5225 uint64_t *XOffset) {
5228 uint64_t FieldSize, FieldOffset;
5229 uint32_t FieldAlign;
5231 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5236 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
5237 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
5239 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
5240 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
5243 if (HasCopyAndDispose) {
5246 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
5248 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
5250 bool HasByrefExtendedLayout;
5253 HasByrefExtendedLayout) &&
5254 HasByrefExtendedLayout) {
5257 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
5266 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
5269 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
5272 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
5277 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
5278 FieldSize = CGM.getContext().getTypeSize(FType);
5279 FieldAlign = CGM.getContext().toBits(Align);
5281 *XOffset = FieldOffset;
5282 llvm::DIType *FieldTy = DBuilder.createMemberType(
5283 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
5284 llvm::DINode::FlagZero, WrappedTy);
5285 EltTys.push_back(FieldTy);
5286 FieldOffset += FieldSize;
5288 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
5289 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
5290 llvm::DINode::FlagZero,
nullptr, Elements),
5294llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
5295 llvm::Value *Storage,
5296 std::optional<unsigned> ArgNo,
5298 const bool UsePointerValue) {
5299 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5300 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5301 if (VD->
hasAttr<NoDebugAttr>())
5306 llvm::DIFile *Unit =
nullptr;
5307 if (!VarIsArtificial)
5311 if (VD->
hasAttr<BlocksAttr>())
5312 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5314 Ty = getOrCreateType(VD->
getType(), Unit);
5324 if (!VarIsArtificial) {
5328 SmallVector<uint64_t, 13> Expr;
5329 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
5336 Flags |= llvm::DINode::FlagArtificial;
5340 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(VD->
getType());
5341 AppendAddressSpaceXDeref(AddressSpace, Expr);
5345 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
5348 Flags |= llvm::DINode::FlagObjectPointer;
5349 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
5350 if (PVD->isExplicitObjectParameter())
5351 Flags |= llvm::DINode::FlagObjectPointer;
5359 StringRef Name = VD->
getName();
5360 if (!Name.empty()) {
5366 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5368 offset = CGM.getContext().toCharUnitsFromBits(
5371 Expr.push_back(llvm::dwarf::DW_OP_deref);
5372 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5374 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5377 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
5389 for (
const auto *Field : RD->
fields()) {
5390 llvm::DIType *FieldTy = getOrCreateType(
Field->getType(), Unit);
5391 StringRef FieldName =
Field->getName();
5399 auto *D = DBuilder.createAutoVariable(
5400 Scope, FieldName, Unit,
Line, FieldTy,
5401 CGM.getCodeGenOpts().OptimizationLevel != 0,
5402 Flags | llvm::DINode::FlagArtificial, FieldAlign);
5405 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5406 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5409 Builder.GetInsertBlock());
5417 if (UsePointerValue) {
5418 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5419 "Debug info already contains DW_OP_deref.");
5420 Expr.push_back(llvm::dwarf::DW_OP_deref);
5424 llvm::DILocalVariable *D =
nullptr;
5426 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
5427 D = DBuilder.createParameterVariable(
5428 Scope, Name, *ArgNo, Unit,
Line, Ty,
5429 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
5438 auto RemapCoroArgToLocalVar = [&]() -> llvm::DILocalVariable * {
5444 auto Iter = llvm::find_if(CoroutineParameterMappings, [&](
auto &Pair) {
5445 Stmt *StmtPtr =
const_cast<Stmt *
>(Pair.second);
5446 if (DeclStmt *DeclStmtPtr = dyn_cast<DeclStmt>(StmtPtr)) {
5447 DeclGroupRef DeclGroup = DeclStmtPtr->getDeclGroup();
5449 if (VD == dyn_cast_or_null<VarDecl>(
Decl))
5455 if (Iter != CoroutineParameterMappings.end()) {
5456 ParmVarDecl *PD =
const_cast<ParmVarDecl *
>(Iter->first);
5457 auto Iter2 = llvm::find_if(ParamDbgMappings, [&](
auto &DbgPair) {
5458 return DbgPair.first == PD && DbgPair.second->getScope() == Scope;
5460 if (Iter2 != ParamDbgMappings.end())
5461 return const_cast<llvm::DILocalVariable *
>(Iter2->second);
5467 D = RemapCoroArgToLocalVar();
5470 D = DBuilder.createAutoVariable(
5471 Scope, Name, Unit,
Line, Ty,
5472 CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
5475 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5476 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5477 Column, Scope, CurInlinedAt),
5478 Builder.GetInsertBlock());
5483llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const BindingDecl *BD,
5484 llvm::Value *Storage,
5485 std::optional<unsigned> ArgNo,
5487 const bool UsePointerValue) {
5488 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5489 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5490 if (BD->
hasAttr<NoDebugAttr>())
5497 llvm::DIFile *Unit = getOrCreateFile(BD->
getLocation());
5498 llvm::DIType *Ty = getOrCreateType(BD->
getType(), Unit);
5506 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(BD->
getType());
5508 SmallVector<uint64_t, 3> Expr;
5509 AppendAddressSpaceXDeref(AddressSpace, Expr);
5514 if (UsePointerValue) {
5515 assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) &&
5516 "Debug info already contains DW_OP_deref.");
5517 Expr.push_back(llvm::dwarf::DW_OP_deref);
5522 StringRef Name = BD->
getName();
5525 llvm::DILocalVariable *D = DBuilder.createAutoVariable(
5526 Scope, Name, Unit,
Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
5527 llvm::DINode::FlagZero, Align);
5529 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(BD->
getBinding())) {
5530 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
5531 const unsigned fieldIndex = FD->getFieldIndex();
5532 const clang::CXXRecordDecl *parent =
5533 (
const CXXRecordDecl *)FD->getParent();
5534 const ASTRecordLayout &layout =
5535 CGM.getContext().getASTRecordLayout(parent);
5537 if (FD->isBitField()) {
5538 const CGRecordLayout &RL =
5539 CGM.getTypes().getCGRecordLayout(FD->getParent());
5544 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5550 ? llvm::dwarf::DW_OP_LLVM_extract_bits_sext
5551 : llvm::dwarf::DW_OP_LLVM_extract_bits_zext);
5552 Expr.push_back(Info.
Offset);
5555 const uint64_t TypeSize = CGM.getContext().getTypeSize(BD->
getType());
5556 Expr.push_back(std::min((uint64_t)Info.
Size, TypeSize));
5557 }
else if (fieldOffset != 0) {
5558 assert(fieldOffset % CGM.getContext().getCharWidth() == 0 &&
5559 "Unexpected non-bitfield with non-byte-aligned offset");
5560 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5562 CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity());
5565 }
else if (
const ArraySubscriptExpr *ASE =
5566 dyn_cast<ArraySubscriptExpr>(BD->
getBinding())) {
5567 if (
const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
5568 const uint64_t value = IL->getValue().getZExtValue();
5569 const uint64_t typeSize = CGM.getContext().getTypeSize(BD->
getType());
5572 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5573 Expr.push_back(CGM.getContext()
5574 .toCharUnitsFromBits(value * typeSize)
5581 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
5582 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
5583 Column, Scope, CurInlinedAt),
5584 Builder.GetInsertBlock());
5589llvm::DILocalVariable *
5592 const bool UsePointerValue) {
5593 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5595 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5597 EmitDeclare(B, Storage, std::nullopt, Builder,
5604 return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
5608 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5609 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5611 if (D->
hasAttr<NoDebugAttr>())
5615 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
5621 StringRef Name = D->
getName();
5627 CGM.getCodeGenOpts().OptimizationLevel != 0);
5630 DBuilder.insertLabel(L,
5631 llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5632 Scope, CurInlinedAt),
5633 Builder.GetInsertBlock()->end());
5636llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
5638 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
5641 return DBuilder.createObjectPointerType(Ty,
true);
5646 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
5647 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5648 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
5650 if (Builder.GetInsertBlock() ==
nullptr)
5652 if (VD->
hasAttr<NoDebugAttr>())
5655 bool isByRef = VD->
hasAttr<BlocksAttr>();
5657 uint64_t XOffset = 0;
5658 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
5661 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
5663 Ty = getOrCreateType(VD->
getType(), Unit);
5667 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
5669 Ty = CreateSelfType(VD->
getType(), Ty);
5672 const unsigned Line =
5676 const llvm::DataLayout &target = CGM.getDataLayout();
5683 addr.push_back(llvm::dwarf::DW_OP_deref);
5684 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5687 addr.push_back(llvm::dwarf::DW_OP_deref);
5688 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5691 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
5693 addr.push_back(llvm::dwarf::DW_OP_deref);
5694 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
5696 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
5702 auto *D = DBuilder.createAutoVariable(
5704 Line, Ty,
false, llvm::DINode::FlagZero, Align);
5707 auto DL = llvm::DILocation::get(CGM.getLLVMContext(),
Line,
Column,
5708 LexicalBlockStack.back(), CurInlinedAt);
5709 auto *
Expr = DBuilder.createExpression(addr);
5711 DBuilder.insertDeclare(Storage, D,
Expr, DL, InsertPoint->getIterator());
5713 DBuilder.insertDeclare(Storage, D,
Expr, DL, Builder.GetInsertBlock());
5716llvm::DILocalVariable *
5719 bool UsePointerValue) {
5720 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5721 return EmitDeclare(VD, AI, ArgNo, Builder, UsePointerValue);
5725struct BlockLayoutChunk {
5726 uint64_t OffsetInBits;
5729bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
5730 return l.OffsetInBits < r.OffsetInBits;
5734void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
5736 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
5737 SmallVectorImpl<llvm::Metadata *> &Fields) {
5741 if (CGM.getLangOpts().OpenCL) {
5742 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
5743 BlockLayout.getElementOffsetInBits(0),
5745 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
5746 BlockLayout.getElementOffsetInBits(1),
5750 BlockLayout.getElementOffsetInBits(0),
5752 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
5753 BlockLayout.getElementOffsetInBits(1),
5757 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
5758 auto *FnTy =
Block.getBlockExpr()->getFunctionType();
5759 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
5760 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
5761 BlockLayout.getElementOffsetInBits(3),
5763 Fields.push_back(createFieldType(
5768 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
5775 llvm::AllocaInst *Alloca,
5777 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
5783 llvm::DIFile *tunit = getOrCreateFile(loc);
5784 unsigned line = getLineNumber(loc);
5785 unsigned column = getColumnNumber(loc);
5790 const llvm::StructLayout *blockLayout =
5794 collectDefaultFieldsForBlockLiteralDeclare(block,
C, loc, *blockLayout, tunit,
5803 BlockLayoutChunk chunk;
5804 chunk.OffsetInBits =
5805 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
5806 chunk.Capture =
nullptr;
5807 chunks.push_back(chunk);
5811 for (
const auto &capture :
blockDecl->captures()) {
5812 const VarDecl *variable = capture.getVariable();
5819 BlockLayoutChunk chunk;
5820 chunk.OffsetInBits =
5821 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
5822 chunk.Capture = &capture;
5823 chunks.push_back(chunk);
5827 llvm::array_pod_sort(chunks.begin(), chunks.end());
5829 for (
const BlockLayoutChunk &Chunk : chunks) {
5830 uint64_t offsetInBits = Chunk.OffsetInBits;
5837 cast_or_null<CXXMethodDecl>(
blockDecl->getNonClosureContext()))
5839 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(
blockDecl->getParent()))
5840 type = CGM.getContext().getCanonicalTagType(RDecl);
5842 llvm_unreachable(
"unexpected block declcontext");
5844 fields.push_back(createFieldType(
"this",
type, loc,
AS_public,
5845 offsetInBits, tunit, tunit));
5850 StringRef name = variable->
getName();
5852 llvm::DIType *fieldType;
5854 TypeInfo PtrInfo =
C.getTypeInfo(
C.VoidPtrTy);
5859 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
5860 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
5861 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
5862 PtrInfo.
Width, Align, offsetInBits,
5863 llvm::DINode::FlagZero, fieldType);
5867 offsetInBits, Align, tunit, tunit);
5869 fields.push_back(fieldType);
5873 llvm::raw_svector_ostream(typeName)
5874 <<
"__block_literal_" << CGM.getUniqueBlockCount();
5876 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
5878 llvm::DIType *
type =
5879 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
5880 CGM.getContext().toBits(block.
BlockSize), 0,
5881 llvm::DINode::FlagZero,
nullptr, fieldsArray);
5882 type = DBuilder.createPointerType(
type, CGM.PointerWidthInBits);
5885 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
5889 auto *debugVar = DBuilder.createParameterVariable(
5890 scope, Name, ArgNo, tunit, line,
type,
5891 CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
5894 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
5895 llvm::DILocation::get(CGM.getLLVMContext(), line,
5896 column, scope, CurInlinedAt),
5897 Builder.GetInsertBlock());
5900llvm::DIDerivedType *
5901CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
5906 if (MI != StaticDataMemberCache.end()) {
5907 assert(MI->second &&
"Static data member declaration should still exist");
5918llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
5919 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
5920 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
5921 llvm::DIGlobalVariableExpression *GVE =
nullptr;
5923 for (
const auto *Field : RD->
fields()) {
5924 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
5925 StringRef FieldName = Field->getName();
5928 if (FieldName.empty()) {
5929 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
5930 GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
5931 LineNo, LinkageName, Var, DContext);
5935 GVE = DBuilder.createGlobalVariableExpression(
5936 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
5937 Var->hasLocalLinkage());
5938 Var->addDebugInfo(GVE);
5950 const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
5955 auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD);
5966 struct ReferencesAnonymous
5968 bool RefAnon =
false;
5969 bool VisitRecordType(RecordType *RT) {
5977 ReferencesAnonymous RT;
5990struct ReconstitutableType :
public RecursiveASTVisitor<ReconstitutableType> {
5991 bool Reconstitutable =
true;
5992 bool VisitVectorType(VectorType *FT) {
5993 Reconstitutable =
false;
5996 bool VisitAtomicType(AtomicType *FT) {
5997 Reconstitutable =
false;
6000 bool TraverseEnumType(EnumType *ET,
bool =
false) {
6003 const EnumDecl *ED = ET->getDecl();
6005 Reconstitutable =
false;
6009 Reconstitutable =
false;
6014 bool VisitFunctionProtoType(FunctionProtoType *FT) {
6018 return Reconstitutable;
6020 bool VisitRecordType(RecordType *RT,
bool =
false) {
6022 Reconstitutable =
false;
6032 ReconstitutableType T;
6034 return T.Reconstitutable;
6037bool CGDebugInfo::HasReconstitutableArgs(
6038 ArrayRef<TemplateArgument> Args)
const {
6039 return llvm::all_of(Args, [&](
const TemplateArgument &TA) {
6079 llvm_unreachable(
"Other, unresolved, template arguments should "
6080 "not be seen here");
6085std::string CGDebugInfo::GetName(
const Decl *D,
bool Qualified,
6086 bool *NameIsSimplified)
const {
6088 llvm::raw_string_ostream
OS(Name);
6089 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6092 llvm::codegenoptions::DebugTemplateNamesKind TemplateNamesKind =
6093 CGM.getCodeGenOpts().getDebugSimpleTemplateNames();
6095 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6096 TemplateNamesKind = llvm::codegenoptions::DebugTemplateNamesKind::Full;
6098 std::optional<TemplateArgs> Args;
6100 bool IsOperatorOverload =
false;
6101 if (
auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
6102 Args = GetTemplateArgs(RD);
6103 }
else if (
auto *FD = dyn_cast<FunctionDecl>(ND)) {
6104 Args = GetTemplateArgs(FD);
6106 IsOperatorOverload |=
6109 }
else if (
auto *VD = dyn_cast<VarDecl>(ND)) {
6110 Args = GetTemplateArgs(VD);
6134 bool Reconstitutable =
6135 Args && HasReconstitutableArgs(Args->Args) && !IsOperatorOverload;
6137 PrintingPolicy PP = getPrintingPolicy();
6139 if (TemplateNamesKind == llvm::codegenoptions::DebugTemplateNamesKind::Full ||
6144 if (NameIsSimplified)
6145 *NameIsSimplified =
true;
6146 bool Mangled = TemplateNamesKind ==
6147 llvm::codegenoptions::DebugTemplateNamesKind::Mangled;
6153 std::string EncodedOriginalName;
6154 llvm::raw_string_ostream EncodedOriginalNameOS(EncodedOriginalName);
6159 printTemplateArgumentList(OS, Args->Args, PP);
6160 printTemplateArgumentList(EncodedOriginalNameOS, Args->Args, PP);
6162 std::string CanonicalOriginalName;
6163 llvm::raw_string_ostream OriginalOS(CanonicalOriginalName);
6165 assert(EncodedOriginalName == CanonicalOriginalName);
6174 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6175 if (D->
hasAttr<NoDebugAttr>())
6178 llvm::TimeTraceScope TimeScope(
"DebugGlobalVariable", [&]() {
6179 return GetName(D,
true);
6185 if (Cached != DeclCache.end())
6186 return Var->addDebugInfo(
6190 llvm::DIFile *Unit =
nullptr;
6191 llvm::DIScope *DContext =
nullptr;
6193 StringRef DeclName, LinkageName;
6195 llvm::MDTuple *TemplateParameters =
nullptr;
6196 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
6197 TemplateParameters, DContext);
6201 llvm::DIGlobalVariableExpression *GVE =
nullptr;
6206 if (T->isUnionType() && DeclName.empty()) {
6207 const auto *RD = T->castAsRecordDecl();
6209 "unnamed non-anonymous struct or union?");
6210 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
6215 unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(D->
getType());
6216 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
6217 if (D->
hasAttr<CUDASharedAttr>())
6220 else if (D->
hasAttr<CUDAConstantAttr>())
6224 AppendAddressSpaceXDeref(AddressSpace,
Expr);
6226 llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
6227 GVE = DBuilder.createGlobalVariableExpression(
6228 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
6229 Var->hasLocalLinkage(),
true,
6230 Expr.empty() ?
nullptr : DBuilder.createExpression(
Expr),
6231 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
6232 Align, Annotations);
6233 Var->addDebugInfo(GVE);
6239 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6240 if (VD->
hasAttr<NoDebugAttr>())
6242 llvm::TimeTraceScope TimeScope(
"DebugConstGlobalVariable", [&]() {
6243 return GetName(VD,
true);
6248 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
6249 StringRef Name = VD->
getName();
6250 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
6252 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
6254 if (CGM.getCodeGenOpts().EmitCodeView) {
6265 CanQualType T = CGM.getContext().getCanonicalTagType(ED);
6266 [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
6267 assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
6277 auto *VarD = dyn_cast<VarDecl>(VD);
6278 if (VarD && VarD->isStaticDataMember()) {
6280 getDeclContextDescriptor(VarD);
6285 RetainedTypes.push_back(
6286 CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
6290 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
6292 auto &GV = DeclCache[VD];
6296 llvm::DIExpression *InitExpr = createConstantValueExpression(VD,
Init);
6297 llvm::MDTuple *TemplateParameters =
nullptr;
6301 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
6302 TemplateParameters = parameterNodes.get();
6305 GV.reset(DBuilder.createGlobalVariableExpression(
6306 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
6307 true,
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
6308 TemplateParameters, Align));
6313 assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
6314 if (D->
hasAttr<NoDebugAttr>())
6318 llvm::DIFile *Unit = getOrCreateFile(D->
getLocation());
6319 StringRef Name = D->
getName();
6320 llvm::DIType *Ty = getOrCreateType(D->
getType(), Unit);
6322 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6323 llvm::DIGlobalVariableExpression *GVE =
6324 DBuilder.createGlobalVariableExpression(
6325 DContext, Name, StringRef(), Unit, getLineNumber(D->
getLocation()),
6326 Ty,
false,
false,
nullptr,
nullptr,
nullptr, Align);
6327 Var->addDebugInfo(GVE);
6334 if (CGM.getCodeGenOpts().getDebugInfo() <=
6335 llvm::codegenoptions::DebugLineTablesOnly)
6338 llvm::DILocation *DIL =
Value->getDebugLoc().get();
6342 llvm::DIFile *Unit = DIL->getFile();
6343 llvm::DIType *
Type = getOrCreateType(Ty, Unit);
6348 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Value)) {
6349 llvm::Value *Var = Load->getPointerOperand();
6354 auto DeclareTypeMatches = [&](llvm::DbgVariableRecord *DbgDeclare) {
6355 return DbgDeclare->getVariable()->getType() ==
Type;
6357 if (any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
6361 llvm::DILocalVariable *D =
6362 DBuilder.createAutoVariable(LexicalBlockStack.back(),
"",
nullptr, 0,
6363 Type,
false, llvm::DINode::FlagArtificial);
6365 if (
auto InsertPoint =
Value->getInsertionPointAfterDef()) {
6366 DBuilder.insertDbgValueIntrinsic(
Value, D, DBuilder.createExpression(), DIL,
6376 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6380 if (D->
hasAttr<NoDebugAttr>())
6383 auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
6398 if (!(DI = getDeclarationOrDefinition(
6399 AliaseeDecl.getCanonicalDecl().getDecl())))
6402 llvm::DIScope *DContext = getDeclContextDescriptor(D);
6405 llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
6406 DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
6420 llvm::DIFile *
File = getOrCreateFile(Loc);
6421 llvm::DIGlobalVariableExpression *Debug =
6422 DBuilder.createGlobalVariableExpression(
6423 nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
6424 getLineNumber(Loc), getOrCreateType(S->
getType(),
File),
true);
6425 GV->addDebugInfo(Debug);
6428llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
6429 if (!LexicalBlockStack.empty())
6430 return LexicalBlockStack.back();
6431 llvm::DIScope *Mod = getParentModuleOrNull(D);
6432 return getContextDescriptor(D, Mod ? Mod : TheCU);
6436 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6440 CGM.getCodeGenOpts().DebugExplicitImport) {
6444 DBuilder.createImportedModule(
6446 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
6451 if (llvm::DINode *
Target =
6454 DBuilder.createImportedDeclaration(
6456 getOrCreateFile(Loc), getLineNumber(Loc));
6461 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6464 "We shouldn't be codegening an invalid UsingDecl containing no decls");
6466 for (
const auto *USD : UD.
shadows()) {
6471 if (
const auto *FD = dyn_cast<FunctionDecl>(USD->getUnderlyingDecl()))
6472 if (
const auto *AT = FD->getType()
6475 if (AT->getDeducedType().isNull())
6486 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6489 "We shouldn't be codegening an invalid UsingEnumDecl"
6490 " containing no decls");
6492 for (
const auto *USD : UD.
shadows())
6497 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
6499 if (
Module *M = ID.getImportedModule()) {
6501 auto Loc = ID.getLocation();
6502 DBuilder.createImportedDeclaration(
6503 getCurrentContextDescriptor(
cast<Decl>(ID.getDeclContext())),
6504 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
6505 getLineNumber(Loc));
6509llvm::DIImportedEntity *
6511 if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
6513 auto &VH = NamespaceAliasCache[&NA];
6516 llvm::DIImportedEntity *R;
6518 if (
const auto *Underlying =
6521 R = DBuilder.createImportedDeclaration(
6524 getLineNumber(Loc), NA.
getName());
6526 R = DBuilder.createImportedDeclaration(
6529 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
6535CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
6539 auto I = NamespaceCache.find(NSDecl);
6540 if (I != NamespaceCache.end())
6543 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
6545 llvm::DINamespace *NS =
6546 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
6547 NamespaceCache[NSDecl].reset(NS);
6552 assert(TheCU &&
"no main compile unit");
6553 TheCU->setDWOId(Signature);
6559 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
6560 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
6562 ? CreateTypeDefinition(E.Type, E.Unit)
6564 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
6568 for (
const auto &P : ObjCMethodCache) {
6569 if (P.second.empty())
6572 QualType QTy(P.first->getTypeForDecl(), 0);
6574 assert(It != TypeCache.end());
6576 llvm::DICompositeType *InterfaceDecl =
6579 auto CurElts = InterfaceDecl->getElements();
6583 for (
auto &SubprogramDirect : P.second)
6584 if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
6585 EltTys.push_back(SubprogramDirect.getPointer());
6587 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
6588 DBuilder.replaceArrays(InterfaceDecl, Elements);
6591 for (
const auto &P : ReplaceMap) {
6594 assert(Ty->isForwardDecl());
6596 auto It = TypeCache.find(P.first);
6597 assert(It != TypeCache.end());
6600 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
6604 for (
const auto &P : FwdDeclReplaceMap) {
6607 llvm::Metadata *Repl;
6609 auto It = DeclCache.find(P.first);
6613 if (It == DeclCache.end())
6618 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
6619 Repl = GVE->getVariable();
6625 for (
auto &RT : RetainedTypes)
6626 if (
auto MD = TypeCache[RT])
6629 DBuilder.finalize();
6634 if (CGM.getCodeGenOpts().hasReducedDebugInfo())
6635 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6636 DBuilder.retainType(DieTy);
6640 if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo())
6641 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
6642 DBuilder.retainType(DieTy);
6646 if (LexicalBlockStack.empty())
6647 return llvm::DebugLoc();
6649 llvm::MDNode *
Scope = LexicalBlockStack.back();
6650 return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
6651 getColumnNumber(Loc),
Scope);
6657 if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
6658 DebugKind == llvm::codegenoptions::NoDebugInfo ||
6659 DebugKind == llvm::codegenoptions::LocTrackingOnly ||
6660 !CGM.getCodeGenOpts().DebugCallSiteInfo)
6661 return llvm::DINode::FlagZero;
6666 bool SupportsDWARFv4Ext =
6667 CGM.getCodeGenOpts().DwarfVersion == 4 &&
6668 (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB ||
6669 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
6671 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
6672 return llvm::DINode::FlagZero;
6674 return llvm::DINode::FlagAllCallsDescribed;
6685 return DBuilder.createConstantValueExpression(
6686 Val.
getFloat().bitcastToAPInt().getZExtValue());
6691 llvm::APSInt
const &ValInt = Val.
getInt();
6692 std::optional<uint64_t> ValIntOpt;
6693 if (ValInt.isUnsigned())
6694 ValIntOpt = ValInt.tryZExtValue();
6695 else if (
auto tmp = ValInt.trySExtValue())
6698 ValIntOpt =
static_cast<uint64_t
>(*tmp);
6701 return DBuilder.createConstantValueExpression(ValIntOpt.value());
6706CodeGenFunction::LexicalScope::LexicalScope(CodeGenFunction &
CGF,
6708 : RunCleanupsScope(
CGF), Range(Range), ParentScope(
CGF.CurLexicalScope) {
6709 CGF.CurLexicalScope =
this;
6711 DI->EmitLexicalBlockStart(
CGF.Builder, Range.getBegin());
6716 DI->EmitLexicalBlockEnd(
CGF.Builder, Range.getEnd());
6729#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
6731 Label = "__ubsan_check_" #Name; \
6735#undef SANITIZER_CHECK
6746#define SANITIZER(NAME, ID) \
6747 case SanitizerKind::SO_##ID: \
6748 Label = "__ubsan_check_" NAME; \
6750#include "clang/Basic/Sanitizers.def"
6752 llvm_unreachable(
"unexpected sanitizer kind");
6757 for (
unsigned int i = 0; i < Label.length(); i++)
6758 if (!std::isalpha(Label[i]))
6767 llvm::DILocation *CheckDebugLoc =
Builder.getCurrentDebugLocation();
6769 if (!DI || !CheckDebugLoc)
6770 return CheckDebugLoc;
6771 const auto &AnnotateDebugInfo =
6772 CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo;
6773 if (AnnotateDebugInfo.empty())
6774 return CheckDebugLoc;
6777 if (Ordinals.size() == 1)
6782 if (any_of(Ordinals, [&](
auto Ord) {
return AnnotateDebugInfo.has(Ord); })) {
6786 llvm::DIFile *
File = llvm::DIFile::get(
CGM.getLLVMContext(),
6787 "ubsan_interface.h",
6789 return DI->CreateSyntheticInlineAt(CheckDebugLoc, Label,
File);
6792 return CheckDebugLoc;
6800 assert(!CGF->IsSanitizerScope);
6801 CGF->IsSanitizerScope =
true;
6805 assert(CGF->IsSanitizerScope);
6806 CGF->IsSanitizerScope =
false;
Defines the clang::ASTContext interface.
static bool IsReconstitutableType(QualType QT)
static void stripUnusedQualifiers(Qualifiers &Q)
static std::string SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Constant * buildConstantDataArrayFromElements(llvm::LLVMContext &Ctx, const APValue &Arr)
Build an llvm::ConstantDataArray from the initialized elements of an APValue array,...
static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler)
static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD)
Returns true if the specified variable VD is an explicit parameter of a synthesized Objective-C prope...
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 SourceLocation getMacroDebugLoc(const CodeGenModule &CGM, SourceLocation Loc)
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 bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl)
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty)
static bool canUseCtorHoming(const CXXRecordDecl *RD)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
static llvm::Constant * tryEmitConstexprArrayAsConstant(CodeGenModule &CGM, const VarDecl *Var, const APValue *Value)
Try to create an llvm::Constant for a constexpr array of integer elements.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
static llvm::DISourceLanguageName GetDISourceLanguageName(const CodeGenModule &CGM)
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)
static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
#define CC_VLS_CASE(ABI_VLEN)
Defines the LambdaCapture class.
constexpr llvm::StringRef ClangTrapPrefix
static StringRef getTriple(const Command &Job)
#define LIST_SANITIZER_CHECKS
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],...
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
unsigned getArrayInitializedElts() const
APValue & getArrayFiller()
unsigned getArraySize() const
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.
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
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.
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.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
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.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
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
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
shadow_range shadows() const
A binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
unsigned getNumBits() const
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
StringRef getName(const PrintingPolicy &Policy) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
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).
llvm::iterator_range< base_class_const_iterator > base_class_const_range
specific_decl_iterator< CXXMethodDecl > method_iterator
Iterator access to method members.
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
const LambdaCapture * capture_const_iterator
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
CXXRecordDecl * getDefinitionOrSelf() const
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
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...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
A scoped helper to set the current debug location to the specified location or preferred location of ...
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
@ RAA_Indirect
Pass it as a pointer to temporary memory.
MangleContext & getMangleContext()
Gets the mangle context.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to the current atom group, created using ApplyA...
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 completeFunction()
Reset internal state.
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 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.
llvm::DINode::DIFlags getCallSiteRelatedAttrs() const
Return flags which enable debug info emission for call sites, provided that it is supported and enabl...
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 emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
Emit symbol for debugger that holds the pointer to the vtable.
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 addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
Add KeyInstruction and an optional Backup instruction to the atom group Atom.
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 EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, QualType CalleeType, GlobalDecl CalleeGlobalDecl)
Emit debug info for an extern function being called.
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 directive...
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...
void addCallTargetIfVirtual(const FunctionDecl *FD, llvm::CallBase *CI)
Add call target information.
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.
llvm::DILocation * CreateSyntheticInlineAt(llvm::DebugLoc ParentLocation, llvm::DISubprogram *SynthSubprogram)
Create a debug location from Location that adds an artificial inline frame where the frame name is Fu...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
~LexicalScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CGDebugInfo * getDebugInfo()
llvm::DILocation * SanitizerAnnotateDebugInfo(ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
Returns debug info, with additional annotation if CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordi...
This class organizes the cross-function state that is used while generating LLVM code.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
SanitizerDebugLocation(CodeGenFunction *CGF, ArrayRef< SanitizerKind::SanitizerOrdinal > Ordinals, SanitizerHandler Handler)
~SanitizerDebugLocation()
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
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.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
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.
bool isComplete() const
Returns true if this can be considered a complete type.
EnumDecl * getDefinitionOrSelf() 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...
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...
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Represents the declaration of a label.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
std::optional< uint32_t > getCPlusPlusLangStd() const
Returns the most applicable C++ standard-compliant language version code.
std::optional< uint32_t > getCLangStd() const
Returns the most applicable C standard-compliant language version code.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
QualType getElementType() const
Returns type of the elements being stored in the matrix.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
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.
NamespaceBaseDecl * 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.
ObjCImplementationDecl * getImplementation() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
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()
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents one property declaration in an Objective-C interface.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Represents a parameter to a function.
QualType getElementType() const
bool isIsaPointer() const
bool authenticatesNullValues() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
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
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()
PointerAuthQualifier getPointerAuth() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
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.
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.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getStrTokenLoc(unsigned TokNum) const
Get one of the string literal token.
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 * getDefinitionOrSelf() const
virtual std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
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.
ArrayRef< NamedDecl * > asArray()
The base class of the type hierarchy.
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() 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
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 (...
unsigned getNumElements() const
QualType getElementType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Deleting
Deleting dtor.
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
U cast(CodeGen::Address addr)
@ 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,...
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.
Extra information about a function prototype.
uint64_t Index
Method's index in the vftable.
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 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.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.