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 @@ -867,7 +867,8 @@ case dwarf::DW_TAG_variant_part: case dwarf::DW_TAG_structure_type: case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_class_type: { + case dwarf::DW_TAG_class_type: + case dwarf::DW_TAG_namelist: { // Emit the discriminator for a variant part. DIDerivedType *Discriminator = nullptr; if (Tag == dwarf::DW_TAG_variant_part) { @@ -936,6 +937,13 @@ DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer); constructTypeDIE(VariantPart, Composite); } + } else if (Tag == dwarf::DW_TAG_namelist) { + auto *Var = dyn_cast(Element); + auto *VarDIE = getDIE(Var); + if (VarDIE) { + DIE &ItemDie = createAndAddDIE(dwarf::DW_TAG_namelist_item, Buffer); + addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE); + } } } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1091,7 +1091,8 @@ N.getTag() == dwarf::DW_TAG_union_type || N.getTag() == dwarf::DW_TAG_enumeration_type || N.getTag() == dwarf::DW_TAG_class_type || - N.getTag() == dwarf::DW_TAG_variant_part, + N.getTag() == dwarf::DW_TAG_variant_part || + N.getTag() == dwarf::DW_TAG_namelist, "invalid tag", &N); AssertDI(isScope(N.getRawScope()), "invalid scope", &N, N.getRawScope()); diff --git a/llvm/test/DebugInfo/X86/namelist1.ll b/llvm/test/DebugInfo/X86/namelist1.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/namelist1.ll @@ -0,0 +1,64 @@ +; Namelist is a fortran feature, this test checks whether DW_TAG_namelist and +; DW_TAG_namelist_item attributes are emitted correctly. +; +; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s +; +; CHECK: [[ITEM1:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_name ("a") +; CHECK: [[ITEM2:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_name ("b") +; CHECK: DW_TAG_namelist +; CHECK: DW_AT_name ("nml") +; CHECK: DW_TAG_namelist_item +; CHECK: DW_AT_namelist_item ([[ITEM1]]) +; CHECK: DW_TAG_namelist_item +; CHECK: DW_AT_namelist_item ([[ITEM2]]) +; +; generated from +; +; program main +; +; integer :: a=1, b +; namelist /nml/ a, b +; +; a = 10 +; b = 20 +; Write(*,nml) +; +; end program main + +source_filename = "namelist.ll" + +define void @MAIN_() !dbg !2 { +L.entry: + %b_350 = alloca i32, align 4 + call void @llvm.dbg.declare(metadata i32* %b_350, metadata !12, metadata !DIExpression()), !dbg !13 + call void @llvm.dbg.value(metadata i32 1, metadata !14, metadata !DIExpression()), !dbg !13 + ret void, !dbg !17 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.module.flags = !{!10, !11} +!llvm.dbg.cu = !{!4} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_plus_uconst, 120)) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !9, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 1, type: !7, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4) +!3 = !DIFile(filename: "namelist.f90", directory: "/dir") +!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None) +!5 = !{} +!6 = !{!0} +!7 = !DISubroutineType(cc: DW_CC_program, types: !8) +!8 = !{null} +!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !DILocalVariable(name: "b", scope: !2, file: !3, line: 3, type: !9) +!13 = !DILocation(line: 0, scope: !2) +!14 = distinct !DILocalVariable(scope: !2, file: !3, line: 2, type: !15, flags: DIFlagArtificial) +!15 = !DICompositeType(tag: DW_TAG_namelist, name: "nml", scope: !2, file: !3, elements: !16) +!16 = !{!1, !12} +!17 = !DILocation(line: 10, column: 1, scope: !2) diff --git a/llvm/test/DebugInfo/X86/namelist2.ll b/llvm/test/DebugInfo/X86/namelist2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/namelist2.ll @@ -0,0 +1,62 @@ +; Namelist is a fortran feature, this test checks whether DW_TAG_namelist and +; DW_TAG_namelist_item attributes are emitted correctly, when declared inside +; a module. +; +; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s +; +; CHECK: [[ITEM1:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_name ("aa") +; CHECK: [[ITEM2:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_name ("bb") +; CHECK: DW_TAG_namelist +; CHECK: DW_AT_name ("nml") +; CHECK: DW_TAG_namelist_item +; CHECK: DW_AT_namelist_item ([[ITEM1]]) +; CHECK: DW_TAG_namelist_item +; CHECK: DW_AT_namelist_item ([[ITEM2]]) +; +; generated from +; +; module mm +; integer :: aa=10, bb=20 +; namelist /nml/ aa, bb +; end module mm +; +; subroutine test() +; use mm +; write(*,nml) +; end subroutine test +; +; Program namelist +; Call test() +; End Program + +source_filename = "namelist2.ll" + +!llvm.module.flags = !{!19, !20} +!llvm.dbg.cu = !{!4} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "aa", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true) +!2 = !DIModule(scope: !4, name: "mm", file: !3, line: 1) +!3 = !DIFile(filename: "namelist2.f90", directory: "/dir") +!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist2.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !14, nameTableKind: None) +!5 = !{} +!6 = !{!0, !7, !10} +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4)) +!8 = distinct !DIGlobalVariable(name: "bb", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true) +!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "nml", scope: !2, file: !3, line: 2, type: !12, isLocal: false, isDefinition: true) +!12 = !DICompositeType(tag: DW_TAG_namelist, name: "nml", file: !3, elements: !13) +!13 = !{!1, !8} +!14 = !{!15} +!15 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !16, entity: !2, file: !3, line: 6) +!16 = distinct !DISubprogram(name: "test", scope: !4, file: !3, line: 6, type: !17, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4) +!17 = !DISubroutineType(types: !18) +!18 = !{null} +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = distinct !DISubprogram(name: "namelist", scope: !4, file: !3, line: 11, type: !22, scopeLine: 11, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4) +!22 = !DISubroutineType(cc: DW_CC_program, types: !18)