diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -48,17 +48,21 @@ Function *LabelFn; ///< llvm.dbg.label Function *AddrFn; ///< llvm.dbg.addr - SmallVector AllEnumTypes; /// Track the RetainTypes, since they can be updated later on. SmallVector AllRetainTypes; SmallVector AllSubprograms; - SmallVector AllGVs; - SmallVector AllImportedModules; /// Map Macro parent (which can be DIMacroFile or nullptr) to a list of /// Metadata all of type DIMacroNode. /// DIMacroNode's with nullptr parent are DICompileUnit direct children. MapVector> AllMacrosPerParent; + /// Module level global variables, enum types and imported entities. + SmallVector ModuleGVs; + SmallVector ModuleEnumTypes; + SmallVector ModuleImports; + /// Function-local static vars, types (including enums) and import. + DenseMap> LocalDecls; + /// Track nodes that may be unresolved. SmallVector UnresolvedNodes; bool AllowUnresolvedNodes; diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1538,6 +1538,17 @@ /// scope chain. DILocalScope *getNonLexicalBlockFileScope() const; + /// Get a list of function-local declarations for this scope. + /// + /// Return an array of static variables, types and imported entities + /// declarated in this scope for \a DISubprogram or \a DILexicalScope, + /// and nullptr for other scopes. + MDNodeArray getLocalDecls() const; + + /// Replace a list of function-local declarations by the given one. + /// Assumes 'this' is either \a DISubprogram or \a DILexicalScope. + void replaceLocalDecls(MDNodeArray N); + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DISubprogramKind || MD->getMetadataID() == DILexicalBlockKind || @@ -1850,16 +1861,17 @@ unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, - DINodeArray RetainedNodes, DITypeArray ThrownTypes, - DINodeArray Annotations, StringRef TargetFuncName, - StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, Scope, getCanonicalMDString(Context, Name), - getCanonicalMDString(Context, LinkageName), File, Line, Type, - ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, - Flags, SPFlags, Unit, TemplateParams.get(), Declaration, - RetainedNodes.get(), ThrownTypes.get(), Annotations.get(), - getCanonicalMDString(Context, TargetFuncName), - Storage, ShouldCreate); + DINodeArray RetainedNodes, MDNodeArray LocalDecls, + DITypeArray ThrownTypes, DINodeArray Annotations, + StringRef TargetFuncName, StorageType Storage, + bool ShouldCreate = true) { + return getImpl( + Context, Scope, getCanonicalMDString(Context, Name), + getCanonicalMDString(Context, LinkageName), File, Line, Type, ScopeLine, + ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams.get(), Declaration, RetainedNodes.get(), + LocalDecls.get(), ThrownTypes.get(), Annotations.get(), + getCanonicalMDString(Context, TargetFuncName), Storage, ShouldCreate); } static DISubprogram * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, @@ -1867,8 +1879,8 @@ unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, - Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, - MDString *TargetFuncName, StorageType Storage, + Metadata *RetainedNodes, Metadata *LocalDecls, Metadata *ThrownTypes, + Metadata *Annotations, MDString *TargetFuncName, StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { @@ -1877,8 +1889,8 @@ getContainingType(), getVirtualIndex(), getThisAdjustment(), getFlags(), getSPFlags(), getUnit(), getTemplateParams(), getDeclaration(), - getRetainedNodes(), getThrownTypes(), getAnnotations(), - getTargetFuncName()); + getRetainedNodes(), getLocalDecls(), getThrownTypes(), + getAnnotations(), getTargetFuncName()); } public: @@ -1890,11 +1902,12 @@ DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, - DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr, - StringRef TargetFuncName = ""), + MDNodeArray LocalDecls = nullptr, DITypeArray ThrownTypes = nullptr, + DINodeArray Annotations = nullptr, StringRef TargetFuncName = ""), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) + Declaration, RetainedNodes, LocalDecls, ThrownTypes, Annotations, + TargetFuncName)) DEFINE_MDNODE_GET( DISubprogram, @@ -1903,11 +1916,13 @@ Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, - Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr, - Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr), + Metadata *RetainedNodes = nullptr, Metadata *LocalDecls = nullptr, + Metadata *ThrownTypes = nullptr, Metadata *Annotations = nullptr, + MDString *TargetFuncName = nullptr), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) + Declaration, RetainedNodes, LocalDecls, ThrownTypes, Annotations, + TargetFuncName)) TempDISubprogram clone() const { return cloneImpl(); } @@ -2010,6 +2025,9 @@ DINodeArray getRetainedNodes() const { return cast_or_null(getRawRetainedNodes()); } + MDNodeArray getLocalDecls() const { + return cast_or_null(getRawLocalDecls()); + } DITypeArray getThrownTypes() const { return cast_or_null(getRawThrownTypes()); } @@ -2027,25 +2045,17 @@ Metadata *getRawUnit() const { return getOperand(5); } Metadata *getRawDeclaration() const { return getOperand(6); } Metadata *getRawRetainedNodes() const { return getOperand(7); } - Metadata *getRawContainingType() const { - return getNumOperands() > 8 ? getOperandAs(8) : nullptr; - } - Metadata *getRawTemplateParams() const { - return getNumOperands() > 9 ? getOperandAs(9) : nullptr; - } - Metadata *getRawThrownTypes() const { - return getNumOperands() > 10 ? getOperandAs(10) : nullptr; - } - Metadata *getRawAnnotations() const { - return getNumOperands() > 11 ? getOperandAs(11) : nullptr; - } - MDString *getRawTargetFuncName() const { - return getNumOperands() > 12 ? getOperandAs(12) : nullptr; - } + Metadata *getRawContainingType() const { return getOperandAs(8); } + Metadata *getRawTemplateParams() const { return getOperandAs(9); } + Metadata *getRawThrownTypes() const { return getOperandAs(10); } + Metadata *getRawAnnotations() const { return getOperandAs(11); } + MDString *getRawTargetFuncName() const { return getOperandAs(12); } + Metadata *getRawLocalDecls() const { return getOperand(13); } void replaceRawLinkageName(MDString *LinkageName) { replaceOperandWith(3, LinkageName); } + void replaceLocalDecls(MDNodeArray N) { replaceOperandWith(13, N.get()); } /// Check if this subprogram describes the given function. /// @@ -2091,37 +2101,44 @@ static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope, DIFile *File, unsigned Line, unsigned Column, - StorageType Storage, + MDNodeArray LocalDecls, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, static_cast(Scope), - static_cast(File), Line, Column, Storage, - ShouldCreate); + static_cast(File), Line, Column, + LocalDecls.get(), Storage, ShouldCreate); } static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope, Metadata *File, unsigned Line, unsigned Column, - StorageType Storage, bool ShouldCreate = true); + Metadata *LocalDecls, StorageType Storage, + bool ShouldCreate = true); TempDILexicalBlock cloneImpl() const { return getTemporary(getContext(), getScope(), getFile(), getLine(), - getColumn()); + getColumn(), getLocalDecls()); } public: DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File, unsigned Line, - unsigned Column), - (Scope, File, Line, Column)) + unsigned Column, MDNodeArray LocalDecls = nullptr), + (Scope, File, Line, Column, LocalDecls)) DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File, unsigned Line, - unsigned Column), - (Scope, File, Line, Column)) + unsigned Column, Metadata *LocalDecls = nullptr), + (Scope, File, Line, Column, LocalDecls)) TempDILexicalBlock clone() const { return cloneImpl(); } unsigned getLine() const { return Line; } unsigned getColumn() const { return Column; } + MDNodeArray getLocalDecls() const { + return cast_or_null(getRawLocalDecls()); + } + Metadata *getRawLocalDecls() const { return getOperand(2); } + void replaceLocalDecls(MDNodeArray N) { replaceOperandWith(2, N.get()); } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DILexicalBlockKind; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4797,7 +4797,7 @@ /// virtualIndex: 10, thisAdjustment: 4, flags: 11, /// spFlags: 10, isOptimized: false, templateParams: !4, /// declaration: !5, retainedNodes: !6, thrownTypes: !7, -/// annotations: !8) +/// annotations: !8, targetFuncName !9, localDecls: !10) bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { auto Loc = Lex.getLoc(); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ @@ -4823,7 +4823,8 @@ OPTIONAL(retainedNodes, MDField, ); \ OPTIONAL(thrownTypes, MDField, ); \ OPTIONAL(annotations, MDField, ); \ - OPTIONAL(targetFuncName, MDStringField, ); + OPTIONAL(targetFuncName, MDStringField, ); \ + OPTIONAL(localDecls, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4842,24 +4843,27 @@ (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, - declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val, - targetFuncName.Val)); + declaration.Val, retainedNodes.Val, localDecls.Val, thrownTypes.Val, + annotations.Val, targetFuncName.Val)); return false; } /// parseDILexicalBlock: -/// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9) +/// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9, +/// localDecls: !1) bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ - OPTIONAL(column, ColumnField, ); + OPTIONAL(column, ColumnField, ); \ + OPTIONAL(localDecls, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT( - DILexicalBlock, (Context, scope.Val, file.Val, line.Val, column.Val)); + Result = + GET_OR_DISTINCT(DILexicalBlock, (Context, scope.Val, file.Val, line.Val, + column.Val, localDecls.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1697,6 +1697,7 @@ bool HasFn = false; bool HasThisAdj = true; bool HasThrownTypes = true; + bool HasLocalDecls = false; bool HasAnnotations = false; bool HasTargetFuncName = false; unsigned OffsetA = 0; @@ -1713,6 +1714,7 @@ } else { HasAnnotations = Record.size() >= 19; HasTargetFuncName = Record.size() >= 20; + HasLocalDecls = Record.size() >= 21; } Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]); DISubprogram *SP = GET_OR_DISTINCT( @@ -1734,6 +1736,8 @@ getMDOrNull(Record[13 + OffsetB]), // templateParams getMDOrNull(Record[14 + OffsetB]), // declaration getMDOrNull(Record[15 + OffsetB]), // retainedNodes + HasLocalDecls ? getMDOrNull(Record[20 + OffsetB]) + : nullptr, // localDecls HasThrownTypes ? getMDOrNull(Record[17 + OffsetB]) : nullptr, // thrownTypes HasAnnotations ? getMDOrNull(Record[18 + OffsetB]) @@ -1759,14 +1763,20 @@ break; } case bitc::METADATA_LEXICAL_BLOCK: { - if (Record.size() != 5) + if (Record.size() > 6 || Record.size() < 5) return error("Invalid record"); IsDistinct = Record[0]; - MetadataList.assignValue( - GET_OR_DISTINCT(DILexicalBlock, - (Context, getMDOrNull(Record[1]), - getMDOrNull(Record[2]), Record[3], Record[4])), + bool HasLocalDecls = Record.size() >= 6; + MetadataList.assignValue(GET_OR_DISTINCT( + DILexicalBlock, + (Context, + getMDOrNull(Record[1]), + getMDOrNull(Record[2]), + Record[3], + Record[4], + HasLocalDecls ? getMDOrNull(Record[5]) : nullptr + )), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1828,6 +1828,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Record.push_back(VE.getMetadataOrNullID(N->getRawTargetFuncName())); + Record.push_back(VE.getMetadataOrNullID(N->getLocalDecls().get())); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); @@ -1841,6 +1842,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getFile())); Record.push_back(N->getLine()); Record.push_back(N->getColumn()); + Record.push_back(VE.getMetadataOrNullID(N->getLocalDecls().get())); Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2134,6 +2134,7 @@ Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printMetadata("declaration", N->getRawDeclaration()); Printer.printMetadata("retainedNodes", N->getRawRetainedNodes()); + Printer.printMetadata("localDecls", N->getRawLocalDecls()); Printer.printMetadata("thrownTypes", N->getRawThrownTypes()); Printer.printMetadata("annotations", N->getRawAnnotations()); Printer.printString("targetFuncName", N->getTargetFuncName()); @@ -2148,6 +2149,7 @@ Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLine()); Printer.printInt("column", N->getColumn()); + Printer.printMetadata("localDecls", N->getRawLocalDecls()); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -34,13 +34,13 @@ AllowUnresolvedNodes(AllowUnresolvedNodes) { if (CUNode) { if (const auto &ETs = CUNode->getEnumTypes()) - AllEnumTypes.assign(ETs.begin(), ETs.end()); + ModuleEnumTypes.assign(ETs.begin(), ETs.end()); if (const auto &RTs = CUNode->getRetainedTypes()) AllRetainTypes.assign(RTs.begin(), RTs.end()); if (const auto &GVs = CUNode->getGlobalVariables()) - AllGVs.assign(GVs.begin(), GVs.end()); + ModuleGVs.assign(GVs.begin(), GVs.end()); if (const auto &IMs = CUNode->getImportedEntities()) - AllImportedModules.assign(IMs.begin(), IMs.end()); + ModuleImports.assign(IMs.begin(), IMs.end()); if (const auto &MNs = CUNode->getMacros()) AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}}); } @@ -83,8 +83,8 @@ return; } - if (!AllEnumTypes.empty()) - CUNode->replaceEnumTypes(MDTuple::get(VMContext, AllEnumTypes)); + if (!ModuleEnumTypes.empty()) + CUNode->replaceEnumTypes(MDTuple::get(VMContext, ModuleEnumTypes)); SmallVector RetainValues; // Declarations and definitions of the same type may be retained. Some @@ -106,13 +106,22 @@ if (auto *SP = dyn_cast(N)) finalizeSubprogram(SP); - if (!AllGVs.empty()) - CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs)); + for (auto Scope : LocalDecls) { + auto *LScope = cast(Scope.first); + assert((isa(LScope) || isa(LScope)) && + "Unexpected local scope!"); + LScope->replaceLocalDecls(MDTuple::get( + VMContext, SmallVector(Scope.second.begin(), + Scope.second.end()))); + } + + if (!ModuleGVs.empty()) + CUNode->replaceGlobalVariables(MDTuple::get(VMContext, ModuleGVs)); - if (!AllImportedModules.empty()) + if (!ModuleImports.empty()) CUNode->replaceImportedEntities(MDTuple::get( - VMContext, SmallVector(AllImportedModules.begin(), - AllImportedModules.end()))); + VMContext, SmallVector(ModuleImports.begin(), + ModuleImports.end()))); for (const auto &I : AllMacrosPerParent) { // DIMacroNode's with nullptr parent are DICompileUnit direct children. @@ -176,7 +185,7 @@ createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, Metadata *NS, DIFile *File, unsigned Line, StringRef Name, DINodeArray Elements, - SmallVectorImpl &AllImportedModules) { + SmallVectorImpl &ImportedEntities) { if (Line) assert(File && "Source location has line number but no file"); unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size(); @@ -185,7 +194,7 @@ if (EntitiesCount < C.pImpl->DIImportedEntitys.size()) // A new Imported Entity was just added to the context. // Add it to the Imported Modules list. - AllImportedModules.emplace_back(M); + ImportedEntities.emplace_back(M); return M; } @@ -195,7 +204,7 @@ DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, NS, File, Line, StringRef(), Elements, - AllImportedModules); + ModuleImports); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, @@ -204,7 +213,7 @@ DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, NS, File, Line, StringRef(), Elements, - AllImportedModules); + ModuleImports); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M, @@ -212,7 +221,7 @@ DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, M, File, Line, StringRef(), Elements, - AllImportedModules); + ModuleImports); } DIImportedEntity * @@ -223,7 +232,7 @@ // types that have one. return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, Context, Decl, File, Line, Name, Elements, - AllImportedModules); + ModuleImports); } DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory, @@ -556,7 +565,7 @@ getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0, IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements, 0, nullptr, nullptr, UniqueIdentifier); - AllEnumTypes.push_back(CTy); + ModuleEnumTypes.push_back(CTy); trackIfUnresolved(CTy); return CTy; } @@ -748,7 +757,7 @@ if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); - AllGVs.push_back(N); + ModuleGVs.push_back(N); return N; } @@ -853,7 +862,7 @@ /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, - MDTuple::getTemporary(VMContext, None).release(), ThrownTypes, + MDTuple::getTemporary(VMContext, None).release(), nullptr, ThrownTypes, Annotations, TargetFuncName); if (IsDefinition) @@ -873,7 +882,7 @@ Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, - Decl, nullptr, ThrownTypes) + Decl, nullptr, nullptr, ThrownTypes) .release(); } @@ -892,7 +901,7 @@ /*IsDistinct=*/IsDefinition, VMContext, cast(Context), Name, LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment, Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr, - nullptr, ThrownTypes); + nullptr, nullptr, ThrownTypes); if (IsDefinition) AllSubprograms.push_back(SP); @@ -939,7 +948,7 @@ // Make these distinct, to avoid merging two lexical blocks on the same // file/line/column. return DILexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope), - File, Line, Col); + File, Line, Col, nullptr); } Instruction *DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -939,6 +939,24 @@ return const_cast(this); } +MDNodeArray DILocalScope::getLocalDecls() const { + if (auto *SP = dyn_cast(this)) + return SP->getLocalDecls(); + if (auto *LB = dyn_cast(this)) + return LB->getLocalDecls(); + return nullptr; +} + +void DILocalScope::replaceLocalDecls(MDNodeArray N) { + if (auto *SP = dyn_cast(this)) + SP->replaceLocalDecls(N); + else if (auto *LB = dyn_cast(this)) + LB->replaceLocalDecls(N); + else + llvm_unreachable( + "replaceLocalDecls() for this node is not yet implemented."); +} + DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) { return StringSwitch(Flag) #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME) @@ -980,36 +998,20 @@ unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName, - StorageType Storage, bool ShouldCreate) { + Metadata *LocalDecls, Metadata *ThrownTypes, Metadata *Annotations, + MDString *TargetFuncName, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); assert(isCanonical(TargetFuncName) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DISubprogram, - (Scope, Name, LinkageName, File, Line, Type, ScopeLine, - ContainingType, VirtualIndex, ThisAdjustment, Flags, - SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); - SmallVector Ops = { - File, Scope, Name, LinkageName, - Type, Unit, Declaration, RetainedNodes, - ContainingType, TemplateParams, ThrownTypes, Annotations, - TargetFuncName}; - if (!TargetFuncName) { - Ops.pop_back(); - if (!Annotations) { - Ops.pop_back(); - if (!ThrownTypes) { - Ops.pop_back(); - if (!TemplateParams) { - Ops.pop_back(); - if (!ContainingType) - Ops.pop_back(); - } - } - } - } + DEFINE_GETIMPL_LOOKUP( + DISubprogram, (Scope, Name, LinkageName, File, Line, Type, ScopeLine, + ContainingType, VirtualIndex, ThisAdjustment, Flags, + SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, + LocalDecls, ThrownTypes, Annotations, TargetFuncName)); + SmallVector Ops = { + File, Scope, Name, LinkageName, Type, + Unit, Declaration, RetainedNodes, ContainingType, TemplateParams, + ThrownTypes, Annotations, TargetFuncName, LocalDecls}; DEFINE_GETIMPL_STORE_N( DISubprogram, (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, @@ -1027,15 +1029,17 @@ DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope, Metadata *File, unsigned Line, - unsigned Column, StorageType Storage, + unsigned Column, Metadata *LocalDecls, + StorageType Storage, bool ShouldCreate) { // Fixup column. adjustColumn(Column); assert(Scope && "Expected scope"); - DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column)); - Metadata *Ops[] = {File, Scope}; - DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops); + DEFINE_GETIMPL_LOOKUP(DILexicalBlock, + (Scope, File, Line, Column, LocalDecls)); + SmallVector Ops = {File, Scope, LocalDecls}; + DEFINE_GETIMPL_STORE_N(DILexicalBlock, (Line, Column), Ops, Ops.size()); } DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context, diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -708,6 +708,7 @@ Metadata *TemplateParams; Metadata *Declaration; Metadata *RetainedNodes; + Metadata *LocalDecls; Metadata *ThrownTypes; Metadata *Annotations; MDString *TargetFuncName; @@ -718,15 +719,16 @@ unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes, Metadata *Annotations, - MDString *TargetFuncName) + Metadata *LocalDecls, Metadata *ThrownTypes, + Metadata *Annotations, MDString *TargetFuncName) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), ScopeLine(ScopeLine), ContainingType(ContainingType), VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), - RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes), - Annotations(Annotations), TargetFuncName(TargetFuncName) {} + RetainedNodes(RetainedNodes), LocalDecls(LocalDecls), + ThrownTypes(ThrownTypes), Annotations(Annotations), + TargetFuncName(TargetFuncName) {} MDNodeKeyImpl(const DISubprogram *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), @@ -738,7 +740,7 @@ TemplateParams(N->getRawTemplateParams()), Declaration(N->getRawDeclaration()), RetainedNodes(N->getRawRetainedNodes()), - ThrownTypes(N->getRawThrownTypes()), + LocalDecls(N->getRawLocalDecls()), ThrownTypes(N->getRawThrownTypes()), Annotations(N->getRawAnnotations()), TargetFuncName(N->getRawTargetFuncName()) {} @@ -755,6 +757,7 @@ TemplateParams == RHS->getRawTemplateParams() && Declaration == RHS->getRawDeclaration() && RetainedNodes == RHS->getRawRetainedNodes() && + LocalDecls == RHS->getRawLocalDecls() && ThrownTypes == RHS->getRawThrownTypes() && Annotations == RHS->getRawAnnotations() && TargetFuncName == RHS->getRawTargetFuncName(); @@ -824,16 +827,20 @@ Metadata *File; unsigned Line; unsigned Column; + Metadata *LocalDecls; - MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column) - : Scope(Scope), File(File), Line(Line), Column(Column) {} + MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column, + Metadata *LocalDecls) + : Scope(Scope), File(File), Line(Line), Column(Column), + LocalDecls(LocalDecls) {} MDNodeKeyImpl(const DILexicalBlock *N) : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()), - Column(N->getColumn()) {} + Column(N->getColumn()), LocalDecls(N->getRawLocalDecls()) {} bool isKeyOf(const DILexicalBlock *RHS) const { return Scope == RHS->getRawScope() && File == RHS->getRawFile() && - Line == RHS->getLine() && Column == RHS->getColumn(); + Line == RHS->getLine() && Column == RHS->getColumn() && + LocalDecls == RHS->getRawLocalDecls(); } unsigned getHashValue() const { diff --git a/llvm/test/Assembler/disubprogram-localdecls.ll b/llvm/test/Assembler/disubprogram-localdecls.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/disubprogram-localdecls.ll @@ -0,0 +1,78 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s + +; Test localDecls field of DISubprogram and DILexicalBlock. + +; CHECK: = !DIGlobalVariableExpression +; CHECK: = !DIGlobalVariableExpression +; CHECK: [[AGVE:![0-9]+]] = !DIGlobalVariableExpression(var: [[AGV:![0-9]+]] +; CHECK: [[AGV]] = distinct !DIGlobalVariable(name: "A", scope: [[SP:![0-9]+]] +; CHECK: [[SP]] = distinct !DISubprogram(name: "foo" +; CHECK-SAME: localDecls: [[SPDECLS:![0-9]+]]) +; CHECK: [[SPDECLS]] = !{[[AGVE]], [[NIE:![0-9]+]], [[SSTRUCT:![0-9]+]], [[EENUM:![0-9]+]], [[CTYPEDEF:![0-9]+]]} +; CHECK: [[NIE]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[SP]] +; CHECK: [[SSTRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", scope: [[SP]] +; CHECK: [[EENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E", scope: [[SP]] +; CHECK: [[CTYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "C", scope: [[SP]] +; CHECK: [[BGVE:![0-9]+]] = !DIGlobalVariableExpression(var: [[BGV:![0-9]+]] +; CHECK: [[BGV]] = distinct !DIGlobalVariable(name: "B", scope: [[LB:![0-9]+]] +; CHECK: [[LB]] = distinct !DILexicalBlock(scope: [[SP]], +; CHECK-SAME: localDecls: [[LBDECLS:![0-9]+]]) +; CHECK: [[LBDECLS]] = !{[[BGVE]], [[MIE:![0-9]+]], [[ITYPEDEF:![0-9]+]], [[TSTRUCT:![0-9]+]], [[UENUM:![0-9]+]]} +; CHECK: [[MIE]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[LB]] +; CHECK: [[ITYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "I", scope: [[LB]] +; CHECK: [[TSTRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "T", scope: [[LB]] +; CHECK: [[UENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "U", scope: [[LB]] + +%struct.S = type { i8 } +%struct.T = type { i8 } + +@_ZN1n1NE = dso_local global i32 0, align 4, !dbg !0 +@_ZN1m1ME = dso_local global i32 0, align 4, !dbg !5 +@_ZZ3foovE1A = internal global i32 0, align 4, !dbg !8 +@_ZZ3foovE1B = internal global i32 0, align 4, !dbg !25 + +define dso_local void @_Z3foov() !dbg !10 { +entry: + ret void +} + +!llvm.dbg.cu = !{!13} +!llvm.module.flags = !{!35, !36} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "N", linkageName: "_ZN1n1NE", scope: !2, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true) +!2 = !DINamespace(name: "n", scope: null) +!3 = !DIFile(filename: "test.cpp", directory: "/home/kbessonova/workspace/llvm/llvm-project", checksumkind: CSK_MD5, checksum: "ab4cbaa2f798b8d5f15f2d3b1d5d396b") +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "M", linkageName: "_ZN1m1ME", scope: !7, file: !3, line: 6, type: !4, isLocal: false, isDefinition: true) +!7 = !DINamespace(name: "m", scope: null) +!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!9 = distinct !DIGlobalVariable(name: "A", scope: !10, file: !3, line: 10, type: !4, isLocal: true, isDefinition: true) +!10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 9, type: !11, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !13, retainedNodes: !15, localDecls: !16) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 15.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !14, splitDebugInlining: false, nameTableKind: None) +!14 = !{!0, !5} +!15 = !{} +!16 = !{!8, !17, !18, !19, !23} +!17 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !10, entity: !1, file: !3, line: 14) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", scope: !10, file: !3, line: 12, size: 8, flags: DIFlagTypePassByValue, elements: !15) +!19 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E", scope: !10, file: !3, line: 13, baseType: !20, size: 32, elements: !21) +!20 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!21 = !{!22} +!22 = !DIEnumerator(name: "e", value: 0, isUnsigned: true) +!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "C", scope: !10, file: !3, line: 11, baseType: !24) +!24 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression()) +!26 = distinct !DIGlobalVariable(name: "B", scope: !27, file: !3, line: 21, type: !4, isLocal: true, isDefinition: true) +!27 = distinct !DILexicalBlock(scope: !10, file: !3, line: 20, column: 3, localDecls: !28) +!28 = !{!25, !29, !30, !31, !32} +!29 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !27, entity: !6, file: !3, line: 25) +!30 = !DIDerivedType(tag: DW_TAG_typedef, name: "I", scope: !27, file: !3, line: 22, baseType: !4) +!31 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "T", scope: !27, file: !3, line: 23, size: 8, flags: DIFlagTypePassByValue, elements: !15) +!32 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "U", scope: !27, file: !3, line: 24, baseType: !20, size: 32, elements: !33) +!33 = !{!34} +!34 = !DIEnumerator(name: "u", value: 0, isUnsigned: true) +!35 = !{i32 7, !"Dwarf Version", i32 5} +!36 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2282,6 +2282,7 @@ MDTuple *TemplateParams = getTuple(); DISubprogram *Declaration = getSubprogram(); MDTuple *RetainedNodes = getTuple(); + MDTuple *LocalDecls = getTuple(); MDTuple *ThrownTypes = getTuple(); MDTuple *Annotations = getTuple(); StringRef TargetFuncName = "target"; @@ -2295,8 +2296,8 @@ auto *N = DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations, - TargetFuncName); + TemplateParams, Declaration, RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2325,121 +2326,135 @@ Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes, Annotations, TargetFuncName)); + LocalDecls, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes, Annotations, TargetFuncName)); + LocalDecls, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, getSubroutineType(), ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes, - Annotations, TargetFuncName)); + TemplateParams, Declaration, RetainedNodes, LocalDecls, + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes, - Annotations, TargetFuncName)); + TemplateParams, Declaration, RetainedNodes, LocalDecls, + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine + 1, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, getCompositeType(), VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes, - Annotations, TargetFuncName)); + TemplateParams, Declaration, RetainedNodes, LocalDecls, + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex + 1, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations, - TargetFuncName)); + RetainedNodes, LocalDecls, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes, - Annotations, TargetFuncName)); + TemplateParams, Declaration, RetainedNodes, LocalDecls, + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, nullptr, TemplateParams, Declaration, RetainedNodes, - ThrownTypes, Annotations, TargetFuncName)); + LocalDecls, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, getTuple(), - Declaration, RetainedNodes, ThrownTypes, - Annotations, TargetFuncName)); + Declaration, RetainedNodes, LocalDecls, + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, getSubprogram(), RetainedNodes, - ThrownTypes, Annotations, TargetFuncName)); + LocalDecls, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, getTuple(), - ThrownTypes, Annotations, TargetFuncName)); + LocalDecls, ThrownTypes, Annotations, + TargetFuncName)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + getTuple(), ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - getTuple(), Annotations, TargetFuncName)); + LocalDecls, getTuple(), Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes, getTuple(), TargetFuncName)); + LocalDecls, ThrownTypes, getTuple(), + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes, Annotations, "other")); + LocalDecls, ThrownTypes, Annotations, + "other")); TempDISubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));