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 @@ -772,14 +772,18 @@ /// definitions as they would appear on a command line. /// \param IncludePath The path to the module map file. /// \param APINotesFile The path to an API notes file for this module. - /// \param File Source file of the module declaration. Used for - /// Fortran modules. - /// \param LineNo Source line number of the module declaration. + /// \param File Source file of the module. /// Used for Fortran modules. + /// \param LineNo Source line number of the module. + /// Used for Fortran modules. + /// \param IsDecl This is a module declaration; default to false; + /// when set to true, only Scope and Name are required + /// as this entry is just a hint for the debugger to find + /// the corresponding definition in the global scope. DIModule *createModule(DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, StringRef APINotesFile = {}, DIFile *File = nullptr, - unsigned LineNo = 0); + unsigned LineNo = 0, bool IsDecl = false); /// This creates a descriptor for a lexical block with a new file /// attached. This merely extends the existing 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 @@ -2297,49 +2297,52 @@ friend class LLVMContextImpl; friend class MDNode; unsigned LineNo; + bool IsDecl; DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo, - ArrayRef Ops) + bool IsDecl, ArrayRef Ops) : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops), - LineNo(LineNo) {} + LineNo(LineNo), IsDecl(IsDecl) {} ~DIModule() = default; static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, StringRef APINotesFile, - unsigned LineNo, StorageType Storage, + unsigned LineNo, bool IsDecl, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, ConfigurationMacros), getCanonicalMDString(Context, IncludePath), - getCanonicalMDString(Context, APINotesFile), LineNo, Storage, - ShouldCreate); + getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl, + Storage, ShouldCreate); } static DIModule *getImpl(LLVMContext &Context, Metadata *File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, - MDString *APINotesFile, unsigned LineNo, + MDString *APINotesFile, unsigned LineNo, bool IsDecl, StorageType Storage, bool ShouldCreate = true); TempDIModule cloneImpl() const { return getTemporary(getContext(), getFile(), getScope(), getName(), getConfigurationMacros(), getIncludePath(), - getAPINotesFile(), getLineNo()); + getAPINotesFile(), getLineNo(), getIsDecl()); } public: DEFINE_MDNODE_GET(DIModule, (DIFile * File, DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, - StringRef APINotesFile, unsigned LineNo), + StringRef APINotesFile, unsigned LineNo, + bool IsDecl = false), (File, Scope, Name, ConfigurationMacros, IncludePath, - APINotesFile, LineNo)) + APINotesFile, LineNo, IsDecl)) DEFINE_MDNODE_GET(DIModule, (Metadata * File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, - MDString *APINotesFile, unsigned LineNo), + MDString *APINotesFile, unsigned LineNo, + bool IsDecl = false), (File, Scope, Name, ConfigurationMacros, IncludePath, - APINotesFile, LineNo)) + APINotesFile, LineNo, IsDecl)) TempDIModule clone() const { return cloneImpl(); } @@ -2349,6 +2352,7 @@ StringRef getIncludePath() const { return getStringOperand(4); } StringRef getAPINotesFile() const { return getStringOperand(5); } unsigned getLineNo() const { return LineNo; } + bool getIsDecl() const { return IsDecl; } Metadata *getRawScope() const { return getOperand(1); } MDString *getRawName() const { return getOperandAs(2); } 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 @@ -5119,7 +5119,7 @@ /// parseDIModule: /// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: /// "-DNDEBUG", includePath: "/usr/include", apinotes: "module.apinotes", -/// file: !1, line: 4) +/// file: !1, line: 4, isDecl: false) bool LLParser::parseDIModule(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(scope, MDField, ); \ @@ -5128,13 +5128,14 @@ OPTIONAL(includePath, MDStringField, ); \ OPTIONAL(apinotes, MDStringField, ); \ OPTIONAL(file, MDField, ); \ - OPTIONAL(line, LineField, ); + OPTIONAL(line, LineField, ); \ + OPTIONAL(isDecl, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS Result = GET_OR_DISTINCT(DIModule, (Context, file.Val, scope.Val, name.Val, configMacros.Val, includePath.Val, - apinotes.Val, line.Val)); + apinotes.Val, line.Val, isDecl.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 @@ -1565,19 +1565,20 @@ } case bitc::METADATA_MODULE: { - if (Record.size() < 5 || Record.size() > 8) + if (Record.size() < 5 || Record.size() > 9) return error("Invalid record"); - unsigned Offset = Record.size() >= 7 ? 2 : 1; + unsigned Offset = Record.size() >= 8 ? 2 : 1; IsDistinct = Record[0]; MetadataList.assignValue( GET_OR_DISTINCT( DIModule, - (Context, Record.size() >= 7 ? getMDOrNull(Record[1]) : nullptr, + (Context, Record.size() >= 8 ? getMDOrNull(Record[1]) : nullptr, getMDOrNull(Record[0 + Offset]), getMDString(Record[1 + Offset]), getMDString(Record[2 + Offset]), getMDString(Record[3 + Offset]), getMDString(Record[4 + Offset]), - Record.size() <= 7 ? 0 : Record[7])), + Record.size() <= 7 ? 0 : Record[7], + Record.size() <= 8 ? false : Record[8])), 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 @@ -1868,6 +1868,7 @@ for (auto &I : N->operands()) Record.push_back(VE.getMetadataOrNullID(I)); Record.push_back(N->getLineNo()); + Record.push_back(N->getIsDecl()); Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1067,6 +1067,8 @@ getOrCreateSourceID(M->getFile())); if (M->getLineNo()) addUInt(MDie, dwarf::DW_AT_decl_line, None, M->getLineNo()); + if (M->getIsDecl()) + addFlag(MDie, dwarf::DW_AT_declaration); return &MDie; } 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 @@ -2245,6 +2245,7 @@ Printer.printString("apinotes", N->getAPINotesFile()); Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLineNo()); + Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false); 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 @@ -874,9 +874,10 @@ DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, StringRef APINotesFile, - DIFile *File, unsigned LineNo) { + DIFile *File, unsigned LineNo, bool IsDecl) { return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name, - ConfigurationMacros, IncludePath, APINotesFile, LineNo); + ConfigurationMacros, IncludePath, APINotesFile, LineNo, + IsDecl); } DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope, 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 @@ -926,14 +926,14 @@ Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, MDString *APINotesFile, - unsigned LineNo, StorageType Storage, + unsigned LineNo, bool IsDecl, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros, - IncludePath, APINotesFile, LineNo)); + IncludePath, APINotesFile, LineNo, IsDecl)); Metadata *Ops[] = {File, Scope, Name, ConfigurationMacros, IncludePath, APINotesFile}; - DEFINE_GETIMPL_STORE(DIModule, (LineNo), Ops); + DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops); } DITemplateTypeParameter * 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 @@ -891,25 +891,28 @@ MDString *IncludePath; MDString *APINotesFile; unsigned LineNo; + bool IsDecl; MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, - MDString *APINotesFile, unsigned LineNo) + MDString *APINotesFile, unsigned LineNo, bool IsDecl) : File(File), Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath), - APINotesFile(APINotesFile), LineNo(LineNo) {} + APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {} MDNodeKeyImpl(const DIModule *N) : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()), ConfigurationMacros(N->getRawConfigurationMacros()), IncludePath(N->getRawIncludePath()), - APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()) {} + APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()), + IsDecl(N->getIsDecl()) {} bool isKeyOf(const DIModule *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && ConfigurationMacros == RHS->getRawConfigurationMacros() && IncludePath == RHS->getRawIncludePath() && APINotesFile == RHS->getRawAPINotesFile() && - File == RHS->getRawFile() && LineNo == RHS->getLineNo(); + File == RHS->getRawFile() && LineNo == RHS->getLineNo() && + IsDecl == RHS->getIsDecl(); } unsigned getHashValue() const { diff --git a/llvm/test/Assembler/dimodule.ll b/llvm/test/Assembler/dimodule.ll --- a/llvm/test/Assembler/dimodule.ll +++ b/llvm/test/Assembler/dimodule.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !1, !2, !1, !3} -!named = !{!0, !1, !2, !3, !4} +; CHECK: !named = !{!0, !1, !2, !1, !3, !4} +!named = !{!0, !1, !2, !3, !4, !5} !0 = distinct !{} @@ -16,3 +16,6 @@ ; CHECK: !3 = !DIModule(scope: !0, name: "Module", configMacros: "-DNDEBUG", includePath: "/usr/include", apinotes: "/tmp/m.apinotes", file: !0, line: 1) !4 = !DIModule(scope: !0, name: "Module", configMacros: "-DNDEBUG", includePath: "/usr/include", apinotes: "/tmp/m.apinotes", file: !0, line: 1) + +; CHECK: !4 = !DIModule(scope: !0, name: "Module", isDecl: true) +!5 = !DIModule(scope: !0, name: "Module", isDecl: true) diff --git a/llvm/test/Bitcode/DIModule-fortran-external-module.ll b/llvm/test/Bitcode/DIModule-fortran-external-module.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/DIModule-fortran-external-module.ll @@ -0,0 +1,59 @@ +; RUN: llvm-as -o - %s | llvm-dis -o - | FileCheck %s +; CHECK: DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2) +; CHECK: DIModule(scope: !2, name: "external_module", isDecl: true) + +; ModuleID = 'em.f90' +source_filename = "em.f90" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@external_module_mp_dummy_ = available_externally global float 0.000000e+00, align 8, !dbg !0 +@0 = internal unnamed_addr constant i32 2 + +; Function Attrs: noinline nounwind uwtable +define void @MAIN__() #0 !dbg !2 { +alloca_0: + %"var$1" = alloca [8 x i64], align 8 + %"use_external_module_$X" = alloca float, align 8 + call void @llvm.dbg.declare(metadata float* %"use_external_module_$X", metadata !13, metadata !DIExpression()), !dbg !17 + %func_result = call i32 @for_set_reentrancy(i32* @0), !dbg !18 + %external_module_mp_dummy__fetch = load float, float* @external_module_mp_dummy_, align 1, !dbg !19 + %add = fadd reassoc ninf nsz arcp contract afn float 2.000000e+00, %external_module_mp_dummy__fetch, !dbg !20 + store float %add, float* %"use_external_module_$X", align 1, !dbg !19 + ret void, !dbg !21 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare i32 @for_set_reentrancy(i32*) + +attributes #0 = { noinline nounwind uwtable "intel-lang"="fortran" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.module.flags = !{!15, !16} +!llvm.dbg.cu = !{!6} +!omp_offload.info = !{} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "dummy", linkageName: "external_module_mp_dummy_", scope: !2, file: !3, line: 1, type: !14, isLocal: false, isDefinition: true) +!2 = distinct !DISubprogram(name: "use_external_module", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !12) +!3 = !DIFile(filename: "em.f90", directory: "tests") +!4 = !DISubroutineType(types: !5) +!5 = !{null} +!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, imports: !9, splitDebugInlining: false, nameTableKind: None) +!7 = !{} +!8 = !{!0} +!9 = !{!10} +!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2) +!11 = !DIModule(scope: !2, name: "external_module", isDecl: true) +!12 = !{!13} +!13 = !DILocalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14) +!14 = !DIBasicType(name: "REAL*4", size: 32, encoding: DW_ATE_float) +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !DILocation(line: 5, column: 12, scope: !2) +!18 = !DILocation(line: 1, column: 9, scope: !2) +!19 = !DILocation(line: 6, column: 4, scope: !2) +!20 = !DILocation(line: 6, column: 12, scope: !2) +!21 = !DILocation(line: 8, column: 1, scope: !2) diff --git a/llvm/test/DebugInfo/X86/dimodule.ll b/llvm/test/DebugInfo/X86/dimodule.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dimodule.ll @@ -0,0 +1,91 @@ +; This test verifies that the debug info for an external Fortran module +; is correctly generated. +; +; To generate the test source, compile the following two files in order in +; the same directory (as the second compilation uses the .mod from the first): +; external_module.f90 (to compile: -g -c external_module.f90) +; module external_module +; real :: dummy +; end module external_module +; +; em.f90 (to compile: -g -llvm-emit -c -S em.f90) +; program use_external_module +; use external_module +; implicit none +; +; real :: x +; x = 2.0 + dummy +; +; end program use_external_module +; +; The test would be in em.ll. + +; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s + +; CHECK: [[DIE_ID:0x[0-9a-f]+]]: DW_TAG_module +; CHECK-NEXT: DW_AT_name ("external_module") +; CHECK-NEXT: DW_AT_declaration (true) + +; CHECK: DW_TAG_imported_module +; CHECK-NEXT: DW_AT_decl_file +; CHECK-NEXT: DW_AT_decl_line +; CHECK-NEXT: DW_AT_import ([[DIE_ID]]) + +; When the debugger sees the module being imported is a declaration, +; it should go to the global scope to find the module's definition. + +; ModuleID = 'em.f90' +source_filename = "em.f90" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@external_module_mp_dummy_ = available_externally global float 0.000000e+00, align 8, !dbg !0 +@0 = internal unnamed_addr constant i32 2 + +; Function Attrs: noinline nounwind uwtable +define void @MAIN__() #0 !dbg !2 { +alloca_0: + %"var$1" = alloca [8 x i64], align 8 + %"use_external_module_$X" = alloca float, align 8 + call void @llvm.dbg.declare(metadata float* %"use_external_module_$X", metadata !13, metadata !DIExpression()), !dbg !17 + %func_result = call i32 @for_set_reentrancy(i32* @0), !dbg !18 + %external_module_mp_dummy__fetch = load float, float* @external_module_mp_dummy_, align 1, !dbg !19 + %add = fadd reassoc ninf nsz arcp contract afn float 2.000000e+00, %external_module_mp_dummy__fetch, !dbg !20 + store float %add, float* %"use_external_module_$X", align 1, !dbg !19 + ret void, !dbg !21 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare i32 @for_set_reentrancy(i32*) + +attributes #0 = { noinline nounwind uwtable "intel-lang"="fortran" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.module.flags = !{!15, !16} +!llvm.dbg.cu = !{!6} +!omp_offload.info = !{} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "dummy", linkageName: "external_module_mp_dummy_", scope: !2, file: !3, line: 1, type: !14, isLocal: false, isDefinition: true) +!2 = distinct !DISubprogram(name: "use_external_module", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !12) +!3 = !DIFile(filename: "em.f90", directory: "tests") +!4 = !DISubroutineType(types: !5) +!5 = !{null} +!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, imports: !9, splitDebugInlining: false, nameTableKind: None) +!7 = !{} +!8 = !{!0} +!9 = !{!10} +!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2) +!11 = !DIModule(scope: !2, name: "external_module", isDecl: true) +!12 = !{!13} +!13 = !DILocalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14) +!14 = !DIBasicType(name: "REAL*4", size: 32, encoding: DW_ATE_float) +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !DILocation(line: 5, column: 12, scope: !2) +!18 = !DILocation(line: 1, column: 9, scope: !2) +!19 = !DILocation(line: 6, column: 4, scope: !2) +!20 = !DILocation(line: 6, column: 12, scope: !2) +!21 = !DILocation(line: 8, column: 1, scope: !2) 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 @@ -2459,9 +2459,10 @@ StringRef Includes = "-I."; StringRef APINotes = "/tmp/m.apinotes"; unsigned LineNo = 4; + bool IsDecl = true; auto *N = DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, - APINotes, LineNo); + APINotes, LineNo, IsDecl); EXPECT_EQ(dwarf::DW_TAG_module, N->getTag()); EXPECT_EQ(File, N->getFile()); @@ -2471,22 +2472,25 @@ EXPECT_EQ(Includes, N->getIncludePath()); EXPECT_EQ(APINotes, N->getAPINotesFile()); EXPECT_EQ(LineNo, N->getLineNo()); + EXPECT_EQ(IsDecl, N->getIsDecl()); EXPECT_EQ(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, - APINotes, LineNo)); + APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, getFile(), getFile(), Name, ConfigMacro, - Includes, APINotes, LineNo)); + Includes, APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, File, Scope, "other", ConfigMacro, - Includes, APINotes, LineNo)); + Includes, APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, "other", Includes, - APINotes, LineNo)); + APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, "other", - APINotes, LineNo)); + APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, - "other", LineNo)); + "other", LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, getFile(), Scope, Name, ConfigMacro, - Includes, APINotes, LineNo)); + Includes, APINotes, LineNo, IsDecl)); EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, - APINotes, 5)); + APINotes, 5, IsDecl)); + EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, + APINotes, LineNo, false)); TempDIModule Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));