diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp | 776 |
1 files changed, 405 insertions, 371 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp index b7b9d8c..048c8f8 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -52,30 +52,35 @@ CGDebugInfo::~CGDebugInfo() { "Region stack mismatch, stack not empty!"); } - -NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B) - : DI(CGF.getDebugInfo()), Builder(B) { +SaveAndRestoreLocation::SaveAndRestoreLocation(CodeGenFunction &CGF, + CGBuilderTy &B) + : DI(CGF.getDebugInfo()), Builder(B) { if (DI) { SavedLoc = DI->getLocation(); DI->CurLoc = SourceLocation(); - Builder.SetCurrentDebugLocation(llvm::DebugLoc()); } } +SaveAndRestoreLocation::~SaveAndRestoreLocation() { + if (DI) + DI->EmitLocation(Builder, SavedLoc); +} + +NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B) + : SaveAndRestoreLocation(CGF, B) { + if (DI) + Builder.SetCurrentDebugLocation(llvm::DebugLoc()); +} + NoLocation::~NoLocation() { - if (DI) { + if (DI) assert(Builder.getCurrentDebugLocation().isUnknown()); - DI->CurLoc = SavedLoc; - } } ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B) - : DI(CGF.getDebugInfo()), Builder(B) { - if (DI) { - SavedLoc = DI->getLocation(); - DI->CurLoc = SourceLocation(); + : SaveAndRestoreLocation(CGF, B) { + if (DI) Builder.SetCurrentDebugLocation(llvm::DebugLoc()); - } } void ArtificialLocation::Emit() { @@ -91,10 +96,8 @@ void ArtificialLocation::Emit() { } ArtificialLocation::~ArtificialLocation() { - if (DI) { + if (DI) assert(Builder.getCurrentDebugLocation().getLine() == 0); - DI->CurLoc = SavedLoc; - } } void CGDebugInfo::setLocation(SourceLocation Loc) { @@ -109,17 +112,14 @@ void CGDebugInfo::setLocation(SourceLocation Loc) { if (LexicalBlockStack.empty()) return; SourceManager &SM = CGM.getContext().getSourceManager(); + llvm::DIScope Scope(LexicalBlockStack.back()); PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc); - PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc); - if (PCLoc.isInvalid() || PPLoc.isInvalid() || - !strcmp(PPLoc.getFilename(), PCLoc.getFilename())) + if (PCLoc.isInvalid() || Scope.getFilename() == PCLoc.getFilename()) return; - llvm::MDNode *LB = LexicalBlockStack.back(); - llvm::DIScope Scope = llvm::DIScope(LB); if (Scope.isLexicalBlockFile()) { - llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB); + llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(Scope); llvm::DIDescriptor D = DBuilder.createLexicalBlockFile(LBF.getScope(), getOrCreateFile(CurLoc)); @@ -225,34 +225,20 @@ StringRef CGDebugInfo::getSelectorName(Selector S) { /// getClassName - Get class name including template argument list. StringRef CGDebugInfo::getClassName(const RecordDecl *RD) { - const ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(RD); - if (!Spec) + // quick optimization to avoid having to intern strings that are already + // stored reliably elsewhere + if (!isa<ClassTemplateSpecializationDecl>(RD)) return RD->getName(); - const TemplateArgument *Args; - unsigned NumArgs; - if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { - const TemplateSpecializationType *TST = - cast<TemplateSpecializationType>(TAW->getType()); - Args = TST->getArgs(); - NumArgs = TST->getNumArgs(); - } else { - const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Args = TemplateArgs.data(); - NumArgs = TemplateArgs.size(); - } - StringRef Name = RD->getIdentifier()->getName(); - PrintingPolicy Policy(CGM.getLangOpts()); - SmallString<128> TemplateArgList; + SmallString<128> Name; { - llvm::raw_svector_ostream OS(TemplateArgList); - TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs, - Policy); + llvm::raw_svector_ostream OS(Name); + RD->getNameForDiagnostic(OS, CGM.getContext().getPrintingPolicy(), + /*Qualified*/ false); } // Copy this name on the side and use its reference. - return internString(Name, TemplateArgList); + return internString(Name); } /// getOrCreateFile - Get the file debug info descriptor for the input location. @@ -328,11 +314,18 @@ StringRef CGDebugInfo::getCurrentDirname() { /// CreateCompileUnit - Create new compile unit. void CGDebugInfo::CreateCompileUnit() { + // Should we be asking the SourceManager for the main file name, instead of + // accepting it as an argument? This just causes the main file name to + // mismatch with source locations and create extra lexical scopes or + // mismatched debug info (a CU with a DW_AT_file of "-", because that's what + // the driver passed, but functions/other things have DW_AT_file of "<stdin>" + // because that's what the SourceManager says) + // Get absolute path name. SourceManager &SM = CGM.getContext().getSourceManager(); std::string MainFileName = CGM.getCodeGenOpts().MainFileName; if (MainFileName.empty()) - MainFileName = "<unknown>"; + MainFileName = "<stdin>"; // The main file name provided via the "-main-file-name" option contains just // the file name itself with no path information. This file name may have had @@ -355,7 +348,7 @@ void CGDebugInfo::CreateCompileUnit() { std::string SplitDwarfFile = CGM.getCodeGenOpts().SplitDwarfFile; StringRef SplitDwarfFilename = internString(SplitDwarfFile); - unsigned LangTag; + llvm::dwarf::SourceLanguage LangTag; const LangOptions &LO = CGM.getLangOpts(); if (LO.CPlusPlus) { if (LO.ObjC1) @@ -379,16 +372,19 @@ void CGDebugInfo::CreateCompileUnit() { // Create new compile unit. // FIXME - Eliminate TheCU. - TheCU = DBuilder.createCompileUnit(LangTag, Filename, getCurrentDirname(), - Producer, LO.Optimize, - CGM.getCodeGenOpts().DwarfDebugFlags, - RuntimeVers, SplitDwarfFilename); + TheCU = DBuilder.createCompileUnit( + LangTag, Filename, getCurrentDirname(), Producer, LO.Optimize, + CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, SplitDwarfFilename, + DebugKind <= CodeGenOptions::DebugLineTablesOnly + ? llvm::DIBuilder::LineTablesOnly + : llvm::DIBuilder::FullDebug, + DebugKind != CodeGenOptions::LocTrackingOnly); } /// CreateType - Get the Basic type from the cache or create a new /// one if necessary. llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { - unsigned Encoding = 0; + llvm::dwarf::TypeKind Encoding; StringRef BTName; switch (BT->getKind()) { #define BUILTIN_TYPE(Id, SingletonId) @@ -402,11 +398,10 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::Void: return llvm::DIType(); case BuiltinType::ObjCClass: - if (ClassTy) - return ClassTy; - ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - "objc_class", TheCU, - getOrCreateMainFile(), 0); + if (!ClassTy) + ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, + "objc_class", TheCU, + getOrCreateMainFile(), 0); return ClassTy; case BuiltinType::ObjCId: { // typedef struct objc_class *Class; @@ -435,12 +430,10 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { return ObjTy; } case BuiltinType::ObjCSel: { - if (SelTy) - return SelTy; - SelTy = - DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - "objc_selector", TheCU, getOrCreateMainFile(), - 0); + if (!SelTy) + SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, + "objc_selector", TheCU, + getOrCreateMainFile(), 0); return SelTy; } @@ -515,7 +508,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) { // Bit size, align and offset of the type. - unsigned Encoding = llvm::dwarf::DW_ATE_complex_float; + llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float; if (Ty->isComplexIntegerType()) Encoding = llvm::dwarf::DW_ATE_lo_user; @@ -540,7 +533,7 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) { // We will create one Derived type for one qualifier and recurse to handle any // additional ones. - unsigned Tag; + llvm::dwarf::Tag Tag; if (Qc.hasConst()) { Tag = llvm::dwarf::DW_TAG_const_type; Qc.removeConst(); @@ -620,7 +613,7 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - unsigned Tag = 0; + llvm::dwarf::Tag Tag; if (RD->isStruct() || RD->isInterface()) Tag = llvm::dwarf::DW_TAG_structure_type; else if (RD->isUnion()) @@ -632,11 +625,13 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, // Create the type. SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); - return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, - FullName); + llvm::DICompositeType RetTy = DBuilder.createReplaceableForwardDecl( + Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, FullName); + ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy))); + return RetTy; } -llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, +llvm::DIType CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty, QualType PointeeTy, llvm::DIFile Unit) { @@ -728,22 +723,47 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, return BlockLiteralGeneric; } +llvm::DIType CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Unit) { + assert(Ty->isTypeAlias()); + llvm::DIType Src = getOrCreateType(Ty->getAliasedType(), Unit); + + SmallString<128> NS; + llvm::raw_svector_ostream OS(NS); + Ty->getTemplateName().print(OS, CGM.getContext().getPrintingPolicy(), /*qualified*/ false); + + TemplateSpecializationType::PrintTemplateArgumentList( + OS, Ty->getArgs(), Ty->getNumArgs(), + CGM.getContext().getPrintingPolicy()); + + TypeAliasDecl *AliasDecl = + cast<TypeAliasTemplateDecl>(Ty->getTemplateName().getAsTemplateDecl()) + ->getTemplatedDecl(); + + SourceLocation Loc = AliasDecl->getLocation(); + llvm::DIFile File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); + + llvm::DIDescriptor Ctxt = getContextDescriptor(cast<Decl>(AliasDecl->getDeclContext())); + + return DBuilder.createTypedef(Src, internString(OS.str()), File, Line, Ctxt); +} + llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) { // Typedefs are derived from some other type. If we have a typedef of a // typedef, make sure to emit the whole chain. llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); - if (!Src) - return llvm::DIType(); // We don't set size information, but do specify where the typedef was // declared. - unsigned Line = getLineNumber(Ty->getDecl()->getLocation()); + SourceLocation Loc = Ty->getDecl()->getLocation(); + llvm::DIFile File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); const TypedefNameDecl *TyDecl = Ty->getDecl(); llvm::DIDescriptor TypedefContext = getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext())); return - DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext); + DBuilder.createTypedef(Src, TyDecl->getName(), File, Line, TypedefContext); } llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, @@ -751,15 +771,15 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, SmallVector<llvm::Value *, 16> EltTys; // Add the result type at least. - EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit)); + EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit)); // Set up remainder of arguments if there is a prototype. - // FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'! + // otherwise emit it as a variadic function. if (isa<FunctionNoProtoType>(Ty)) EltTys.push_back(DBuilder.createUnspecifiedParameter()); else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) { - for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) - EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit)); + for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i) + EltTys.push_back(getOrCreateType(FPT->getParamType(i), Unit)); if (FPT->isVariadic()) EltTys.push_back(DBuilder.createUnspecifiedParameter()); } @@ -786,7 +806,7 @@ llvm::DIType CGDebugInfo::createFieldType(StringRef name, uint64_t sizeInBits = 0; unsigned alignInBits = 0; if (!type->isIncompleteArrayType()) { - llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type); + std::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type); if (sizeInBitsOverride) sizeInBits = sizeInBitsOverride; @@ -815,7 +835,7 @@ CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl, unsigned fieldno = 0; for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(), E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) { - const LambdaExpr::Capture C = *I; + const LambdaCapture &C = *I; if (C.capturesVariable()) { VarDecl *V = C.getCapturedVar(); llvm::DIFile VUnit = getOrCreateFile(C.getLocation()); @@ -859,7 +879,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, unsigned LineNumber = getLineNumber(Var->getLocation()); StringRef VName = Var->getName(); - llvm::Constant *C = NULL; + llvm::Constant *C = nullptr; if (Var->getInit()) { const APValue *Value = Var->evaluateValue(); if (Value) { @@ -928,9 +948,8 @@ void CGDebugInfo::CollectRecordFields(const RecordDecl *record, // Static and non-static members should appear in the same order as // the corresponding declarations in the source program. - for (RecordDecl::decl_iterator I = record->decls_begin(), - E = record->decls_end(); I != E; ++I) - if (const VarDecl *V = dyn_cast<VarDecl>(*I)) { + for (const auto *I : record->decls()) + if (const auto *V = dyn_cast<VarDecl>(I)) { // Reuse the existing static member declaration if one exists llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI = StaticDataMemberCache.find(V->getCanonicalDecl()); @@ -941,7 +960,7 @@ void CGDebugInfo::CollectRecordFields(const RecordDecl *record, llvm::DIDerivedType(cast<llvm::MDNode>(MI->second))); } else elements.push_back(CreateRecordStaticField(V, RecordTy)); - } else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) { + } else if (const auto *field = dyn_cast<FieldDecl>(I)) { CollectRecordNormalField(field, layout.getFieldOffset(fieldNo), tunit, elements, RecordTy); @@ -1007,7 +1026,13 @@ llvm::DICompositeType CGDebugInfo::getOrCreateInstanceMethodType( llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts); - return DBuilder.createSubroutineType(Unit, EltTypeArray); + unsigned Flags = 0; + if (Func->getExtProtoInfo().RefQualifier == RQ_LValue) + Flags |= llvm::DIDescriptor::FlagLValueReference; + if (Func->getExtProtoInfo().RefQualifier == RQ_RValue) + Flags |= llvm::DIDescriptor::FlagRValueReference; + + return DBuilder.createSubroutineType(Unit, EltTypeArray, Flags); } /// isFunctionLocalClass - Return true if CXXRecordDecl is defined @@ -1086,6 +1111,10 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, } if (Method->hasPrototype()) Flags |= llvm::DIDescriptor::FlagPrototyped; + if (Method->getRefQualifier() == RQ_LValue) + Flags |= llvm::DIDescriptor::FlagLValueReference; + if (Method->getRefQualifier() == RQ_RValue) + Flags |= llvm::DIDescriptor::FlagRValueReference; llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit); llvm::DISubprogram SP = @@ -1094,7 +1123,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, MethodTy, /*isLocalToUnit=*/false, /* isDefinition=*/ false, Virtuality, VIndex, ContainingType, - Flags, CGM.getLangOpts().Optimize, NULL, + Flags, CGM.getLangOpts().Optimize, nullptr, TParamsArray); SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP); @@ -1113,9 +1142,8 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, // Since we want more than just the individual member decls if we // have templated functions iterate over every declaration to gather // the functions. - for(DeclContext::decl_iterator I = RD->decls_begin(), - E = RD->decls_end(); I != E; ++I) { - if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) { + for(const auto *I : RD->decls()) { + if (const auto *Method = dyn_cast<CXXMethodDecl>(I)) { // Reuse the existing member function declaration if it exists. // It may be associated with the declaration of the type & should be // reused as we're building the definition. @@ -1132,16 +1160,13 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); } else EltTys.push_back(MI->second); - } else if (const FunctionTemplateDecl *FTD = - dyn_cast<FunctionTemplateDecl>(*I)) { + } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(I)) { // Add any template specializations that have already been seen. Like // implicit member functions, these may have been added to a declaration // in the case of vtable-based debug info reduction. - for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(), - SE = FTD->spec_end(); - SI != SE; ++SI) { + for (const auto *SI : FTD->specializations()) { llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI = - SPCache.find(cast<CXXMethodDecl>(*SI)->getCanonicalDecl()); + SPCache.find(cast<CXXMethodDecl>(SI)->getCanonicalDecl()); if (MI != SPCache.end()) EltTys.push_back(MI->second); } @@ -1158,15 +1183,14 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, llvm::DIType RecordTy) { const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); - for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(), - BE = RD->bases_end(); BI != BE; ++BI) { + for (const auto &BI : RD->bases()) { unsigned BFlags = 0; uint64_t BaseOffset; const CXXRecordDecl *Base = - cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl()); + cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl()); - if (BI->isVirtual()) { + if (BI.isVirtual()) { // virtual base offset offset is -ve. The code generator emits dwarf // expression where it expects +ve number. BaseOffset = @@ -1178,7 +1202,7 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, // FIXME: Inconsistent units for BaseOffset. It is in bytes when // BI->isVirtual() and bits when not. - AccessSpecifier Access = BI->getAccessSpecifier(); + AccessSpecifier Access = BI.getAccessSpecifier(); if (Access == clang::AS_private) BFlags |= llvm::DIDescriptor::FlagPrivate; else if (Access == clang::AS_protected) @@ -1186,7 +1210,7 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, llvm::DIType DTy = DBuilder.createInheritance(RecordTy, - getOrCreateType(BI->getType(), Unit), + getOrCreateType(BI.getType(), Unit), BaseOffset, BFlags); EltTys.push_back(DTy); } @@ -1227,7 +1251,7 @@ CollectTemplateParams(const TemplateParameterList *TPList, ->getTypeForDecl()) : CGM.getContext().getPointerType(D->getType()); llvm::DIType TTy = getOrCreateType(T, Unit); - llvm::Value *V = 0; + llvm::Value *V = nullptr; // Variable pointer template parameters have a value that is the address // of the variable. if (const VarDecl *VD = dyn_cast<VarDecl>(D)) @@ -1259,7 +1283,7 @@ CollectTemplateParams(const TemplateParameterList *TPList, case TemplateArgument::NullPtr: { QualType T = TA.getNullPtrType(); llvm::DIType TTy = getOrCreateType(T, Unit); - llvm::Value *V = 0; + llvm::Value *V = nullptr; // Special case member data pointer null values since they're actually -1 // instead of zero. if (const MemberPointerType *MPT = @@ -1289,7 +1313,7 @@ CollectTemplateParams(const TemplateParameterList *TPList, llvm::DITemplateValueParameter TVP = DBuilder.createTemplateParameterPack( TheCU, Name, llvm::DIType(), - CollectTemplateParams(NULL, TA.getPackAsArray(), Unit)); + CollectTemplateParams(nullptr, TA.getPackAsArray(), Unit)); TemplateParams.push_back(TVP); } break; case TemplateArgument::Expression: { @@ -1333,14 +1357,11 @@ CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit) { llvm::DIArray CGDebugInfo:: CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile Unit) { - llvm::PointerUnion<ClassTemplateDecl *, - ClassTemplatePartialSpecializationDecl *> - PU = TSpecial->getSpecializedTemplateOrPartial(); - - TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ? - PU.get<ClassTemplateDecl *>()->getTemplateParameters() : - PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters(); - const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs(); + // Always get the full list of parameters, not just the ones from + // the specialization. + TemplateParameterList *TPList = + TSpecial->getSpecializedTemplate()->getTemplateParameters(); + const TemplateArgumentList &TAList = TSpecial->getTemplateArgs(); return CollectTemplateParams(TPList, TAList.asArray(), Unit); } @@ -1411,6 +1432,21 @@ llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D, return T; } +void CGDebugInfo::completeType(const EnumDecl *ED) { + if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + return; + QualType Ty = CGM.getContext().getEnumType(ED); + void* TyPtr = Ty.getAsOpaquePtr(); + auto I = TypeCache.find(TyPtr); + if (I == TypeCache.end() || + !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second))) + .isForwardDecl()) + return; + llvm::DIType Res = CreateTypeDefinition(Ty->castAs<EnumType>()); + assert(!Res.isForwardDecl()); + TypeCache[TyPtr] = Res; +} + void CGDebugInfo::completeType(const RecordDecl *RD) { if (DebugKind > CodeGenOptions::LimitedDebugInfo || !CGM.getLangOpts().CPlusPlus) @@ -1418,6 +1454,9 @@ void CGDebugInfo::completeType(const RecordDecl *RD) { } void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { + if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + return; + if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) if (CXXDecl->isDynamicClass()) return; @@ -1433,40 +1472,67 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) { return; QualType Ty = CGM.getContext().getRecordType(RD); void* TyPtr = Ty.getAsOpaquePtr(); - if (CompletedTypeCache.count(TyPtr)) + auto I = TypeCache.find(TyPtr); + if (I != TypeCache.end() && + !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second))) + .isForwardDecl()) return; llvm::DIType Res = CreateTypeDefinition(Ty->castAs<RecordType>()); assert(!Res.isForwardDecl()); - CompletedTypeCache[TyPtr] = Res; TypeCache[TyPtr] = Res; } +static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, + CXXRecordDecl::method_iterator End) { + for (; I != End; ++I) + if (FunctionDecl *Tmpl = I->getInstantiatedFromMemberFunction()) + if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() && + !I->getMemberSpecializationInfo()->isExplicitSpecialization()) + return true; + return false; +} + +static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind, + const RecordDecl *RD, + const LangOptions &LangOpts) { + if (DebugKind > CodeGenOptions::LimitedDebugInfo) + return false; + + if (!LangOpts.CPlusPlus) + return false; + + if (!RD->isCompleteDefinitionRequired()) + return true; + + const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); + + if (!CXXDecl) + return false; + + if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass()) + return true; + + TemplateSpecializationKind Spec = TSK_Undeclared; + if (const ClassTemplateSpecializationDecl *SD = + dyn_cast<ClassTemplateSpecializationDecl>(RD)) + Spec = SD->getSpecializationKind(); + + if (Spec == TSK_ExplicitInstantiationDeclaration && + hasExplicitMemberDefinition(CXXDecl->method_begin(), + CXXDecl->method_end())) + return true; + + return false; +} + /// CreateType - get structure or union type. llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { RecordDecl *RD = Ty->getDecl(); - const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); - // Always emit declarations for types that aren't required to be complete when - // in limit-debug-info mode. If the type is later found to be required to be - // complete this declaration will be upgraded to a definition by - // `completeRequiredType`. - // If the type is dynamic, only emit the definition in TUs that require class - // data. This is handled by `completeClassData`. llvm::DICompositeType T(getTypeOrNull(QualType(Ty, 0))); - // If we've already emitted the type, just use that, even if it's only a - // declaration. The completeType, completeRequiredType, and completeClassData - // callbacks will handle promoting the declaration to a definition. - if (T || - // Under -flimit-debug-info: - (DebugKind <= CodeGenOptions::LimitedDebugInfo && - // Emit only a forward declaration unless the type is required. - ((!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || - // If the class is dynamic, only emit a declaration. A definition will be - // emitted whenever the vtable is emitted. - (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())))) { - llvm::DIDescriptor FDContext = - getContextDescriptor(cast<Decl>(RD->getDeclContext())); + if (T || shouldOmitDefinition(DebugKind, RD, CGM.getLangOpts())) { if (!T) - T = getOrCreateRecordFwdDecl(Ty, FDContext); + T = getOrCreateRecordFwdDecl( + Ty, getContextDescriptor(cast<Decl>(RD->getDeclContext()))); return T; } @@ -1500,9 +1566,6 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { LexicalBlockStack.push_back(&*FwdDecl); RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl); - // Add this to the completed-type cache while we're completing it recursively. - CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl; - // Convert all the elements. SmallVector<llvm::Value *, 16> EltTys; // what about nested types? @@ -1574,20 +1637,28 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, // Get overall information about the record type for the debug info. llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation()); unsigned Line = getLineNumber(ID->getLocation()); - unsigned RuntimeLang = TheCU.getLanguage(); + llvm::dwarf::SourceLanguage RuntimeLang = TheCU.getLanguage(); // If this is just a forward declaration return a special forward-declaration // debug type since we won't be able to lay out the entire type. ObjCInterfaceDecl *Def = ID->getDefinition(); - if (!Def) { - llvm::DIType FwdDecl = - DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - ID->getName(), TheCU, DefUnit, Line, - RuntimeLang); + if (!Def || !Def->getImplementation()) { + llvm::DIType FwdDecl = DBuilder.createReplaceableForwardDecl( + llvm::dwarf::DW_TAG_structure_type, ID->getName(), TheCU, DefUnit, Line, + RuntimeLang); + ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit)); return FwdDecl; } - ID = Def; + + return CreateTypeDefinition(Ty, Unit); +} + +llvm::DIType CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile Unit) { + ObjCInterfaceDecl *ID = Ty->getDecl(); + llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation()); + unsigned Line = getLineNumber(ID->getLocation()); + unsigned RuntimeLang = TheCU.getLanguage(); // Bit size, align and offset of the type. uint64_t Size = CGM.getContext().getTypeSize(Ty); @@ -1602,10 +1673,8 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, Line, Size, Align, Flags, llvm::DIType(), llvm::DIArray(), RuntimeLang); - // Otherwise, insert it into the CompletedTypeCache so that recursive uses - // will find it and we're emitting the complete type. - QualType QualTy = QualType(Ty, 0); - CompletedTypeCache[QualTy.getAsOpaquePtr()] = RealDecl; + QualType QTy(Ty, 0); + TypeCache[QTy.getAsOpaquePtr()] = RealDecl; // Push the struct on region stack. LexicalBlockStack.push_back(static_cast<llvm::MDNode*>(RealDecl)); @@ -1627,9 +1696,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, } // Create entries for all of the properties. - for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(), - E = ID->prop_end(); I != E; ++I) { - const ObjCPropertyDecl *PD = *I; + for (const auto *PD : ID->properties()) { SourceLocation Loc = PD->getLocation(); llvm::DIFile PUnit = getOrCreateFile(Loc); unsigned PLine = getLineNumber(Loc); @@ -1699,7 +1766,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, else if (Field->getAccessControl() == ObjCIvarDecl::Private) Flags = llvm::DIDescriptor::FlagPrivate; - llvm::MDNode *PropertyNode = NULL; + llvm::MDNode *PropertyNode = nullptr; if (ObjCImplementationDecl *ImpD = ID->getImplementation()) { if (ObjCPropertyImplDecl *PImpD = ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) { @@ -1731,12 +1798,6 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); RealDecl.setTypeArray(Elements); - // If the implementation is not yet set, we do not want to mark it - // as complete. An implementation may declare additional - // private ivars that we would miss otherwise. - if (ID->getImplementation() == 0) - CompletedTypeCache.erase(QualTy.getAsOpaquePtr()); - LexicalBlockStack.pop_back(); return RealDecl; } @@ -1831,11 +1892,13 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, if (!Ty->getPointeeType()->isFunctionType()) return DBuilder.createMemberPointerType( getOrCreateType(Ty->getPointeeType(), U), ClassType); + + const FunctionProtoType *FPT = + Ty->getPointeeType()->getAs<FunctionProtoType>(); return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType( - CGM.getContext().getPointerType( - QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())), - Ty->getPointeeType()->getAs<FunctionProtoType>(), U), - ClassType); + CGM.getContext().getPointerType(QualType(Ty->getClass(), + FPT->getTypeQuals())), + FPT, U), ClassType); } llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty, @@ -1865,17 +1928,31 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumType *Ty) { llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); StringRef EDName = ED->getName(); - return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type, - EDName, EDContext, DefUnit, Line, 0, - Size, Align, FullName); + llvm::DIType RetTy = DBuilder.createReplaceableForwardDecl( + llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line, + 0, Size, Align, FullName); + ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy))); + return RetTy; } + return CreateTypeDefinition(Ty); +} + +llvm::DIType CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) { + const EnumDecl *ED = Ty->getDecl(); + uint64_t Size = 0; + uint64_t Align = 0; + if (!ED->getTypeForDecl()->isIncompleteType()) { + Size = CGM.getContext().getTypeSize(ED->getTypeForDecl()); + Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl()); + } + + SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); + // Create DIEnumerator elements for each enumerator. SmallVector<llvm::Value *, 16> Enumerators; ED = ED->getDefinition(); - for (EnumDecl::enumerator_iterator - Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end(); - Enum != EnumEnd; ++Enum) { + for (const auto *Enum : ED->enumerators()) { Enumerators.push_back( DBuilder.createEnumerator(Enum->getName(), Enum->getInitVal().getSExtValue())); @@ -1909,9 +1986,12 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) { switch (T->getTypeClass()) { default: return C.getQualifiedType(T.getTypePtr(), Quals); - case Type::TemplateSpecialization: - T = cast<TemplateSpecializationType>(T)->desugar(); - break; + case Type::TemplateSpecialization: { + const auto *Spec = cast<TemplateSpecializationType>(T); + if (Spec->isTypeAlias()) + return C.getQualifiedType(T.getTypePtr(), Quals); + T = Spec->desugar(); + break; } case Type::TypeOfExpr: T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType(); break; @@ -1956,16 +2036,7 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) { // Unwrap the type as needed for debug information. Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); - // Check for existing entry. - if (Ty->getTypeClass() == Type::ObjCInterface) { - llvm::Value *V = getCachedInterfaceTypeOrNull(Ty); - if (V) - return llvm::DIType(cast<llvm::MDNode>(V)); - else return llvm::DIType(); - } - - llvm::DenseMap<void *, llvm::WeakVH>::iterator it = - TypeCache.find(Ty.getAsOpaquePtr()); + auto it = TypeCache.find(Ty.getAsOpaquePtr()); if (it != TypeCache.end()) { // Verify that the debug info still exists. if (llvm::Value *V = it->second) @@ -1975,41 +2046,15 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) { return llvm::DIType(); } -/// getCompletedTypeOrNull - Get the type from the cache or return null if it -/// doesn't exist. -llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) { - - // Unwrap the type as needed for debug information. - Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); - - // Check for existing entry. - llvm::Value *V = 0; - llvm::DenseMap<void *, llvm::WeakVH>::iterator it = - CompletedTypeCache.find(Ty.getAsOpaquePtr()); - if (it != CompletedTypeCache.end()) - V = it->second; - else { - V = getCachedInterfaceTypeOrNull(Ty); - } - - // Verify that any cached debug info still exists. - return llvm::DIType(cast_or_null<llvm::MDNode>(V)); -} - -/// getCachedInterfaceTypeOrNull - Get the type from the interface -/// cache, unless it needs to regenerated. Otherwise return null. -llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) { - // Is there a cached interface that hasn't changed? - llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned > > - ::iterator it1 = ObjCInterfaceCache.find(Ty.getAsOpaquePtr()); - - if (it1 != ObjCInterfaceCache.end()) - if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty)) - if (Checksum(Decl) == it1->second.second) - // Return cached forward declaration. - return it1->second.first; +void CGDebugInfo::completeTemplateDefinition( + const ClassTemplateSpecializationDecl &SD) { + if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + return; - return 0; + completeClassData(&SD); + // In case this type has no member function definitions being emitted, ensure + // it is retained + RetainedTypes.push_back(CGM.getContext().getRecordType(&SD).getAsOpaquePtr()); } /// getOrCreateType - Get the type from the cache or create a new @@ -2021,7 +2066,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { // Unwrap the type as needed for debug information. Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); - if (llvm::DIType T = getCompletedTypeOrNull(Ty)) + if (llvm::DIType T = getTypeOrNull(Ty)) return T; // Otherwise create the type. @@ -2031,39 +2076,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { // And update the type cache. TypeCache[TyPtr] = Res; - // FIXME: this getTypeOrNull call seems silly when we just inserted the type - // into the cache - but getTypeOrNull has a special case for cached interface - // types. We should probably just pull that out as a special case for the - // "else" block below & skip the otherwise needless lookup. - llvm::DIType TC = getTypeOrNull(Ty); - if (TC && TC.isForwardDecl()) - ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC))); - else if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty)) { - // Interface types may have elements added to them by a - // subsequent implementation or extension, so we keep them in - // the ObjCInterfaceCache together with a checksum. Instead of - // the (possibly) incomplete interface type, we return a forward - // declaration that gets RAUW'd in CGDebugInfo::finalize(). - std::pair<llvm::WeakVH, unsigned> &V = ObjCInterfaceCache[TyPtr]; - if (V.first) - return llvm::DIType(cast<llvm::MDNode>(V.first)); - TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - Decl->getName(), TheCU, Unit, - getLineNumber(Decl->getLocation()), - TheCU.getLanguage()); - // Store the forward declaration in the cache. - V.first = TC; - V.second = Checksum(Decl); - - // Register the type for replacement in finalize(). - ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC))); - - return TC; - } - - if (!Res.isForwardDecl()) - CompletedTypeCache[TyPtr] = Res; - return Res; } @@ -2075,7 +2087,7 @@ unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl *ID) { // a checksum. unsigned Sum = 0; for (const ObjCIvarDecl *Ivar = ID->all_declared_ivar_begin(); - Ivar != 0; Ivar = Ivar->getNextIvar()) + Ivar != nullptr; Ivar = Ivar->getNextIvar()) ++Sum; return Sum; @@ -2089,7 +2101,7 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCInterfaceDecl(QualType Ty) { case Type::ObjCInterface: return cast<ObjCInterfaceType>(Ty)->getDecl(); default: - return 0; + return nullptr; } } @@ -2099,7 +2111,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { if (Ty.hasLocalQualifiers()) return CreateQualifiedType(Ty, Unit); - const char *Diag = 0; + const char *Diag = nullptr; // Work out details of type. switch (Ty->getTypeClass()) { @@ -2125,10 +2137,11 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { return CreateType(cast<ComplexType>(Ty)); case Type::Pointer: return CreateType(cast<PointerType>(Ty), Unit); + case Type::Adjusted: case Type::Decayed: - // Decayed types are just pointers in LLVM and DWARF. + // Decayed and adjusted types use the adjusted type in LLVM and DWARF. return CreateType( - cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit); + cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit); case Type::BlockPointer: return CreateType(cast<BlockPointerType>(Ty), Unit); case Type::Typedef: @@ -2156,8 +2169,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { case Type::Atomic: return CreateType(cast<AtomicType>(Ty), Unit); - case Type::Attributed: case Type::TemplateSpecialization: + return CreateType(cast<TemplateSpecializationType>(Ty), Unit); + + case Type::Attributed: case Type::Elaborated: case Type::Paren: case Type::SubstTemplateTypeParm: @@ -2201,10 +2216,6 @@ llvm::DIType CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty, // correct order if the full type is needed. Res.setTypeArray(T.getTypeArray()); - if (T && T.isForwardDecl()) - ReplaceMap.push_back( - std::make_pair(QTy.getAsOpaquePtr(), static_cast<llvm::Value *>(T))); - // And update the type cache. TypeCache[QTy.getAsOpaquePtr()] = Res; return Res; @@ -2224,13 +2235,6 @@ llvm::DICompositeType CGDebugInfo::CreateLimitedType(const RecordType *Ty) { // If we ended up creating the type during the context chain construction, // just return that. - // FIXME: this could be dealt with better if the type was recorded as - // completed before we started this (see the CompletedTypeCache usage in - // CGDebugInfo::CreateTypeDefinition(const RecordType*) - that would need to - // be pushed to before context creation, but after it was known to be - // destined for completion (might still have an issue if this caller only - // required a declaration but the context construction ended up creating a - // definition) llvm::DICompositeType T(getTypeOrNull(CGM.getContext().getRecordType(RD))); if (T && (!T.isForwardDecl() || !RD->getDefinition())) return T; @@ -2280,7 +2284,7 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType ContainingType; const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { - // Seek non virtual primary base root. + // Seek non-virtual primary base root. while (1) { const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase); const CXXRecordDecl *PBT = BRL.getPrimaryBase(); @@ -2312,7 +2316,7 @@ llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType, return Ty; } -llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { +llvm::DIScope CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { // We only need a declaration (not a definition) of the type - so use whatever // we would otherwise do to get a type for a pointee. (forward declarations in // limited debug info, full definitions (if the type definition is available) @@ -2330,15 +2334,15 @@ llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator I = DeclCache.find(D->getCanonicalDecl()); if (I == DeclCache.end()) - return llvm::DIDescriptor(); + return llvm::DIScope(); llvm::Value *V = I->second; - return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V)); + return llvm::DIScope(dyn_cast_or_null<llvm::MDNode>(V)); } /// getFunctionDeclaration - Return debug info descriptor to describe method /// declaration for the given method definition. llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { - if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) return llvm::DISubprogram(); const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); @@ -2355,7 +2359,6 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { llvm::DICompositeType T(S); llvm::DISubprogram SP = CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T); - T.addMember(SP); return SP; } } @@ -2366,9 +2369,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { return SP; } - for (FunctionDecl::redecl_iterator I = FD->redecls_begin(), - E = FD->redecls_end(); I != E; ++I) { - const FunctionDecl *NextFD = *I; + for (auto NextFD : FD->redecls()) { llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI = SPCache.find(NextFD->getCanonicalDecl()); if (MI != SPCache.end()) { @@ -2386,7 +2387,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile F) { - if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) // Create fake but valid subroutine type. Otherwise // llvm::DISubprogram::Verify() would return false, and // subprogram DIE will miss DW_AT_decl_file and @@ -2400,7 +2401,7 @@ llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, SmallVector<llvm::Value *, 16> Elts; // First element is always return type. For 'void' functions it is NULL. - QualType ResultTy = OMethod->getResultType(); + QualType ResultTy = OMethod->getReturnType(); // Replace the instancetype keyword with the actual type. if (ResultTy == CGM.getContext().getObjCInstanceType()) @@ -2416,22 +2417,22 @@ llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F); Elts.push_back(DBuilder.createArtificialType(CmdTy)); // Get rest of the arguments. - for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(), - PE = OMethod->param_end(); PI != PE; ++PI) - Elts.push_back(getOrCreateType((*PI)->getType(), F)); + for (const auto *PI : OMethod->params()) + Elts.push_back(getOrCreateType(PI->getType(), F)); llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts); return DBuilder.createSubroutineType(F, EltTypeArray); } - // Variadic function. + // Handle variadic function types; they need an additional + // unspecified parameter. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) if (FD->isVariadic()) { SmallVector<llvm::Value *, 16> EltTys; - EltTys.push_back(getOrCreateType(FD->getResultType(), F)); + EltTys.push_back(getOrCreateType(FD->getReturnType(), F)); if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FnType)) - for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) - EltTys.push_back(getOrCreateType(FPT->getArgType(i), F)); + for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i) + EltTys.push_back(getOrCreateType(FPT->getParamType(i), F)); EltTys.push_back(DBuilder.createUnspecifiedParameter()); llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys); return DBuilder.createSubroutineType(F, EltTypeArray); @@ -2441,7 +2442,10 @@ llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, } /// EmitFunctionStart - Constructs the debug code for entering a function. -void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, +void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, + SourceLocation Loc, + SourceLocation ScopeLoc, + QualType FnType, llvm::Function *Fn, CGBuilderTy &Builder) { @@ -2451,13 +2455,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, FnBeginRegionCount.push_back(LexicalBlockStack.size()); const Decl *D = GD.getDecl(); - // Function may lack declaration in source code if it is created by Clang - // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk). - bool HasDecl = (D != 0); - // Use the location of the declaration. - SourceLocation Loc; - if (HasDecl) - Loc = D->getLocation(); + bool HasDecl = (D != nullptr); unsigned Flags = 0; llvm::DIFile Unit = getOrCreateFile(Loc); @@ -2517,23 +2515,34 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, if (!Name.empty() && Name[0] == '\01') Name = Name.substr(1); - unsigned LineNo = getLineNumber(Loc); - if (!HasDecl || D->isImplicit()) + if (!HasDecl || D->isImplicit()) { Flags |= llvm::DIDescriptor::FlagArtificial; + // Artificial functions without a location should not silently reuse CurLoc. + if (Loc.isInvalid()) + CurLoc = SourceLocation(); + } + unsigned LineNo = getLineNumber(Loc); + unsigned ScopeLine = getLineNumber(ScopeLoc); + // FIXME: The function declaration we're constructing here is mostly reusing + // declarations from CXXMethodDecl and not constructing new ones for arbitrary + // FunctionDecls. When/if we fix this we can have FDContext be TheCU/null for + // all subprograms instead of the actual context since subprogram definitions + // are emitted as CU level entities by the backend. llvm::DISubprogram SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo, getOrCreateFunctionType(D, FnType, Unit), Fn->hasInternalLinkage(), true /*definition*/, - getLineNumber(CurLoc), Flags, + ScopeLine, Flags, CGM.getLangOpts().Optimize, Fn, TParamsArray, getFunctionDeclaration(D)); if (HasDecl) DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(SP))); - // Push function on region stack. + // Push the function onto the lexical block stack. llvm::MDNode *SPN = SP; LexicalBlockStack.push_back(SPN); + if (HasDecl) RegionMap[D] = llvm::WeakVH(SP); } @@ -2571,13 +2580,11 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc, /// CreateLexicalBlock - Creates a new lexical block node and pushes it on /// the stack. void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) { - llvm::DIDescriptor D = - DBuilder.createLexicalBlock(LexicalBlockStack.empty() ? - llvm::DIDescriptor() : - llvm::DIDescriptor(LexicalBlockStack.back()), - getOrCreateFile(CurLoc), - getLineNumber(CurLoc), - getColumnNumber(CurLoc)); + llvm::DIDescriptor D = DBuilder.createLexicalBlock( + llvm::DIDescriptor(LexicalBlockStack.empty() ? nullptr + : LexicalBlockStack.back()), + getOrCreateFile(CurLoc), getLineNumber(CurLoc), getColumnNumber(CurLoc), + 0); llvm::MDNode *DN = D; LexicalBlockStack.push_back(DN); } @@ -2681,7 +2688,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, } FType = Type; - llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + llvm::DIType FieldTy = getOrCreateType(FType, Unit); FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().toBits(Align); @@ -2701,7 +2708,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, } /// EmitDeclare - Emit local variable declaration debug info. -void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, +void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::LLVMConstants Tag, llvm::Value *Storage, unsigned ArgNo, CGBuilderTy &Builder) { assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); @@ -2785,10 +2792,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, // all union fields. const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); if (RD->isUnion() && RD->isAnonymousStructOrUnion()) { - for (RecordDecl::field_iterator I = RD->field_begin(), - E = RD->field_end(); - I != E; ++I) { - FieldDecl *Field = *I; + for (const auto *Field : RD->fields()) { llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit); StringRef FieldName = Field->getName(); @@ -2841,7 +2845,6 @@ llvm::DIType CGDebugInfo::CreateSelfType(const QualType &QualTy, llvm::DIType Ty) { llvm::DIType CachedTy = getTypeOrNull(QualTy); if (CachedTy) Ty = CachedTy; - else DEBUG(llvm::dbgs() << "No cached type for self."); return DBuilder.createObjectPointerType(Ty); } @@ -2852,7 +2855,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD, assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); - if (Builder.GetInsertBlock() == 0) + if (Builder.GetInsertBlock() == nullptr) return; bool isByRef = VD->hasAttr<BlocksAttr>(); @@ -2982,15 +2985,12 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, BlockLayoutChunk chunk; chunk.OffsetInBits = blockLayout->getElementOffsetInBits(block.CXXThisIndex); - chunk.Capture = 0; + chunk.Capture = nullptr; chunks.push_back(chunk); } // Variable captures. - for (BlockDecl::capture_const_iterator - i = blockDecl->capture_begin(), e = blockDecl->capture_end(); - i != e; ++i) { - const BlockDecl::Capture &capture = *i; + for (const auto &capture : blockDecl->captures()) { const VarDecl *variable = capture.getVariable(); const CGBlockInfo::Capture &captureInfo = block.getCapture(variable); @@ -3102,10 +3102,40 @@ CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) { llvm::DICompositeType Ctxt( getContextDescriptor(cast<Decl>(D->getDeclContext()))); llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt); - Ctxt.addMember(T); return T; } +/// Recursively collect all of the member fields of a global anonymous decl and +/// create static variables for them. The first time this is called it needs +/// to be on a union and then from there we can have additional unnamed fields. +llvm::DIGlobalVariable +CGDebugInfo::CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile Unit, + unsigned LineNo, StringRef LinkageName, + llvm::GlobalVariable *Var, + llvm::DIDescriptor DContext) { + llvm::DIGlobalVariable GV; + + for (const auto *Field : RD->fields()) { + llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit); + StringRef FieldName = Field->getName(); + + // Ignore unnamed fields, but recurse into anonymous records. + if (FieldName.empty()) { + const RecordType *RT = dyn_cast<RecordType>(Field->getType()); + if (RT) + GV = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName, + Var, DContext); + continue; + } + // Use VarDecl's Tag, Scope and Line number. + GV = DBuilder.createStaticVariable(DContext, FieldName, LinkageName, Unit, + LineNo, FieldTy, + Var->hasInternalLinkage(), Var, + llvm::DIDerivedType()); + } + return GV; +} + /// EmitGlobalVariable - Emit information about a global variable. void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, const VarDecl *D) { @@ -3126,46 +3156,36 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, T = CGM.getContext().getConstantArrayType(ET, ConstVal, ArrayType::Normal, 0); } + StringRef DeclName = D->getName(); StringRef LinkageName; - if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext()) - && !isa<ObjCMethodDecl>(D->getDeclContext())) + if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext()) && + !isa<ObjCMethodDecl>(D->getDeclContext())) LinkageName = Var->getName(); if (LinkageName == DeclName) LinkageName = StringRef(); + llvm::DIDescriptor DContext = getContextDescriptor(dyn_cast<Decl>(D->getDeclContext())); - llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( - DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), - Var->hasInternalLinkage(), Var, - getOrCreateStaticDataMemberDeclarationOrNull(D)); - DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV))); -} -/// EmitGlobalVariable - Emit information about an objective-c interface. -void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, - ObjCInterfaceDecl *ID) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); - // Create global variable debug descriptor. - llvm::DIFile Unit = getOrCreateFile(ID->getLocation()); - unsigned LineNo = getLineNumber(ID->getLocation()); - - StringRef Name = ID->getName(); - - QualType T = CGM.getContext().getObjCInterfaceType(ID); - if (T->isIncompleteArrayType()) { - - // CodeGen turns int[] into int[1] so we'll do the same here. - llvm::APInt ConstVal(32, 1); - QualType ET = CGM.getContext().getAsArrayType(T)->getElementType(); - - T = CGM.getContext().getConstantArrayType(ET, ConstVal, - ArrayType::Normal, 0); + // Attempt to store one global variable for the declaration - even if we + // emit a lot of fields. + llvm::DIGlobalVariable GV; + + // If this is an anonymous union then we'll want to emit a global + // variable for each member of the anonymous union so that it's possible + // to find the name of any field in the union. + if (T->isUnionType() && DeclName.empty()) { + const RecordDecl *RD = cast<RecordType>(T)->getDecl(); + assert(RD->isAnonymousStructOrUnion() && "unnamed non-anonymous struct or union?"); + GV = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext); + } else { + GV = DBuilder.createStaticVariable( + DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), + Var->hasInternalLinkage(), Var, + getOrCreateStaticDataMemberDeclarationOrNull(D)); } - - DBuilder.createGlobalVariable(Name, Unit, LineNo, - getOrCreateType(T, Unit), - Var->hasInternalLinkage(), Var); + DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV))); } /// EmitGlobalVariable - Emit global variable's debug info. @@ -3184,10 +3204,20 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, // Do not use DIGlobalVariable for enums. if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type) return; + // Do not emit separate definitions for function local const/statics. + if (isa<FunctionDecl>(VD->getDeclContext())) + return; + VD = cast<ValueDecl>(VD->getCanonicalDecl()); + auto pair = DeclCache.insert(std::make_pair(VD, llvm::WeakVH())); + if (!pair.second) + return; + llvm::DIDescriptor DContext = + getContextDescriptor(dyn_cast<Decl>(VD->getDeclContext())); llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( - Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init, + DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty, + true, Init, getOrCreateStaticDataMemberDeclarationOrNull(cast<VarDecl>(VD))); - DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV))); + pair.first->second = llvm::WeakVH(GV); } llvm::DIScope CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { @@ -3213,7 +3243,7 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { // Emitting one decl is sufficient - debuggers can detect that this is an // overloaded name & provide lookup for all the overloads. const UsingShadowDecl &USD = **UD.shadow_begin(); - if (llvm::DIDescriptor Target = + if (llvm::DIScope Target = getDeclarationOrDefinition(USD.getUnderlyingDecl())) DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target, @@ -3223,20 +3253,20 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { llvm::DIImportedEntity CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) - return llvm::DIImportedEntity(0); + return llvm::DIImportedEntity(nullptr); llvm::WeakVH &VH = NamespaceAliasCache[&NA]; if (VH) return llvm::DIImportedEntity(cast<llvm::MDNode>(VH)); - llvm::DIImportedEntity R(0); + llvm::DIImportedEntity R(nullptr); if (const NamespaceAliasDecl *Underlying = dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace())) // This could cache & dedup here rather than relying on metadata deduping. - R = DBuilder.createImportedModule( + R = DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())), EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()), NA.getName()); else - R = DBuilder.createImportedModule( + R = DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())), getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())), getLineNumber(NA.getLocation()), NA.getName()); @@ -3265,23 +3295,27 @@ CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) { } void CGDebugInfo::finalize() { - for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI - = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) { - llvm::DIType Ty, RepTy; - // Verify that the debug info still exists. - if (llvm::Value *V = VI->second) - Ty = llvm::DIType(cast<llvm::MDNode>(V)); - - llvm::DenseMap<void *, llvm::WeakVH>::iterator it = - TypeCache.find(VI->first); - if (it != TypeCache.end()) { - // Verify that the debug info still exists. - if (llvm::Value *V = it->second) - RepTy = llvm::DIType(cast<llvm::MDNode>(V)); - } - - if (Ty && Ty.isForwardDecl() && RepTy) - Ty.replaceAllUsesWith(RepTy); + // Creating types might create further types - invalidating the current + // element and the size(), so don't cache/reference them. + for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { + ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i]; + E.Decl.replaceAllUsesWith(CGM.getLLVMContext(), + E.Type->getDecl()->getDefinition() + ? CreateTypeDefinition(E.Type, E.Unit) + : E.Decl); + } + + for (auto p : ReplaceMap) { + assert(p.second); + llvm::DIType Ty(cast<llvm::MDNode>(p.second)); + assert(Ty.isForwardDecl()); + + auto it = TypeCache.find(p.first); + assert(it != TypeCache.end()); + assert(it->second); + + llvm::DIType RepTy(cast<llvm::MDNode>(it->second)); + Ty.replaceAllUsesWith(CGM.getLLVMContext(), RepTy); } // We keep our own list of retained types, because we need to look |