36 #include "llvm/ADT/DenseSet.h" 37 #include "llvm/ADT/SmallVector.h" 38 #include "llvm/ADT/StringExtras.h" 39 #include "llvm/IR/Constants.h" 40 #include "llvm/IR/DataLayout.h" 41 #include "llvm/IR/DerivedTypes.h" 42 #include "llvm/IR/Instructions.h" 43 #include "llvm/IR/Intrinsics.h" 44 #include "llvm/IR/Metadata.h" 45 #include "llvm/IR/Module.h" 46 #include "llvm/Support/FileSystem.h" 47 #include "llvm/Support/MD5.h" 48 #include "llvm/Support/Path.h" 49 using namespace clang;
66 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
67 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
68 DBuilder(CGM.getModule()) {
70 DebugPrefixMap[KV.first] = KV.second;
75 assert(LexicalBlockStack.empty() &&
76 "Region stack mismatch, stack not empty!");
82 init(TemporaryLocation);
89 init(TemporaryLocation, DefaultToEmpty);
93 bool DefaultToEmpty) {
100 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
102 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
105 if (TemporaryLocation.
isValid()) {
106 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
110 if (DefaultToEmpty) {
111 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
116 assert(!DI->LexicalBlockStack.empty());
117 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
118 0, 0, DI->LexicalBlockStack.back(), DI->getInlinedAt()));
132 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
134 CGF.
Builder.SetCurrentDebugLocation(std::move(Loc));
141 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
152 SavedLocation = DI.getLocation();
153 assert((DI.getInlinedAt() ==
154 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
155 "CGDebugInfo and IRBuilder are out of sync");
157 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
165 DI.EmitLocation(CGF->
Builder, SavedLocation);
173 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
178 if (LexicalBlockStack.empty())
182 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
184 if (PCLoc.isInvalid() ||
Scope->getFile() == getOrCreateFile(CurLoc))
187 if (
auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(
Scope)) {
188 LexicalBlockStack.pop_back();
189 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
190 LBF->getScope(), getOrCreateFile(CurLoc)));
191 }
else if (isa<llvm::DILexicalBlock>(
Scope) ||
192 isa<llvm::DISubprogram>(
Scope)) {
193 LexicalBlockStack.pop_back();
194 LexicalBlockStack.emplace_back(
195 DBuilder.createLexicalBlockFile(
Scope, getOrCreateFile(CurLoc)));
199 llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(
const Decl *D) {
200 llvm::DIScope *Mod = getParentModuleOrNull(D);
205 llvm::DIScope *CGDebugInfo::getContextDescriptor(
const Decl *Context,
210 auto I = RegionMap.find(Context);
211 if (I != RegionMap.end()) {
212 llvm::Metadata *V = I->second;
213 return dyn_cast_or_null<llvm::DIScope>(V);
217 if (
const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
218 return getOrCreateNamespace(NSDecl);
220 if (
const auto *RDecl = dyn_cast<RecordDecl>(Context))
221 if (!RDecl->isDependentType())
222 return getOrCreateType(CGM.getContext().getTypeDeclType(RDecl),
234 if (CGM.getCodeGenOpts().EmitCodeView)
239 PP.
remapPath = [
this](StringRef Path) {
return remapDIPath(Path); };
243 StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
244 assert(FD &&
"Invalid FunctionDecl!");
256 CGM.getCodeGenOpts().EmitCodeView;
258 if (!Info && FII && !UseQualifiedName)
262 llvm::raw_svector_ostream OS(NS);
263 if (!UseQualifiedName)
275 return internString(OS.str());
278 StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
280 llvm::raw_svector_ostream OS(MethodName);
283 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
284 OS << OID->getName();
285 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
286 OS << OID->getName();
287 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
288 if (OC->IsClassExtension()) {
289 OS << OC->getClassInterface()->getName();
291 OS << OC->getIdentifier()->getNameStart() <<
'(' 292 << OC->getIdentifier()->getNameStart() <<
')';
294 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
295 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
296 }
else if (isa<ObjCProtocolDecl>(DC)) {
300 cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
306 return internString(OS.str());
309 StringRef CGDebugInfo::getSelectorName(
Selector S) {
313 StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
314 if (isa<ClassTemplateSpecializationDecl>(RD)) {
316 llvm::raw_svector_ostream OS(Name);
321 return internString(Name);
327 return II->getName();
331 if (CGM.getCodeGenOpts().EmitCodeView) {
334 "Typedef should not be in another decl context!");
335 assert(D->getDeclName().getAsIdentifierInfo() &&
336 "Typedef was not named!");
337 return D->getDeclName().getAsIdentifierInfo()->getName();
340 if (CGM.getLangOpts().CPlusPlus) {
347 Name = DD->getName();
352 Name = TND->getName();
358 return internString(UnnamedType);
370 if (!CGM.getCodeGenOpts().EmitCodeView &&
371 CGM.getCodeGenOpts().DwarfVersion < 5)
376 llvm::MemoryBuffer *MemBuffer = SM.
getBuffer(FID, &Invalid);
381 llvm::MD5::MD5Result Result;
383 Hash.update(MemBuffer->getBuffer());
386 Hash.stringifyResult(Result, Checksum);
387 return llvm::DIFile::CSK_MD5;
392 if (!CGM.getCodeGenOpts().EmbedSource)
395 bool SourceInvalid =
false;
407 return TheCU->getFile();
413 if (PLoc.
isInvalid() || FileName.empty())
415 return TheCU->getFile();
418 auto It = DIFileCache.find(FileName.data());
419 if (It != DIFileCache.end()) {
421 if (llvm::Metadata *V = It->second)
422 return cast<llvm::DIFile>(V);
427 computeChecksum(SM.
getFileID(Loc), Checksum);
430 CSInfo.emplace(*CSKind, Checksum);
435 CGDebugInfo::createFile(StringRef FileName,
436 Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
440 std::string RemappedFile = remapDIPath(FileName);
441 std::string CurDir = remapDIPath(getCurrentDirname());
444 if (llvm::sys::path::is_absolute(RemappedFile)) {
447 auto FileIt = llvm::sys::path::begin(RemappedFile);
448 auto FileE = llvm::sys::path::end(RemappedFile);
449 auto CurDirIt = llvm::sys::path::begin(CurDir);
450 auto CurDirE = llvm::sys::path::end(CurDir);
451 for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
452 llvm::sys::path::append(DirBuf, *CurDirIt);
453 if (
std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) {
459 for (; FileIt != FileE; ++FileIt)
460 llvm::sys::path::append(FileBuf, *FileIt);
468 llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source);
469 DIFileCache[FileName.data()].reset(F);
474 for (
const auto &Entry : DebugPrefixMap)
475 if (Path.startswith(Entry.first))
476 return (Twine(Entry.second) + Path.substr(Entry.first.size())).str();
481 if (Loc.
isInvalid() && CurLoc.isInvalid())
488 unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
490 if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
494 if (Loc.
isInvalid() && CurLoc.isInvalid())
501 StringRef CGDebugInfo::getCurrentDirname() {
502 if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())
503 return CGM.getCodeGenOpts().DebugCompilationDir;
505 if (!CWDName.empty())
508 llvm::sys::fs::current_path(CWD);
509 return CWDName = internString(CWD);
512 void CGDebugInfo::CreateCompileUnit() {
526 std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
527 if (MainFileName.empty())
528 MainFileName =
"<stdin>";
534 std::string MainFileDir;
536 MainFileDir = remapDIPath(MainFile->getDir()->getName());
537 if (MainFileDir !=
".") {
539 llvm::sys::path::append(MainFileDirSS, MainFileName);
540 MainFileName = MainFileDirSS.str();
546 if (MainFile->getName() == MainFileName &&
548 MainFile->getName().rsplit(
'.').second)
550 MainFileName = CGM.getModule().getName().str();
555 llvm::dwarf::SourceLanguage LangTag;
559 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
561 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
562 }
else if (LO.ObjC) {
563 LangTag = llvm::dwarf::DW_LANG_ObjC;
564 }
else if (LO.RenderScript) {
565 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
567 LangTag = llvm::dwarf::DW_LANG_C99;
569 LangTag = llvm::dwarf::DW_LANG_C89;
575 unsigned RuntimeVers = 0;
579 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
583 EmissionKind = llvm::DICompileUnit::NoDebug;
586 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
593 EmissionKind = llvm::DICompileUnit::FullDebug;
598 auto &CGOpts = CGM.getCodeGenOpts();
604 CSInfo.emplace(*CSKind, Checksum);
605 llvm::DIFile *CUFile = DBuilder.createFile(
606 remapDIPath(MainFileName), remapDIPath(getCurrentDirname()), CSInfo,
610 TheCU = DBuilder.createCompileUnit(
611 LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer :
"",
612 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
613 CGOpts.DwarfDebugFlags, RuntimeVers,
616 : CGOpts.SplitDwarfFile,
617 EmissionKind, DwoId, CGOpts.SplitDwarfInlining,
618 CGOpts.DebugInfoForProfiling,
619 CGM.getTarget().getTriple().isNVPTX()
621 :
static_cast<llvm::DICompileUnit::DebugNameTableKind
>(
622 CGOpts.DebugNameTable),
623 CGOpts.DebugRangesBaseAddress);
626 llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
630 #define BUILTIN_TYPE(Id, SingletonId) 631 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 632 #include "clang/AST/BuiltinTypes.def" 633 case BuiltinType::Dependent:
634 llvm_unreachable(
"Unexpected builtin type");
635 case BuiltinType::NullPtr:
636 return DBuilder.createNullPtrType();
637 case BuiltinType::Void:
639 case BuiltinType::ObjCClass:
642 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
643 "objc_class", TheCU, TheCU->getFile(), 0);
645 case BuiltinType::ObjCId: {
656 DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
657 "objc_class", TheCU, TheCU->getFile(), 0);
659 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
661 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
663 ObjTy = DBuilder.createStructType(TheCU,
"objc_object", TheCU->getFile(), 0,
664 0, 0, llvm::DINode::FlagZero,
nullptr,
665 llvm::DINodeArray());
667 DBuilder.replaceArrays(
668 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
669 ObjTy,
"isa", TheCU->getFile(), 0, Size, 0, 0,
670 llvm::DINode::FlagZero, ISATy)));
673 case BuiltinType::ObjCSel: {
675 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
676 "objc_selector", TheCU,
677 TheCU->getFile(), 0);
681 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 682 case BuiltinType::Id: \ 683 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \ 685 #include "clang/Basic/OpenCLImageTypes.def" 686 case BuiltinType::OCLSampler:
687 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
688 case BuiltinType::OCLEvent:
689 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
690 case BuiltinType::OCLClkEvent:
691 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
692 case BuiltinType::OCLQueue:
693 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
694 case BuiltinType::OCLReserveID:
695 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
696 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 697 case BuiltinType::Id: \ 698 return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty); 699 #include "clang/Basic/OpenCLExtensionTypes.def" 701 case BuiltinType::UChar:
702 case BuiltinType::Char_U:
703 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
705 case BuiltinType::Char_S:
706 case BuiltinType::SChar:
707 Encoding = llvm::dwarf::DW_ATE_signed_char;
709 case BuiltinType::Char8:
710 case BuiltinType::Char16:
711 case BuiltinType::Char32:
712 Encoding = llvm::dwarf::DW_ATE_UTF;
714 case BuiltinType::UShort:
715 case BuiltinType::UInt:
716 case BuiltinType::UInt128:
717 case BuiltinType::ULong:
718 case BuiltinType::WChar_U:
719 case BuiltinType::ULongLong:
720 Encoding = llvm::dwarf::DW_ATE_unsigned;
722 case BuiltinType::Short:
723 case BuiltinType::Int:
724 case BuiltinType::Int128:
725 case BuiltinType::Long:
726 case BuiltinType::WChar_S:
727 case BuiltinType::LongLong:
728 Encoding = llvm::dwarf::DW_ATE_signed;
730 case BuiltinType::Bool:
731 Encoding = llvm::dwarf::DW_ATE_boolean;
733 case BuiltinType::Half:
734 case BuiltinType::Float:
735 case BuiltinType::LongDouble:
736 case BuiltinType::Float16:
737 case BuiltinType::Float128:
738 case BuiltinType::Double:
744 Encoding = llvm::dwarf::DW_ATE_float;
746 case BuiltinType::ShortAccum:
747 case BuiltinType::Accum:
748 case BuiltinType::LongAccum:
749 case BuiltinType::ShortFract:
750 case BuiltinType::Fract:
751 case BuiltinType::LongFract:
752 case BuiltinType::SatShortFract:
753 case BuiltinType::SatFract:
754 case BuiltinType::SatLongFract:
755 case BuiltinType::SatShortAccum:
756 case BuiltinType::SatAccum:
757 case BuiltinType::SatLongAccum:
758 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
760 case BuiltinType::UShortAccum:
761 case BuiltinType::UAccum:
762 case BuiltinType::ULongAccum:
763 case BuiltinType::UShortFract:
764 case BuiltinType::UFract:
765 case BuiltinType::ULongFract:
766 case BuiltinType::SatUShortAccum:
767 case BuiltinType::SatUAccum:
768 case BuiltinType::SatULongAccum:
769 case BuiltinType::SatUShortFract:
770 case BuiltinType::SatUFract:
771 case BuiltinType::SatULongFract:
772 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
777 case BuiltinType::Long:
780 case BuiltinType::LongLong:
781 BTName =
"long long int";
783 case BuiltinType::ULong:
784 BTName =
"long unsigned int";
786 case BuiltinType::ULongLong:
787 BTName =
"long long unsigned int";
790 BTName = BT->
getName(CGM.getLangOpts());
794 uint64_t Size = CGM.getContext().getTypeSize(BT);
795 return DBuilder.createBasicType(BTName, Size, Encoding);
798 llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
800 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
802 Encoding = llvm::dwarf::DW_ATE_lo_user;
804 uint64_t Size = CGM.getContext().getTypeSize(Ty);
805 return DBuilder.createBasicType(
"complex", Size, Encoding);
808 llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
809 llvm::DIFile *Unit) {
820 llvm::dwarf::Tag Tag;
822 Tag = llvm::dwarf::DW_TAG_const_type;
825 Tag = llvm::dwarf::DW_TAG_volatile_type;
828 Tag = llvm::dwarf::DW_TAG_restrict_type;
831 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
832 return getOrCreateType(
QualType(T, 0), Unit);
835 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
839 return DBuilder.createQualifiedType(Tag, FromTy);
843 llvm::DIFile *Unit) {
849 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
851 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
855 llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
856 llvm::DIFile *Unit) {
857 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
863 switch (TheCU->getSourceLanguage()) {
864 case llvm::dwarf::DW_LANG_C_plus_plus:
866 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
867 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
895 llvm::DICompileUnit *TheCU) {
913 llvm::DICompileUnit *TheCU) {
922 llvm::raw_svector_ostream Out(Identifier);
929 llvm::dwarf::Tag Tag;
931 Tag = llvm::dwarf::DW_TAG_structure_type;
933 Tag = llvm::dwarf::DW_TAG_union_type;
938 Tag = llvm::dwarf::DW_TAG_class_type;
943 llvm::DICompositeType *
944 CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
945 llvm::DIScope *Ctx) {
947 if (llvm::DIType *T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
948 return cast<llvm::DICompositeType>(T);
949 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
951 StringRef RDName = getClassName(RD);
958 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
960 llvm::DINode::FlagFwdDecl, Identifier);
961 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
962 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
963 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
964 CollectCXXTemplateParams(TSpecial, DefUnit));
965 ReplaceMap.emplace_back(
966 std::piecewise_construct, std::make_tuple(Ty),
967 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
971 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
974 llvm::DIFile *Unit) {
978 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy);
979 uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace);
982 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
984 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
985 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
986 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
987 Size, Align, DWARFAddressSpace);
989 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
990 Align, DWARFAddressSpace);
993 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
994 llvm::DIType *&
Cache) {
997 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
998 TheCU, TheCU->getFile(), 0);
999 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1000 Cache = DBuilder.createPointerType(Cache, Size);
1004 uint64_t CGDebugInfo::collectDefaultElementTypesForBlockPointer(
1005 const BlockPointerType *Ty, llvm::DIFile *Unit, llvm::DIDerivedType *DescTy,
1011 uint64_t FieldOffset = 0;
1016 if (CGM.getLangOpts().OpenCL) {
1017 FType = CGM.getContext().IntTy;
1018 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
1019 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
1021 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1022 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
1023 FType = CGM.getContext().IntTy;
1024 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
1025 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
1027 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
1028 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1029 uint64_t FieldSize = CGM.getContext().getTypeSize(Ty);
1030 uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty);
1031 EltTys.push_back(DBuilder.createMemberType(
1032 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign,
1033 FieldOffset, llvm::DINode::FlagZero, DescTy));
1034 FieldOffset += FieldSize;
1041 llvm::DIFile *Unit) {
1044 uint64_t FieldOffset;
1045 llvm::DINodeArray Elements;
1048 FType = CGM.getContext().UnsignedLongTy;
1049 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
1050 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
1052 Elements = DBuilder.getOrCreateArray(EltTys);
1055 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
1058 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, 0,
1059 FieldOffset, 0, Flags,
nullptr, Elements);
1062 uint64_t Size = CGM.getContext().getTypeSize(Ty);
1064 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
1066 FieldOffset = collectDefaultElementTypesForBlockPointer(Ty, Unit, DescTy,
1069 Elements = DBuilder.getOrCreateArray(EltTys);
1075 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, 0, FieldOffset, 0,
1076 Flags,
nullptr, Elements);
1078 return DBuilder.createPointerType(EltTy, Size);
1082 llvm::DIFile *Unit) {
1086 SmallString<128> NS;
1087 llvm::raw_svector_ostream OS(NS);
1093 ->getTemplatedDecl();
1096 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
1098 getDeclContextDescriptor(AliasDecl));
1101 llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1102 llvm::DIFile *Unit) {
1108 return DBuilder.createTypedef(
1110 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
1111 getDeclContextDescriptor(Ty->
getDecl()));
1121 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1123 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1125 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1127 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1129 return llvm::dwarf::DW_CC_BORLAND_pascal;
1131 return llvm::dwarf::DW_CC_LLVM_Win64;
1133 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1136 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1138 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1140 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1142 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1144 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1146 return llvm::dwarf::DW_CC_LLVM_Swift;
1148 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1150 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1152 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1157 llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1158 llvm::DIFile *Unit) {
1162 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1166 if (isa<FunctionNoProtoType>(Ty))
1167 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1168 else if (
const auto *FPT = dyn_cast<FunctionProtoType>(Ty)) {
1169 for (
const QualType &ParamType : FPT->param_types())
1170 EltTys.push_back(getOrCreateType(ParamType, Unit));
1171 if (FPT->isVariadic())
1172 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1175 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1176 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
1191 if (Access == Default)
1192 return llvm::DINode::FlagZero;
1196 return llvm::DINode::FlagPrivate;
1198 return llvm::DINode::FlagProtected;
1200 return llvm::DINode::FlagPublic;
1202 return llvm::DINode::FlagZero;
1204 llvm_unreachable(
"unexpected access enumerator");
1207 llvm::DIType *CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1208 llvm::DIScope *RecordTy,
1210 StringRef Name = BitFieldDecl->
getName();
1213 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1214 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1217 llvm::DIFile *File = getOrCreateFile(Loc);
1218 unsigned Line = getLineNumber(Loc);
1221 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1222 uint64_t SizeInBits = BitFieldInfo.
Size;
1223 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1224 uint64_t StorageOffsetInBits =
1230 if (CGM.getDataLayout().isBigEndian())
1232 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1234 return DBuilder.createBitFieldMemberType(
1235 RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1242 uint32_t AlignInBits, llvm::DIFile *tunit,
1243 llvm::DIScope *scope,
const RecordDecl *RD) {
1244 llvm::DIType *debugType = getOrCreateType(type, tunit);
1247 llvm::DIFile *file = getOrCreateFile(loc);
1248 unsigned line = getLineNumber(loc);
1250 uint64_t SizeInBits = 0;
1251 auto Align = AlignInBits;
1253 TypeInfo TI = CGM.getContext().getTypeInfo(type);
1254 SizeInBits = TI.
Width;
1260 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1261 offsetInBits, flags, debugType);
1264 void CGDebugInfo::CollectRecordLambdaFields(
1266 llvm::DIType *RecordTy) {
1270 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
1272 unsigned fieldno = 0;
1275 I != E; ++I, ++Field, ++fieldno) {
1279 assert(!Field->isBitField() &&
"lambdas don't have bitfield members!");
1281 StringRef VName = V->
getName();
1282 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1284 llvm::DIType *FieldType = createFieldType(
1285 VName, Field->getType(), Loc, Field->getAccess(),
1286 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1287 elements.push_back(FieldType);
1294 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1296 llvm::DIType *fieldType = createFieldType(
1300 elements.push_back(fieldType);
1305 llvm::DIDerivedType *
1306 CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1311 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1312 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1314 unsigned LineNumber = getLineNumber(Var->
getLocation());
1315 StringRef VName = Var->
getName();
1316 llvm::Constant *C =
nullptr;
1321 C = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->
getInt());
1323 C = llvm::ConstantFP::get(CGM.getLLVMContext(), Value->
getFloat());
1329 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1330 RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align);
1335 void CGDebugInfo::CollectRecordNormalField(
1336 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1339 StringRef name = field->
getName();
1346 llvm::DIType *FieldType;
1348 FieldType = createBitFieldType(field, RecordTy, RD);
1353 OffsetInBits, Align, tunit, RecordTy, RD);
1356 elements.push_back(FieldType);
1359 void CGDebugInfo::CollectRecordNestedType(
1361 QualType Ty = CGM.getContext().getTypeDeclType(TD);
1363 if (isa<InjectedClassNameType>(Ty))
1366 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc));
1367 elements.push_back(nestedType);
1370 void CGDebugInfo::CollectRecordFields(
1371 const RecordDecl *record, llvm::DIFile *tunit,
1373 llvm::DICompositeType *RecordTy) {
1376 if (CXXDecl && CXXDecl->
isLambda())
1377 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1379 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
1382 unsigned fieldNo = 0;
1386 for (
const auto *I : record->
decls())
1387 if (
const auto *V = dyn_cast<VarDecl>(I)) {
1388 if (V->hasAttr<NoDebugAttr>())
1393 if (CGM.getCodeGenOpts().EmitCodeView &&
1394 isa<VarTemplateSpecializationDecl>(V))
1398 auto MI = StaticDataMemberCache.find(V->getCanonicalDecl());
1399 if (MI != StaticDataMemberCache.end()) {
1400 assert(MI->second &&
1401 "Static data member declaration should still exist");
1402 elements.push_back(MI->second);
1404 auto Field = CreateRecordStaticField(V, RecordTy, record);
1405 elements.push_back(Field);
1407 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1408 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1409 elements, RecordTy, record);
1413 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
1416 if (
const auto *nestedType = dyn_cast<TypeDecl>(I))
1417 if (!nestedType->isImplicit() &&
1418 nestedType->getDeclContext() == record)
1419 CollectRecordNestedType(nestedType, elements);
1424 llvm::DISubroutineType *
1425 CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1426 llvm::DIFile *Unit) {
1429 return cast_or_null<llvm::DISubroutineType>(
1430 getOrCreateType(
QualType(Func, 0), Unit));
1431 return getOrCreateInstanceMethodType(Method->
getThisType(), Func, Unit);
1434 llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1437 llvm::DITypeRefArray Args(
1438 cast<llvm::DISubroutineType>(getOrCreateType(
QualType(Func, 0), Unit))
1440 assert(Args.size() &&
"Invalid number of arguments!");
1445 Elts.push_back(Args[0]);
1449 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1451 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1453 unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
1454 uint64_t Size = CGM.getTarget().getPointerWidth(AS);
1456 llvm::DIType *PointeeType = getOrCreateType(PointeeTy, Unit);
1457 llvm::DIType *ThisPtrType =
1458 DBuilder.createPointerType(PointeeType, Size, Align);
1463 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1464 Elts.push_back(ThisPtrType);
1466 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1468 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1469 Elts.push_back(ThisPtrType);
1473 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1474 Elts.push_back(Args[i]);
1476 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1478 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1480 Flags |= llvm::DINode::FlagLValueReference;
1482 Flags |= llvm::DINode::FlagRValueReference;
1484 return DBuilder.createSubroutineType(EltTypeArray, Flags,
1491 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1498 llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1499 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1501 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1503 StringRef MethodName = getFunctionName(Method);
1504 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1508 StringRef MethodLinkageName;
1515 MethodLinkageName = CGM.getMangledName(Method);
1518 llvm::DIFile *MethodDefUnit =
nullptr;
1519 unsigned MethodLine = 0;
1521 MethodDefUnit = getOrCreateFile(Method->
getLocation());
1522 MethodLine = getLineNumber(Method->
getLocation());
1526 llvm::DIType *ContainingType =
nullptr;
1527 unsigned VIndex = 0;
1528 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1529 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
1534 SPFlags |= llvm::DISubprogram::SPFlagPureVirtual;
1536 SPFlags |= llvm::DISubprogram::SPFlagVirtual;
1538 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1541 if (!isa<CXXDestructorDecl>(Method))
1542 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method);
1549 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1558 Flags |= llvm::DINode::FlagIntroducedVirtual;
1563 ThisAdjustment = CGM.getCXXABI()
1564 .getVirtualFunctionPrologueThisAdjustment(GD)
1567 ContainingType = RecordTy;
1571 Flags |= llvm::DINode::FlagStaticMember;
1573 Flags |= llvm::DINode::FlagArtificial;
1575 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
1576 if (CXXC->isExplicit())
1577 Flags |= llvm::DINode::FlagExplicit;
1578 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
1579 if (CXXC->isExplicit())
1580 Flags |= llvm::DINode::FlagExplicit;
1583 Flags |= llvm::DINode::FlagPrototyped;
1585 Flags |= llvm::DINode::FlagLValueReference;
1587 Flags |= llvm::DINode::FlagRValueReference;
1588 if (CGM.getLangOpts().Optimize)
1589 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
1591 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
1592 llvm::DISubprogram *SP = DBuilder.createMethod(
1593 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
1594 MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
1595 TParamsArray.get());
1602 void CGDebugInfo::CollectCXXMemberFunctions(
1609 for (
const auto *I : RD->
decls()) {
1634 EltTys.push_back(MI == SPCache.end()
1635 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
1636 :
static_cast<llvm::Metadata *
>(MI->second));
1640 void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1642 llvm::DIType *RecordTy) {
1644 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
1645 llvm::DINode::FlagZero);
1649 if (CGM.getCodeGenOpts().EmitCodeView) {
1650 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
1651 llvm::DINode::FlagIndirectVirtualBase);
1655 void CGDebugInfo::CollectCXXBasesAux(
1660 llvm::DINode::DIFlags StartingFlags) {
1662 for (
const auto &BI : Bases) {
1664 cast<CXXRecordDecl>(BI.getType()->getAs<
RecordType>()->getDecl());
1665 if (!SeenTypes.insert(
Base).second)
1667 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
1668 llvm::DINode::DIFlags BFlags = StartingFlags;
1669 uint64_t BaseOffset;
1670 uint32_t VBPtrOffset = 0;
1672 if (BI.isVirtual()) {
1673 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1676 BaseOffset = 0 - CGM.getItaniumVTableContext()
1677 .getVirtualBaseOffsetOffset(RD,
Base)
1683 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD,
Base);
1684 VBPtrOffset = CGM.getContext()
1685 .getASTRecordLayout(RD)
1689 BFlags |= llvm::DINode::FlagVirtual;
1696 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
1697 VBPtrOffset, BFlags);
1698 EltTys.push_back(DTy);
1705 llvm::DIFile *Unit) {
1707 for (
unsigned i = 0, e = TAList.size(); i != e; ++i) {
1714 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
1715 TemplateParams.push_back(
1716 DBuilder.createTemplateTypeParameter(TheCU, Name, TTy));
1720 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1722 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
1727 llvm::DIType *TTy = getOrCreateType(T, Unit);
1728 llvm::Constant *V =
nullptr;
1732 if (
const auto *VD = dyn_cast<VarDecl>(D))
1733 V = CGM.GetAddrOfGlobalVar(VD);
1736 else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->
isInstance())
1737 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
1738 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
1739 V = CGM.GetAddrOfFunction(FD);
1742 else if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr())) {
1746 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
1748 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
1749 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
1751 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1753 cast_or_null<llvm::Constant>(V->stripPointerCasts())));
1757 llvm::DIType *TTy = getOrCreateType(T, Unit);
1758 llvm::Constant *V =
nullptr;
1761 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
1767 if (MPT->isMemberDataPointer())
1768 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
1770 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
1771 TemplateParams.push_back(
1772 DBuilder.createTemplateValueParameter(TheCU, Name, TTy, V));
1775 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
1776 TheCU, Name,
nullptr,
1780 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
1781 TheCU, Name,
nullptr,
1788 T = CGM.getContext().getLValueReferenceType(T);
1790 assert(V &&
"Expression in template argument isn't constant");
1791 llvm::DIType *TTy = getOrCreateType(T, Unit);
1792 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1793 TheCU, Name, TTy, V->stripPointerCasts()));
1799 "These argument types shouldn't exist in concrete types");
1802 return DBuilder.getOrCreateArray(TemplateParams);
1806 CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
1807 llvm::DIFile *Unit) {
1813 return CollectTemplateParams(
1816 return llvm::DINodeArray();
1819 llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(
const VarDecl *VL,
1820 llvm::DIFile *Unit) {
1821 if (
auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL)) {
1822 auto T = TS->getSpecializedTemplateOrPartial();
1823 auto TA = TS->getTemplateArgs().asArray();
1828 ->getTemplateParameters();
1829 return CollectTemplateParams(TList, TA, Unit);
1835 ->getTemplateParameters();
1836 return CollectTemplateParams(TList, TA, Unit);
1839 return llvm::DINodeArray();
1842 llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
1849 return CollectTemplateParams(TPList, TAList.
asArray(), Unit);
1852 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
1854 return VTablePtrType;
1859 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
1860 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
1861 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
1863 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1865 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1867 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
1868 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
1869 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
1870 return VTablePtrType;
1873 StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
1878 void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1880 llvm::DICompositeType *RecordTy) {
1896 llvm::DIType *VPtrTy =
nullptr;
1897 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
1898 CGM.getTarget().getCXXABI().isMicrosoft();
1899 if (NeedVTableShape) {
1901 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1903 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
1904 unsigned VSlotCount =
1906 unsigned VTableWidth = PtrWidth * VSlotCount;
1907 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1909 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1912 llvm::DIType *VTableType = DBuilder.createPointerType(
1913 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
1914 EltTys.push_back(VTableType);
1917 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
1925 VPtrTy = getOrCreateVTablePtrType(Unit);
1927 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1928 llvm::DIType *VPtrMember =
1929 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
1930 llvm::DINode::FlagArtificial, VPtrTy);
1931 EltTys.push_back(VPtrMember);
1937 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
1943 return getOrCreateStandaloneType(D, Loc);
1949 assert(!D.
isNull() &&
"null type");
1950 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
1951 assert(T &&
"could not create debug info for type");
1960 QualType Ty = CGM.getContext().getEnumType(ED);
1962 auto I = TypeCache.find(TyPtr);
1963 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
1965 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
1966 assert(!Res->isForwardDecl());
1967 TypeCache[TyPtr].reset(Res);
1972 !CGM.getLangOpts().CPlusPlus)
1973 completeRequiredType(RD);
1978 if (RD->
hasAttr<DLLImportAttr>())
1981 if (MD->hasAttr<DLLImportAttr>())
1994 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
2003 bool Explicit =
false;
2004 if (
auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
2005 Explicit = TD->isExplicitInstantiationOrSpecialization();
2019 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
2020 if (CXXRD->isDynamicClass() &&
2021 CGM.getVTableLinkage(CXXRD) ==
2022 llvm::GlobalValue::AvailableExternallyLinkage &&
2035 QualType Ty = CGM.getContext().getRecordType(RD);
2037 auto I = TypeCache.find(TyPtr);
2038 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
2041 assert(!Res->isForwardDecl());
2042 TypeCache[TyPtr].reset(Res);
2049 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
2050 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
2068 if (!LangOpts.CPlusPlus)
2090 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2091 Spec = SD->getSpecializationKind();
2105 QualType Ty = CGM.getContext().getRecordType(RD);
2106 llvm::DIType *T = getTypeOrNull(Ty);
2107 if (T && T->isForwardDecl())
2108 completeClassData(RD);
2111 llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2113 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2115 CGM.getLangOpts())) {
2117 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2121 return CreateTypeDefinition(Ty);
2124 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2128 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2136 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty, DefUnit);
2142 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2143 CollectContainingType(CXXDecl, FwdDecl);
2146 LexicalBlockStack.emplace_back(&*FwdDecl);
2147 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2159 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2160 CollectVTableInfo(CXXDecl, DefUnit, EltTys, FwdDecl);
2164 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2166 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2168 LexicalBlockStack.pop_back();
2169 RegionMap.erase(Ty->
getDecl());
2171 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2172 DBuilder.replaceArrays(FwdDecl, Elements);
2174 if (FwdDecl->isTemporary())
2176 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2178 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2183 llvm::DIFile *Unit) {
2189 llvm::DIFile *Unit) {
2194 return DBuilder.createTypedef(
2196 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
2197 getDeclContextDescriptor(Ty->
getDecl()));
2225 llvm::DIFile *Unit) {
2235 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2237 getDeclContextDescriptor(ID), Unit, 0);
2240 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2243 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2249 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2250 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2251 llvm::dwarf::DW_TAG_structure_type, ID->
getName(), Mod ? Mod : TheCU,
2252 DefUnit,
Line, RuntimeLang);
2253 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2257 return CreateTypeDefinition(Ty, Unit);
2262 bool CreateSkeletonCU) {
2267 auto ModRef = ModuleCache.find(M);
2268 if (ModRef != ModuleCache.end())
2269 return cast<llvm::DIModule>(ModRef->second);
2272 SmallString<128> ConfigMacros;
2274 llvm::raw_svector_ostream OS(ConfigMacros);
2275 const auto &PPOpts = CGM.getPreprocessorOpts();
2278 for (
auto &M : PPOpts.Macros) {
2281 const std::string &Macro = M.first;
2282 bool Undef = M.second;
2283 OS <<
"\"-" << (Undef ?
'U' :
'D');
2284 for (
char c : Macro)
2299 bool IsRootModule = M ? !M->
Parent :
true;
2300 if (CreateSkeletonCU && IsRootModule) {
2304 uint64_t Signature =
2308 llvm::DIBuilder DIB(CGM.getModule());
2309 DIB.createCompileUnit(TheCU->getSourceLanguage(),
2312 TheCU->getProducer(),
true, StringRef(), 0,
2313 Mod.
getASTFile(), llvm::DICompileUnit::FullDebug,
2318 IsRootModule ? nullptr
2319 : getOrCreateModuleRef(
2322 llvm::DIModule *DIMod =
2323 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
2324 Mod.
getPath(), CGM.getHeaderSearchOpts().Sysroot);
2325 ModuleCache[M].reset(DIMod);
2330 llvm::DIFile *Unit) {
2332 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2334 unsigned RuntimeLang = TheCU->getSourceLanguage();
2337 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2340 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2342 Flags |= llvm::DINode::FlagObjcClassComplete;
2344 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2345 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
2346 Mod ? Mod : Unit, ID->
getName(), DefUnit,
Line, Size, Align, Flags,
2347 nullptr, llvm::DINodeArray(), RuntimeLang);
2353 LexicalBlockStack.emplace_back(RealDecl);
2354 RegionMap[Ty->
getDecl()].reset(RealDecl);
2361 llvm::DIType *SClassTy =
2362 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
2366 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
2367 llvm::DINode::FlagZero);
2368 EltTys.push_back(InhTag);
2374 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2375 unsigned PLine = getLineNumber(Loc);
2378 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
2379 PD->getName(), PUnit, PLine,
2381 : getSelectorName(PD->getGetterName()),
2383 : getSelectorName(PD->getSetterName()),
2384 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
2385 EltTys.push_back(PropertyNode);
2388 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
2390 for (
auto *PD : ClassExt->properties()) {
2391 PropertySet.insert(PD->getIdentifier());
2397 if (!PropertySet.insert(PD->getIdentifier()).second)
2403 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
2404 unsigned FieldNo = 0;
2406 Field = Field->getNextIvar(), ++FieldNo) {
2407 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
2411 StringRef FieldName = Field->getName();
2414 if (FieldName.empty())
2418 llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation());
2419 unsigned FieldLine = getLineNumber(Field->getLocation());
2421 uint64_t FieldSize = 0;
2422 uint32_t FieldAlign = 0;
2424 if (!FType->isIncompleteArrayType()) {
2427 FieldSize = Field->isBitField()
2428 ? Field->getBitWidthValue(CGM.getContext())
2429 : CGM.getContext().getTypeSize(FType);
2433 uint64_t FieldOffset;
2434 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2438 if (Field->isBitField()) {
2440 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
2441 FieldOffset %= CGM.getContext().getCharWidth();
2449 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2451 Flags = llvm::DINode::FlagProtected;
2453 Flags = llvm::DINode::FlagPrivate;
2455 Flags = llvm::DINode::FlagPublic;
2457 llvm::MDNode *PropertyNode =
nullptr;
2460 ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
2463 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2464 unsigned PLine = getLineNumber(Loc);
2467 PropertyNode = DBuilder.createObjCProperty(
2468 PD->getName(), PUnit, PLine,
2471 : getSelectorName(PD->getGetterName()),
2474 : getSelectorName(PD->getSetterName()),
2475 PD->getPropertyAttributes(),
2476 getOrCreateType(PD->getType(), PUnit));
2480 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
2481 FieldSize, FieldAlign, FieldOffset, Flags,
2482 FieldTy, PropertyNode);
2483 EltTys.push_back(FieldTy);
2486 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2487 DBuilder.replaceArrays(RealDecl, Elements);
2489 LexicalBlockStack.pop_back();
2493 llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
2494 llvm::DIFile *Unit) {
2495 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
2498 llvm::Metadata *Subscript;
2500 auto SizeExpr = SizeExprCache.find(QTy);
2501 if (SizeExpr != SizeExprCache.end())
2502 Subscript = DBuilder.getOrCreateSubrange(0, SizeExpr->getSecond());
2504 Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
2505 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
2507 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2510 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
2513 llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
2518 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2533 Size = CGM.getContext().getTypeSize(Ty);
2542 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
2551 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
2552 Count = CAT->getSize().getZExtValue();
2553 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2554 if (
Expr *Size = VAT->getSizeExpr()) {
2556 if (Size->EvaluateAsInt(Result, CGM.getContext()))
2557 Count = Result.
Val.
getInt().getExtValue();
2561 auto SizeNode = SizeExprCache.find(EltTy);
2562 if (SizeNode != SizeExprCache.end())
2563 Subscripts.push_back(
2564 DBuilder.getOrCreateSubrange(0, SizeNode->getSecond()));
2566 Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
2570 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
2572 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
2577 llvm::DIFile *Unit) {
2578 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
2583 llvm::DIFile *Unit) {
2584 return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type, Ty,
2590 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2594 Size = CGM.getContext().getTypeSize(Ty);
2597 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
2599 case MSInheritanceAttr::Keyword_single_inheritance:
2600 Flags |= llvm::DINode::FlagSingleInheritance;
2602 case MSInheritanceAttr::Keyword_multiple_inheritance:
2603 Flags |= llvm::DINode::FlagMultipleInheritance;
2605 case MSInheritanceAttr::Keyword_virtual_inheritance:
2606 Flags |= llvm::DINode::FlagVirtualInheritance;
2608 case MSInheritanceAttr::Keyword_unspecified_inheritance:
2616 return DBuilder.createMemberPointerType(
2622 return DBuilder.createMemberPointerType(
2623 getOrCreateInstanceMethodType(
2626 ClassType, Size, 0, Flags);
2629 llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
2631 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
2634 llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
2638 llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
2650 bool isImportedFromModule =
2662 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
2663 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2664 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
2665 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
2668 StringRef EDName = ED->
getName();
2669 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
2670 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
2671 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
2673 ReplaceMap.emplace_back(
2674 std::piecewise_construct, std::make_tuple(Ty),
2675 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
2679 return CreateTypeDefinition(Ty);
2682 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
2698 const auto &InitVal = Enum->getInitVal();
2699 auto Value = IsSigned ? InitVal.getSExtValue() : InitVal.getZExtValue();
2700 Enumerators.push_back(
2701 DBuilder.createEnumerator(Enum->getName(),
Value, !IsSigned));
2705 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
2707 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2709 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
2710 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
2711 return DBuilder.createEnumerationType(EnumContext, ED->
getName(), DefUnit,
2712 Line, Size, Align, EltArray, ClassTy,
2718 StringRef Name, StringRef
Value) {
2719 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2720 return DBuilder.createMacro(Parent, Line, MType, Name, Value);
2726 llvm::DIFile *FName = getOrCreateFile(FileLoc);
2727 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2728 return DBuilder.createTempMacroFile(Parent, Line, FName);
2738 Quals += InnerQuals;
2743 case Type::TemplateSpecialization: {
2744 const auto *Spec = cast<TemplateSpecializationType>(T);
2745 if (Spec->isTypeAlias())
2747 T = Spec->desugar();
2750 case Type::TypeOfExpr:
2751 T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
2756 case Type::Decltype:
2759 case Type::UnaryTransform:
2762 case Type::Attributed:
2763 T = cast<AttributedType>(T)->getEquivalentType();
2765 case Type::Elaborated:
2766 T = cast<ElaboratedType>(T)->getNamedType();
2769 T = cast<ParenType>(T)->getInnerType();
2771 case Type::SubstTemplateTypeParm:
2772 T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
2775 case Type::DeducedTemplateSpecialization: {
2776 QualType DT = cast<DeducedType>(T)->getDeducedType();
2777 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
2781 case Type::Adjusted:
2784 T = cast<AdjustedType>(T)->getAdjustedType();
2788 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
2793 llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
2799 if (It != TypeCache.end()) {
2801 if (llvm::Metadata *V = It->second)
2802 return cast<llvm::DIType>(V);
2812 completeUnusedClass(SD);
2819 completeClassData(&D);
2822 RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
2825 llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
2832 if (
auto *T = getTypeOrNull(Ty))
2835 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
2839 TypeCache[TyPtr].reset(Res);
2844 llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
2846 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
2850 auto *Reader = CGM.getContext().getExternalSource();
2852 auto Info = Reader->getSourceDescriptor(Idx);
2854 return getOrCreateModuleRef(*Info,
true);
2855 }
else if (ClangModuleMap) {
2869 return getOrCreateModuleRef(Info,
false);
2872 return getOrCreateModuleRef(PCHDescriptor,
false);
2879 llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
2882 return CreateQualifiedType(Ty, Unit);
2886 #define TYPE(Class, Base) 2887 #define ABSTRACT_TYPE(Class, Base) 2888 #define NON_CANONICAL_TYPE(Class, Base) 2889 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 2890 #include "clang/AST/TypeNodes.def" 2891 llvm_unreachable(
"Dependent types cannot show up in debug information");
2893 case Type::ExtVector:
2895 return CreateType(cast<VectorType>(Ty), Unit);
2896 case Type::ObjCObjectPointer:
2897 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
2898 case Type::ObjCObject:
2899 return CreateType(cast<ObjCObjectType>(Ty), Unit);
2900 case Type::ObjCTypeParam:
2901 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
2902 case Type::ObjCInterface:
2903 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
2905 return CreateType(cast<BuiltinType>(Ty));
2907 return CreateType(cast<ComplexType>(Ty));
2909 return CreateType(cast<PointerType>(Ty), Unit);
2910 case Type::BlockPointer:
2911 return CreateType(cast<BlockPointerType>(Ty), Unit);
2913 return CreateType(cast<TypedefType>(Ty), Unit);
2915 return CreateType(cast<RecordType>(Ty));
2917 return CreateEnumType(cast<EnumType>(Ty));
2918 case Type::FunctionProto:
2919 case Type::FunctionNoProto:
2920 return CreateType(cast<FunctionType>(Ty), Unit);
2921 case Type::ConstantArray:
2922 case Type::VariableArray:
2923 case Type::IncompleteArray:
2924 return CreateType(cast<ArrayType>(Ty), Unit);
2926 case Type::LValueReference:
2927 return CreateType(cast<LValueReferenceType>(Ty), Unit);
2928 case Type::RValueReference:
2929 return CreateType(cast<RValueReferenceType>(Ty), Unit);
2931 case Type::MemberPointer:
2932 return CreateType(cast<MemberPointerType>(Ty), Unit);
2935 return CreateType(cast<AtomicType>(Ty), Unit);
2938 return CreateType(cast<PipeType>(Ty), Unit);
2940 case Type::TemplateSpecialization:
2941 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
2944 case Type::Attributed:
2945 case Type::Adjusted:
2947 case Type::DeducedTemplateSpecialization:
2948 case Type::Elaborated:
2950 case Type::SubstTemplateTypeParm:
2951 case Type::TypeOfExpr:
2953 case Type::Decltype:
2954 case Type::UnaryTransform:
2955 case Type::PackExpansion:
2959 llvm_unreachable(
"type should have been unwrapped!");
2962 llvm::DICompositeType *CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty,
2963 llvm::DIFile *Unit) {
2966 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
2971 if (T && !T->isForwardDecl())
2975 llvm::DICompositeType *Res = CreateLimitedType(Ty);
2980 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
2988 llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
2992 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2994 StringRef RDName = getClassName(RD);
2996 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
3000 auto *T = cast_or_null<llvm::DICompositeType>(
3001 getTypeOrNull(CGM.getContext().getRecordType(RD)));
3009 return getOrCreateRecordFwdDecl(Ty, RDContext);
3011 uint64_t Size = CGM.getContext().getTypeSize(Ty);
3017 auto Flags = llvm::DINode::FlagZero;
3018 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3020 Flags |= llvm::DINode::FlagTypePassByReference;
3022 Flags |= llvm::DINode::FlagTypePassByValue;
3025 if (CXXRD->isTrivial())
3026 Flags |= llvm::DINode::FlagTrivial;
3029 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
3030 getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
3035 switch (RealDecl->getTag()) {
3037 llvm_unreachable(
"invalid composite type tag");
3039 case llvm::dwarf::DW_TAG_array_type:
3040 case llvm::dwarf::DW_TAG_enumeration_type:
3045 if (Identifier.empty())
3049 case llvm::dwarf::DW_TAG_structure_type:
3050 case llvm::dwarf::DW_TAG_union_type:
3051 case llvm::dwarf::DW_TAG_class_type:
3054 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
3058 RegionMap[Ty->
getDecl()].reset(RealDecl);
3061 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
3062 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
3063 CollectCXXTemplateParams(TSpecial, DefUnit));
3067 void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
3068 llvm::DICompositeType *RealDecl) {
3070 llvm::DICompositeType *ContainingType =
nullptr;
3075 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
3082 ContainingType = cast<llvm::DICompositeType>(
3083 getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
3086 ContainingType = RealDecl;
3088 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
3091 llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
3092 StringRef Name, uint64_t *
Offset) {
3093 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
3094 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
3097 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
3098 *Offset, llvm::DINode::FlagZero, FieldTy);
3099 *Offset += FieldSize;
3103 void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
3105 StringRef &LinkageName,
3106 llvm::DIScope *&FDContext,
3107 llvm::DINodeArray &TParamsArray,
3108 llvm::DINode::DIFlags &Flags) {
3109 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
3110 Name = getFunctionName(FD);
3113 LinkageName = CGM.getMangledName(GD);
3114 Flags |= llvm::DINode::FlagPrototyped;
3119 if (LinkageName == Name || (!CGM.getCodeGenOpts().EmitGcovArcs &&
3120 !CGM.getCodeGenOpts().EmitGcovNotes &&
3121 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
3123 LinkageName = StringRef();
3128 FDContext = getOrCreateNamespace(NSDecl);
3131 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
3132 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
3136 Flags |= llvm::DINode::FlagNoReturn;
3138 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
3142 void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
3144 StringRef &Name, StringRef &LinkageName,
3145 llvm::MDTuple *&TemplateParameters,
3146 llvm::DIScope *&VDContext) {
3153 if (T->isIncompleteArrayType()) {
3155 llvm::APInt ConstVal(32, 1);
3156 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
3165 LinkageName = CGM.getMangledName(VD);
3166 if (LinkageName == Name)
3167 LinkageName = StringRef();
3169 if (isa<VarTemplateSpecializationDecl>(VD)) {
3170 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VD, &*Unit);
3171 TemplateParameters = parameterNodes.get();
3173 TemplateParameters =
nullptr;
3191 DC = CGM.getContext().getTranslationUnitDecl();
3193 llvm::DIScope *Mod = getParentModuleOrNull(VD);
3194 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
3197 llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
3199 llvm::DINodeArray TParamsArray;
3200 StringRef Name, LinkageName;
3201 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3202 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
3204 llvm::DIFile *Unit = getOrCreateFile(Loc);
3205 llvm::DIScope *DContext = Unit;
3206 unsigned Line = getLineNumber(Loc);
3207 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
3215 ArgTypes.push_back(Parm->getType());
3217 QualType FnType = CGM.getContext().getFunctionType(
3220 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
3221 if (CGM.getLangOpts().Optimize)
3222 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
3225 Flags |= getCallSiteRelatedAttrs();
3226 SPFlags |= llvm::DISubprogram::SPFlagDefinition;
3227 return DBuilder.createFunction(
3228 DContext, Name, LinkageName, Unit, Line,
3229 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
3230 TParamsArray.get(), getFunctionDeclaration(FD));
3233 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
3234 DContext, Name, LinkageName, Unit, Line,
3235 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit), 0, Flags, SPFlags,
3236 TParamsArray.get(), getFunctionDeclaration(FD));
3238 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
3239 std::make_tuple(CanonDecl),
3240 std::make_tuple(SP));
3244 llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
3245 return getFunctionFwdDeclOrStub(GD,
false);
3248 llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
3249 return getFunctionFwdDeclOrStub(GD,
true);
3252 llvm::DIGlobalVariable *
3253 CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
3255 StringRef Name, LinkageName;
3257 llvm::DIFile *Unit = getOrCreateFile(Loc);
3258 llvm::DIScope *DContext = Unit;
3259 unsigned Line = getLineNumber(Loc);
3260 llvm::MDTuple *TemplateParameters =
nullptr;
3262 collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, TemplateParameters,
3265 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
3266 DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
3268 FwdDeclReplaceMap.emplace_back(
3269 std::piecewise_construct,
3271 std::make_tuple(static_cast<llvm::Metadata *>(GV)));
3275 llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
3280 if (
const auto *TD = dyn_cast<TypeDecl>(D))
3281 return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
3285 if (I != DeclCache.end()) {
3287 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
3288 return GVE->getVariable();
3289 return dyn_cast_or_null<llvm::DINode>(N);
3294 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3295 return getFunctionForwardDeclaration(FD);
3296 else if (
const auto *VD = dyn_cast<VarDecl>(D))
3297 return getGlobalVariableForwardDeclaration(VD);
3302 llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
3311 auto *S = getDeclContextDescriptor(D);
3314 if (MI == SPCache.end()) {
3316 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
3317 cast<llvm::DICompositeType>(S));
3320 if (MI != SPCache.end()) {
3321 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3322 if (SP && !SP->isDefinition())
3326 for (
auto NextFD : FD->
redecls()) {
3327 auto MI = SPCache.find(NextFD->getCanonicalDecl());
3328 if (MI != SPCache.end()) {
3329 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3330 if (SP && !SP->isDefinition())
3339 llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
3345 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray(None));
3347 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
3348 return getOrCreateMethodType(Method, F);
3353 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
3358 QualType ResultTy = OMethod->getReturnType();
3361 if (ResultTy == CGM.getContext().getObjCInstanceType())
3362 ResultTy = CGM.getContext().getPointerType(
3363 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
3365 Elts.push_back(getOrCreateType(ResultTy, F));
3368 if (
auto *SelfDecl = OMethod->getSelfDecl())
3369 SelfDeclTy = SelfDecl->getType();
3370 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3371 if (FPT->getNumParams() > 1)
3372 SelfDeclTy = FPT->getParamType(0);
3373 if (!SelfDeclTy.
isNull())
3375 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
3377 Elts.push_back(DBuilder.createArtificialType(
3378 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
3380 for (
const auto *PI : OMethod->parameters())
3381 Elts.push_back(getOrCreateType(PI->getType(), F));
3383 if (OMethod->isVariadic())
3384 Elts.push_back(DBuilder.createUnspecifiedParameter());
3386 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
3387 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3393 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3397 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3398 for (
QualType ParamType : FPT->param_types())
3399 EltTys.push_back(getOrCreateType(ParamType, F));
3400 EltTys.push_back(DBuilder.createUnspecifiedParameter());
3401 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
3402 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3406 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
3411 llvm::Function *Fn,
bool CurFuncIsThunk,
3415 StringRef LinkageName;
3417 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3420 bool HasDecl = (D !=
nullptr);
3422 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3423 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
3424 llvm::DIFile *Unit = getOrCreateFile(Loc);
3425 llvm::DIScope *FDContext = Unit;
3426 llvm::DINodeArray TParamsArray;
3429 LinkageName = Fn->getName();
3430 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3433 if (FI != SPCache.end()) {
3434 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3435 if (SP && SP->isDefinition()) {
3436 LexicalBlockStack.emplace_back(SP);
3437 RegionMap[D].reset(SP);
3441 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3442 TParamsArray, Flags);
3443 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3444 Name = getObjCMethodName(OMD);
3445 Flags |= llvm::DINode::FlagPrototyped;
3448 Name = Fn->getName();
3449 Flags |= llvm::DINode::FlagPrototyped;
3451 if (Name.startswith(
"\01"))
3452 Name = Name.substr(1);
3455 Flags |= llvm::DINode::FlagArtificial;
3461 Flags |= llvm::DINode::FlagThunk;
3463 if (Fn->hasLocalLinkage())
3464 SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
3465 if (CGM.getLangOpts().Optimize)
3466 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
3468 llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
3469 llvm::DISubprogram::DISPFlags SPFlagsForDef =
3470 SPFlags | llvm::DISubprogram::SPFlagDefinition;
3472 unsigned LineNo = getLineNumber(Loc);
3473 unsigned ScopeLine = getLineNumber(ScopeLoc);
3480 llvm::DISubprogram *SP = DBuilder.createFunction(
3481 FDContext, Name, LinkageName, Unit, LineNo,
3482 getOrCreateFunctionType(D, FnType, Unit), ScopeLine, FlagsForDef,
3483 SPFlagsForDef, TParamsArray.get(), getFunctionDeclaration(D));
3484 Fn->setSubprogram(SP);
3488 if (HasDecl && isa<FunctionDecl>(D))
3491 if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
3494 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
3497 auto It = TypeCache.find(QTy.getAsOpaquePtr());
3498 if (It != TypeCache.end()) {
3499 llvm::DICompositeType *InterfaceDecl =
3500 cast<llvm::DICompositeType>(It->second);
3501 llvm::DISubprogram *FD = DBuilder.createFunction(
3502 InterfaceDecl, Name, LinkageName, Unit, LineNo,
3503 getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
3504 TParamsArray.get());
3505 DBuilder.finalizeSubprogram(FD);
3506 ObjCMethodCache[
ID].push_back(FD);
3512 LexicalBlockStack.emplace_back(SP);
3515 RegionMap[D].reset(SP);
3521 StringRef LinkageName;
3527 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3528 llvm::DIFile *Unit = getOrCreateFile(Loc);
3529 llvm::DIScope *FDContext = getDeclContextDescriptor(D);
3530 llvm::DINodeArray TParamsArray;
3531 if (isa<FunctionDecl>(D)) {
3533 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3534 TParamsArray, Flags);
3535 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3536 Name = getObjCMethodName(OMD);
3537 Flags |= llvm::DINode::FlagPrototyped;
3539 llvm_unreachable(
"not a function or ObjC method");
3541 if (!Name.empty() && Name[0] ==
'\01')
3542 Name = Name.substr(1);
3545 Flags |= llvm::DINode::FlagArtificial;
3550 unsigned LineNo = getLineNumber(Loc);
3551 unsigned ScopeLine = 0;
3552 llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
3553 if (CGM.getLangOpts().Optimize)
3554 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
3556 DBuilder.retainType(DBuilder.createFunction(
3557 FDContext, Name, LinkageName, Unit, LineNo,
3558 getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
3559 TParamsArray.get(), getFunctionDeclaration(D)));
3563 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
3566 llvm::DISubprogram *SP =
nullptr;
3567 if (FI != SPCache.end())
3568 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3569 if (!SP || !SP->isDefinition())
3570 SP = getFunctionStub(GD);
3571 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3572 LexicalBlockStack.emplace_back(SP);
3573 setInlinedAt(Builder.getCurrentDebugLocation());
3578 assert(CurInlinedAt &&
"unbalanced inline scope stack");
3579 EmitFunctionEnd(Builder,
nullptr);
3580 setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
3587 if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
3590 llvm::MDNode *
Scope = LexicalBlockStack.back();
3591 Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
3592 getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
3596 llvm::MDNode *Back =
nullptr;
3597 if (!LexicalBlockStack.empty())
3598 Back = LexicalBlockStack.back().get();
3599 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
3600 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
3601 getColumnNumber(CurLoc)));
3604 void CGDebugInfo::AppendAddressSpaceXDeref(
3607 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
3608 if (!DWARFAddressSpace)
3611 Expr.push_back(llvm::dwarf::DW_OP_constu);
3612 Expr.push_back(DWARFAddressSpace.getValue());
3613 Expr.push_back(llvm::dwarf::DW_OP_swap);
3614 Expr.push_back(llvm::dwarf::DW_OP_xderef);
3623 Builder.SetCurrentDebugLocation(
3624 llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc),
3625 LexicalBlockStack.back(), CurInlinedAt));
3631 CreateLexicalBlock(Loc);
3636 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3644 LexicalBlockStack.pop_back();
3648 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3649 unsigned RCount = FnBeginRegionCount.back();
3650 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
3653 while (LexicalBlockStack.size() != RCount) {
3656 LexicalBlockStack.pop_back();
3658 FnBeginRegionCount.pop_back();
3660 if (Fn && Fn->getSubprogram())
3661 DBuilder.finalizeSubprogram(Fn->getSubprogram());
3664 CGDebugInfo::BlockByRefType
3665 CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
3666 uint64_t *XOffset) {
3669 uint64_t FieldSize, FieldOffset;
3670 uint32_t FieldAlign;
3672 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3676 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3677 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
3678 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
3679 FType = CGM.getContext().IntTy;
3680 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
3681 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
3683 bool HasCopyAndDispose = CGM.getContext().BlockRequiresCopying(Type, VD);
3684 if (HasCopyAndDispose) {
3685 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3687 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
3689 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
3691 bool HasByrefExtendedLayout;
3693 if (CGM.getContext().getByrefLifetime(Type, Lifetime,
3694 HasByrefExtendedLayout) &&
3695 HasByrefExtendedLayout) {
3696 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3698 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
3701 CharUnits Align = CGM.getContext().getDeclAlign(VD);
3702 if (Align > CGM.getContext().toCharUnitsFromBits(
3703 CGM.getTarget().getPointerAlign(0))) {
3705 CGM.getContext().toCharUnitsFromBits(FieldOffset);
3707 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
3710 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
3711 FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
3713 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
3718 llvm::DIType *WrappedTy = getOrCreateType(FType, Unit);
3719 FieldSize = CGM.getContext().getTypeSize(FType);
3720 FieldAlign = CGM.getContext().toBits(Align);
3722 *XOffset = FieldOffset;
3723 llvm::DIType *FieldTy = DBuilder.createMemberType(
3724 Unit, VD->
getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset,
3725 llvm::DINode::FlagZero, WrappedTy);
3726 EltTys.push_back(FieldTy);
3727 FieldOffset += FieldSize;
3729 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3730 return {DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0,
3731 llvm::DINode::FlagZero,
nullptr, Elements),
3735 llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
3740 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3741 if (VD->
hasAttr<NoDebugAttr>())
3747 llvm::DIFile *Unit =
nullptr;
3751 uint64_t XOffset = 0;
3752 if (VD->
hasAttr<BlocksAttr>())
3753 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
3755 Ty = getOrCreateType(VD->
getType(), Unit);
3764 unsigned Column = 0;
3770 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3772 Flags |= llvm::DINode::FlagArtificial;
3776 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->
getType());
3777 AppendAddressSpaceXDeref(AddressSpace, Expr);
3781 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
3784 Flags |= llvm::DINode::FlagObjectPointer;
3791 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
3792 StringRef Name = VD->
getName();
3793 if (!Name.empty()) {
3794 if (VD->
hasAttr<BlocksAttr>()) {
3797 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3799 offset = CGM.getContext().toCharUnitsFromBits(
3800 CGM.getTarget().getPointerWidth(0));
3802 Expr.push_back(llvm::dwarf::DW_OP_deref);
3803 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3805 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3808 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
3820 for (
const auto *Field : RD->
fields()) {
3821 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
3822 StringRef FieldName = Field->getName();
3825 if (FieldName.empty() && !isa<RecordType>(Field->getType()))
3830 auto *D = DBuilder.createAutoVariable(
3831 Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
3832 Flags | llvm::DINode::FlagArtificial, FieldAlign);
3835 DBuilder.insertDeclare(
3836 Storage, D, DBuilder.createExpression(Expr),
3837 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3838 Builder.GetInsertBlock());
3844 auto *D = ArgNo ? DBuilder.createParameterVariable(
3845 Scope, Name, *ArgNo, Unit, Line, Ty,
3846 CGM.getLangOpts().Optimize, Flags)
3847 : DBuilder.createAutoVariable(
Scope, Name, Unit, Line, Ty,
3848 CGM.getLangOpts().Optimize,
3852 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
3853 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3854 Builder.GetInsertBlock());
3859 llvm::DILocalVariable *
3863 return EmitDeclare(VD, Storage,
llvm::None, Builder);
3866 llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
3868 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
3871 return DBuilder.createObjectPointerType(Ty);
3876 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
3878 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3880 if (Builder.GetInsertBlock() ==
nullptr)
3882 if (VD->
hasAttr<NoDebugAttr>())
3885 bool isByRef = VD->
hasAttr<BlocksAttr>();
3887 uint64_t XOffset = 0;
3888 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3891 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
3893 Ty = getOrCreateType(VD->
getType(), Unit);
3897 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
3899 Ty = CreateSelfType(VD->
getType(), Ty);
3903 unsigned Column = getColumnNumber(VD->
getLocation());
3905 const llvm::DataLayout &target = CGM.getDataLayout();
3912 addr.push_back(llvm::dwarf::DW_OP_deref);
3913 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3916 addr.push_back(llvm::dwarf::DW_OP_deref);
3917 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3920 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
3922 addr.push_back(llvm::dwarf::DW_OP_deref);
3923 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3925 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3931 auto *D = DBuilder.createAutoVariable(
3932 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
3933 Line, Ty,
false, llvm::DINode::FlagZero, Align);
3937 llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
3938 auto *Expr = DBuilder.createExpression(addr);
3940 DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
3942 DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
3949 EmitDeclare(VD, AI, ArgNo, Builder);
3953 struct BlockLayoutChunk {
3954 uint64_t OffsetInBits;
3957 bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
3958 return l.OffsetInBits < r.OffsetInBits;
3962 void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
3964 const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
3969 if (CGM.getLangOpts().OpenCL) {
3970 Fields.push_back(createFieldType(
"__size", Context.
IntTy, Loc,
AS_public,
3971 BlockLayout.getElementOffsetInBits(0),
3973 Fields.push_back(createFieldType(
"__align", Context.
IntTy, Loc,
AS_public,
3974 BlockLayout.getElementOffsetInBits(1),
3978 BlockLayout.getElementOffsetInBits(0),
3980 Fields.push_back(createFieldType(
"__flags", Context.
IntTy, Loc,
AS_public,
3981 BlockLayout.getElementOffsetInBits(1),
3985 BlockLayout.getElementOffsetInBits(2), Unit, Unit));
3987 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
3988 Fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, Loc,
AS_public,
3989 BlockLayout.getElementOffsetInBits(3),
3991 Fields.push_back(createFieldType(
3996 Loc,
AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
4003 llvm::AllocaInst *Alloca,
4011 llvm::DIFile *tunit = getOrCreateFile(loc);
4012 unsigned line = getLineNumber(loc);
4013 unsigned column = getColumnNumber(loc);
4016 getDeclContextDescriptor(blockDecl);
4018 const llvm::StructLayout *blockLayout =
4022 collectDefaultFieldsForBlockLiteralDeclare(block, C, loc, *blockLayout, tunit,
4031 BlockLayoutChunk chunk;
4032 chunk.OffsetInBits =
4033 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
4034 chunk.Capture =
nullptr;
4035 chunks.push_back(chunk);
4039 for (
const auto &capture : blockDecl->
captures()) {
4040 const VarDecl *variable = capture.getVariable();
4047 BlockLayoutChunk chunk;
4048 chunk.OffsetInBits =
4049 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
4050 chunk.Capture = &capture;
4051 chunks.push_back(chunk);
4055 llvm::array_pod_sort(chunks.begin(), chunks.end());
4057 for (
const BlockLayoutChunk &Chunk : chunks) {
4058 uint64_t offsetInBits = Chunk.OffsetInBits;
4067 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->
getParent()))
4068 type =
QualType(RDecl->getTypeForDecl(), 0);
4070 llvm_unreachable(
"unexpected block declcontext");
4072 fields.push_back(createFieldType(
"this", type, loc,
AS_public,
4073 offsetInBits, tunit, tunit));
4078 StringRef name = variable->
getName();
4080 llvm::DIType *fieldType;
4087 EmitTypeForVarWithBlocksAttr(variable, &xoffset).BlockByRefWrapper;
4088 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
4089 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
4090 PtrInfo.
Width, Align, offsetInBits,
4091 llvm::DINode::FlagZero, fieldType);
4095 offsetInBits, Align, tunit, tunit);
4097 fields.push_back(fieldType);
4101 llvm::raw_svector_ostream(typeName)
4102 <<
"__block_literal_" << CGM.getUniqueBlockCount();
4104 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
4106 llvm::DIType *type =
4107 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
4108 CGM.getContext().toBits(block.
BlockSize), 0,
4109 llvm::DINode::FlagZero,
nullptr, fieldsArray);
4110 type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
4113 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
4114 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
4117 auto *debugVar = DBuilder.createParameterVariable(
4118 scope, Name, ArgNo, tunit, line, type, CGM.getLangOpts().Optimize, flags);
4121 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
4122 llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
4123 Builder.GetInsertBlock());
4126 llvm::DIDerivedType *
4127 CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
4132 if (MI != StaticDataMemberCache.end()) {
4133 assert(MI->second &&
"Static data member declaration should still exist");
4140 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
4141 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
4144 llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
4145 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
4146 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
4147 llvm::DIGlobalVariableExpression *GVE =
nullptr;
4149 for (
const auto *Field : RD->
fields()) {
4150 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
4151 StringRef FieldName = Field->getName();
4154 if (FieldName.empty()) {
4155 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
4156 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
4161 GVE = DBuilder.createGlobalVariableExpression(
4162 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
4163 Var->hasLocalLinkage());
4164 Var->addDebugInfo(GVE);
4172 if (D->
hasAttr<NoDebugAttr>())
4178 if (Cached != DeclCache.end())
4179 return Var->addDebugInfo(
4180 cast<llvm::DIGlobalVariableExpression>(Cached->second));
4183 llvm::DIFile *Unit =
nullptr;
4184 llvm::DIScope *DContext =
nullptr;
4186 StringRef DeclName, LinkageName;
4188 llvm::MDTuple *TemplateParameters =
nullptr;
4189 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
4190 TemplateParameters, DContext);
4194 llvm::DIGlobalVariableExpression *GVE =
nullptr;
4202 "unnamed non-anonymous struct or union?");
4203 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
4208 unsigned AddressSpace =
4209 CGM.getContext().getTargetAddressSpace(D->
getType());
4210 AppendAddressSpaceXDeref(AddressSpace, Expr);
4212 GVE = DBuilder.createGlobalVariableExpression(
4213 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
4214 Var->hasLocalLinkage(),
4215 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
4216 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
4218 Var->addDebugInfo(GVE);
4225 if (VD->
hasAttr<NoDebugAttr>())
4229 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4230 StringRef Name = VD->
getName();
4231 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
4232 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
4233 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
4234 assert(isa<EnumType>(ED->getTypeForDecl()) &&
"Enum without EnumType?");
4235 Ty = getOrCreateType(
QualType(ED->getTypeForDecl(), 0), Unit);
4240 if (Ty->getTag() == llvm::dwarf::DW_TAG_enumeration_type)
4246 auto *VarD = cast<VarDecl>(VD);
4247 if (VarD->isStaticDataMember()) {
4248 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
4249 getDeclContextDescriptor(VarD);
4254 RetainedTypes.push_back(
4255 CGM.getContext().getRecordType(RD).getAsOpaquePtr());
4259 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
4261 auto &GV = DeclCache[VD];
4264 llvm::DIExpression *InitExpr =
nullptr;
4265 if (CGM.getContext().getTypeSize(VD->
getType()) <= 64) {
4269 DBuilder.createConstantValueExpression(Init.
getInt().getExtValue());
4271 InitExpr = DBuilder.createConstantValueExpression(
4272 Init.
getFloat().bitcastToAPInt().getZExtValue());
4275 llvm::MDTuple *TemplateParameters =
nullptr;
4277 if (isa<VarTemplateSpecializationDecl>(VD))
4279 llvm::DINodeArray parameterNodes = CollectVarTemplateParams(VarD, &*Unit);
4280 TemplateParameters = parameterNodes.get();
4283 GV.reset(DBuilder.createGlobalVariableExpression(
4284 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
4285 true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
4286 TemplateParameters, Align));
4289 llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
4290 if (!LexicalBlockStack.empty())
4291 return LexicalBlockStack.back();
4292 llvm::DIScope *Mod = getParentModuleOrNull(D);
4293 return getContextDescriptor(D, Mod ? Mod : TheCU);
4301 CGM.getCodeGenOpts().DebugExplicitImport) {
4303 DBuilder.createImportedModule(
4305 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
4313 "We shouldn't be codegening an invalid UsingDecl containing no decls");
4322 if (
const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl()))
4323 if (
const auto *AT =
4325 if (AT->getDeducedType().isNull())
4327 if (llvm::DINode *
Target =
4328 getDeclarationOrDefinition(USD.getUnderlyingDecl())) {
4329 auto Loc = USD.getLocation();
4330 DBuilder.createImportedDeclaration(
4331 getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())),
Target,
4332 getOrCreateFile(Loc), getLineNumber(Loc));
4337 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
4342 DBuilder.createImportedDeclaration(
4344 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
4345 getLineNumber(Loc));
4349 llvm::DIImportedEntity *
4353 auto &VH = NamespaceAliasCache[&NA];
4355 return cast<llvm::DIImportedEntity>(VH);
4356 llvm::DIImportedEntity *R;
4358 if (
const auto *Underlying =
4361 R = DBuilder.createImportedDeclaration(
4363 EmitNamespaceAlias(*Underlying), getOrCreateFile(Loc),
4364 getLineNumber(Loc), NA.
getName());
4366 R = DBuilder.createImportedDeclaration(
4369 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
4375 CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
4379 auto I = NamespaceCache.find(NSDecl);
4380 if (I != NamespaceCache.end())
4381 return cast<llvm::DINamespace>(I->second);
4383 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
4385 llvm::DINamespace *NS =
4386 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
4387 NamespaceCache[NSDecl].reset(NS);
4392 assert(TheCU &&
"no main compile unit");
4393 TheCU->setDWOId(Signature);
4399 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
4400 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
4401 llvm::DIType *Ty = E.
Type->getDecl()->getDefinition()
4402 ? CreateTypeDefinition(E.Type, E.Unit)
4404 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
4407 if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
4409 for (
const auto &
P : ObjCMethodCache) {
4410 if (
P.second.empty())
4413 QualType QTy(
P.first->getTypeForDecl(), 0);
4414 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4415 assert(It != TypeCache.end());
4417 llvm::DICompositeType *InterfaceDecl =
4418 cast<llvm::DICompositeType>(It->second);
4421 auto CurrenetElts = InterfaceDecl->getElements();
4422 EltTys.append(CurrenetElts.begin(), CurrenetElts.end());
4423 for (
auto &MD :
P.second)
4424 EltTys.push_back(MD);
4425 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4426 DBuilder.replaceArrays(InterfaceDecl, Elements);
4430 for (
const auto &
P : ReplaceMap) {
4432 auto *Ty = cast<llvm::DIType>(
P.second);
4433 assert(Ty->isForwardDecl());
4435 auto It = TypeCache.find(
P.first);
4436 assert(It != TypeCache.end());
4439 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
4440 cast<llvm::DIType>(It->second));
4443 for (
const auto &
P : FwdDeclReplaceMap) {
4445 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
4446 llvm::Metadata *Repl;
4448 auto It = DeclCache.find(
P.first);
4452 if (It == DeclCache.end())
4457 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
4458 Repl = GVE->getVariable();
4459 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
4464 for (
auto &RT : RetainedTypes)
4465 if (
auto MD = TypeCache[RT])
4466 DBuilder.retainType(cast<llvm::DIType>(MD));
4468 DBuilder.finalize();
4475 if (
auto *DieTy = getOrCreateType(Ty, TheCU->getFile()))
4477 DBuilder.retainType(DieTy);
4481 if (LexicalBlockStack.empty())
4482 return llvm::DebugLoc();
4484 llvm::MDNode *
Scope = LexicalBlockStack.back();
4485 return llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc), Scope);
4488 llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs()
const {
4493 return llvm::DINode::FlagZero;
4498 bool SupportsDWARFv4Ext =
4499 CGM.getCodeGenOpts().DwarfVersion == 4 &&
4500 CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB;
4501 if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
4502 return llvm::DINode::FlagZero;
4504 return llvm::DINode::FlagAllCallsDescribed;
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
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 ...
const Type * getTypeForDecl() const
VarDecl * getCapturedVar() const
Retrieve the declaration of the local variable being captured.
const Capture & getCapture(const VarDecl *var) const
Represents a function declaration or definition.
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Setter)
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Smart pointer class that efficiently represents Objective-C method names.
A class which contains all the information about a particular captured value.
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
StringRef getName(const PrintingPolicy &Policy) const
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getElementType() const
QualType getPointeeType() const
void EmitLocation(raw_ostream &o, const SourceManager &SM, SourceLocation L, const FIDMap &FM, unsigned indent)
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not...
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx)
A (possibly-)qualified type.
const CodeGenOptions & getCodeGenOpts() const
ObjCInterfaceDecl * getClassInterface()
void EmitExplicitCastType(QualType Ty)
Emit the type explicitly casted to.
static ClassTemplateDecl * getDefinition(ClassTemplateDecl *D)
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Defines the clang::FileManager interface and associated types.
bool isMemberDataPointerType() const
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number...
TypePropertyCache< Private > Cache
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
FunctionType - C99 6.7.5.3 - Function Declarators.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Defines the SourceManager interface.
QualType getThisType() const
Returns the type of the this pointer.
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts)
The template argument is an expression, and we've not resolved it to one of the other forms yet...
bool isRecordType() const
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
const Type * getTypeForDecl() const
Decl - This represents one declaration (or definition), e.g.
TagDecl * getDecl() const
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
Defines the C++ template declaration subclasses.
Parameter for C++ 'this' argument.
static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C)
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, const ObjCMethodDecl *Getter)
The base class of the type hierarchy.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Declaration of a variable template.
The template argument is a declaration that was provided for a pointer, reference, or pointer to member non-type template parameter.
Represent a C++ namespace.
NamedDecl * getParam(unsigned Idx)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
RefQualifierKind RefQualifier
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
Describes the capture of a variable or of this, or of a C++1y init-capture.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
enumerator_range enumerators() const
Represents a variable declaration or definition.
void removeObjCLifetime()
QualType getReturnType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents an empty template argument, e.g., one that has not been deduced.
Extra information about a function prototype.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
A this pointer adjustment.
ObjCMethodDecl - Represents an instance or class method declaration.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Describes how types, statements, expressions, and declarations should be printed. ...
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD)
bool hasDefinition() const
Represents a parameter to a function.
QualType getIntegralType() const
Retrieve the type of the integral value.
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD)
The collection of all-type qualifiers we support.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
Represents a struct/union/class.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a class template specialization, which refers to a class template with a given set of temp...
One of these records is kept for each identifier that is lexed.
std::map< std::string, std::string > DebugPrefixMap
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS=false) const
Print the template name.
Represents a class type in Objective C.
QualType getPointeeType() const
CGDebugInfo * getDebugInfo()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isInline() const
Returns true if this is an inline namespace declaration.
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
static bool isFunctionLocalClass(const CXXRecordDecl *RD)
isFunctionLocalClass - Return true if CXXRecordDecl is defined inside a function. ...
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
void EmitImportDecl(const ImportDecl &ID)
Emit an declaration.
field_range fields() const
Represents a member of a struct/union/class.
StringRef getPath() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
prop_range properties() const
void completeClassData(const RecordDecl *RD)
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a #define directive or a macro undefined by a #undef directi...
method_iterator method_begin() const
Method begin iterator.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
QualType getParamTypeForDecl() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
ArrayRef< ParmVarDecl * > parameters() const
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Represents a C++ using-declaration.
Type(TypeClass tc, QualType canon, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack)
const TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
ArrayRef< VTableComponent > vtable_components() const
unsigned Size
The total size of the bit-field, in bits.
An rvalue reference type, per C++11 [dcl.ref].
bool isBitField() const
Determines whether this field is a bitfield.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
An lvalue ref-qualifier was provided (&).
~ApplyInlineDebugLocation()
Restore everything back to the original state.
CharUnits - This is an opaque type for sizes expressed in character units.
bool capturesThis() const
Determine whether this capture handles the C++ this pointer.
APValue Val
Val - This is the value the expression can be folded to.
const BlockDecl * getBlockDecl() const
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Emit location information but do not generate debug info in the output.
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
bool isByRef() const
Whether this is a "by ref" capture, i.e.
Represents a declaration of a type.
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU)
Module * Parent
The parent of this module.
const Type * getClass() const
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
bool isLambda() const
Determine whether this class describes a lambda function object.
Scope - A scope is a transient data structure that is used while parsing the program.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
llvm::DIType * getOrCreateInterfaceType(QualType Ty, SourceLocation Loc)
Emit an Objective-C interface type standalone debug info.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
field_iterator field_begin() const
bool isCompleteDefinitionRequired() const
Return true if this complete decl is required to be complete for some existing use.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx)
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn)
Constructs the debug code for exiting a function.
llvm::DIImportedEntity * EmitNamespaceAlias(const NamespaceAliasDecl &NA)
Emit C++ namespace alias.
void * getAsOpaquePtr() const
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization, retrieves the function from which it was instantiated.
Represents an ObjC class declaration.
shadow_iterator shadow_begin() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Module * getImportedModule() const
Retrieve the module that was imported by the import declaration.
const Module * getModuleOrNull() const
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
unsigned getIndex() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
QualType getBlockDescriptorExtendedType() const
Gets the struct used to keep track of the extended descriptor for pointer to blocks.
static unsigned getDwarfCC(CallingConv CC)
QualType getBaseType() const
Gets the base type of this object type.
Represents a prototype with parameter type info, e.g.
bool isDynamicClass() const
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
ASTFileSignature getSignature() const
CGBlockInfo - Information to generate a block literal.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Represents a ValueDecl that came out of a declarator.
std::string getModuleName() const
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ObjCTypeParamDecl * getDecl() const
void setDwoId(uint64_t Signature)
Module debugging: Support for building PCMs.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
capture_const_iterator captures_end() const
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate a change in line/column information in the source file. ...
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn)
Set up the CodeGenFunction's DebugInfo to produce inline locations for the function InlinedFn...
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
QualType getPointeeType() const
known_extensions_range known_extensions() const
Emit only debug info necessary for generating line number tables (-gline-tables-only).
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isVariadic() const
Whether this function is variadic.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD)
Start a new scope for an inlined function.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
const AnnotatedLine * Line
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
const T * castAs() const
Member-template castAs<specific type>.
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
unsigned getLine() const
Return the presumed line number of this location.
Represents a C++ destructor within a class.
Defines version macros and version-related utility functions for Clang.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an #include directive.
field_iterator field_end() const
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
DeclContext * getDeclContext()
ObjCInterfaceDecl * getSuperClass() const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
void completeUnusedClass(const CXXRecordDecl &D)
EnumDecl * getDefinition() const
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
clang::ObjCRuntime ObjCRuntime
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl, 0 if there are none.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
method_iterator method_end() const
Method past-the-end iterator.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInstanceMethod() const
QualType getBlockDescriptorType() const
Gets the struct used to keep track of the descriptor for pointer to blocks.
Represents a GCC generic vector type.
SourceLocation getCaretLocation() const
An lvalue reference type, per C++11 [dcl.ref].
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Selector getSelector() const
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 isNull() const
Return true if this QualType doesn't point to a type yet.
ImplicitParamDecl * getSelfDecl() const
static json::Object createFile(const FileEntry &FE)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
bool isObjCOneArgSelector() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
const char * getFilename() const
Return the presumed filename of this location.
void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for an argument variable declaration.
bool capturesVariable() const
Determine whether this capture handles a variable.
Pass it as a pointer to temporary memory.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
virtual void printName(raw_ostream &os) const
unsigned size_overridden_methods() const
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType)
Emit debug info for a function declaration.
StringRef getASTFile() const
static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD)
Convert an AccessSpecifier into the corresponding DINode flag.
std::string getAsString() const
Derive the full selector name (e.g.
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &)=0
ExtProtoInfo getExtProtoInfo() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
unsigned getColumn() const
Return the presumed column number of this location.
Encodes a location in the source.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
QualType getReturnType() const
bool isPure() const
Whether this virtual function is pure, i.e.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Interfaces are the core concept in Objective-C for object oriented design.
llvm::StructType * StructureType
void completeRequiredType(const RecordDecl *RD)
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...
Limit generated debug info to reduce size (-fno-standalone-debug).
Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
QualType getElementType() const
const Decl * getDecl() const
static QualType getUnderlyingType(const SubRegion *R)
Cached information about one file (either on disk or in the virtual file system). ...
Represents a static or instance method of a struct/union/class.
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
ObjCCategoryDecl - Represents a category declaration.
unsigned RemapFilePaths
Whether to apply -fdebug-prefix-map to any file paths.
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded...
Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
Represents one property declaration in an Objective-C interface.
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
const BlockExpr * getBlockExpr() const
TypeClass getTypeClass() const
MangleContext & getMangleContext()
Gets the mangle context.
This template specialization was formed from a template-id but has not yet been declared, defined, or instantiated.
constexpr XRayInstrMask None
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
VarDecl * getVariable() const
The variable being captured.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
EnumDecl * getDecl() const
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
An rvalue ref-qualifier was provided (&&).
ObjCImplementationDecl * getImplementation() const
static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End)
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc)
Describes a module import declaration, which makes the contents of the named module visible in the cu...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
StringRef getName() const
Return the actual identifier string.
Base class for declarations which introduce a typedef-name.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a template argument.
void completeClass(const RecordDecl *RD)
This class organizes the cross-function state that is used while generating LLVM code.
NamespaceDecl * getNominatedNamespace()
Returns the namespace nominated by this using-directive.
Dataflow Directional Tag Classes.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
bool isValid() const
Return true if this is a valid SourceLocation object.
A qualifier set is used to build a set of qualifiers.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
EvalResult is a struct with detailed info about an evaluated expression.
uint64_t Index
Method's index in the vftable.
ArrayRef< Capture > captures() const
static SmallString< 256 > getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
The template argument is a pack expansion of a template name that was provided for a template templat...
Parameter for Objective-C 'self' argument.
QualType getUnderlyingType() const
llvm::iterator_range< base_class_const_iterator > base_class_const_range
const Expr * getInit() const
AccessSpecifier getAccess() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
FileID getMainFileID() const
Returns the FileID of the main source file.
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Emit only debug directives with the line numbers data.
This template specialization was instantiated from a template due to an explicit instantiation declar...
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks, lambdas, etc.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
CGDebugInfo(CodeGenModule &CGM)
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A pointer to member type per C++ 8.3.3 - Pointers to members.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
Represents a pointer to an Objective C object.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
bool isIncompleteArrayType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
Don't generate debug info.
void EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, bool CurFnIsThunk, CGBuilderTy &Builder)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
std::string remapDIPath(StringRef) const
Remap a given path with the current debug prefix map.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
void completeType(const EnumDecl *ED)
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
The template argument is a type.
The template argument is actually a parameter pack.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
bool capturesCXXThis() const
std::function< std::string(StringRef)> remapPath
When RemapFilePaths is true, this function performs the action.
A template argument list.
TypedefNameDecl * getDecl() const
void EmitUsingDecl(const UsingDecl &UD)
Emit C++ using declaration.
void EmitUsingDirective(const UsingDirectiveDecl &UD)
Emit C++ using directive.
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack...
ArgKind getKind() const
Return the kind of stored template argument.
Represents a type parameter type in Objective C.
CallingConv getCallConv() const
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
TypedefNameDecl * getTypedefNameForAnonDecl() const
Represents a C++ struct/union/class.
ArrayRef< TemplateArgument > template_arguments() const
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
The template argument is a template name that was provided for a template template parameter...
ObjCIvarDecl - Represents an ObjC instance variable.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
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.
This class is used for builtin types like 'int'.
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...
SourceLocation getLocation() const
Retrieve the source location of the capture.
bool isComplexIntegerType() const
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
void setLocation(SourceLocation Loc)
Update the current source location.
CGCXXABI & getCXXABI() const
std::string getQualifiedNameAsString() const
Abstracts clang modules and precompiled header files and holds everything needed to generate debug in...
unsigned getNumElements() const
QualType getAsType() const
Retrieve the type for a type template argument.
Represents a type template specialization; the template must be a class template, a type alias templa...
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD)
Return true if the class or any of its methods are marked dllimport.
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
capture_const_iterator captures_begin() const
bool isStaticDataMember() const
Determines whether this is a static data member.
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
A wrapper class around a pointer that always points to its canonical declaration. ...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
Represents a C++ namespace alias.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
static bool isDefinedInClangModule(const RecordDecl *RD)
Does a type definition exist in an imported clang module?
Represents C++ using-directive.
void removeAddressSpace()
bool isObjCZeroArgSelector() const
base_class_range vbases()
This class handles loading and caching of source files into memory.
SourceLocation getLocation() const
QualType getPointeeType() const
Represents a shadow declaration introduced into a scope by a (resolved) using declaration.
bool isExternallyVisible() const
Structure with information about how a bitfield should be accessed.
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
method_range methods() const