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/Module.h" 45 #include "llvm/Support/FileSystem.h" 46 #include "llvm/Support/MD5.h" 47 #include "llvm/Support/Path.h" 48 using namespace clang;
65 : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
66 DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
67 DBuilder(CGM.getModule()) {
69 DebugPrefixMap[KV.first] = KV.second;
74 assert(LexicalBlockStack.empty() &&
75 "Region stack mismatch, stack not empty!");
81 init(TemporaryLocation);
88 init(TemporaryLocation, DefaultToEmpty);
92 bool DefaultToEmpty) {
99 OriginalLocation = CGF->
Builder.getCurrentDebugLocation();
101 if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
104 if (TemporaryLocation.
isValid()) {
105 DI->EmitLocation(CGF->
Builder, TemporaryLocation);
109 if (DefaultToEmpty) {
110 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
115 assert(!DI->LexicalBlockStack.empty());
116 CGF->
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
117 0, 0, DI->LexicalBlockStack.back(), DI->getInlinedAt()));
131 OriginalLocation = CGF.
Builder.getCurrentDebugLocation();
133 CGF.
Builder.SetCurrentDebugLocation(std::move(Loc));
140 CGF->
Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
151 SavedLocation = DI.getLocation();
152 assert((DI.getInlinedAt() ==
153 CGF.
Builder.getCurrentDebugLocation()->getInlinedAt()) &&
154 "CGDebugInfo and IRBuilder are out of sync");
156 DI.EmitInlineFunctionStart(CGF.
Builder, InlinedFn);
164 DI.EmitLocation(CGF->
Builder, SavedLocation);
172 CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
177 if (LexicalBlockStack.empty())
181 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
184 if (PCLoc.isInvalid() ||
Scope->getFilename() == PCLoc.getFilename())
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),
223 getOrCreateMainFile());
234 if (CGM.getCodeGenOpts().EmitCodeView)
240 StringRef CGDebugInfo::getFunctionName(
const FunctionDecl *FD) {
241 assert(FD &&
"Invalid FunctionDecl!");
253 CGM.getCodeGenOpts().EmitCodeView;
255 if (!Info && FII && !UseQualifiedName)
259 llvm::raw_svector_ostream OS(NS);
260 if (!UseQualifiedName)
272 return internString(OS.str());
275 StringRef CGDebugInfo::getObjCMethodName(
const ObjCMethodDecl *OMD) {
277 llvm::raw_svector_ostream OS(MethodName);
280 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
281 OS << OID->getName();
282 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
283 OS << OID->getName();
284 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
285 if (OC->IsClassExtension()) {
286 OS << OC->getClassInterface()->getName();
288 OS << OC->getIdentifier()->getNameStart() <<
'(' 289 << OC->getIdentifier()->getNameStart() <<
')';
291 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
292 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
293 }
else if (isa<ObjCProtocolDecl>(DC)) {
297 cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
303 return internString(OS.str());
306 StringRef CGDebugInfo::getSelectorName(
Selector S) {
310 StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
311 if (isa<ClassTemplateSpecializationDecl>(RD)) {
313 llvm::raw_svector_ostream OS(Name);
318 return internString(Name);
324 return II->getName();
328 if (CGM.getCodeGenOpts().EmitCodeView) {
331 "Typedef should not be in another decl context!");
332 assert(D->getDeclName().getAsIdentifierInfo() &&
333 "Typedef was not named!");
334 return D->getDeclName().getAsIdentifierInfo()->getName();
337 if (CGM.getLangOpts().CPlusPlus) {
344 Name = DD->getName();
349 Name = TND->getName();
355 return internString(UnnamedType);
367 if (!CGM.getCodeGenOpts().EmitCodeView &&
368 CGM.getCodeGenOpts().DwarfVersion < 5)
373 llvm::MemoryBuffer *MemBuffer = SM.
getBuffer(FID, &Invalid);
378 llvm::MD5::MD5Result Result;
380 Hash.update(MemBuffer->getBuffer());
383 Hash.stringifyResult(Result, Checksum);
384 return llvm::DIFile::CSK_MD5;
389 if (!CGM.getCodeGenOpts().EmbedSource)
392 bool SourceInvalid =
false;
404 return getOrCreateMainFile();
411 return getOrCreateMainFile();
415 auto It = DIFileCache.find(fname);
417 if (It != DIFileCache.end()) {
419 if (llvm::Metadata *V = It->second)
420 return cast<llvm::DIFile>(V);
425 computeChecksum(SM.
getFileID(Loc), Checksum);
428 CSInfo.emplace(*CSKind, Checksum);
430 llvm::DIFile *F = DBuilder.createFile(
431 remapDIPath(PLoc.
getFilename()), remapDIPath(getCurrentDirname()), CSInfo,
434 DIFileCache[fname].reset(F);
438 llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
439 return DBuilder.createFile(
440 remapDIPath(TheCU->getFilename()), remapDIPath(TheCU->getDirectory()),
441 TheCU->getFile()->getChecksum(),
442 CGM.getCodeGenOpts().EmbedSource ? TheCU->getSource() : None);
445 std::string CGDebugInfo::remapDIPath(StringRef Path)
const {
446 for (
const auto &Entry : DebugPrefixMap)
447 if (Path.startswith(Entry.first))
448 return (Twine(Entry.second) + Path.substr(Entry.first.size())).str();
453 if (Loc.
isInvalid() && CurLoc.isInvalid())
460 unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
462 if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
466 if (Loc.
isInvalid() && CurLoc.isInvalid())
473 StringRef CGDebugInfo::getCurrentDirname() {
474 if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())
475 return CGM.getCodeGenOpts().DebugCompilationDir;
477 if (!CWDName.empty())
480 llvm::sys::fs::current_path(CWD);
481 return CWDName = internString(CWD);
484 void CGDebugInfo::CreateCompileUnit() {
498 std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
499 if (MainFileName.empty())
500 MainFileName =
"<stdin>";
506 std::string MainFileDir;
508 MainFileDir = remapDIPath(MainFile->getDir()->getName());
509 if (MainFileDir !=
".") {
511 llvm::sys::path::append(MainFileDirSS, MainFileName);
512 MainFileName = MainFileDirSS.str();
518 if (MainFile->getName() == MainFileName &&
520 MainFile->getName().rsplit(
'.').second)
522 MainFileName = CGM.getModule().getName().str();
527 llvm::dwarf::SourceLanguage LangTag;
531 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
533 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
534 }
else if (LO.ObjC1) {
535 LangTag = llvm::dwarf::DW_LANG_ObjC;
536 }
else if (LO.RenderScript) {
537 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
539 LangTag = llvm::dwarf::DW_LANG_C99;
541 LangTag = llvm::dwarf::DW_LANG_C89;
547 unsigned RuntimeVers = 0;
551 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
555 EmissionKind = llvm::DICompileUnit::NoDebug;
558 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
562 EmissionKind = llvm::DICompileUnit::FullDebug;
567 CSInfo.emplace(*CSKind, Checksum);
571 auto &CGOpts = CGM.getCodeGenOpts();
572 TheCU = DBuilder.createCompileUnit(
574 DBuilder.createFile(remapDIPath(MainFileName),
575 remapDIPath(getCurrentDirname()), CSInfo,
577 CGOpts.EmitVersionIdentMetadata ? Producer :
"",
578 LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
579 CGOpts.DwarfDebugFlags, RuntimeVers,
580 CGOpts.EnableSplitDwarf ?
"" : CGOpts.SplitDwarfFile, EmissionKind,
581 0 , CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
585 llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
589 #define BUILTIN_TYPE(Id, SingletonId) 590 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 591 #include "clang/AST/BuiltinTypes.def" 592 case BuiltinType::Dependent:
593 llvm_unreachable(
"Unexpected builtin type");
594 case BuiltinType::NullPtr:
595 return DBuilder.createNullPtrType();
596 case BuiltinType::Void:
598 case BuiltinType::ObjCClass:
600 ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
602 getOrCreateMainFile(), 0);
604 case BuiltinType::ObjCId: {
614 ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
616 getOrCreateMainFile(), 0);
618 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
620 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
622 ObjTy = DBuilder.createStructType(
623 TheCU,
"objc_object", getOrCreateMainFile(), 0, 0, 0,
624 llvm::DINode::FlagZero,
nullptr, llvm::DINodeArray());
626 DBuilder.replaceArrays(
627 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
628 ObjTy,
"isa", getOrCreateMainFile(), 0, Size, 0, 0,
629 llvm::DINode::FlagZero, ISATy)));
632 case BuiltinType::ObjCSel: {
634 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
635 "objc_selector", TheCU,
636 getOrCreateMainFile(), 0);
640 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 641 case BuiltinType::Id: \ 642 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \ 644 #include "clang/Basic/OpenCLImageTypes.def" 645 case BuiltinType::OCLSampler:
646 return getOrCreateStructPtrType(
"opencl_sampler_t", OCLSamplerDITy);
647 case BuiltinType::OCLEvent:
648 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
649 case BuiltinType::OCLClkEvent:
650 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
651 case BuiltinType::OCLQueue:
652 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
653 case BuiltinType::OCLReserveID:
654 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
656 case BuiltinType::UChar:
657 case BuiltinType::Char_U:
658 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
660 case BuiltinType::Char_S:
661 case BuiltinType::SChar:
662 Encoding = llvm::dwarf::DW_ATE_signed_char;
664 case BuiltinType::Char8:
665 case BuiltinType::Char16:
666 case BuiltinType::Char32:
667 Encoding = llvm::dwarf::DW_ATE_UTF;
669 case BuiltinType::UShort:
670 case BuiltinType::UInt:
671 case BuiltinType::UInt128:
672 case BuiltinType::ULong:
673 case BuiltinType::WChar_U:
674 case BuiltinType::ULongLong:
675 Encoding = llvm::dwarf::DW_ATE_unsigned;
677 case BuiltinType::Short:
678 case BuiltinType::Int:
679 case BuiltinType::Int128:
680 case BuiltinType::Long:
681 case BuiltinType::WChar_S:
682 case BuiltinType::LongLong:
683 Encoding = llvm::dwarf::DW_ATE_signed;
685 case BuiltinType::Bool:
686 Encoding = llvm::dwarf::DW_ATE_boolean;
688 case BuiltinType::Half:
689 case BuiltinType::Float:
690 case BuiltinType::LongDouble:
691 case BuiltinType::Float16:
692 case BuiltinType::Float128:
693 case BuiltinType::Double:
699 Encoding = llvm::dwarf::DW_ATE_float;
701 case BuiltinType::ShortAccum:
702 case BuiltinType::Accum:
703 case BuiltinType::LongAccum:
704 case BuiltinType::ShortFract:
705 case BuiltinType::Fract:
706 case BuiltinType::LongFract:
707 case BuiltinType::SatShortFract:
708 case BuiltinType::SatFract:
709 case BuiltinType::SatLongFract:
710 case BuiltinType::SatShortAccum:
711 case BuiltinType::SatAccum:
712 case BuiltinType::SatLongAccum:
713 Encoding = llvm::dwarf::DW_ATE_signed_fixed;
715 case BuiltinType::UShortAccum:
716 case BuiltinType::UAccum:
717 case BuiltinType::ULongAccum:
718 case BuiltinType::UShortFract:
719 case BuiltinType::UFract:
720 case BuiltinType::ULongFract:
721 case BuiltinType::SatUShortAccum:
722 case BuiltinType::SatUAccum:
723 case BuiltinType::SatULongAccum:
724 case BuiltinType::SatUShortFract:
725 case BuiltinType::SatUFract:
726 case BuiltinType::SatULongFract:
727 Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
732 case BuiltinType::Long:
735 case BuiltinType::LongLong:
736 BTName =
"long long int";
738 case BuiltinType::ULong:
739 BTName =
"long unsigned int";
741 case BuiltinType::ULongLong:
742 BTName =
"long long unsigned int";
745 BTName = BT->
getName(CGM.getLangOpts());
749 uint64_t Size = CGM.getContext().getTypeSize(BT);
750 return DBuilder.createBasicType(BTName, Size, Encoding);
753 llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
755 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
757 Encoding = llvm::dwarf::DW_ATE_lo_user;
759 uint64_t Size = CGM.getContext().getTypeSize(Ty);
760 return DBuilder.createBasicType(
"complex", Size, Encoding);
763 llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
764 llvm::DIFile *Unit) {
775 llvm::dwarf::Tag Tag;
777 Tag = llvm::dwarf::DW_TAG_const_type;
780 Tag = llvm::dwarf::DW_TAG_volatile_type;
783 Tag = llvm::dwarf::DW_TAG_restrict_type;
786 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
787 return getOrCreateType(
QualType(T, 0), Unit);
790 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(), T), Unit);
794 return DBuilder.createQualifiedType(Tag, FromTy);
798 llvm::DIFile *Unit) {
804 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
806 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
810 llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
811 llvm::DIFile *Unit) {
812 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
818 switch (TheCU->getSourceLanguage()) {
819 case llvm::dwarf::DW_LANG_C_plus_plus:
821 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
822 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
830 llvm::DICompileUnit *TheCU) {
854 llvm::DICompileUnit *TheCU) {
855 SmallString<256> Identifier;
863 llvm::raw_svector_ostream Out(Identifier);
870 llvm::dwarf::Tag Tag;
872 Tag = llvm::dwarf::DW_TAG_structure_type;
874 Tag = llvm::dwarf::DW_TAG_union_type;
879 Tag = llvm::dwarf::DW_TAG_class_type;
884 llvm::DICompositeType *
885 CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
886 llvm::DIScope *Ctx) {
888 if (llvm::DIType *T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
889 return cast<llvm::DICompositeType>(T);
890 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
892 StringRef RDName = getClassName(RD);
899 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
901 llvm::DINode::FlagFwdDecl, Identifier);
902 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
903 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
904 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
905 CollectCXXTemplateParams(TSpecial, DefUnit));
906 ReplaceMap.emplace_back(
907 std::piecewise_construct, std::make_tuple(Ty),
908 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
912 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
915 llvm::DIFile *Unit) {
919 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy);
920 uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace);
923 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
925 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
926 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
927 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
928 Size, Align, DWARFAddressSpace);
930 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
931 Align, DWARFAddressSpace);
934 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
935 llvm::DIType *&
Cache) {
938 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
939 TheCU, getOrCreateMainFile(), 0);
940 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
941 Cache = DBuilder.createPointerType(Cache, Size);
946 llvm::DIFile *Unit) {
949 uint64_t FieldSize, FieldOffset;
951 llvm::DINodeArray Elements;
954 FType = CGM.getContext().UnsignedLongTy;
955 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
956 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
958 Elements = DBuilder.getOrCreateArray(EltTys);
961 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
965 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, LineNo,
966 FieldOffset, 0, Flags,
nullptr, Elements);
969 uint64_t Size = CGM.getContext().getTypeSize(Ty);
971 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
974 if (CGM.getLangOpts().OpenCL) {
975 FType = CGM.getContext().IntTy;
976 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
977 EltTys.push_back(CreateMemberType(Unit, FType,
"__align", &FieldOffset));
979 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
980 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
981 FType = CGM.getContext().IntTy;
982 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
983 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
985 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
986 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
987 FieldSize = CGM.getContext().getTypeSize(Ty);
988 FieldAlign = CGM.getContext().getTypeAlign(Ty);
989 EltTys.push_back(DBuilder.createMemberType(
990 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign, FieldOffset,
991 llvm::DINode::FlagZero, DescTy));
992 FieldOffset += FieldSize;
995 Elements = DBuilder.getOrCreateArray(EltTys);
1001 EltTy = DBuilder.createStructType(Unit,
"",
nullptr, LineNo, FieldOffset, 0,
1002 Flags,
nullptr, Elements);
1004 return DBuilder.createPointerType(EltTy, Size);
1008 llvm::DIFile *Unit) {
1012 SmallString<128> NS;
1013 llvm::raw_svector_ostream OS(NS);
1019 ->getTemplatedDecl();
1022 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
1024 getDeclContextDescriptor(AliasDecl));
1027 llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
1028 llvm::DIFile *Unit) {
1034 return DBuilder.createTypedef(
1036 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
1037 getDeclContextDescriptor(Ty->
getDecl()));
1047 return llvm::dwarf::DW_CC_BORLAND_stdcall;
1049 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
1051 return llvm::dwarf::DW_CC_BORLAND_thiscall;
1053 return llvm::dwarf::DW_CC_LLVM_vectorcall;
1055 return llvm::dwarf::DW_CC_BORLAND_pascal;
1057 return llvm::dwarf::DW_CC_LLVM_Win64;
1059 return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
1061 return llvm::dwarf::DW_CC_LLVM_AAPCS;
1063 return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
1065 return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
1067 return llvm::dwarf::DW_CC_LLVM_SpirFunction;
1069 return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
1071 return llvm::dwarf::DW_CC_LLVM_Swift;
1073 return llvm::dwarf::DW_CC_LLVM_PreserveMost;
1075 return llvm::dwarf::DW_CC_LLVM_PreserveAll;
1077 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
1082 llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1083 llvm::DIFile *Unit) {
1087 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1091 if (isa<FunctionNoProtoType>(Ty))
1092 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1093 else if (
const auto *FPT = dyn_cast<FunctionProtoType>(Ty)) {
1094 for (
const QualType &ParamType : FPT->param_types())
1095 EltTys.push_back(getOrCreateType(ParamType, Unit));
1096 if (FPT->isVariadic())
1097 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1100 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1101 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
1116 if (Access == Default)
1117 return llvm::DINode::FlagZero;
1121 return llvm::DINode::FlagPrivate;
1123 return llvm::DINode::FlagProtected;
1125 return llvm::DINode::FlagPublic;
1127 return llvm::DINode::FlagZero;
1129 llvm_unreachable(
"unexpected access enumerator");
1132 llvm::DIType *CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1133 llvm::DIScope *RecordTy,
1135 StringRef Name = BitFieldDecl->
getName();
1138 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1139 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1142 llvm::DIFile *File = getOrCreateFile(Loc);
1143 unsigned Line = getLineNumber(Loc);
1146 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1147 uint64_t SizeInBits = BitFieldInfo.
Size;
1148 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1149 uint64_t StorageOffsetInBits =
1155 if (CGM.getDataLayout().isBigEndian())
1157 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1159 return DBuilder.createBitFieldMemberType(
1160 RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1167 uint32_t AlignInBits, llvm::DIFile *tunit,
1168 llvm::DIScope *scope,
const RecordDecl *RD) {
1169 llvm::DIType *debugType = getOrCreateType(type, tunit);
1172 llvm::DIFile *file = getOrCreateFile(loc);
1173 unsigned line = getLineNumber(loc);
1175 uint64_t SizeInBits = 0;
1176 auto Align = AlignInBits;
1178 TypeInfo TI = CGM.getContext().getTypeInfo(type);
1179 SizeInBits = TI.
Width;
1185 return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
1186 offsetInBits, flags, debugType);
1189 void CGDebugInfo::CollectRecordLambdaFields(
1191 llvm::DIType *RecordTy) {
1195 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
1197 unsigned fieldno = 0;
1200 I != E; ++I, ++Field, ++fieldno) {
1204 assert(!Field->isBitField() &&
"lambdas don't have bitfield members!");
1206 StringRef VName = V->
getName();
1207 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1209 llvm::DIType *FieldType = createFieldType(
1210 VName, Field->getType(), Loc, Field->getAccess(),
1211 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1212 elements.push_back(FieldType);
1219 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1221 llvm::DIType *fieldType = createFieldType(
1225 elements.push_back(fieldType);
1230 llvm::DIDerivedType *
1231 CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1236 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1237 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1239 unsigned LineNumber = getLineNumber(Var->
getLocation());
1240 StringRef VName = Var->
getName();
1241 llvm::Constant *C =
nullptr;
1246 C = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->
getInt());
1248 C = llvm::ConstantFP::get(CGM.getLLVMContext(), Value->
getFloat());
1254 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1255 RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align);
1260 void CGDebugInfo::CollectRecordNormalField(
1261 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1264 StringRef name = field->
getName();
1271 llvm::DIType *FieldType;
1273 FieldType = createBitFieldType(field, RecordTy, RD);
1278 OffsetInBits, Align, tunit, RecordTy, RD);
1281 elements.push_back(FieldType);
1284 void CGDebugInfo::CollectRecordNestedType(
1286 QualType Ty = CGM.getContext().getTypeDeclType(TD);
1288 if (isa<InjectedClassNameType>(Ty))
1291 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc));
1292 elements.push_back(nestedType);
1295 void CGDebugInfo::CollectRecordFields(
1296 const RecordDecl *record, llvm::DIFile *tunit,
1298 llvm::DICompositeType *RecordTy) {
1301 if (CXXDecl && CXXDecl->
isLambda())
1302 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1304 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
1307 unsigned fieldNo = 0;
1311 for (
const auto *I : record->
decls())
1312 if (
const auto *V = dyn_cast<VarDecl>(I)) {
1313 if (V->hasAttr<NoDebugAttr>())
1318 if (CGM.getCodeGenOpts().EmitCodeView &&
1319 isa<VarTemplateSpecializationDecl>(V))
1323 auto MI = StaticDataMemberCache.find(V->getCanonicalDecl());
1324 if (MI != StaticDataMemberCache.end()) {
1325 assert(MI->second &&
1326 "Static data member declaration should still exist");
1327 elements.push_back(MI->second);
1329 auto Field = CreateRecordStaticField(V, RecordTy, record);
1330 elements.push_back(Field);
1332 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1333 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1334 elements, RecordTy, record);
1338 }
else if (CGM.getCodeGenOpts().EmitCodeView) {
1341 if (
const auto *nestedType = dyn_cast<TypeDecl>(I))
1342 if (!nestedType->isImplicit() &&
1343 nestedType->getDeclContext() == record)
1344 CollectRecordNestedType(nestedType, elements);
1349 llvm::DISubroutineType *
1350 CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1351 llvm::DIFile *Unit) {
1354 return cast_or_null<llvm::DISubroutineType>(
1355 getOrCreateType(
QualType(Func, 0), Unit));
1356 return getOrCreateInstanceMethodType(Method->
getThisType(CGM.getContext()),
1360 llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1363 llvm::DITypeRefArray Args(
1364 cast<llvm::DISubroutineType>(getOrCreateType(
QualType(Func, 0), Unit))
1366 assert(Args.size() &&
"Invalid number of arguments!");
1371 Elts.push_back(Args[0]);
1375 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1377 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1379 unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
1380 uint64_t Size = CGM.getTarget().getPointerWidth(AS);
1382 llvm::DIType *PointeeType = getOrCreateType(PointeeTy, Unit);
1383 llvm::DIType *ThisPtrType =
1384 DBuilder.createPointerType(PointeeType, Size, Align);
1389 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1390 Elts.push_back(ThisPtrType);
1392 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1394 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1395 Elts.push_back(ThisPtrType);
1399 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1400 Elts.push_back(Args[i]);
1402 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1404 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1406 Flags |= llvm::DINode::FlagLValueReference;
1408 Flags |= llvm::DINode::FlagRValueReference;
1410 return DBuilder.createSubroutineType(EltTypeArray, Flags,
1417 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1424 llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1425 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1427 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1429 StringRef MethodName = getFunctionName(Method);
1430 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1434 StringRef MethodLinkageName;
1441 MethodLinkageName = CGM.getMangledName(Method);
1444 llvm::DIFile *MethodDefUnit =
nullptr;
1445 unsigned MethodLine = 0;
1447 MethodDefUnit = getOrCreateFile(Method->
getLocation());
1448 MethodLine = getLineNumber(Method->
getLocation());
1452 llvm::DIType *ContainingType =
nullptr;
1453 unsigned Virtuality = 0;
1454 unsigned VIndex = 0;
1455 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1460 Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;
1462 Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;
1464 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1467 if (!isa<CXXDestructorDecl>(Method))
1468 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method);
1475 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1484 Flags |= llvm::DINode::FlagIntroducedVirtual;
1489 ThisAdjustment = CGM.getCXXABI()
1490 .getVirtualFunctionPrologueThisAdjustment(GD)
1493 ContainingType = RecordTy;
1497 Flags |= llvm::DINode::FlagStaticMember;
1499 Flags |= llvm::DINode::FlagArtificial;
1501 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
1502 if (CXXC->isExplicit())
1503 Flags |= llvm::DINode::FlagExplicit;
1504 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
1505 if (CXXC->isExplicit())
1506 Flags |= llvm::DINode::FlagExplicit;
1509 Flags |= llvm::DINode::FlagPrototyped;
1511 Flags |= llvm::DINode::FlagLValueReference;
1513 Flags |= llvm::DINode::FlagRValueReference;
1515 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
1516 llvm::DISubprogram *SP = DBuilder.createMethod(
1517 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
1518 MethodTy,
false,
false, Virtuality,
1519 VIndex, ThisAdjustment, ContainingType, Flags, CGM.getLangOpts().Optimize,
1520 TParamsArray.get());
1527 void CGDebugInfo::CollectCXXMemberFunctions(
1534 for (
const auto *I : RD->
decls()) {
1559 EltTys.push_back(MI == SPCache.end()
1560 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
1561 :
static_cast<llvm::Metadata *
>(MI->second));
1565 void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1567 llvm::DIType *RecordTy) {
1569 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
1570 llvm::DINode::FlagZero);
1574 if (CGM.getCodeGenOpts().EmitCodeView) {
1575 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
1576 llvm::DINode::FlagIndirectVirtualBase);
1580 void CGDebugInfo::CollectCXXBasesAux(
1585 llvm::DINode::DIFlags StartingFlags) {
1587 for (
const auto &BI : Bases) {
1589 cast<CXXRecordDecl>(BI.getType()->getAs<
RecordType>()->getDecl());
1590 if (!SeenTypes.insert(
Base).second)
1592 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
1593 llvm::DINode::DIFlags BFlags = StartingFlags;
1594 uint64_t BaseOffset;
1595 uint32_t VBPtrOffset = 0;
1597 if (BI.isVirtual()) {
1598 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1601 BaseOffset = 0 - CGM.getItaniumVTableContext()
1602 .getVirtualBaseOffsetOffset(RD,
Base)
1608 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD,
Base);
1609 VBPtrOffset = CGM.getContext()
1610 .getASTRecordLayout(RD)
1614 BFlags |= llvm::DINode::FlagVirtual;
1621 llvm::DIType *DTy = DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset,
1622 VBPtrOffset, BFlags);
1623 EltTys.push_back(DTy);
1630 llvm::DIFile *Unit) {
1632 for (
unsigned i = 0, e = TAList.size(); i != e; ++i) {
1639 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
1640 TemplateParams.push_back(
1641 DBuilder.createTemplateTypeParameter(TheCU, Name, TTy));
1645 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1647 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
1652 llvm::DIType *TTy = getOrCreateType(T, Unit);
1653 llvm::Constant *V =
nullptr;
1657 if (
const auto *VD = dyn_cast<VarDecl>(D))
1658 V = CGM.GetAddrOfGlobalVar(VD);
1661 else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->
isInstance())
1662 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
1663 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
1664 V = CGM.GetAddrOfFunction(FD);
1667 else if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr())) {
1671 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
1673 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
1674 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
1676 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1678 cast_or_null<llvm::Constant>(V->stripPointerCasts())));
1682 llvm::DIType *TTy = getOrCreateType(T, Unit);
1683 llvm::Constant *V =
nullptr;
1686 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
1692 if (MPT->isMemberDataPointer())
1693 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
1695 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
1696 TemplateParams.push_back(
1697 DBuilder.createTemplateValueParameter(TheCU, Name, TTy, V));
1700 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
1701 TheCU, Name,
nullptr,
1705 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
1706 TheCU, Name,
nullptr,
1713 T = CGM.getContext().getLValueReferenceType(T);
1715 assert(V &&
"Expression in template argument isn't constant");
1716 llvm::DIType *TTy = getOrCreateType(T, Unit);
1717 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1718 TheCU, Name, TTy, V->stripPointerCasts()));
1724 "These argument types shouldn't exist in concrete types");
1727 return DBuilder.getOrCreateArray(TemplateParams);
1731 CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
1732 llvm::DIFile *Unit) {
1738 return CollectTemplateParams(
1741 return llvm::DINodeArray();
1744 llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
1751 return CollectTemplateParams(TPList, TAList.
asArray(), Unit);
1754 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
1756 return VTablePtrType;
1761 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
1762 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
1763 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
1765 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1767 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1769 llvm::DIType *vtbl_ptr_type = DBuilder.createPointerType(
1770 SubTy, Size, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
1771 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
1772 return VTablePtrType;
1775 StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
1780 void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1782 llvm::DICompositeType *RecordTy) {
1798 llvm::DIType *VPtrTy =
nullptr;
1799 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
1800 CGM.getTarget().getCXXABI().isMicrosoft();
1801 if (NeedVTableShape) {
1803 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1805 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
1806 unsigned VSlotCount =
1808 unsigned VTableWidth = PtrWidth * VSlotCount;
1809 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1811 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1814 llvm::DIType *VTableType = DBuilder.createPointerType(
1815 nullptr, VTableWidth, 0, DWARFAddressSpace,
"__vtbl_ptr_type");
1816 EltTys.push_back(VTableType);
1819 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
1827 VPtrTy = getOrCreateVTablePtrType(Unit);
1829 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1830 llvm::DIType *VPtrMember =
1831 DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
1832 llvm::DINode::FlagArtificial, VPtrTy);
1833 EltTys.push_back(VPtrMember);
1839 llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
1845 return getOrCreateStandaloneType(D, Loc);
1851 assert(!D.
isNull() &&
"null type");
1852 llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
1853 assert(T &&
"could not create debug info for type");
1862 QualType Ty = CGM.getContext().getEnumType(ED);
1864 auto I = TypeCache.find(TyPtr);
1865 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
1867 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
1868 assert(!Res->isForwardDecl());
1869 TypeCache[TyPtr].reset(Res);
1874 !CGM.getLangOpts().CPlusPlus)
1875 completeRequiredType(RD);
1880 if (RD->
hasAttr<DLLImportAttr>())
1883 if (MD->hasAttr<DLLImportAttr>())
1896 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
1912 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1913 if (CXXRD->isDynamicClass() &&
1914 CGM.getVTableLinkage(CXXRD) ==
1915 llvm::GlobalValue::AvailableExternallyLinkage &&
1928 QualType Ty = CGM.getContext().getRecordType(RD);
1930 auto I = TypeCache.find(TyPtr);
1931 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
1934 assert(!Res->isForwardDecl());
1935 TypeCache[TyPtr].reset(Res);
1942 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
1943 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
1961 if (!LangOpts.CPlusPlus)
1983 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1984 Spec = SD->getSpecializationKind();
1998 QualType Ty = CGM.getContext().getRecordType(RD);
1999 llvm::DIType *T = getTypeOrNull(Ty);
2000 if (T && T->isForwardDecl())
2001 completeClassData(RD);
2004 llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
2006 llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
2008 CGM.getLangOpts())) {
2010 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
2014 return CreateTypeDefinition(Ty);
2017 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
2021 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2029 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty, DefUnit);
2035 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
2036 CollectContainingType(CXXDecl, FwdDecl);
2039 LexicalBlockStack.emplace_back(&*FwdDecl);
2040 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2052 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
2053 CollectVTableInfo(CXXDecl, DefUnit, EltTys, FwdDecl);
2057 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2059 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
2061 LexicalBlockStack.pop_back();
2062 RegionMap.erase(Ty->
getDecl());
2064 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2065 DBuilder.replaceArrays(FwdDecl, Elements);
2067 if (FwdDecl->isTemporary())
2069 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
2071 RegionMap[Ty->
getDecl()].reset(FwdDecl);
2076 llvm::DIFile *Unit) {
2082 llvm::DIFile *Unit) {
2087 return DBuilder.createTypedef(
2089 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
2090 getDeclContextDescriptor(Ty->
getDecl()));
2118 llvm::DIFile *Unit) {
2128 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2130 getDeclContextDescriptor(ID), Unit, 0);
2133 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2136 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2142 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2143 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2144 llvm::dwarf::DW_TAG_structure_type, ID->
getName(), Mod ? Mod : TheCU,
2145 DefUnit,
Line, RuntimeLang);
2146 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2150 return CreateTypeDefinition(Ty, Unit);
2155 bool CreateSkeletonCU) {
2160 auto ModRef = ModuleCache.find(M);
2161 if (ModRef != ModuleCache.end())
2162 return cast<llvm::DIModule>(ModRef->second);
2165 SmallString<128> ConfigMacros;
2167 llvm::raw_svector_ostream OS(ConfigMacros);
2168 const auto &PPOpts = CGM.getPreprocessorOpts();
2171 for (
auto &M : PPOpts.Macros) {
2174 const std::string &Macro = M.first;
2175 bool Undef = M.second;
2176 OS <<
"\"-" << (Undef ?
'U' :
'D');
2177 for (
char c : Macro)
2192 bool IsRootModule = M ? !M->
Parent :
true;
2193 if (CreateSkeletonCU && IsRootModule) {
2197 uint64_t Signature =
2201 llvm::DIBuilder DIB(CGM.getModule());
2202 DIB.createCompileUnit(TheCU->getSourceLanguage(),
2205 TheCU->getProducer(),
true, StringRef(), 0,
2206 Mod.
getASTFile(), llvm::DICompileUnit::FullDebug,
2211 IsRootModule ? nullptr
2212 : getOrCreateModuleRef(
2215 llvm::DIModule *DIMod =
2216 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
2217 Mod.
getPath(), CGM.getHeaderSearchOpts().Sysroot);
2218 ModuleCache[M].reset(DIMod);
2223 llvm::DIFile *Unit) {
2225 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2227 unsigned RuntimeLang = TheCU->getSourceLanguage();
2230 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2233 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2235 Flags |= llvm::DINode::FlagObjcClassComplete;
2237 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2238 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
2239 Mod ? Mod : Unit, ID->
getName(), DefUnit,
Line, Size, Align, Flags,
2240 nullptr, llvm::DINodeArray(), RuntimeLang);
2246 LexicalBlockStack.emplace_back(RealDecl);
2247 RegionMap[Ty->
getDecl()].reset(RealDecl);
2254 llvm::DIType *SClassTy =
2255 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
2259 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0,
2260 llvm::DINode::FlagZero);
2261 EltTys.push_back(InhTag);
2267 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2268 unsigned PLine = getLineNumber(Loc);
2271 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
2272 PD->getName(), PUnit, PLine,
2274 : getSelectorName(PD->getGetterName()),
2276 : getSelectorName(PD->getSetterName()),
2277 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
2278 EltTys.push_back(PropertyNode);
2281 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
2283 for (
auto *PD : ClassExt->properties()) {
2284 PropertySet.insert(PD->getIdentifier());
2290 if (!PropertySet.insert(PD->getIdentifier()).second)
2296 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
2297 unsigned FieldNo = 0;
2299 Field = Field->getNextIvar(), ++FieldNo) {
2300 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
2304 StringRef FieldName = Field->getName();
2307 if (FieldName.empty())
2311 llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation());
2312 unsigned FieldLine = getLineNumber(Field->getLocation());
2314 uint64_t FieldSize = 0;
2315 uint32_t FieldAlign = 0;
2317 if (!FType->isIncompleteArrayType()) {
2320 FieldSize = Field->isBitField()
2321 ? Field->getBitWidthValue(CGM.getContext())
2322 : CGM.getContext().getTypeSize(FType);
2326 uint64_t FieldOffset;
2327 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2331 if (Field->isBitField()) {
2333 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
2334 FieldOffset %= CGM.getContext().getCharWidth();
2342 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2344 Flags = llvm::DINode::FlagProtected;
2346 Flags = llvm::DINode::FlagPrivate;
2348 Flags = llvm::DINode::FlagPublic;
2350 llvm::MDNode *PropertyNode =
nullptr;
2353 ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
2356 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2357 unsigned PLine = getLineNumber(Loc);
2360 PropertyNode = DBuilder.createObjCProperty(
2361 PD->getName(), PUnit, PLine,
2364 : getSelectorName(PD->getGetterName()),
2367 : getSelectorName(PD->getSetterName()),
2368 PD->getPropertyAttributes(),
2369 getOrCreateType(PD->getType(), PUnit));
2373 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
2374 FieldSize, FieldAlign, FieldOffset, Flags,
2375 FieldTy, PropertyNode);
2376 EltTys.push_back(FieldTy);
2379 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2380 DBuilder.replaceArrays(RealDecl, Elements);
2382 LexicalBlockStack.pop_back();
2386 llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
2387 llvm::DIFile *Unit) {
2388 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
2391 llvm::Metadata *Subscript;
2393 auto SizeExpr = SizeExprCache.find(QTy);
2394 if (SizeExpr != SizeExprCache.end())
2395 Subscript = DBuilder.getOrCreateSubrange(0, SizeExpr->getSecond());
2397 Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
2398 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
2400 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2403 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
2406 llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
2411 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2426 Size = CGM.getContext().getTypeSize(Ty);
2435 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
2444 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
2445 Count = CAT->getSize().getZExtValue();
2446 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2447 if (
Expr *Size = VAT->getSizeExpr()) {
2449 if (Size->EvaluateAsInt(V, CGM.getContext()))
2450 Count = V.getExtValue();
2454 auto SizeNode = SizeExprCache.find(EltTy);
2455 if (SizeNode != SizeExprCache.end())
2456 Subscripts.push_back(
2457 DBuilder.getOrCreateSubrange(0, SizeNode->getSecond()));
2459 Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
2463 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
2465 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
2470 llvm::DIFile *Unit) {
2471 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
2476 llvm::DIFile *Unit) {
2477 return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type, Ty,
2483 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2487 Size = CGM.getContext().getTypeSize(Ty);
2490 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
2492 case MSInheritanceAttr::Keyword_single_inheritance:
2493 Flags |= llvm::DINode::FlagSingleInheritance;
2495 case MSInheritanceAttr::Keyword_multiple_inheritance:
2496 Flags |= llvm::DINode::FlagMultipleInheritance;
2498 case MSInheritanceAttr::Keyword_virtual_inheritance:
2499 Flags |= llvm::DINode::FlagVirtualInheritance;
2501 case MSInheritanceAttr::Keyword_unspecified_inheritance:
2509 return DBuilder.createMemberPointerType(
2515 return DBuilder.createMemberPointerType(
2516 getOrCreateInstanceMethodType(CGM.getContext().getPointerType(
QualType(
2519 ClassType, Size, 0, Flags);
2522 llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
2524 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
2527 llvm::DIType *CGDebugInfo::CreateType(
const PipeType *Ty, llvm::DIFile *U) {
2531 llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
2543 bool isImportedFromModule =
2555 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
2556 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2557 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
2558 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
2561 StringRef EDName = ED->
getName();
2562 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
2563 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
2564 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
2566 ReplaceMap.emplace_back(
2567 std::piecewise_construct, std::make_tuple(Ty),
2568 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
2572 return CreateTypeDefinition(Ty);
2575 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
2591 const auto &InitVal = Enum->getInitVal();
2592 auto Value = IsSigned ? InitVal.getSExtValue() : InitVal.getZExtValue();
2593 Enumerators.push_back(
2594 DBuilder.createEnumerator(Enum->getName(),
Value, !IsSigned));
2598 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
2600 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2602 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
2603 llvm::DIType *ClassTy = getOrCreateType(ED->
getIntegerType(), DefUnit);
2604 return DBuilder.createEnumerationType(EnumContext, ED->
getName(), DefUnit,
2605 Line, Size, Align, EltArray, ClassTy,
2611 StringRef Name, StringRef
Value) {
2612 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2613 return DBuilder.createMacro(Parent, Line, MType, Name, Value);
2619 llvm::DIFile *FName = getOrCreateFile(FileLoc);
2620 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2621 return DBuilder.createTempMacroFile(Parent, Line, FName);
2631 Quals += InnerQuals;
2636 case Type::TemplateSpecialization: {
2637 const auto *Spec = cast<TemplateSpecializationType>(T);
2638 if (Spec->isTypeAlias())
2640 T = Spec->desugar();
2643 case Type::TypeOfExpr:
2644 T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
2649 case Type::Decltype:
2652 case Type::UnaryTransform:
2655 case Type::Attributed:
2656 T = cast<AttributedType>(T)->getEquivalentType();
2658 case Type::Elaborated:
2659 T = cast<ElaboratedType>(T)->getNamedType();
2662 T = cast<ParenType>(T)->getInnerType();
2664 case Type::SubstTemplateTypeParm:
2665 T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
2668 case Type::DeducedTemplateSpecialization: {
2669 QualType DT = cast<DeducedType>(T)->getDeducedType();
2670 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
2674 case Type::Adjusted:
2677 T = cast<AdjustedType>(T)->getAdjustedType();
2681 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
2686 llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
2692 if (It != TypeCache.end()) {
2694 if (llvm::Metadata *V = It->second)
2695 return cast<llvm::DIType>(V);
2705 completeUnusedClass(SD);
2712 completeClassData(&D);
2715 RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
2718 llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
2725 if (
auto *T = getTypeOrNull(Ty))
2728 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
2732 TypeCache[TyPtr].reset(Res);
2737 llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
2739 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
2743 auto *Reader = CGM.getContext().getExternalSource();
2745 auto Info = Reader->getSourceDescriptor(Idx);
2747 return getOrCreateModuleRef(*Info,
true);
2748 }
else if (ClangModuleMap) {
2762 return getOrCreateModuleRef(Info,
false);
2765 return getOrCreateModuleRef(PCHDescriptor,
false);
2772 llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
2775 return CreateQualifiedType(Ty, Unit);
2779 #define TYPE(Class, Base) 2780 #define ABSTRACT_TYPE(Class, Base) 2781 #define NON_CANONICAL_TYPE(Class, Base) 2782 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 2783 #include "clang/AST/TypeNodes.def" 2784 llvm_unreachable(
"Dependent types cannot show up in debug information");
2786 case Type::ExtVector:
2788 return CreateType(cast<VectorType>(Ty), Unit);
2789 case Type::ObjCObjectPointer:
2790 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
2791 case Type::ObjCObject:
2792 return CreateType(cast<ObjCObjectType>(Ty), Unit);
2793 case Type::ObjCTypeParam:
2794 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
2795 case Type::ObjCInterface:
2796 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
2798 return CreateType(cast<BuiltinType>(Ty));
2800 return CreateType(cast<ComplexType>(Ty));
2802 return CreateType(cast<PointerType>(Ty), Unit);
2803 case Type::BlockPointer:
2804 return CreateType(cast<BlockPointerType>(Ty), Unit);
2806 return CreateType(cast<TypedefType>(Ty), Unit);
2808 return CreateType(cast<RecordType>(Ty));
2810 return CreateEnumType(cast<EnumType>(Ty));
2811 case Type::FunctionProto:
2812 case Type::FunctionNoProto:
2813 return CreateType(cast<FunctionType>(Ty), Unit);
2814 case Type::ConstantArray:
2815 case Type::VariableArray:
2816 case Type::IncompleteArray:
2817 return CreateType(cast<ArrayType>(Ty), Unit);
2819 case Type::LValueReference:
2820 return CreateType(cast<LValueReferenceType>(Ty), Unit);
2821 case Type::RValueReference:
2822 return CreateType(cast<RValueReferenceType>(Ty), Unit);
2824 case Type::MemberPointer:
2825 return CreateType(cast<MemberPointerType>(Ty), Unit);
2828 return CreateType(cast<AtomicType>(Ty), Unit);
2831 return CreateType(cast<PipeType>(Ty), Unit);
2833 case Type::TemplateSpecialization:
2834 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
2837 case Type::Attributed:
2838 case Type::Adjusted:
2840 case Type::DeducedTemplateSpecialization:
2841 case Type::Elaborated:
2843 case Type::SubstTemplateTypeParm:
2844 case Type::TypeOfExpr:
2846 case Type::Decltype:
2847 case Type::UnaryTransform:
2848 case Type::PackExpansion:
2852 llvm_unreachable(
"type should have been unwrapped!");
2855 llvm::DICompositeType *CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty,
2856 llvm::DIFile *Unit) {
2859 auto *T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
2864 if (T && !T->isForwardDecl())
2868 llvm::DICompositeType *Res = CreateLimitedType(Ty);
2873 DBuilder.replaceArrays(Res, T ? T->getElements() : llvm::DINodeArray());
2881 llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
2885 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2887 StringRef RDName = getClassName(RD);
2889 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
2893 auto *T = cast_or_null<llvm::DICompositeType>(
2894 getTypeOrNull(CGM.getContext().getRecordType(RD)));
2902 return getOrCreateRecordFwdDecl(Ty, RDContext);
2904 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2910 auto Flags = llvm::DINode::FlagZero;
2911 if (
auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
2913 Flags |= llvm::DINode::FlagTypePassByReference;
2915 Flags |= llvm::DINode::FlagTypePassByValue;
2918 if (CXXRD->isTrivial())
2919 Flags |= llvm::DINode::FlagTrivial;
2922 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
2923 getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
2928 switch (RealDecl->getTag()) {
2930 llvm_unreachable(
"invalid composite type tag");
2932 case llvm::dwarf::DW_TAG_array_type:
2933 case llvm::dwarf::DW_TAG_enumeration_type:
2938 if (Identifier.empty())
2942 case llvm::dwarf::DW_TAG_structure_type:
2943 case llvm::dwarf::DW_TAG_union_type:
2944 case llvm::dwarf::DW_TAG_class_type:
2947 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
2951 RegionMap[Ty->
getDecl()].reset(RealDecl);
2954 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2955 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
2956 CollectCXXTemplateParams(TSpecial, DefUnit));
2960 void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
2961 llvm::DICompositeType *RealDecl) {
2963 llvm::DICompositeType *ContainingType =
nullptr;
2968 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
2975 ContainingType = cast<llvm::DICompositeType>(
2976 getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
2979 ContainingType = RealDecl;
2981 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
2984 llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
2985 StringRef Name, uint64_t *
Offset) {
2986 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
2987 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
2990 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
2991 *Offset, llvm::DINode::FlagZero, FieldTy);
2992 *Offset += FieldSize;
2996 void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
2998 StringRef &LinkageName,
2999 llvm::DIScope *&FDContext,
3000 llvm::DINodeArray &TParamsArray,
3001 llvm::DINode::DIFlags &Flags) {
3002 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
3003 Name = getFunctionName(FD);
3006 LinkageName = CGM.getMangledName(GD);
3007 Flags |= llvm::DINode::FlagPrototyped;
3012 if (LinkageName == Name || (!CGM.getCodeGenOpts().EmitGcovArcs &&
3013 !CGM.getCodeGenOpts().EmitGcovNotes &&
3014 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
3016 LinkageName = StringRef();
3021 FDContext = getOrCreateNamespace(NSDecl);
3024 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
3025 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
3029 Flags |= llvm::DINode::FlagNoReturn;
3031 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
3035 void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
3037 StringRef &Name, StringRef &LinkageName,
3038 llvm::DIScope *&VDContext) {
3045 if (T->isIncompleteArrayType()) {
3047 llvm::APInt ConstVal(32, 1);
3048 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
3057 LinkageName = CGM.getMangledName(VD);
3058 if (LinkageName == Name)
3059 LinkageName = StringRef();
3076 DC = CGM.getContext().getTranslationUnitDecl();
3078 llvm::DIScope *Mod = getParentModuleOrNull(VD);
3079 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
3082 llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
3084 llvm::DINodeArray TParamsArray;
3085 StringRef Name, LinkageName;
3086 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3088 llvm::DIFile *Unit = getOrCreateFile(Loc);
3089 llvm::DIScope *DContext = Unit;
3090 unsigned Line = getLineNumber(Loc);
3091 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
3099 ArgTypes.push_back(Parm->getType());
3101 QualType FnType = CGM.getContext().getFunctionType(
3104 return DBuilder.createFunction(
3105 DContext, Name, LinkageName, Unit, Line,
3106 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit),
3108 true, 0, Flags, CGM.getLangOpts().Optimize,
3109 TParamsArray.get(), getFunctionDeclaration(FD));
3112 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
3113 DContext, Name, LinkageName, Unit, Line,
3114 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit),
3116 false, 0, Flags, CGM.getLangOpts().Optimize,
3117 TParamsArray.get(), getFunctionDeclaration(FD));
3119 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
3120 std::make_tuple(CanonDecl),
3121 std::make_tuple(SP));
3125 llvm::DISubprogram *CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
3126 return getFunctionFwdDeclOrStub(GD,
false);
3129 llvm::DISubprogram *CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
3130 return getFunctionFwdDeclOrStub(GD,
true);
3133 llvm::DIGlobalVariable *
3134 CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
3136 StringRef Name, LinkageName;
3138 llvm::DIFile *Unit = getOrCreateFile(Loc);
3139 llvm::DIScope *DContext = Unit;
3140 unsigned Line = getLineNumber(Loc);
3142 collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, DContext);
3144 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
3145 DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
3147 FwdDeclReplaceMap.emplace_back(
3148 std::piecewise_construct,
3150 std::make_tuple(static_cast<llvm::Metadata *>(GV)));
3154 llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
3159 if (
const auto *TD = dyn_cast<TypeDecl>(D))
3160 return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
3164 if (I != DeclCache.end()) {
3166 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
3167 return GVE->getVariable();
3168 return dyn_cast_or_null<llvm::DINode>(N);
3173 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3174 return getFunctionForwardDeclaration(FD);
3175 else if (
const auto *VD = dyn_cast<VarDecl>(D))
3176 return getGlobalVariableForwardDeclaration(VD);
3181 llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
3190 auto *S = getDeclContextDescriptor(D);
3193 if (MI == SPCache.end()) {
3195 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
3196 cast<llvm::DICompositeType>(S));
3199 if (MI != SPCache.end()) {
3200 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3201 if (SP && !SP->isDefinition())
3205 for (
auto NextFD : FD->
redecls()) {
3206 auto MI = SPCache.find(NextFD->getCanonicalDecl());
3207 if (MI != SPCache.end()) {
3208 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3209 if (SP && !SP->isDefinition())
3218 llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
3224 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray(None));
3226 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
3227 return getOrCreateMethodType(Method, F);
3232 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
3237 QualType ResultTy = OMethod->getReturnType();
3240 if (ResultTy == CGM.getContext().getObjCInstanceType())
3241 ResultTy = CGM.getContext().getPointerType(
3242 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
3244 Elts.push_back(getOrCreateType(ResultTy, F));
3247 if (
auto *SelfDecl = OMethod->getSelfDecl())
3248 SelfDeclTy = SelfDecl->getType();
3249 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3250 if (FPT->getNumParams() > 1)
3251 SelfDeclTy = FPT->getParamType(0);
3252 if (!SelfDeclTy.
isNull())
3254 CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
3256 Elts.push_back(DBuilder.createArtificialType(
3257 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
3259 for (
const auto *PI : OMethod->parameters())
3260 Elts.push_back(getOrCreateType(PI->getType(), F));
3262 if (OMethod->isVariadic())
3263 Elts.push_back(DBuilder.createUnspecifiedParameter());
3265 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
3266 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3272 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3276 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3277 for (
QualType ParamType : FPT->param_types())
3278 EltTys.push_back(getOrCreateType(ParamType, F));
3279 EltTys.push_back(DBuilder.createUnspecifiedParameter());
3280 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
3281 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3285 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
3290 llvm::Function *Fn,
bool CurFuncIsThunk,
3294 StringRef LinkageName;
3296 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3299 bool HasDecl = (D !=
nullptr);
3301 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3302 llvm::DIFile *Unit = getOrCreateFile(Loc);
3303 llvm::DIScope *FDContext = Unit;
3304 llvm::DINodeArray TParamsArray;
3307 LinkageName = Fn->getName();
3308 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3311 if (FI != SPCache.end()) {
3312 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3313 if (SP && SP->isDefinition()) {
3314 LexicalBlockStack.emplace_back(SP);
3315 RegionMap[D].reset(SP);
3319 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3320 TParamsArray, Flags);
3321 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3322 Name = getObjCMethodName(OMD);
3323 Flags |= llvm::DINode::FlagPrototyped;
3326 Name = Fn->getName();
3327 Flags |= llvm::DINode::FlagPrototyped;
3329 if (Name.startswith(
"\01"))
3330 Name = Name.substr(1);
3333 Flags |= llvm::DINode::FlagArtificial;
3339 Flags |= llvm::DINode::FlagThunk;
3341 unsigned LineNo = getLineNumber(Loc);
3342 unsigned ScopeLine = getLineNumber(ScopeLoc);
3349 llvm::DISubprogram *SP = DBuilder.createFunction(
3350 FDContext, Name, LinkageName, Unit, LineNo,
3351 getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(),
3352 true , ScopeLine, Flags, CGM.getLangOpts().Optimize,
3353 TParamsArray.get(), getFunctionDeclaration(D));
3354 Fn->setSubprogram(SP);
3358 if (HasDecl && isa<FunctionDecl>(D))
3361 if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
3364 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
3367 auto It = TypeCache.find(QTy.getAsOpaquePtr());
3368 if (It != TypeCache.end()) {
3369 llvm::DICompositeType *InterfaceDecl =
3370 cast<llvm::DICompositeType>(It->second);
3371 llvm::DISubprogram *FD = DBuilder.createFunction(
3372 InterfaceDecl, Name, LinkageName, Unit, LineNo,
3373 getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(),
3374 false , ScopeLine, Flags, CGM.getLangOpts().Optimize,
3375 TParamsArray.get());
3376 DBuilder.finalizeSubprogram(FD);
3377 ObjCMethodCache[
ID].push_back(FD);
3383 LexicalBlockStack.emplace_back(SP);
3386 RegionMap[D].reset(SP);
3392 StringRef LinkageName;
3398 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3399 llvm::DIFile *Unit = getOrCreateFile(Loc);
3400 llvm::DIScope *FDContext = getDeclContextDescriptor(D);
3401 llvm::DINodeArray TParamsArray;
3402 if (isa<FunctionDecl>(D)) {
3404 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3405 TParamsArray, Flags);
3406 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3407 Name = getObjCMethodName(OMD);
3408 Flags |= llvm::DINode::FlagPrototyped;
3410 llvm_unreachable(
"not a function or ObjC method");
3412 if (!Name.empty() && Name[0] ==
'\01')
3413 Name = Name.substr(1);
3416 Flags |= llvm::DINode::FlagArtificial;
3421 unsigned LineNo = getLineNumber(Loc);
3422 unsigned ScopeLine = 0;
3424 DBuilder.retainType(DBuilder.createFunction(
3425 FDContext, Name, LinkageName, Unit, LineNo,
3426 getOrCreateFunctionType(D, FnType, Unit),
false ,
3427 false , ScopeLine, Flags, CGM.getLangOpts().Optimize,
3428 TParamsArray.get(), getFunctionDeclaration(D)));
3432 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
3435 llvm::DISubprogram *SP =
nullptr;
3436 if (FI != SPCache.end())
3437 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3438 if (!SP || !SP->isDefinition())
3439 SP = getFunctionStub(GD);
3440 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3441 LexicalBlockStack.emplace_back(SP);
3442 setInlinedAt(Builder.getCurrentDebugLocation());
3447 assert(CurInlinedAt &&
"unbalanced inline scope stack");
3448 EmitFunctionEnd(Builder,
nullptr);
3449 setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
3456 if (CurLoc.isInvalid() || CurLoc.isMacroID())
3459 llvm::MDNode *
Scope = LexicalBlockStack.back();
3460 Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
3461 getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
3465 llvm::MDNode *Back =
nullptr;
3466 if (!LexicalBlockStack.empty())
3467 Back = LexicalBlockStack.back().get();
3468 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
3469 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
3470 getColumnNumber(CurLoc)));
3473 void CGDebugInfo::AppendAddressSpaceXDeref(
3476 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
3477 if (!DWARFAddressSpace)
3480 Expr.push_back(llvm::dwarf::DW_OP_constu);
3481 Expr.push_back(DWARFAddressSpace.getValue());
3482 Expr.push_back(llvm::dwarf::DW_OP_swap);
3483 Expr.push_back(llvm::dwarf::DW_OP_xderef);
3492 Builder.SetCurrentDebugLocation(
3493 llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc),
3494 LexicalBlockStack.back(), CurInlinedAt));
3500 CreateLexicalBlock(Loc);
3505 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3513 LexicalBlockStack.pop_back();
3517 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3518 unsigned RCount = FnBeginRegionCount.back();
3519 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
3522 while (LexicalBlockStack.size() != RCount) {
3525 LexicalBlockStack.pop_back();
3527 FnBeginRegionCount.pop_back();
3529 if (Fn && Fn->getSubprogram())
3530 DBuilder.finalizeSubprogram(Fn->getSubprogram());
3533 llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
3534 uint64_t *XOffset) {
3538 uint64_t FieldSize, FieldOffset;
3539 uint32_t FieldAlign;
3541 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3545 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3546 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
3547 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
3548 FType = CGM.getContext().IntTy;
3549 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
3550 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
3552 bool HasCopyAndDispose = CGM.getContext().BlockRequiresCopying(Type, VD);
3553 if (HasCopyAndDispose) {
3554 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3556 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
3558 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
3560 bool HasByrefExtendedLayout;
3562 if (CGM.getContext().getByrefLifetime(Type, Lifetime,
3563 HasByrefExtendedLayout) &&
3564 HasByrefExtendedLayout) {
3565 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3567 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
3570 CharUnits Align = CGM.getContext().getDeclAlign(VD);
3571 if (Align > CGM.getContext().toCharUnitsFromBits(
3572 CGM.getTarget().getPointerAlign(0))) {
3574 CGM.getContext().toCharUnitsFromBits(FieldOffset);
3576 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
3579 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
3580 FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
3582 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
3587 llvm::DIType *FieldTy = getOrCreateType(FType, Unit);
3588 FieldSize = CGM.getContext().getTypeSize(FType);
3589 FieldAlign = CGM.getContext().toBits(Align);
3591 *XOffset = FieldOffset;
3592 FieldTy = DBuilder.createMemberType(Unit, VD->
getName(), Unit, 0, FieldSize,
3593 FieldAlign, FieldOffset,
3594 llvm::DINode::FlagZero, FieldTy);
3595 EltTys.push_back(FieldTy);
3596 FieldOffset += FieldSize;
3598 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3600 llvm::DINode::DIFlags Flags = llvm::DINode::FlagBlockByrefStruct;
3602 return DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0, Flags,
3606 llvm::DILocalVariable *CGDebugInfo::EmitDeclare(
const VarDecl *VD,
3611 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3612 if (VD->
hasAttr<NoDebugAttr>())
3618 llvm::DIFile *Unit =
nullptr;
3622 uint64_t XOffset = 0;
3623 if (VD->
hasAttr<BlocksAttr>())
3624 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
3626 Ty = getOrCreateType(VD->
getType(), Unit);
3635 unsigned Column = 0;
3641 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3643 Flags |= llvm::DINode::FlagArtificial;
3647 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->
getType());
3648 AppendAddressSpaceXDeref(AddressSpace, Expr);
3652 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
3655 Flags |= llvm::DINode::FlagObjectPointer;
3662 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
3663 StringRef Name = VD->
getName();
3664 if (!Name.empty()) {
3665 if (VD->
hasAttr<BlocksAttr>()) {
3668 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3670 offset = CGM.getContext().toCharUnitsFromBits(
3671 CGM.getTarget().getPointerWidth(0));
3673 Expr.push_back(llvm::dwarf::DW_OP_deref);
3674 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3676 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3679 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
3691 for (
const auto *Field : RD->
fields()) {
3692 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
3693 StringRef FieldName = Field->getName();
3696 if (FieldName.empty() && !isa<RecordType>(Field->getType()))
3701 auto *D = DBuilder.createAutoVariable(
3702 Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
3703 Flags | llvm::DINode::FlagArtificial, FieldAlign);
3706 DBuilder.insertDeclare(
3707 Storage, D, DBuilder.createExpression(Expr),
3708 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3709 Builder.GetInsertBlock());
3715 auto *D = ArgNo ? DBuilder.createParameterVariable(
3716 Scope, Name, *ArgNo, Unit, Line, Ty,
3717 CGM.getLangOpts().Optimize, Flags)
3718 : DBuilder.createAutoVariable(
Scope, Name, Unit, Line, Ty,
3719 CGM.getLangOpts().Optimize,
3723 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
3724 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3725 Builder.GetInsertBlock());
3730 llvm::DILocalVariable *
3734 return EmitDeclare(VD, Storage,
llvm::None, Builder);
3737 llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
3739 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
3742 return DBuilder.createObjectPointerType(Ty);
3747 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
3749 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3751 if (Builder.GetInsertBlock() ==
nullptr)
3753 if (VD->
hasAttr<NoDebugAttr>())
3756 bool isByRef = VD->
hasAttr<BlocksAttr>();
3758 uint64_t XOffset = 0;
3759 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3762 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
3764 Ty = getOrCreateType(VD->
getType(), Unit);
3768 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
3770 Ty = CreateSelfType(VD->
getType(), Ty);
3774 unsigned Column = getColumnNumber(VD->
getLocation());
3776 const llvm::DataLayout &target = CGM.getDataLayout();
3783 addr.push_back(llvm::dwarf::DW_OP_deref);
3784 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3787 addr.push_back(llvm::dwarf::DW_OP_deref);
3788 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3791 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
3793 addr.push_back(llvm::dwarf::DW_OP_deref);
3794 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3796 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3802 auto *D = DBuilder.createAutoVariable(
3803 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
3804 Line, Ty,
false, llvm::DINode::FlagZero, Align);
3808 llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
3809 auto *Expr = DBuilder.createExpression(addr);
3811 DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
3813 DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
3820 EmitDeclare(VD, AI, ArgNo, Builder);
3824 struct BlockLayoutChunk {
3825 uint64_t OffsetInBits;
3828 bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
3829 return l.OffsetInBits < r.OffsetInBits;
3836 llvm::AllocaInst *Alloca,
3844 llvm::DIFile *tunit = getOrCreateFile(loc);
3845 unsigned line = getLineNumber(loc);
3846 unsigned column = getColumnNumber(loc);
3849 getDeclContextDescriptor(blockDecl);
3851 const llvm::StructLayout *blockLayout =
3855 if (CGM.getLangOpts().OpenCL) {
3856 fields.push_back(createFieldType(
"__size", C.
IntTy, loc,
AS_public,
3857 blockLayout->getElementOffsetInBits(0),
3859 fields.push_back(createFieldType(
"__align", C.
IntTy, loc,
AS_public,
3860 blockLayout->getElementOffsetInBits(1),
3864 blockLayout->getElementOffsetInBits(0),
3866 fields.push_back(createFieldType(
"__flags", C.
IntTy, loc,
AS_public,
3867 blockLayout->getElementOffsetInBits(1),
3869 fields.push_back(createFieldType(
"__reserved", C.
IntTy, loc,
AS_public,
3870 blockLayout->getElementOffsetInBits(2),
3873 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
3874 fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, loc,
AS_public,
3875 blockLayout->getElementOffsetInBits(3),
3877 fields.push_back(createFieldType(
3882 loc,
AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit));
3891 BlockLayoutChunk chunk;
3892 chunk.OffsetInBits =
3893 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
3894 chunk.Capture =
nullptr;
3895 chunks.push_back(chunk);
3899 for (
const auto &capture : blockDecl->
captures()) {
3900 const VarDecl *variable = capture.getVariable();
3907 BlockLayoutChunk chunk;
3908 chunk.OffsetInBits =
3909 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
3910 chunk.Capture = &capture;
3911 chunks.push_back(chunk);
3915 llvm::array_pod_sort(chunks.begin(), chunks.end());
3917 for (
const BlockLayoutChunk &Chunk : chunks) {
3918 uint64_t offsetInBits = Chunk.OffsetInBits;
3927 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->
getParent()))
3928 type =
QualType(RDecl->getTypeForDecl(), 0);
3930 llvm_unreachable(
"unexpected block declcontext");
3932 fields.push_back(createFieldType(
"this", type, loc,
AS_public,
3933 offsetInBits, tunit, tunit));
3938 StringRef name = variable->
getName();
3940 llvm::DIType *fieldType;
3947 fieldType = EmitTypeForVarWithBlocksAttr(variable, &xoffset);
3948 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
3949 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
3950 PtrInfo.
Width, Align, offsetInBits,
3951 llvm::DINode::FlagZero, fieldType);
3955 offsetInBits, Align, tunit, tunit);
3957 fields.push_back(fieldType);
3961 llvm::raw_svector_ostream(typeName)
3962 <<
"__block_literal_" << CGM.getUniqueBlockCount();
3964 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
3966 llvm::DIType *type =
3967 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
3968 CGM.getContext().toBits(block.
BlockSize), 0,
3969 llvm::DINode::FlagZero,
nullptr, fieldsArray);
3970 type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
3973 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
3974 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
3977 auto *debugVar = DBuilder.createParameterVariable(
3978 scope, Name, ArgNo, tunit, line, type, CGM.getLangOpts().Optimize, flags);
3981 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
3982 llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
3983 Builder.GetInsertBlock());
3986 llvm::DIDerivedType *
3987 CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
3992 if (MI != StaticDataMemberCache.end()) {
3993 assert(MI->second &&
"Static data member declaration should still exist");
4000 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
4001 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
4004 llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
4005 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
4006 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
4007 llvm::DIGlobalVariableExpression *GVE =
nullptr;
4009 for (
const auto *Field : RD->
fields()) {
4010 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
4011 StringRef FieldName = Field->getName();
4014 if (FieldName.empty()) {
4015 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
4016 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
4021 GVE = DBuilder.createGlobalVariableExpression(
4022 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
4023 Var->hasLocalLinkage());
4024 Var->addDebugInfo(GVE);
4032 if (D->
hasAttr<NoDebugAttr>())
4038 if (Cached != DeclCache.end())
4039 return Var->addDebugInfo(
4040 cast<llvm::DIGlobalVariableExpression>(Cached->second));
4043 llvm::DIFile *Unit =
nullptr;
4044 llvm::DIScope *DContext =
nullptr;
4046 StringRef DeclName, LinkageName;
4048 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName, DContext);
4052 llvm::DIGlobalVariableExpression *GVE =
nullptr;
4060 "unnamed non-anonymous struct or union?");
4061 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
4066 unsigned AddressSpace =
4067 CGM.getContext().getTargetAddressSpace(D->
getType());
4068 AppendAddressSpaceXDeref(AddressSpace, Expr);
4070 GVE = DBuilder.createGlobalVariableExpression(
4071 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
4072 Var->hasLocalLinkage(),
4073 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
4074 getOrCreateStaticDataMemberDeclarationOrNull(D), Align);
4075 Var->addDebugInfo(GVE);
4082 if (VD->
hasAttr<NoDebugAttr>())
4086 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
4087 StringRef Name = VD->
getName();
4088 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
4089 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
4090 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
4091 assert(isa<EnumType>(ED->getTypeForDecl()) &&
"Enum without EnumType?");
4092 Ty = getOrCreateType(
QualType(ED->getTypeForDecl(), 0), Unit);
4097 if (Ty->getTag() == llvm::dwarf::DW_TAG_enumeration_type)
4103 auto *VarD = cast<VarDecl>(VD);
4104 if (VarD->isStaticDataMember()) {
4105 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
4106 getDeclContextDescriptor(VarD);
4111 RetainedTypes.push_back(
4112 CGM.getContext().getRecordType(RD).getAsOpaquePtr());
4116 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
4118 auto &GV = DeclCache[VD];
4121 llvm::DIExpression *InitExpr =
nullptr;
4122 if (CGM.getContext().getTypeSize(VD->
getType()) <= 64) {
4126 DBuilder.createConstantValueExpression(Init.
getInt().getExtValue());
4128 InitExpr = DBuilder.createConstantValueExpression(
4129 Init.
getFloat().bitcastToAPInt().getZExtValue());
4131 GV.reset(DBuilder.createGlobalVariableExpression(
4132 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
4133 true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
4137 llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
4138 if (!LexicalBlockStack.empty())
4139 return LexicalBlockStack.back();
4140 llvm::DIScope *Mod = getParentModuleOrNull(D);
4141 return getContextDescriptor(D, Mod ? Mod : TheCU);
4149 CGM.getCodeGenOpts().DebugExplicitImport) {
4151 DBuilder.createImportedModule(
4153 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
4161 "We shouldn't be codegening an invalid UsingDecl containing no decls");
4170 if (
const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl()))
4171 if (
const auto *AT =
4173 if (AT->getDeducedType().isNull())
4175 if (llvm::DINode *
Target =
4176 getDeclarationOrDefinition(USD.getUnderlyingDecl())) {
4177 auto Loc = USD.getLocation();
4178 DBuilder.createImportedDeclaration(
4179 getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())),
Target,
4180 getOrCreateFile(Loc), getLineNumber(Loc));
4185 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
4190 DBuilder.createImportedDeclaration(
4192 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
4193 getLineNumber(Loc));
4197 llvm::DIImportedEntity *
4201 auto &VH = NamespaceAliasCache[&NA];
4203 return cast<llvm::DIImportedEntity>(VH);
4204 llvm::DIImportedEntity *R;
4206 if (
const auto *Underlying =
4209 R = DBuilder.createImportedDeclaration(
4211 EmitNamespaceAlias(*Underlying), getOrCreateFile(Loc),
4212 getLineNumber(Loc), NA.
getName());
4214 R = DBuilder.createImportedDeclaration(
4217 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
4223 CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
4227 auto I = NamespaceCache.find(NSDecl);
4228 if (I != NamespaceCache.end())
4229 return cast<llvm::DINamespace>(I->second);
4231 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
4233 llvm::DINamespace *NS =
4234 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
4235 NamespaceCache[NSDecl].reset(NS);
4240 assert(TheCU &&
"no main compile unit");
4241 TheCU->setDWOId(Signature);
4247 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
4248 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
4249 llvm::DIType *Ty = E.
Type->getDecl()->getDefinition()
4250 ? CreateTypeDefinition(E.Type, E.Unit)
4252 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
4255 if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
4257 for (
const auto &
P : ObjCMethodCache) {
4258 if (
P.second.empty())
4261 QualType QTy(
P.first->getTypeForDecl(), 0);
4262 auto It = TypeCache.find(QTy.getAsOpaquePtr());
4263 assert(It != TypeCache.end());
4265 llvm::DICompositeType *InterfaceDecl =
4266 cast<llvm::DICompositeType>(It->second);
4269 auto CurrenetElts = InterfaceDecl->getElements();
4270 EltTys.append(CurrenetElts.begin(), CurrenetElts.end());
4271 for (
auto &MD :
P.second)
4272 EltTys.push_back(MD);
4273 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4274 DBuilder.replaceArrays(InterfaceDecl, Elements);
4278 for (
const auto &
P : ReplaceMap) {
4280 auto *Ty = cast<llvm::DIType>(
P.second);
4281 assert(Ty->isForwardDecl());
4283 auto It = TypeCache.find(
P.first);
4284 assert(It != TypeCache.end());
4287 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
4288 cast<llvm::DIType>(It->second));
4291 for (
const auto &
P : FwdDeclReplaceMap) {
4293 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(
P.second));
4294 llvm::Metadata *Repl;
4296 auto It = DeclCache.find(
P.first);
4300 if (It == DeclCache.end())
4305 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
4306 Repl = GVE->getVariable();
4307 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
4312 for (
auto &RT : RetainedTypes)
4313 if (
auto MD = TypeCache[RT])
4314 DBuilder.retainType(cast<llvm::DIType>(MD));
4316 DBuilder.finalize();
4323 if (
auto *DieTy = getOrCreateType(Ty, getOrCreateMainFile()))
4325 DBuilder.retainType(DieTy);
4329 if (LexicalBlockStack.empty())
4330 return llvm::DebugLoc();
4332 llvm::MDNode *
Scope = LexicalBlockStack.back();
4333 return llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc), Scope);
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.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
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.
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
getObjCSelector - 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.
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.
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
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
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
unsigned getTypeQuals() 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].
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
bool isBitField() const
Determines whether this field is a bitfield.
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 orginial 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.
const BlockDecl * getBlockDecl() const
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
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 ...
Expr - 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
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.
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.
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...
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 location information but do not generate debug info in the output.
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.
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
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...
bool MSVCFormatting
Use whitespace and punctuation like MSVC does.
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