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() <<
'(' 293 << OCD->getName() <<
')';
294 }
else if (isa<ObjCProtocolDecl>(DC)) {
298 cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
304 return internString(OS.str());
307 StringRef CGDebugInfo::getSelectorName(
Selector S) {
311 StringRef CGDebugInfo::getClassName(
const RecordDecl *RD) {
312 if (isa<ClassTemplateSpecializationDecl>(RD)) {
314 llvm::raw_svector_ostream OS(Name);
319 return internString(Name);
325 return II->getName();
329 if (CGM.getCodeGenOpts().EmitCodeView) {
332 "Typedef should not be in another decl context!");
333 assert(D->getDeclName().getAsIdentifierInfo() &&
334 "Typedef was not named!");
335 return D->getDeclName().getAsIdentifierInfo()->getName();
338 if (CGM.getLangOpts().CPlusPlus) {
345 Name = DD->getName();
350 Name = TND->getName();
356 return internString(UnnamedType);
364 llvm::DIFile::ChecksumKind
368 if (!CGM.getCodeGenOpts().EmitCodeView)
369 return llvm::DIFile::CSK_None;
373 llvm::MemoryBuffer *MemBuffer = SM.
getBuffer(FID, &Invalid);
375 return llvm::DIFile::CSK_None;
378 llvm::MD5::MD5Result Result;
380 Hash.update(MemBuffer->getBuffer());
383 Hash.stringifyResult(Result, Checksum);
384 return llvm::DIFile::CSK_MD5;
390 return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
391 remapDIPath(TheCU->getDirectory()),
392 TheCU->getFile()->getChecksumKind(),
393 TheCU->getFile()->getChecksum());
400 return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
401 remapDIPath(TheCU->getDirectory()),
402 TheCU->getFile()->getChecksumKind(),
403 TheCU->getFile()->getChecksum());
407 auto it = DIFileCache.find(fname);
409 if (it != DIFileCache.end()) {
411 if (llvm::Metadata *V = it->second)
412 return cast<llvm::DIFile>(V);
416 llvm::DIFile::ChecksumKind CSKind =
417 computeChecksum(SM.
getFileID(Loc), Checksum);
419 llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.
getFilename()),
420 remapDIPath(getCurrentDirname()),
423 DIFileCache[fname].reset(F);
427 llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
428 return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
429 remapDIPath(TheCU->getDirectory()),
430 TheCU->getFile()->getChecksumKind(),
431 TheCU->getFile()->getChecksum());
434 std::string CGDebugInfo::remapDIPath(StringRef Path)
const {
435 for (
const auto &Entry : DebugPrefixMap)
436 if (Path.startswith(Entry.first))
437 return (Twine(Entry.second) + Path.substr(Entry.first.size())).str();
442 if (Loc.
isInvalid() && CurLoc.isInvalid())
449 unsigned CGDebugInfo::getColumnNumber(
SourceLocation Loc,
bool Force) {
451 if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
455 if (Loc.
isInvalid() && CurLoc.isInvalid())
462 StringRef CGDebugInfo::getCurrentDirname() {
463 if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())
464 return CGM.getCodeGenOpts().DebugCompilationDir;
466 if (!CWDName.empty())
469 llvm::sys::fs::current_path(CWD);
470 return CWDName = internString(CWD);
473 void CGDebugInfo::CreateCompileUnit() {
475 llvm::DIFile::ChecksumKind CSKind = llvm::DIFile::CSK_None;
486 std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
487 if (MainFileName.empty())
488 MainFileName =
"<stdin>";
494 std::string MainFileDir;
496 MainFileDir = remapDIPath(MainFile->getDir()->getName());
497 if (MainFileDir !=
".") {
499 llvm::sys::path::append(MainFileDirSS, MainFileName);
500 MainFileName = MainFileDirSS.str();
506 if (MainFile->getName() == MainFileName &&
508 MainFile->getName().rsplit(
'.').second)
510 MainFileName = CGM.getModule().getName().str();
515 llvm::dwarf::SourceLanguage LangTag;
519 LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
521 LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
522 }
else if (LO.ObjC1) {
523 LangTag = llvm::dwarf::DW_LANG_ObjC;
524 }
else if (LO.RenderScript) {
525 LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript;
527 LangTag = llvm::dwarf::DW_LANG_C99;
529 LangTag = llvm::dwarf::DW_LANG_C89;
535 unsigned RuntimeVers = 0;
539 llvm::DICompileUnit::DebugEmissionKind EmissionKind;
543 EmissionKind = llvm::DICompileUnit::NoDebug;
546 EmissionKind = llvm::DICompileUnit::LineTablesOnly;
550 EmissionKind = llvm::DICompileUnit::FullDebug;
556 auto &CGOpts = CGM.getCodeGenOpts();
557 TheCU = DBuilder.createCompileUnit(
559 DBuilder.createFile(remapDIPath(MainFileName),
560 remapDIPath(getCurrentDirname()), CSKind, Checksum),
561 Producer, LO.Optimize || CGOpts.PrepareForLTO || CGOpts.EmitSummaryIndex,
562 CGOpts.DwarfDebugFlags, RuntimeVers,
563 CGOpts.EnableSplitDwarf ?
"" : CGOpts.SplitDwarfFile, EmissionKind,
564 0 , CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
568 llvm::DIType *CGDebugInfo::CreateType(
const BuiltinType *BT) {
572 #define BUILTIN_TYPE(Id, SingletonId) 573 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 574 #include "clang/AST/BuiltinTypes.def" 575 case BuiltinType::Dependent:
576 llvm_unreachable(
"Unexpected builtin type");
577 case BuiltinType::NullPtr:
578 return DBuilder.createNullPtrType();
579 case BuiltinType::Void:
581 case BuiltinType::ObjCClass:
583 ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
585 getOrCreateMainFile(), 0);
587 case BuiltinType::ObjCId: {
597 ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
599 getOrCreateMainFile(), 0);
601 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
603 auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
605 ObjTy = DBuilder.createStructType(
606 TheCU,
"objc_object", getOrCreateMainFile(), 0, 0, 0,
607 llvm::DINode::FlagZero,
nullptr, llvm::DINodeArray());
609 DBuilder.replaceArrays(
610 ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
611 ObjTy,
"isa", getOrCreateMainFile(), 0, Size, 0, 0,
612 llvm::DINode::FlagZero, ISATy)));
615 case BuiltinType::ObjCSel: {
617 SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
618 "objc_selector", TheCU,
619 getOrCreateMainFile(), 0);
623 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 624 case BuiltinType::Id: \ 625 return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \ 627 #include "clang/Basic/OpenCLImageTypes.def" 628 case BuiltinType::OCLSampler:
629 return getOrCreateStructPtrType(
"opencl_sampler_t",
631 case BuiltinType::OCLEvent:
632 return getOrCreateStructPtrType(
"opencl_event_t", OCLEventDITy);
633 case BuiltinType::OCLClkEvent:
634 return getOrCreateStructPtrType(
"opencl_clk_event_t", OCLClkEventDITy);
635 case BuiltinType::OCLQueue:
636 return getOrCreateStructPtrType(
"opencl_queue_t", OCLQueueDITy);
637 case BuiltinType::OCLReserveID:
638 return getOrCreateStructPtrType(
"opencl_reserve_id_t", OCLReserveIDDITy);
640 case BuiltinType::UChar:
641 case BuiltinType::Char_U:
642 Encoding = llvm::dwarf::DW_ATE_unsigned_char;
644 case BuiltinType::Char_S:
645 case BuiltinType::SChar:
646 Encoding = llvm::dwarf::DW_ATE_signed_char;
648 case BuiltinType::Char16:
649 case BuiltinType::Char32:
650 Encoding = llvm::dwarf::DW_ATE_UTF;
652 case BuiltinType::UShort:
653 case BuiltinType::UInt:
654 case BuiltinType::UInt128:
655 case BuiltinType::ULong:
656 case BuiltinType::WChar_U:
657 case BuiltinType::ULongLong:
658 Encoding = llvm::dwarf::DW_ATE_unsigned;
660 case BuiltinType::Short:
661 case BuiltinType::Int:
662 case BuiltinType::Int128:
663 case BuiltinType::Long:
664 case BuiltinType::WChar_S:
665 case BuiltinType::LongLong:
666 Encoding = llvm::dwarf::DW_ATE_signed;
668 case BuiltinType::Bool:
669 Encoding = llvm::dwarf::DW_ATE_boolean;
671 case BuiltinType::Half:
672 case BuiltinType::Float:
673 case BuiltinType::LongDouble:
674 case BuiltinType::Float16:
675 case BuiltinType::Float128:
676 case BuiltinType::Double:
682 Encoding = llvm::dwarf::DW_ATE_float;
687 case BuiltinType::Long:
690 case BuiltinType::LongLong:
691 BTName =
"long long int";
693 case BuiltinType::ULong:
694 BTName =
"long unsigned int";
696 case BuiltinType::ULongLong:
697 BTName =
"long long unsigned int";
700 BTName = BT->
getName(CGM.getLangOpts());
704 uint64_t Size = CGM.getContext().getTypeSize(BT);
705 return DBuilder.createBasicType(BTName, Size, Encoding);
708 llvm::DIType *CGDebugInfo::CreateType(
const ComplexType *Ty) {
710 llvm::dwarf::TypeKind
Encoding = llvm::dwarf::DW_ATE_complex_float;
712 Encoding = llvm::dwarf::DW_ATE_lo_user;
714 uint64_t Size = CGM.getContext().getTypeSize(Ty);
715 return DBuilder.createBasicType(
"complex", Size, Encoding);
718 llvm::DIType *CGDebugInfo::CreateQualifiedType(
QualType Ty,
719 llvm::DIFile *Unit) {
730 llvm::dwarf::Tag Tag;
732 Tag = llvm::dwarf::DW_TAG_const_type;
735 Tag = llvm::dwarf::DW_TAG_volatile_type;
738 Tag = llvm::dwarf::DW_TAG_restrict_type;
741 assert(Qc.
empty() &&
"Unknown type qualifier for debug info");
742 return getOrCreateType(
QualType(T, 0), Unit);
745 auto *FromTy = getOrCreateType(Qc.
apply(CGM.getContext(),
T), Unit);
749 return DBuilder.createQualifiedType(Tag, FromTy);
753 llvm::DIFile *Unit) {
759 return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);
761 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
765 llvm::DIType *CGDebugInfo::CreateType(
const PointerType *Ty,
766 llvm::DIFile *Unit) {
767 return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
773 switch (TheCU->getSourceLanguage()) {
774 case llvm::dwarf::DW_LANG_C_plus_plus:
776 case llvm::dwarf::DW_LANG_ObjC_plus_plus:
777 return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
787 llvm::DICompileUnit *TheCU) {
788 SmallString<256> FullName;
796 llvm::raw_svector_ostream Out(FullName);
803 llvm::dwarf::Tag Tag;
805 Tag = llvm::dwarf::DW_TAG_structure_type;
807 Tag = llvm::dwarf::DW_TAG_union_type;
812 Tag = llvm::dwarf::DW_TAG_class_type;
817 llvm::DICompositeType *
818 CGDebugInfo::getOrCreateRecordFwdDecl(
const RecordType *Ty,
819 llvm::DIScope *Ctx) {
821 if (llvm::DIType *
T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
822 return cast<llvm::DICompositeType>(
T);
823 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
825 StringRef RDName = getClassName(RD);
832 llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
834 llvm::DINode::FlagFwdDecl, FullName);
835 if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
836 if (
auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
837 DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
838 CollectCXXTemplateParams(TSpecial, DefUnit));
839 ReplaceMap.emplace_back(
840 std::piecewise_construct, std::make_tuple(Ty),
841 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
845 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
848 llvm::DIFile *Unit) {
852 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy);
853 uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace);
856 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
858 if (Tag == llvm::dwarf::DW_TAG_reference_type ||
859 Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
860 return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
861 Size, Align, DWARFAddressSpace);
863 return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
864 Align, DWARFAddressSpace);
867 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
868 llvm::DIType *&
Cache) {
871 Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name,
872 TheCU, getOrCreateMainFile(), 0);
873 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
874 Cache = DBuilder.createPointerType(Cache, Size);
879 llvm::DIFile *Unit) {
882 uint64_t FieldSize, FieldOffset;
884 llvm::DINodeArray Elements;
887 FType = CGM.getContext().UnsignedLongTy;
888 EltTys.push_back(CreateMemberType(Unit, FType,
"reserved", &FieldOffset));
889 EltTys.push_back(CreateMemberType(Unit, FType,
"Size", &FieldOffset));
891 Elements = DBuilder.getOrCreateArray(EltTys);
894 llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock;
898 DBuilder.createStructType(Unit,
"__block_descriptor",
nullptr, LineNo,
899 FieldOffset, 0, Flags,
nullptr, Elements);
902 uint64_t Size = CGM.getContext().getTypeSize(Ty);
904 auto *DescTy = DBuilder.createPointerType(EltTy, Size);
907 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
908 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
909 FType = CGM.getContext().IntTy;
910 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
911 EltTys.push_back(CreateMemberType(Unit, FType,
"__reserved", &FieldOffset));
913 EltTys.push_back(CreateMemberType(Unit, FType,
"__FuncPtr", &FieldOffset));
915 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
916 FieldSize = CGM.getContext().getTypeSize(Ty);
917 FieldAlign = CGM.getContext().getTypeAlign(Ty);
918 EltTys.push_back(DBuilder.createMemberType(
919 Unit,
"__descriptor",
nullptr, LineNo, FieldSize, FieldAlign, FieldOffset,
920 llvm::DINode::FlagZero, DescTy));
922 FieldOffset += FieldSize;
923 Elements = DBuilder.getOrCreateArray(EltTys);
930 DBuilder.createStructType(Unit,
"",
nullptr, LineNo,
931 FieldOffset, 0, Flags,
nullptr, Elements);
933 return DBuilder.createPointerType(EltTy, Size);
937 llvm::DIFile *Unit) {
942 llvm::raw_svector_ostream OS(NS);
946 auto *AliasDecl = cast<TypeAliasTemplateDecl>(
950 return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
952 getDeclContextDescriptor(AliasDecl));
955 llvm::DIType *CGDebugInfo::CreateType(
const TypedefType *Ty,
956 llvm::DIFile *Unit) {
962 return DBuilder.createTypedef(
964 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
965 getDeclContextDescriptor(Ty->
getDecl()));
975 return llvm::dwarf::DW_CC_BORLAND_stdcall;
977 return llvm::dwarf::DW_CC_BORLAND_msfastcall;
979 return llvm::dwarf::DW_CC_BORLAND_thiscall;
981 return llvm::dwarf::DW_CC_LLVM_vectorcall;
983 return llvm::dwarf::DW_CC_BORLAND_pascal;
1002 llvm::DIType *CGDebugInfo::CreateType(
const FunctionType *Ty,
1003 llvm::DIFile *Unit) {
1007 EltTys.push_back(getOrCreateType(Ty->
getReturnType(), Unit));
1011 if (isa<FunctionNoProtoType>(Ty))
1012 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1013 else if (
const auto *FPT = dyn_cast<FunctionProtoType>(Ty)) {
1014 for (
const QualType &ParamType : FPT->param_types())
1015 EltTys.push_back(getOrCreateType(ParamType, Unit));
1016 if (FPT->isVariadic())
1017 EltTys.push_back(DBuilder.createUnspecifiedParameter());
1020 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
1021 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
1036 if (Access == Default)
1037 return llvm::DINode::FlagZero;
1041 return llvm::DINode::FlagPrivate;
1043 return llvm::DINode::FlagProtected;
1045 return llvm::DINode::FlagPublic;
1047 return llvm::DINode::FlagZero;
1049 llvm_unreachable(
"unexpected access enumerator");
1052 llvm::DIType *CGDebugInfo::createBitFieldType(
const FieldDecl *BitFieldDecl,
1053 llvm::DIScope *RecordTy,
1055 StringRef Name = BitFieldDecl->
getName();
1058 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1059 llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
1062 llvm::DIFile *File = getOrCreateFile(Loc);
1063 unsigned Line = getLineNumber(Loc);
1066 CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
1067 uint64_t SizeInBits = BitFieldInfo.
Size;
1068 assert(SizeInBits > 0 &&
"found named 0-width bitfield");
1069 uint64_t StorageOffsetInBits =
1075 if (CGM.getDataLayout().isBigEndian())
1077 uint64_t OffsetInBits = StorageOffsetInBits + Offset;
1079 return DBuilder.createBitFieldMemberType(
1080 RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits,
1087 uint32_t AlignInBits, llvm::DIFile *tunit,
1088 llvm::DIScope *scope,
const RecordDecl *RD) {
1089 llvm::DIType *debugType = getOrCreateType(type, tunit);
1092 llvm::DIFile *file = getOrCreateFile(loc);
1093 unsigned line = getLineNumber(loc);
1095 uint64_t SizeInBits = 0;
1096 auto Align = AlignInBits;
1098 TypeInfo TI = CGM.getContext().getTypeInfo(type);
1099 SizeInBits = TI.
Width;
1105 return DBuilder.createMemberType(scope, name, file, line, SizeInBits,
1106 Align, offsetInBits, flags, debugType);
1109 void CGDebugInfo::CollectRecordLambdaFields(
1111 llvm::DIType *RecordTy) {
1115 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
1117 unsigned fieldno = 0;
1120 I != E; ++I, ++Field, ++fieldno) {
1124 assert(!Field->isBitField() &&
"lambdas don't have bitfield members!");
1126 StringRef VName = V->
getName();
1127 llvm::DIFile *VUnit = getOrCreateFile(Loc);
1129 llvm::DIType *FieldType = createFieldType(
1130 VName, Field->getType(), Loc, Field->getAccess(),
1131 layout.
getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
1132 elements.push_back(FieldType);
1139 llvm::DIFile *VUnit = getOrCreateFile(f->
getLocation());
1141 llvm::DIType *fieldType = createFieldType(
1145 elements.push_back(fieldType);
1150 llvm::DIDerivedType *
1151 CGDebugInfo::CreateRecordStaticField(
const VarDecl *Var, llvm::DIType *RecordTy,
1156 llvm::DIFile *VUnit = getOrCreateFile(Var->
getLocation());
1157 llvm::DIType *VTy = getOrCreateType(Var->
getType(), VUnit);
1159 unsigned LineNumber = getLineNumber(Var->
getLocation());
1160 StringRef VName = Var->
getName();
1161 llvm::Constant *C =
nullptr;
1166 C = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->
getInt());
1168 C = llvm::ConstantFP::get(CGM.getLLVMContext(), Value->
getFloat());
1174 llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
1175 RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align);
1180 void CGDebugInfo::CollectRecordNormalField(
1181 const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
1184 StringRef name = field->
getName();
1191 llvm::DIType *FieldType;
1193 FieldType = createBitFieldType(field, RecordTy, RD);
1198 OffsetInBits, Align, tunit, RecordTy, RD);
1201 elements.push_back(FieldType);
1204 void CGDebugInfo::CollectRecordNestedType(
1206 QualType Ty = CGM.getContext().getTypeDeclType(TD);
1208 if (isa<InjectedClassNameType>(Ty))
1211 llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc));
1212 elements.push_back(nestedType);
1215 void CGDebugInfo::CollectRecordFields(
1216 const RecordDecl *record, llvm::DIFile *tunit,
1218 llvm::DICompositeType *RecordTy) {
1221 if (CXXDecl && CXXDecl->
isLambda())
1222 CollectRecordLambdaFields(CXXDecl, elements, RecordTy);
1224 const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
1228 bool IncludeNestedTypes = CGM.getCodeGenOpts().EmitCodeView;
1231 unsigned fieldNo = 0;
1235 for (
const auto *I : record->
decls())
1236 if (
const auto *V = dyn_cast<VarDecl>(I)) {
1237 if (V->hasAttr<NoDebugAttr>())
1240 auto MI = StaticDataMemberCache.find(V->getCanonicalDecl());
1241 if (MI != StaticDataMemberCache.end()) {
1242 assert(MI->second &&
1243 "Static data member declaration should still exist");
1244 elements.push_back(MI->second);
1246 auto Field = CreateRecordStaticField(V, RecordTy, record);
1247 elements.push_back(Field);
1249 }
else if (
const auto *field = dyn_cast<FieldDecl>(I)) {
1250 CollectRecordNormalField(field, layout.
getFieldOffset(fieldNo), tunit,
1251 elements, RecordTy, record);
1255 }
else if (IncludeNestedTypes) {
1256 if (
const auto *nestedType = dyn_cast<TypeDecl>(I))
1257 if (!nestedType->isImplicit() &&
1258 nestedType->getDeclContext() == record)
1259 CollectRecordNestedType(nestedType, elements);
1264 llvm::DISubroutineType *
1265 CGDebugInfo::getOrCreateMethodType(
const CXXMethodDecl *Method,
1266 llvm::DIFile *Unit) {
1269 return cast_or_null<llvm::DISubroutineType>(
1270 getOrCreateType(
QualType(Func, 0), Unit));
1271 return getOrCreateInstanceMethodType(Method->
getThisType(CGM.getContext()),
1275 llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1278 llvm::DITypeRefArray Args(
1279 cast<llvm::DISubroutineType>(getOrCreateType(
QualType(Func, 0), Unit))
1281 assert(Args.size() &&
"Invalid number of arguments!");
1286 Elts.push_back(Args[0]);
1290 if (isa<ClassTemplateSpecializationDecl>(RD)) {
1292 const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1294 unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
1295 uint64_t Size = CGM.getTarget().getPointerWidth(AS);
1297 llvm::DIType *PointeeType = getOrCreateType(PointeeTy, Unit);
1298 llvm::DIType *ThisPtrType =
1299 DBuilder.createPointerType(PointeeType, Size, Align);
1304 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1305 Elts.push_back(ThisPtrType);
1307 llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1309 ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1310 Elts.push_back(ThisPtrType);
1314 for (
unsigned i = 1, e = Args.size(); i != e; ++i)
1315 Elts.push_back(Args[i]);
1317 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
1319 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1321 Flags |= llvm::DINode::FlagLValueReference;
1323 Flags |= llvm::DINode::FlagRValueReference;
1325 return DBuilder.createSubroutineType(EltTypeArray, Flags,
1332 if (
const auto *NRD = dyn_cast<CXXRecordDecl>(RD->
getDeclContext()))
1339 llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
1340 const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
1342 isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
1344 StringRef MethodName = getFunctionName(Method);
1345 llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1349 StringRef MethodLinkageName;
1356 MethodLinkageName = CGM.getMangledName(Method);
1359 llvm::DIFile *MethodDefUnit =
nullptr;
1360 unsigned MethodLine = 0;
1362 MethodDefUnit = getOrCreateFile(Method->
getLocation());
1363 MethodLine = getLineNumber(Method->
getLocation());
1367 llvm::DIType *ContainingType =
nullptr;
1368 unsigned Virtuality = 0;
1369 unsigned VIndex = 0;
1370 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1375 Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;
1377 Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;
1379 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1382 if (!isa<CXXDestructorDecl>(Method))
1383 VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method);
1390 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1399 Flags |= llvm::DINode::FlagIntroducedVirtual;
1404 ThisAdjustment = CGM.getCXXABI()
1405 .getVirtualFunctionPrologueThisAdjustment(GD)
1408 ContainingType = RecordTy;
1412 Flags |= llvm::DINode::FlagStaticMember;
1414 Flags |= llvm::DINode::FlagArtificial;
1416 if (
const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
1417 if (CXXC->isExplicit())
1418 Flags |= llvm::DINode::FlagExplicit;
1419 }
else if (
const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
1420 if (CXXC->isExplicit())
1421 Flags |= llvm::DINode::FlagExplicit;
1424 Flags |= llvm::DINode::FlagPrototyped;
1426 Flags |= llvm::DINode::FlagLValueReference;
1428 Flags |= llvm::DINode::FlagRValueReference;
1430 llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
1431 llvm::DISubprogram *SP = DBuilder.createMethod(
1432 RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
1433 MethodTy,
false,
false, Virtuality,
1434 VIndex, ThisAdjustment, ContainingType, Flags, CGM.getLangOpts().Optimize,
1435 TParamsArray.get());
1442 void CGDebugInfo::CollectCXXMemberFunctions(
1449 for (
const auto *I : RD->
decls()) {
1474 EltTys.push_back(MI == SPCache.end()
1475 ? CreateCXXMemberFunction(Method, Unit, RecordTy)
1476 :
static_cast<llvm::Metadata *
>(MI->second));
1480 void CGDebugInfo::CollectCXXBases(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1482 llvm::DIType *RecordTy) {
1484 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
bases(), SeenTypes,
1485 llvm::DINode::FlagZero);
1489 if (CGM.getCodeGenOpts().EmitCodeView) {
1490 CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->
vbases(), SeenTypes,
1491 llvm::DINode::FlagIndirectVirtualBase);
1495 void CGDebugInfo::CollectCXXBasesAux(
1500 llvm::DINode::DIFlags StartingFlags) {
1502 for (
const auto &BI : Bases) {
1504 cast<CXXRecordDecl>(BI.getType()->getAs<
RecordType>()->getDecl());
1505 if (!SeenTypes.insert(
Base).second)
1507 auto *BaseTy = getOrCreateType(BI.getType(), Unit);
1508 llvm::DINode::DIFlags BFlags = StartingFlags;
1509 uint64_t BaseOffset;
1511 if (BI.isVirtual()) {
1512 if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
1515 BaseOffset = 0 - CGM.getItaniumVTableContext()
1516 .getVirtualBaseOffsetOffset(RD,
Base)
1522 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD,
Base);
1524 BFlags |= llvm::DINode::FlagVirtual;
1532 DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset, BFlags);
1533 EltTys.push_back(DTy);
1540 llvm::DIFile *Unit) {
1542 for (
unsigned i = 0, e = TAList.size(); i != e; ++i) {
1549 llvm::DIType *TTy = getOrCreateType(TA.
getAsType(), Unit);
1550 TemplateParams.push_back(
1551 DBuilder.createTemplateTypeParameter(TheCU, Name, TTy));
1555 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1557 llvm::ConstantInt::get(CGM.getLLVMContext(), TA.
getAsIntegral())));
1562 llvm::DIType *TTy = getOrCreateType(T, Unit);
1563 llvm::Constant *V =
nullptr;
1567 if (
const auto *VD = dyn_cast<VarDecl>(D))
1568 V = CGM.GetAddrOfGlobalVar(VD);
1571 else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->
isInstance())
1572 V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
1573 else if (
const auto *FD = dyn_cast<FunctionDecl>(D))
1574 V = CGM.GetAddrOfFunction(FD);
1577 else if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr())) {
1581 uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
1583 CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
1584 V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
1586 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1588 cast_or_null<llvm::Constant>(V->stripPointerCasts())));
1592 llvm::DIType *TTy = getOrCreateType(T, Unit);
1593 llvm::Constant *V =
nullptr;
1596 if (
const auto *MPT = dyn_cast<MemberPointerType>(T.
getTypePtr()))
1602 if (MPT->isMemberDataPointer())
1603 V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
1605 V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
1606 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1607 TheCU, Name, TTy, V));
1610 TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
1611 TheCU, Name,
nullptr,
1615 TemplateParams.push_back(DBuilder.createTemplateParameterPack(
1616 TheCU, Name,
nullptr,
1623 T = CGM.getContext().getLValueReferenceType(T);
1625 assert(V &&
"Expression in template argument isn't constant");
1626 llvm::DIType *TTy = getOrCreateType(T, Unit);
1627 TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1628 TheCU, Name, TTy, V->stripPointerCasts()));
1634 "These argument types shouldn't exist in concrete types");
1637 return DBuilder.getOrCreateArray(TemplateParams);
1641 CGDebugInfo::CollectFunctionTemplateParams(
const FunctionDecl *FD,
1642 llvm::DIFile *Unit) {
1648 return CollectTemplateParams(
1651 return llvm::DINodeArray();
1654 llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
1661 return CollectTemplateParams(TPList, TAList.
asArray(), Unit);
1664 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
1666 return VTablePtrType;
1671 llvm::Metadata *STy = getOrCreateType(Context.
IntTy, Unit);
1672 llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
1673 llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
1675 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1677 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1679 llvm::DIType *vtbl_ptr_type =
1680 DBuilder.createPointerType(SubTy, Size, 0, DWARFAddressSpace,
1682 VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
1683 return VTablePtrType;
1686 StringRef CGDebugInfo::getVTableName(
const CXXRecordDecl *RD) {
1691 void CGDebugInfo::CollectVTableInfo(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
1693 llvm::DICompositeType *RecordTy) {
1709 llvm::DIType *VPtrTy =
nullptr;
1710 bool NeedVTableShape = CGM.getCodeGenOpts().EmitCodeView &&
1711 CGM.getTarget().getCXXABI().isMicrosoft();
1712 if (NeedVTableShape) {
1714 CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1716 CGM.getMicrosoftVTableContext().getVFTableLayout(RD,
CharUnits::Zero());
1717 unsigned VSlotCount =
1719 unsigned VTableWidth = PtrWidth * VSlotCount;
1720 unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
1722 CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
1725 llvm::DIType *VTableType =
1726 DBuilder.createPointerType(
nullptr, VTableWidth, 0, DWARFAddressSpace,
1728 EltTys.push_back(VTableType);
1731 VPtrTy = DBuilder.createPointerType(VTableType, PtrWidth);
1739 VPtrTy = getOrCreateVTablePtrType(Unit);
1741 unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
1742 llvm::DIType *VPtrMember = DBuilder.createMemberType(
1743 Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
1744 llvm::DINode::FlagArtificial, VPtrTy);
1745 EltTys.push_back(VPtrMember);
1751 llvm::DIType *
T = getOrCreateType(RTy, getOrCreateFile(Loc));
1757 return getOrCreateStandaloneType(D, Loc);
1763 assert(!D.
isNull() &&
"null type");
1764 llvm::DIType *
T = getOrCreateType(D, getOrCreateFile(Loc));
1765 assert(T &&
"could not create debug info for type");
1774 QualType Ty = CGM.getContext().getEnumType(ED);
1776 auto I = TypeCache.find(TyPtr);
1777 if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
1779 llvm::DIType *Res = CreateTypeDefinition(Ty->
castAs<
EnumType>());
1780 assert(!Res->isForwardDecl());
1781 TypeCache[TyPtr].reset(Res);
1786 !CGM.getLangOpts().CPlusPlus)
1787 completeRequiredType(RD);
1792 if (RD->
hasAttr<DLLImportAttr>())
1795 if (MD->hasAttr<DLLImportAttr>())
1808 if (
auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
1824 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1825 if (CXXRD->isDynamicClass() &&
1826 CGM.getVTableLinkage(CXXRD) ==
1827 llvm::GlobalValue::AvailableExternallyLinkage &&
1840 QualType Ty = CGM.getContext().getRecordType(RD);
1842 auto I = TypeCache.find(TyPtr);
1843 if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
1846 assert(!Res->isForwardDecl());
1847 TypeCache[TyPtr].reset(Res);
1854 if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
1855 !MD->getMemberSpecializationInfo()->isExplicitSpecialization())
1873 if (!LangOpts.CPlusPlus)
1895 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
1896 Spec = SD->getSpecializationKind();
1910 QualType Ty = CGM.getContext().getRecordType(RD);
1911 llvm::DIType *
T = getTypeOrNull(Ty);
1912 if (T && T->isForwardDecl())
1913 completeClassData(RD);
1916 llvm::DIType *CGDebugInfo::CreateType(
const RecordType *Ty) {
1918 llvm::DIType *
T = cast_or_null<llvm::DIType>(getTypeOrNull(
QualType(Ty, 0)));
1920 CGM.getLangOpts())) {
1922 T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));
1926 return CreateTypeDefinition(Ty);
1929 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const RecordType *Ty) {
1933 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
1941 llvm::DICompositeType *FwdDecl = getOrCreateLimitedType(Ty, DefUnit);
1947 if (
const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
1948 CollectContainingType(CXXDecl, FwdDecl);
1951 LexicalBlockStack.emplace_back(&*FwdDecl);
1952 RegionMap[Ty->
getDecl()].reset(FwdDecl);
1964 CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
1965 CollectVTableInfo(CXXDecl, DefUnit, EltTys, FwdDecl);
1969 CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
1971 CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
1973 LexicalBlockStack.pop_back();
1974 RegionMap.erase(Ty->
getDecl());
1976 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
1977 DBuilder.replaceArrays(FwdDecl, Elements);
1979 if (FwdDecl->isTemporary())
1981 llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
1983 RegionMap[Ty->
getDecl()].reset(FwdDecl);
1988 llvm::DIFile *Unit) {
1994 llvm::DIFile *Unit) {
1999 return DBuilder.createTypedef(
2001 Ty->
getDecl()->
getName(), getOrCreateFile(Loc), getLineNumber(Loc),
2002 getDeclContextDescriptor(Ty->
getDecl()));
2030 llvm::DIFile *Unit) {
2040 return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
2042 getDeclContextDescriptor(ID), Unit, 0);
2045 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2048 static_cast<llvm::dwarf::SourceLanguage
>(TheCU->getSourceLanguage());
2054 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2055 llvm::DIType *FwdDecl = DBuilder.createReplaceableCompositeType(
2056 llvm::dwarf::DW_TAG_structure_type, ID->
getName(), Mod ? Mod : TheCU,
2057 DefUnit,
Line, RuntimeLang);
2058 ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
2062 return CreateTypeDefinition(Ty, Unit);
2067 bool CreateSkeletonCU) {
2072 auto ModRef = ModuleCache.find(M);
2073 if (ModRef != ModuleCache.end())
2074 return cast<llvm::DIModule>(ModRef->second);
2077 SmallString<128> ConfigMacros;
2079 llvm::raw_svector_ostream OS(ConfigMacros);
2080 const auto &PPOpts = CGM.getPreprocessorOpts();
2083 for (
auto &M : PPOpts.Macros) {
2086 const std::string &Macro = M.first;
2087 bool Undef = M.second;
2088 OS <<
"\"-" << (Undef ?
'U' :
'D');
2089 for (
char c : Macro)
2091 case '\\' : OS <<
"\\\\";
break;
2092 case '"' : OS <<
"\\\"";
break;
2099 bool IsRootModule = M ? !M->
Parent :
true;
2100 if (CreateSkeletonCU && IsRootModule) {
2104 uint64_t Signature =
2108 llvm::DIBuilder DIB(CGM.getModule());
2109 DIB.createCompileUnit(TheCU->getSourceLanguage(),
2111 TheCU->getProducer(),
true, StringRef(), 0,
2112 Mod.
getASTFile(), llvm::DICompileUnit::FullDebug,
2117 IsRootModule ? nullptr
2118 : getOrCreateModuleRef(
2121 llvm::DIModule *DIMod =
2122 DBuilder.createModule(Parent, Mod.
getModuleName(), ConfigMacros,
2123 Mod.
getPath(), CGM.getHeaderSearchOpts().Sysroot);
2124 ModuleCache[M].reset(DIMod);
2129 llvm::DIFile *Unit) {
2131 llvm::DIFile *DefUnit = getOrCreateFile(ID->
getLocation());
2133 unsigned RuntimeLang = TheCU->getSourceLanguage();
2136 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2139 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2141 Flags |= llvm::DINode::FlagObjcClassComplete;
2143 llvm::DIScope *Mod = getParentModuleOrNull(ID);
2144 llvm::DICompositeType *RealDecl = DBuilder.createStructType(
2145 Mod ? Mod : Unit, ID->
getName(), DefUnit,
Line, Size, Align, Flags,
2146 nullptr, llvm::DINodeArray(), RuntimeLang);
2152 LexicalBlockStack.emplace_back(RealDecl);
2153 RegionMap[Ty->
getDecl()].reset(RealDecl);
2160 llvm::DIType *SClassTy =
2161 getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
2165 llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0,
2166 llvm::DINode::FlagZero);
2167 EltTys.push_back(InhTag);
2173 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2174 unsigned PLine = getLineNumber(Loc);
2177 llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
2178 PD->getName(), PUnit, PLine,
2180 : getSelectorName(PD->getGetterName()),
2182 : getSelectorName(PD->getSetterName()),
2183 PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
2184 EltTys.push_back(PropertyNode);
2187 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2189 for (
auto *PD : ClassExt->properties()) {
2190 PropertySet.insert(PD->getIdentifier());
2196 if (!PropertySet.insert(PD->getIdentifier()).second)
2202 const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
2203 unsigned FieldNo = 0;
2205 Field = Field->getNextIvar(), ++FieldNo) {
2206 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
2210 StringRef FieldName = Field->getName();
2213 if (FieldName.empty())
2217 llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation());
2218 unsigned FieldLine = getLineNumber(Field->getLocation());
2220 uint64_t FieldSize = 0;
2221 uint32_t FieldAlign = 0;
2223 if (!FType->isIncompleteArrayType()) {
2226 FieldSize = Field->isBitField()
2227 ? Field->getBitWidthValue(CGM.getContext())
2228 : CGM.getContext().getTypeSize(FType);
2232 uint64_t FieldOffset;
2233 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2237 if (Field->isBitField()) {
2239 CGM.getObjCRuntime().ComputeBitfieldBitOffset(CGM, ID, Field);
2240 FieldOffset %= CGM.getContext().getCharWidth();
2248 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2250 Flags = llvm::DINode::FlagProtected;
2252 Flags = llvm::DINode::FlagPrivate;
2254 Flags = llvm::DINode::FlagPublic;
2256 llvm::MDNode *PropertyNode =
nullptr;
2259 ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
2262 llvm::DIFile *PUnit = getOrCreateFile(Loc);
2263 unsigned PLine = getLineNumber(Loc);
2266 PropertyNode = DBuilder.createObjCProperty(
2267 PD->getName(), PUnit, PLine,
2269 PD->getGetterName()),
2271 PD->getSetterName()),
2272 PD->getPropertyAttributes(),
2273 getOrCreateType(PD->getType(), PUnit));
2277 FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
2278 FieldSize, FieldAlign, FieldOffset, Flags,
2279 FieldTy, PropertyNode);
2280 EltTys.push_back(FieldTy);
2283 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
2284 DBuilder.replaceArrays(RealDecl, Elements);
2286 LexicalBlockStack.pop_back();
2290 llvm::DIType *CGDebugInfo::CreateType(
const VectorType *Ty,
2291 llvm::DIFile *Unit) {
2292 llvm::DIType *ElementTy = getOrCreateType(Ty->
getElementType(), Unit);
2299 llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(0, Count);
2300 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
2302 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2305 return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
2308 llvm::DIType *CGDebugInfo::CreateType(
const ArrayType *Ty, llvm::DIFile *Unit) {
2313 if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2328 Size = CGM.getContext().getTypeSize(Ty);
2337 while ((Ty = dyn_cast<ArrayType>(EltTy))) {
2346 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
2347 Count = CAT->getSize().getZExtValue();
2348 else if (
const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
2349 if (
Expr *Size = VAT->getSizeExpr()) {
2351 if (Size->EvaluateAsInt(V, CGM.getContext()))
2352 Count = V.getExtValue();
2357 Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
2361 llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
2363 return DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
2368 llvm::DIFile *Unit) {
2369 return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty,
2374 llvm::DIFile *Unit) {
2375 return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type, Ty,
2381 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2385 Size = CGM.getContext().getTypeSize(Ty);
2388 if (CGM.getTarget().getCXXABI().isMicrosoft()) {
2390 case MSInheritanceAttr::Keyword_single_inheritance:
2391 Flags |= llvm::DINode::FlagSingleInheritance;
2393 case MSInheritanceAttr::Keyword_multiple_inheritance:
2394 Flags |= llvm::DINode::FlagMultipleInheritance;
2396 case MSInheritanceAttr::Keyword_virtual_inheritance:
2397 Flags |= llvm::DINode::FlagVirtualInheritance;
2399 case MSInheritanceAttr::Keyword_unspecified_inheritance:
2407 return DBuilder.createMemberPointerType(
2413 return DBuilder.createMemberPointerType(
2414 getOrCreateInstanceMethodType(CGM.getContext().getPointerType(
QualType(
2417 ClassType, Size, 0, Flags);
2420 llvm::DIType *CGDebugInfo::CreateType(
const AtomicType *Ty, llvm::DIFile *U) {
2422 return DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_atomic_type, FromTy);
2425 llvm::DIType* CGDebugInfo::CreateType(
const PipeType *Ty,
2430 llvm::DIType *CGDebugInfo::CreateEnumType(
const EnumType *Ty) {
2442 bool isImportedFromModule =
2454 llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
2455 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2456 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
2457 llvm::dwarf::DW_TAG_enumeration_type,
"", TheCU, DefUnit, 0));
2460 StringRef EDName = ED->
getName();
2461 llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
2462 llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
2463 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName);
2465 ReplaceMap.emplace_back(
2466 std::piecewise_construct, std::make_tuple(Ty),
2467 std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));
2471 return CreateTypeDefinition(Ty);
2474 llvm::DIType *CGDebugInfo::CreateTypeDefinition(
const EnumType *Ty) {
2489 Enumerators.push_back(DBuilder.createEnumerator(
2490 Enum->getName(), Enum->getInitVal().getSExtValue()));
2494 llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
2496 llvm::DIFile *DefUnit = getOrCreateFile(ED->
getLocation());
2498 llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
2499 llvm::DIType *ClassTy =
2501 return DBuilder.createEnumerationType(EnumContext, ED->
getName(), DefUnit,
2502 Line, Size, Align, EltArray, ClassTy,
2508 StringRef Name, StringRef
Value) {
2509 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2510 return DBuilder.createMacro(Parent, Line, MType, Name, Value);
2516 llvm::DIFile *FName = getOrCreateFile(FileLoc);
2517 unsigned Line = LineLoc.
isInvalid() ? 0 : getLineNumber(LineLoc);
2518 return DBuilder.createTempMacroFile(Parent, Line, FName);
2528 Quals += InnerQuals;
2533 case Type::TemplateSpecialization: {
2534 const auto *Spec = cast<TemplateSpecializationType>(
T);
2535 if (Spec->isTypeAlias())
2537 T = Spec->desugar();
2540 case Type::TypeOfExpr:
2541 T = cast<TypeOfExprType>(
T)->getUnderlyingExpr()->getType();
2546 case Type::Decltype:
2549 case Type::UnaryTransform:
2552 case Type::Attributed:
2553 T = cast<AttributedType>(
T)->getEquivalentType();
2555 case Type::Elaborated:
2556 T = cast<ElaboratedType>(
T)->getNamedType();
2559 T = cast<ParenType>(
T)->getInnerType();
2561 case Type::SubstTemplateTypeParm:
2562 T = cast<SubstTemplateTypeParmType>(
T)->getReplacementType();
2565 case Type::DeducedTemplateSpecialization: {
2566 QualType DT = cast<DeducedType>(
T)->getDeducedType();
2567 assert(!DT.
isNull() &&
"Undeduced types shouldn't reach here.");
2571 case Type::Adjusted:
2574 T = cast<AdjustedType>(
T)->getAdjustedType();
2578 assert(T != LastT &&
"Type unwrapping failed to unwrap!");
2583 llvm::DIType *CGDebugInfo::getTypeOrNull(
QualType Ty) {
2589 if (it != TypeCache.end()) {
2591 if (llvm::Metadata *V = it->second)
2592 return cast<llvm::DIType>(V);
2602 completeUnusedClass(SD);
2609 completeClassData(&D);
2612 RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
2615 llvm::DIType *CGDebugInfo::getOrCreateType(
QualType Ty, llvm::DIFile *Unit) {
2622 if (
auto *
T = getTypeOrNull(Ty))
2625 llvm::DIType *Res = CreateTypeNode(Ty, Unit);
2629 TypeCache[TyPtr].reset(Res);
2634 llvm::DIModule *CGDebugInfo::getParentModuleOrNull(
const Decl *D) {
2636 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->
getDefinition())
2640 auto *Reader = CGM.getContext().getExternalSource();
2642 auto Info = Reader->getSourceDescriptor(Idx);
2644 return getOrCreateModuleRef(*Info,
true);
2645 }
else if (ClangModuleMap) {
2659 return getOrCreateModuleRef(Info,
false);
2662 return getOrCreateModuleRef(PCHDescriptor,
false);
2669 llvm::DIType *CGDebugInfo::CreateTypeNode(
QualType Ty, llvm::DIFile *Unit) {
2672 return CreateQualifiedType(Ty, Unit);
2676 #define TYPE(Class, Base) 2677 #define ABSTRACT_TYPE(Class, Base) 2678 #define NON_CANONICAL_TYPE(Class, Base) 2679 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 2680 #include "clang/AST/TypeNodes.def" 2681 llvm_unreachable(
"Dependent types cannot show up in debug information");
2683 case Type::ExtVector:
2685 return CreateType(cast<VectorType>(Ty), Unit);
2686 case Type::ObjCObjectPointer:
2687 return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
2688 case Type::ObjCObject:
2689 return CreateType(cast<ObjCObjectType>(Ty), Unit);
2690 case Type::ObjCTypeParam:
2691 return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
2692 case Type::ObjCInterface:
2693 return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
2695 return CreateType(cast<BuiltinType>(Ty));
2697 return CreateType(cast<ComplexType>(Ty));
2699 return CreateType(cast<PointerType>(Ty), Unit);
2700 case Type::BlockPointer:
2701 return CreateType(cast<BlockPointerType>(Ty), Unit);
2703 return CreateType(cast<TypedefType>(Ty), Unit);
2705 return CreateType(cast<RecordType>(Ty));
2707 return CreateEnumType(cast<EnumType>(Ty));
2708 case Type::FunctionProto:
2709 case Type::FunctionNoProto:
2710 return CreateType(cast<FunctionType>(Ty), Unit);
2711 case Type::ConstantArray:
2712 case Type::VariableArray:
2713 case Type::IncompleteArray:
2714 return CreateType(cast<ArrayType>(Ty), Unit);
2716 case Type::LValueReference:
2717 return CreateType(cast<LValueReferenceType>(Ty), Unit);
2718 case Type::RValueReference:
2719 return CreateType(cast<RValueReferenceType>(Ty), Unit);
2721 case Type::MemberPointer:
2722 return CreateType(cast<MemberPointerType>(Ty), Unit);
2725 return CreateType(cast<AtomicType>(Ty), Unit);
2728 return CreateType(cast<PipeType>(Ty), Unit);
2730 case Type::TemplateSpecialization:
2731 return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
2734 case Type::Attributed:
2735 case Type::Adjusted:
2737 case Type::DeducedTemplateSpecialization:
2738 case Type::Elaborated:
2740 case Type::SubstTemplateTypeParm:
2741 case Type::TypeOfExpr:
2743 case Type::Decltype:
2744 case Type::UnaryTransform:
2745 case Type::PackExpansion:
2749 llvm_unreachable(
"type should have been unwrapped!");
2752 llvm::DICompositeType *CGDebugInfo::getOrCreateLimitedType(
const RecordType *Ty,
2753 llvm::DIFile *Unit) {
2756 auto *
T = cast_or_null<llvm::DICompositeType>(getTypeOrNull(QTy));
2761 if (
T && !
T->isForwardDecl())
2765 llvm::DICompositeType *Res = CreateLimitedType(Ty);
2770 DBuilder.replaceArrays(Res,
T ?
T->getElements() : llvm::DINodeArray());
2778 llvm::DICompositeType *CGDebugInfo::CreateLimitedType(
const RecordType *Ty) {
2782 llvm::DIFile *DefUnit = getOrCreateFile(RD->
getLocation());
2784 StringRef RDName = getClassName(RD);
2786 llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
2790 auto *
T = cast_or_null<llvm::DICompositeType>(
2791 getTypeOrNull(CGM.getContext().getRecordType(RD)));
2799 return getOrCreateRecordFwdDecl(Ty, RDContext);
2801 uint64_t Size = CGM.getContext().getTypeSize(Ty);
2806 llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
2807 getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
2808 llvm::DINode::FlagZero, FullName);
2812 switch (RealDecl->getTag()) {
2814 llvm_unreachable(
"invalid composite type tag");
2816 case llvm::dwarf::DW_TAG_array_type:
2817 case llvm::dwarf::DW_TAG_enumeration_type:
2822 if (FullName.empty())
2826 case llvm::dwarf::DW_TAG_structure_type:
2827 case llvm::dwarf::DW_TAG_union_type:
2828 case llvm::dwarf::DW_TAG_class_type:
2831 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
2835 RegionMap[Ty->
getDecl()].reset(RealDecl);
2838 if (
const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
2839 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
2840 CollectCXXTemplateParams(TSpecial, DefUnit));
2844 void CGDebugInfo::CollectContainingType(
const CXXRecordDecl *RD,
2845 llvm::DICompositeType *RealDecl) {
2847 llvm::DICompositeType *ContainingType =
nullptr;
2852 const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
2859 ContainingType = cast<llvm::DICompositeType>(
2860 getOrCreateType(
QualType(PBase->getTypeForDecl(), 0),
2863 ContainingType = RealDecl;
2865 DBuilder.replaceVTableHolder(RealDecl, ContainingType);
2868 llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit,
QualType FType,
2869 StringRef Name, uint64_t *
Offset) {
2870 llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
2871 uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
2874 DBuilder.createMemberType(Unit, Name, Unit, 0, FieldSize, FieldAlign,
2875 *Offset, llvm::DINode::FlagZero, FieldTy);
2876 *Offset += FieldSize;
2880 void CGDebugInfo::collectFunctionDeclProps(
GlobalDecl GD, llvm::DIFile *Unit,
2882 StringRef &LinkageName,
2883 llvm::DIScope *&FDContext,
2884 llvm::DINodeArray &TParamsArray,
2885 llvm::DINode::DIFlags &Flags) {
2886 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
2887 Name = getFunctionName(FD);
2890 LinkageName = CGM.getMangledName(GD);
2891 Flags |= llvm::DINode::FlagPrototyped;
2896 if (LinkageName == Name || (!CGM.getCodeGenOpts().EmitGcovArcs &&
2897 !CGM.getCodeGenOpts().EmitGcovNotes &&
2898 !CGM.getCodeGenOpts().DebugInfoForProfiling &&
2900 LinkageName = StringRef();
2905 FDContext = getOrCreateNamespace(NSDecl);
2908 llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
2909 FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);
2913 Flags |= llvm::DINode::FlagNoReturn;
2915 TParamsArray = CollectFunctionTemplateParams(FD, Unit);
2919 void CGDebugInfo::collectVarDeclProps(
const VarDecl *VD, llvm::DIFile *&Unit,
2921 StringRef &Name, StringRef &LinkageName,
2922 llvm::DIScope *&VDContext) {
2929 if (T->isIncompleteArrayType()) {
2931 llvm::APInt ConstVal(32, 1);
2932 QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
2934 T = CGM.getContext().getConstantArrayType(ET, ConstVal,
2941 LinkageName = CGM.getMangledName(VD);
2942 if (LinkageName == Name)
2943 LinkageName = StringRef();
2960 DC = CGM.getContext().getTranslationUnitDecl();
2962 llvm::DIScope *Mod = getParentModuleOrNull(VD);
2963 VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
2966 llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(
GlobalDecl GD,
2968 llvm::DINodeArray TParamsArray;
2969 StringRef Name, LinkageName;
2970 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
2972 llvm::DIFile *Unit = getOrCreateFile(Loc);
2973 llvm::DIScope *DContext = Unit;
2974 unsigned Line = getLineNumber(Loc);
2975 collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext,
2976 TParamsArray, Flags);
2983 ArgTypes.push_back(Parm->getType());
2985 QualType FnType = CGM.getContext().getFunctionType(
2988 return DBuilder.createFunction(
2989 DContext, Name, LinkageName, Unit, Line,
2990 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit),
2992 true, 0, Flags, CGM.getLangOpts().Optimize,
2993 TParamsArray.get(), getFunctionDeclaration(FD));
2996 llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
2997 DContext, Name, LinkageName, Unit, Line,
2998 getOrCreateFunctionType(GD.
getDecl(), FnType, Unit),
3000 false, 0, Flags, CGM.getLangOpts().Optimize,
3001 TParamsArray.get(), getFunctionDeclaration(FD));
3003 FwdDeclReplaceMap.emplace_back(std::piecewise_construct,
3004 std::make_tuple(CanonDecl),
3005 std::make_tuple(SP));
3009 llvm::DISubprogram *
3010 CGDebugInfo::getFunctionForwardDeclaration(
GlobalDecl GD) {
3011 return getFunctionFwdDeclOrStub(GD,
false);
3014 llvm::DISubprogram *
3015 CGDebugInfo::getFunctionStub(
GlobalDecl GD) {
3016 return getFunctionFwdDeclOrStub(GD,
true);
3019 llvm::DIGlobalVariable *
3020 CGDebugInfo::getGlobalVariableForwardDeclaration(
const VarDecl *VD) {
3022 StringRef Name, LinkageName;
3024 llvm::DIFile *Unit = getOrCreateFile(Loc);
3025 llvm::DIScope *DContext = Unit;
3026 unsigned Line = getLineNumber(Loc);
3028 collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, DContext);
3030 auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
3031 DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
3033 FwdDeclReplaceMap.emplace_back(
3034 std::piecewise_construct,
3036 std::make_tuple(static_cast<llvm::Metadata *>(GV)));
3040 llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(
const Decl *D) {
3045 if (
const auto *TD = dyn_cast<TypeDecl>(D))
3046 return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
3050 if (I != DeclCache.end()) {
3052 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
3053 return GVE->getVariable();
3054 return dyn_cast_or_null<llvm::DINode>(N);
3059 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3060 return getFunctionForwardDeclaration(FD);
3061 else if (
const auto *VD = dyn_cast<VarDecl>(D))
3062 return getGlobalVariableForwardDeclaration(VD);
3067 llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(
const Decl *D) {
3076 auto *S = getDeclContextDescriptor(D);
3079 if (MI == SPCache.end()) {
3081 return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
3082 cast<llvm::DICompositeType>(S));
3085 if (MI != SPCache.end()) {
3086 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3087 if (SP && !SP->isDefinition())
3091 for (
auto NextFD : FD->
redecls()) {
3092 auto MI = SPCache.find(NextFD->getCanonicalDecl());
3093 if (MI != SPCache.end()) {
3094 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(MI->second);
3095 if (SP && !SP->isDefinition())
3104 llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(
const Decl *D,
3110 return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray(None));
3112 if (
const auto *Method = dyn_cast<CXXMethodDecl>(D))
3113 return getOrCreateMethodType(Method, F);
3118 if (
const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
3123 QualType ResultTy = OMethod->getReturnType();
3126 if (ResultTy == CGM.getContext().getObjCInstanceType())
3127 ResultTy = CGM.getContext().getPointerType(
3128 QualType(OMethod->getClassInterface()->getTypeForDecl(), 0));
3130 Elts.push_back(getOrCreateType(ResultTy, F));
3133 if (
auto *SelfDecl = OMethod->getSelfDecl())
3134 SelfDeclTy = SelfDecl->getType();
3135 else if (
auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3136 if (FPT->getNumParams() > 1)
3137 SelfDeclTy = FPT->getParamType(0);
3138 if (!SelfDeclTy.
isNull())
3139 Elts.push_back(CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
3141 Elts.push_back(DBuilder.createArtificialType(
3142 getOrCreateType(CGM.getContext().getObjCSelType(), F)));
3144 for (
const auto *PI : OMethod->parameters())
3145 Elts.push_back(getOrCreateType(PI->getType(), F));
3147 if (OMethod->isVariadic())
3148 Elts.push_back(DBuilder.createUnspecifiedParameter());
3150 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
3151 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3157 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
3161 if (
const auto *FPT = dyn_cast<FunctionProtoType>(FnType))
3162 for (
QualType ParamType : FPT->param_types())
3163 EltTys.push_back(getOrCreateType(ParamType, F));
3164 EltTys.push_back(DBuilder.createUnspecifiedParameter());
3165 llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
3166 return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
3170 return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
3178 StringRef LinkageName;
3180 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3183 bool HasDecl = (D !=
nullptr);
3185 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3186 llvm::DIFile *Unit = getOrCreateFile(Loc);
3187 llvm::DIScope *FDContext = Unit;
3188 llvm::DINodeArray TParamsArray;
3191 LinkageName = Fn->getName();
3192 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3195 if (FI != SPCache.end()) {
3196 auto *SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3197 if (SP && SP->isDefinition()) {
3198 LexicalBlockStack.emplace_back(SP);
3199 RegionMap[D].reset(SP);
3203 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3204 TParamsArray, Flags);
3205 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3206 Name = getObjCMethodName(OMD);
3207 Flags |= llvm::DINode::FlagPrototyped;
3210 Name = Fn->getName();
3211 Flags |= llvm::DINode::FlagPrototyped;
3213 if (Name.startswith(
"\01"))
3214 Name = Name.substr(1);
3217 Flags |= llvm::DINode::FlagArtificial;
3221 unsigned LineNo = getLineNumber(Loc);
3222 unsigned ScopeLine = getLineNumber(ScopeLoc);
3229 llvm::DISubprogram *SP = DBuilder.createFunction(
3230 FDContext, Name, LinkageName, Unit, LineNo,
3231 getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(),
3232 true , ScopeLine, Flags, CGM.getLangOpts().Optimize,
3233 TParamsArray.get(), getFunctionDeclaration(D));
3234 Fn->setSubprogram(SP);
3238 if (HasDecl && isa<FunctionDecl>(D))
3242 LexicalBlockStack.emplace_back(SP);
3245 RegionMap[D].reset(SP);
3251 StringRef LinkageName;
3257 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3258 llvm::DIFile *Unit = getOrCreateFile(Loc);
3259 llvm::DIScope *FDContext = getDeclContextDescriptor(D);
3260 llvm::DINodeArray TParamsArray;
3261 if (isa<FunctionDecl>(D)) {
3263 collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
3264 TParamsArray, Flags);
3265 }
else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
3266 Name = getObjCMethodName(OMD);
3267 Flags |= llvm::DINode::FlagPrototyped;
3269 llvm_unreachable(
"not a function or ObjC method");
3271 if (!Name.empty() && Name[0] ==
'\01')
3272 Name = Name.substr(1);
3275 Flags |= llvm::DINode::FlagArtificial;
3280 unsigned LineNo = getLineNumber(Loc);
3281 unsigned ScopeLine = 0;
3283 DBuilder.retainType(DBuilder.createFunction(
3284 FDContext, Name, LinkageName, Unit, LineNo,
3285 getOrCreateFunctionType(D, FnType, Unit),
false ,
3286 false , ScopeLine, Flags, CGM.getLangOpts().Optimize,
3287 TParamsArray.get(), getFunctionDeclaration(D)));
3291 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
3294 llvm::DISubprogram *SP =
nullptr;
3295 if (FI != SPCache.end())
3296 SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
3297 if (!SP || !SP->isDefinition())
3298 SP = getFunctionStub(GD);
3299 FnBeginRegionCount.push_back(LexicalBlockStack.size());
3300 LexicalBlockStack.emplace_back(SP);
3301 setInlinedAt(Builder.getCurrentDebugLocation());
3306 assert(CurInlinedAt &&
"unbalanced inline scope stack");
3307 EmitFunctionEnd(Builder,
nullptr);
3308 setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
3315 if (CurLoc.isInvalid() || CurLoc.isMacroID())
3318 llvm::MDNode *
Scope = LexicalBlockStack.back();
3319 Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
3320 getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
3324 llvm::MDNode *Back =
nullptr;
3325 if (!LexicalBlockStack.empty())
3326 Back = LexicalBlockStack.back().get();
3327 LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
3328 cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
3329 getColumnNumber(CurLoc)));
3332 void CGDebugInfo::AppendAddressSpaceXDeref(
3333 unsigned AddressSpace,
3336 CGM.getTarget().getDWARFAddressSpace(AddressSpace);
3337 if (!DWARFAddressSpace)
3340 Expr.push_back(llvm::dwarf::DW_OP_constu);
3341 Expr.push_back(DWARFAddressSpace.getValue());
3342 Expr.push_back(llvm::dwarf::DW_OP_swap);
3343 Expr.push_back(llvm::dwarf::DW_OP_xderef);
3352 Builder.SetCurrentDebugLocation(
3353 llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc),
3354 LexicalBlockStack.back(), CurInlinedAt));
3360 CreateLexicalBlock(Loc);
3365 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3373 LexicalBlockStack.pop_back();
3377 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3378 unsigned RCount = FnBeginRegionCount.back();
3379 assert(RCount <= LexicalBlockStack.size() &&
"Region stack mismatch");
3382 while (LexicalBlockStack.size() != RCount) {
3385 LexicalBlockStack.pop_back();
3387 FnBeginRegionCount.pop_back();
3389 if (Fn && Fn->getSubprogram())
3390 DBuilder.finalizeSubprogram(Fn->getSubprogram());
3393 llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(
const VarDecl *VD,
3394 uint64_t *XOffset) {
3398 uint64_t FieldSize, FieldOffset;
3399 uint32_t FieldAlign;
3401 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3405 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3406 EltTys.push_back(CreateMemberType(Unit, FType,
"__isa", &FieldOffset));
3407 EltTys.push_back(CreateMemberType(Unit, FType,
"__forwarding", &FieldOffset));
3408 FType = CGM.getContext().IntTy;
3409 EltTys.push_back(CreateMemberType(Unit, FType,
"__flags", &FieldOffset));
3410 EltTys.push_back(CreateMemberType(Unit, FType,
"__size", &FieldOffset));
3412 bool HasCopyAndDispose = CGM.getContext().BlockRequiresCopying(Type, VD);
3413 if (HasCopyAndDispose) {
3414 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3416 CreateMemberType(Unit, FType,
"__copy_helper", &FieldOffset));
3418 CreateMemberType(Unit, FType,
"__destroy_helper", &FieldOffset));
3420 bool HasByrefExtendedLayout;
3422 if (CGM.getContext().getByrefLifetime(Type, Lifetime,
3423 HasByrefExtendedLayout) &&
3424 HasByrefExtendedLayout) {
3425 FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
3427 CreateMemberType(Unit, FType,
"__byref_variable_layout", &FieldOffset));
3430 CharUnits Align = CGM.getContext().getDeclAlign(VD);
3431 if (Align > CGM.getContext().toCharUnitsFromBits(
3432 CGM.getTarget().getPointerAlign(0))) {
3434 CGM.getContext().toCharUnitsFromBits(FieldOffset);
3436 CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes;
3439 llvm::APInt pad(32, NumPaddingBytes.
getQuantity());
3440 FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
3442 EltTys.push_back(CreateMemberType(Unit, FType,
"", &FieldOffset));
3447 llvm::DIType *FieldTy = getOrCreateType(FType, Unit);
3448 FieldSize = CGM.getContext().getTypeSize(FType);
3449 FieldAlign = CGM.getContext().toBits(Align);
3451 *XOffset = FieldOffset;
3452 FieldTy = DBuilder.createMemberType(Unit, VD->
getName(), Unit, 0, FieldSize,
3453 FieldAlign, FieldOffset,
3454 llvm::DINode::FlagZero, FieldTy);
3455 EltTys.push_back(FieldTy);
3456 FieldOffset += FieldSize;
3458 llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
3460 llvm::DINode::DIFlags Flags = llvm::DINode::FlagBlockByrefStruct;
3462 return DBuilder.createStructType(Unit,
"", Unit, 0, FieldOffset, 0, Flags,
3470 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3471 if (VD->
hasAttr<NoDebugAttr>())
3477 llvm::DIFile *Unit =
nullptr;
3481 uint64_t XOffset = 0;
3482 if (VD->
hasAttr<BlocksAttr>())
3483 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
3485 Ty = getOrCreateType(VD->
getType(), Unit);
3494 unsigned Column = 0;
3500 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
3502 Flags |= llvm::DINode::FlagArtificial;
3506 unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->
getType());
3507 AppendAddressSpaceXDeref(AddressSpace, Expr);
3511 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD)) {
3514 Flags |= llvm::DINode::FlagObjectPointer;
3521 auto *
Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
3522 StringRef Name = VD->
getName();
3523 if (!Name.empty()) {
3524 if (VD->
hasAttr<BlocksAttr>()) {
3527 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3529 offset = CGM.getContext().toCharUnitsFromBits(
3530 CGM.getTarget().getPointerWidth(0));
3532 Expr.push_back(llvm::dwarf::DW_OP_deref);
3533 Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3535 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3538 }
else if (
const auto *RT = dyn_cast<RecordType>(VD->
getType())) {
3541 const auto *RD = cast<RecordDecl>(RT->getDecl());
3550 for (
const auto *Field : RD->
fields()) {
3551 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
3552 StringRef FieldName = Field->getName();
3555 if (FieldName.empty() && !isa<RecordType>(Field->getType()))
3560 auto *D = DBuilder.createAutoVariable(
3561 Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
3562 Flags | llvm::DINode::FlagArtificial, FieldAlign);
3565 DBuilder.insertDeclare(
3566 Storage, D, DBuilder.createExpression(Expr),
3567 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3568 Builder.GetInsertBlock());
3575 ? DBuilder.createParameterVariable(
3576 Scope, Name, *ArgNo, Unit, Line, Ty,
3577 CGM.getLangOpts().Optimize, Flags)
3578 : DBuilder.createAutoVariable(
Scope, Name, Unit, Line, Ty,
3579 CGM.getLangOpts().Optimize, Flags,
3583 DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
3584 llvm::DebugLoc::get(Line, Column,
Scope, CurInlinedAt),
3585 Builder.GetInsertBlock());
3592 EmitDeclare(VD, Storage,
llvm::None, Builder);
3595 llvm::DIType *CGDebugInfo::CreateSelfType(
const QualType &QualTy,
3597 llvm::DIType *CachedTy = getTypeOrNull(QualTy);
3600 return DBuilder.createObjectPointerType(Ty);
3605 const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) {
3607 assert(!LexicalBlockStack.empty() &&
"Region stack mismatch, stack empty!");
3609 if (Builder.GetInsertBlock() ==
nullptr)
3611 if (VD->
hasAttr<NoDebugAttr>())
3614 bool isByRef = VD->
hasAttr<BlocksAttr>();
3616 uint64_t XOffset = 0;
3617 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3620 Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
3622 Ty = getOrCreateType(VD->
getType(), Unit);
3626 if (
const auto *IPD = dyn_cast<ImplicitParamDecl>(VD))
3628 Ty = CreateSelfType(VD->
getType(), Ty);
3632 unsigned Column = getColumnNumber(VD->
getLocation());
3634 const llvm::DataLayout &target = CGM.getDataLayout();
3641 addr.push_back(llvm::dwarf::DW_OP_deref);
3642 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3645 addr.push_back(llvm::dwarf::DW_OP_deref);
3646 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3649 CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
3651 addr.push_back(llvm::dwarf::DW_OP_deref);
3652 addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
3654 offset = CGM.getContext().toCharUnitsFromBits(XOffset);
3660 auto *D = DBuilder.createAutoVariable(
3661 cast<llvm::DILocalScope>(LexicalBlockStack.back()), VD->
getName(), Unit,
3662 Line, Ty,
false, llvm::DINode::FlagZero, Align);
3666 llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
3667 auto *Expr = DBuilder.createExpression(addr);
3669 DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
3671 DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
3678 EmitDeclare(VD, AI, ArgNo, Builder);
3682 struct BlockLayoutChunk {
3683 uint64_t OffsetInBits;
3686 bool operator<(
const BlockLayoutChunk &l,
const BlockLayoutChunk &r) {
3687 return l.OffsetInBits < r.OffsetInBits;
3694 llvm::AllocaInst *Alloca,
3702 llvm::DIFile *tunit = getOrCreateFile(loc);
3703 unsigned line = getLineNumber(loc);
3704 unsigned column = getColumnNumber(loc);
3707 getDeclContextDescriptor(blockDecl);
3709 const llvm::StructLayout *blockLayout =
3714 blockLayout->getElementOffsetInBits(0),
3716 fields.push_back(createFieldType(
"__flags", C.
IntTy, loc,
AS_public,
3717 blockLayout->getElementOffsetInBits(1),
3719 fields.push_back(createFieldType(
"__reserved", C.
IntTy, loc,
AS_public,
3720 blockLayout->getElementOffsetInBits(2),
3723 auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
3724 fields.push_back(createFieldType(
"__FuncPtr", FnPtrType, loc,
AS_public,
3725 blockLayout->getElementOffsetInBits(3),
3727 fields.push_back(createFieldType(
3731 loc,
AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit));
3739 BlockLayoutChunk chunk;
3740 chunk.OffsetInBits =
3741 blockLayout->getElementOffsetInBits(block.
CXXThisIndex);
3742 chunk.Capture =
nullptr;
3743 chunks.push_back(chunk);
3747 for (
const auto &capture : blockDecl->
captures()) {
3748 const VarDecl *variable = capture.getVariable();
3755 BlockLayoutChunk chunk;
3756 chunk.OffsetInBits =
3757 blockLayout->getElementOffsetInBits(captureInfo.
getIndex());
3758 chunk.Capture = &capture;
3759 chunks.push_back(chunk);
3763 llvm::array_pod_sort(chunks.begin(), chunks.end());
3765 for (
const BlockLayoutChunk &Chunk : chunks) {
3766 uint64_t offsetInBits = Chunk.OffsetInBits;
3775 else if (
auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->
getParent()))
3776 type =
QualType(RDecl->getTypeForDecl(), 0);
3778 llvm_unreachable(
"unexpected block declcontext");
3780 fields.push_back(createFieldType(
"this", type, loc,
AS_public,
3781 offsetInBits, tunit, tunit));
3786 StringRef name = variable->
getName();
3788 llvm::DIType *fieldType;
3795 fieldType = EmitTypeForVarWithBlocksAttr(variable, &xoffset);
3796 fieldType = DBuilder.createPointerType(fieldType, PtrInfo.
Width);
3797 fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
3798 PtrInfo.
Width, Align, offsetInBits,
3799 llvm::DINode::FlagZero, fieldType);
3803 offsetInBits, Align, tunit, tunit);
3805 fields.push_back(fieldType);
3809 llvm::raw_svector_ostream(typeName) <<
"__block_literal_" 3810 << CGM.getUniqueBlockCount();
3812 llvm::DINodeArray fieldsArray = DBuilder.getOrCreateArray(fields);
3814 llvm::DIType *type =
3815 DBuilder.createStructType(tunit, typeName.str(), tunit, line,
3816 CGM.getContext().toBits(block.
BlockSize), 0,
3817 llvm::DINode::FlagZero,
nullptr, fieldsArray);
3818 type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
3821 llvm::DINode::DIFlags flags = llvm::DINode::FlagArtificial;
3822 auto *scope = cast<llvm::DILocalScope>(LexicalBlockStack.back());
3825 auto *debugVar = DBuilder.createParameterVariable(
3826 scope, Name, ArgNo, tunit, line, type,
3827 CGM.getLangOpts().Optimize, flags);
3830 DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
3831 llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
3832 Builder.GetInsertBlock());
3835 llvm::DIDerivedType *
3836 CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(
const VarDecl *D) {
3841 if (MI != StaticDataMemberCache.end()) {
3842 assert(MI->second &&
"Static data member declaration should still exist");
3849 auto *Ctxt = cast<llvm::DICompositeType>(getDeclContextDescriptor(D));
3850 return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
3853 llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
3854 const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo,
3855 StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
3856 llvm::DIGlobalVariableExpression *GVE =
nullptr;
3858 for (
const auto *Field : RD->
fields()) {
3859 llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
3860 StringRef FieldName = Field->getName();
3863 if (FieldName.empty()) {
3864 if (
const auto *RT = dyn_cast<RecordType>(Field->getType()))
3865 GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
3870 GVE = DBuilder.createGlobalVariableExpression(
3871 DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
3872 Var->hasLocalLinkage());
3873 Var->addDebugInfo(GVE);
3881 if (D->
hasAttr<NoDebugAttr>())
3887 if (Cached != DeclCache.end())
3888 return Var->addDebugInfo(
3889 cast<llvm::DIGlobalVariableExpression>(Cached->second));
3892 llvm::DIFile *Unit =
nullptr;
3893 llvm::DIScope *DContext =
nullptr;
3895 StringRef DeclName, LinkageName;
3897 collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName, DContext);
3901 llvm::DIGlobalVariableExpression *GVE =
nullptr;
3909 "unnamed non-anonymous struct or union?");
3910 GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
3915 unsigned AddressSpace =
3916 CGM.getContext().getTargetAddressSpace(D->
getType());
3917 AppendAddressSpaceXDeref(AddressSpace, Expr);
3919 GVE = DBuilder.createGlobalVariableExpression(
3920 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
3921 Var->hasLocalLinkage(),
3922 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
3923 getOrCreateStaticDataMemberDeclarationOrNull(D), Align);
3924 Var->addDebugInfo(GVE);
3931 if (VD->
hasAttr<NoDebugAttr>())
3935 llvm::DIFile *Unit = getOrCreateFile(VD->
getLocation());
3936 StringRef Name = VD->
getName();
3937 llvm::DIType *Ty = getOrCreateType(VD->
getType(), Unit);
3938 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
3939 const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
3940 assert(isa<EnumType>(ED->getTypeForDecl()) &&
"Enum without EnumType?");
3941 Ty = getOrCreateType(
QualType(ED->getTypeForDecl(), 0), Unit);
3946 if (Ty->getTag() == llvm::dwarf::DW_TAG_enumeration_type)
3952 auto *VarD = cast<VarDecl>(VD);
3953 if (VarD->isStaticDataMember()) {
3954 auto *RD = cast<RecordDecl>(VarD->getDeclContext());
3955 getDeclContextDescriptor(VarD);
3960 RetainedTypes.push_back(
3961 CGM.getContext().getRecordType(RD).getAsOpaquePtr());
3965 llvm::DIScope *DContext = getDeclContextDescriptor(VD);
3967 auto &GV = DeclCache[VD];
3970 llvm::DIExpression *InitExpr =
nullptr;
3971 if (CGM.getContext().getTypeSize(VD->
getType()) <= 64) {
3975 DBuilder.createConstantValueExpression(Init.
getInt().getExtValue());
3977 InitExpr = DBuilder.createConstantValueExpression(
3978 Init.
getFloat().bitcastToAPInt().getZExtValue());
3980 GV.reset(DBuilder.createGlobalVariableExpression(
3981 DContext, Name, StringRef(), Unit, getLineNumber(VD->
getLocation()), Ty,
3982 true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
3986 llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(
const Decl *D) {
3987 if (!LexicalBlockStack.empty())
3988 return LexicalBlockStack.back();
3989 llvm::DIScope *Mod = getParentModuleOrNull(D);
3990 return getContextDescriptor(D, Mod ? Mod : TheCU);
3998 CGM.getCodeGenOpts().DebugExplicitImport) {
4000 DBuilder.createImportedModule(
4002 getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
4010 "We shouldn't be codegening an invalid UsingDecl containing no decls");
4019 if (
const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl()))
4020 if (
const auto *AT =
4022 if (AT->getDeducedType().isNull())
4024 if (llvm::DINode *Target =
4025 getDeclarationOrDefinition(USD.getUnderlyingDecl())) {
4026 auto Loc = USD.getLocation();
4027 DBuilder.createImportedDeclaration(
4028 getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target,
4029 getOrCreateFile(Loc), getLineNumber(Loc));
4034 if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB)
4039 DBuilder.createImportedDeclaration(
4041 getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
4042 getLineNumber(Loc));
4046 llvm::DIImportedEntity *
4050 auto &VH = NamespaceAliasCache[&NA];
4052 return cast<llvm::DIImportedEntity>(VH);
4053 llvm::DIImportedEntity *R;
4055 if (
const auto *Underlying =
4058 R = DBuilder.createImportedDeclaration(
4060 EmitNamespaceAlias(*Underlying), getOrCreateFile(Loc),
4061 getLineNumber(Loc), NA.
getName());
4063 R = DBuilder.createImportedDeclaration(
4066 getOrCreateFile(Loc), getLineNumber(Loc), NA.
getName());
4072 CGDebugInfo::getOrCreateNamespace(
const NamespaceDecl *NSDecl) {
4076 auto I = NamespaceCache.find(NSDecl);
4077 if (I != NamespaceCache.end())
4078 return cast<llvm::DINamespace>(I->second);
4080 llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
4082 llvm::DINamespace *NS =
4083 DBuilder.createNameSpace(Context, NSDecl->
getName(), NSDecl->
isInline());
4084 NamespaceCache[NSDecl].reset(NS);
4089 assert(TheCU &&
"no main compile unit");
4090 TheCU->setDWOId(Signature);
4097 for (
size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
4098 ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
4099 llvm::DIType *Ty = E.
Type->getDecl()->getDefinition()
4100 ? CreateTypeDefinition(E.Type, E.Unit)
4102 DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
4105 for (
auto p : ReplaceMap) {
4107 auto *Ty = cast<llvm::DIType>(p.second);
4108 assert(Ty->isForwardDecl());
4110 auto it = TypeCache.find(p.first);
4111 assert(it != TypeCache.end());
4114 DBuilder.replaceTemporary(llvm::TempDIType(Ty),
4115 cast<llvm::DIType>(it->second));
4118 for (
const auto &p : FwdDeclReplaceMap) {
4120 llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(p.second));
4121 llvm::Metadata *Repl;
4123 auto it = DeclCache.find(p.first);
4127 if (it == DeclCache.end())
4132 if (
auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
4133 Repl = GVE->getVariable();
4134 DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
4139 for (
auto &RT : RetainedTypes)
4140 if (
auto MD = TypeCache[RT])
4141 DBuilder.retainType(cast<llvm::DIType>(MD));
4143 DBuilder.finalize();
4150 if (
auto *DieTy = getOrCreateType(Ty, getOrCreateMainFile()))
4152 DBuilder.retainType(DieTy);
4156 if (LexicalBlockStack.empty())
4157 return llvm::DebugLoc();
4159 llvm::MDNode *
Scope = LexicalBlockStack.back();
4160 return llvm::DebugLoc::get(
4161 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 ...
VarDecl * getCapturedVar() const
Retrieve the declaration of the local variable being captured.
const Capture & getCapture(const VarDecl *var) const
An instance of this class is created to represent 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
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
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.
NamespaceDecl - 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.
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
isCompleteDefinition - Return true if this decl has its body fully specified.
enumerator_range enumerators() const
VarDecl - An instance of this class is created to represent 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.
void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder)
Emit call to llvm.dbg.declare for an automatic variable declaration.
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
static const NamedDecl * getDefinition(const Decl *D)
ParmVarDecl - 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
getIdentifier - Get the identifier that names this declaration, if there is one.
void EmitInlineFunctionEnd(CGBuilderTy &Builder)
End an inlined function scope.
RecordDecl - Represents a struct/union/class.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
DeclarationName getDeclName() const
getDeclName - 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
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
void EmitImportDecl(const ImportDecl &ID)
Emit an declaration.
field_range fields() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
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.
TypeDecl - 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
isAnonymousStructOrUnion - 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 needs a custom copy or dispose function.
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
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...
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
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 FunctionProtoType * T
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that that 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.
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
printQualifiedName - Returns human-readable qualified name for declaration, like A::B::i, for i being member of namespace A::B.
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.
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
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
Limit generated debug info to reduce size (-fno-standalone-debug).
TagDecl - 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...
ArrayRef< Capture > captures() const
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)
EnumDecl - Represents an enum.
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.
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.
void EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, SourceLocation ScopeLoc, QualType FnType, llvm::Function *Fn, CGBuilderTy &Builder)
Emit a call to llvm.dbg.function.start to indicate start of a new function.
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
getIntegerType - Return the integer type this enum decl corresponds to.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
uint64_t Index
Method's index in the vftable.
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.
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...
static SmallString< 256 > getUniqueTagTypeName(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU)
In C++ mode, types have linkage, so we can rely on the ODR and on their mangled names, if they're external.
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