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 @@ -850,7 +850,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) { @@ -919,6 +920,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,144 @@ +; Namelist is a fortran feature, this test checks whether DW_TAG_namelist and +; DW_TAG_namelist_item attributes are emitted correctly. +; +; RUN: llc %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]]) +; +; Sample fortran testcase involving namelist. +; +; program main +; +; integer :: a=1, b +; namelist /nml/ a, b +; +; a = 10 +; b = 20 +; Write(*,nml) +; +; end program main + +source_filename = "namelist.f90" +; ModuleID = 'namelist.f90' +target datalayout = "e-p:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +%struct.STATICS1 = type <{ [8 x i8] , i8* , [16 x i8] , i8* , i8* , [32 x i8] , i8* , [36 x i8] }> +@.STATICS1 = internal global %struct.STATICS1 <{ [8 x i8] [i8 3, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([3 x i8]* @.C366_MAIN_ to i8*), i32 0), [16 x i8] [i8 2, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([1 x i8]* @.C368_MAIN_ to i8*), i32 0), i8* getelementptr(i8, i8* bitcast (%struct.STATICS1* @.STATICS1 to i8*), i32 120), [32 x i8] [i8 25, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([1 x i8]* @.C370_MAIN_ to i8*), i32 0), [36 x i8] [i8 157, i8 255, i8 255, i8 255, i8 255, i8 255, i8 255, i8 255, i8 25, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0] }>, align 16, !dbg !25 +@.C331_MAIN_ = internal constant i64 0 +@.C359_MAIN_ = internal constant i32 6 +@.C356_MAIN_ = internal constant [12 x i8] [i8 110,i8 97,i8 109,i8 101,i8 108,i8 105,i8 115,i8 116,i8 46,i8 102,i8 57,i8 48] +@.C358_MAIN_ = internal constant i32 8 +@.C354_MAIN_ = internal constant i32 20 +@.C353_MAIN_ = internal constant i32 10 +@.C355_MAIN_ = internal constant i32 12 +@.C330_MAIN_ = internal constant i32 0 +@.C370_MAIN_ = internal constant [1 x i8] [i8 98] +@.C368_MAIN_ = internal constant [1 x i8] [i8 97] +@.C366_MAIN_ = internal constant [3 x i8] [i8 110,i8 109,i8 108] +define void @MAIN_() #0 !dbg !15 { +L.entry: + %b_350 = alloca i32, align 4 + %z_i_0_361 = alloca i64, align 8 + %z__io_362 = alloca i32, align 4 + %MAIN___$eq_348 = alloca [16 x i8], align 4 + + %0 = bitcast i32* @.C330_MAIN_ to i8* + %1 = bitcast void (...)* @fort_init to void (i8*, ...)* + call void (i8*, ...) %1 (i8* %0) + br label %L.LB1_377 +L.LB1_377: + call void @llvm.dbg.declare (metadata i32* %b_350, metadata !20, metadata !21), !dbg !16 + %2 = bitcast i32* %b_350 to i8* + %3 = ptrtoint i8* %2 to i64 + %4 = bitcast %struct.STATICS1* @.STATICS1 to i8* + %5 = getelementptr i8, i8* %4, i64 88 + %6 = bitcast i8* %5 to i64* + store i64 %3, i64* %6, align 8 + %7 = bitcast %struct.STATICS1* @.STATICS1 to i8*, !dbg !22 + %8 = getelementptr i8, i8* %7, i64 120, !dbg !22 + %9 = bitcast i8* %8 to i32*, !dbg !22 + store i32 10, i32* %9, align 4, !dbg !22 + store i32 20, i32* %b_350, align 4, !dbg !26 + %10 = bitcast i32* @.C358_MAIN_ to i8*, !dbg !27 + %11 = bitcast [12 x i8]* @.C356_MAIN_ to i8*, !dbg !27 + %12 = bitcast void (...)* @f90io_src_info03a to void (i8*, i8*, i64, ...)*, !dbg !27 + call void (i8*, i8*, i64, ...) %12 (i8* %10, i8* %11, i64 12), !dbg !27 + %13 = bitcast i32* @.C359_MAIN_ to i8*, !dbg !27 + %14 = bitcast i32* @.C330_MAIN_ to i8*, !dbg !27 + call void @llvm.dbg.declare (metadata i64* %z_i_0_361, metadata !29, metadata !21), !dbg !16 + %15 = bitcast i64* %z_i_0_361 to i8*, !dbg !27 + %16 = bitcast i32 (...)* @f90io_nmlw_init_i8 to i32 (i8*, i8*, i8*, i8*, ...)*, !dbg !27 + %17 = call i32 (i8*, i8*, i8*, i8*, ...) %16 (i8* %13, i8* null, i8* %14, i8* %15), !dbg !27 + call void @llvm.dbg.declare (metadata i32* %z__io_362, metadata !30, metadata !21), !dbg !16 + store i32 %17, i32* %z__io_362, align 4, !dbg !27 + %18 = bitcast %struct.STATICS1* @.STATICS1 to i8*, !dbg !27 + %19 = bitcast i32 (...)* @f90io_nmlw_i8 to i32 (i8*, ...)*, !dbg !27 + %20 = call i32 (i8*, ...) %19 (i8* %18), !dbg !27 + store i32 %20, i32* %z__io_362, align 4, !dbg !27 + %21 = call i32 (...) @f90io_nmlw_end_i8 (), !dbg !27 + store i32 %21, i32* %z__io_362, align 4, !dbg !27 + call void @llvm.dbg.value (metadata i32 1, i64 0, metadata !34, metadata !21), !dbg !16 + ret void, !dbg !31 +} +attributes #0 = { "no-frame-pointer-elim-non-leaf" } + +; Named metadata +!llvm.module.flags = !{ !1, !2 } +!llvm.dbg.cu = !{ !11 } + +; Metadata +!1 = !{ i32 2, !"Dwarf Version", i32 4 } +!2 = !{ i32 2, !"Debug Info Version", i32 3 } +!3 = !DIFile(filename: "namelist.f90", directory: "/dir") +; !4 = !DIFile(tag: DW_TAG_file_type, pair: !3) +!4 = !{ i32 41, !3 } +!5 = !{ } +!6 = !{ } +!7 = !{ !15 } +!8 = !{ !25 } +!9 = !{ } +!10 = !{ } +!11 = distinct !DICompileUnit(file: !3, language: DW_LANG_Fortran90, producer: " F90 Flang - 1.5 2017-05-01", flags: "'+flang -g namelist.f90 -o out'", enums: !5, retainedTypes: !6, globals: !8, emissionKind: FullDebug, imports: !9, nameTableKind: None) +!12 = !{ null } +!13 = !DISubroutineType(types: !12, cc: 2) +!14 = !{ } +!15 = distinct !DISubprogram(file: !3, scope: !11, name: "main", line: 1, type: !13, flags: 536870912, spFlags: 264, unit: !11, scopeLine: 1) +!16 = !DILocation(scope: !15) +!17 = distinct !{ } +!18 = !DILocation(line: 1, column: 1, scope: !15) +!19 = !DIBasicType(tag: DW_TAG_base_type, name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!20 = !DILocalVariable(scope: !15, name: "b", file: !3, line: 3, type: !19) +!21 = !DIExpression() +!22 = !DILocation(line: 6, column: 1, scope: !15) +!23 = distinct !DIGlobalVariable(scope: !15, name: "a", file: !3, line: 3, type: !19, isLocal: true, isDefinition: true) +!24 = !DIExpression(DW_OP_plus_uconst, 120) +!25 = !DIGlobalVariableExpression(var: !23, expr: !24) +!26 = !DILocation(line: 7, column: 1, scope: !15) +!27 = !DILocation(line: 8, column: 1, scope: !15) +!28 = !DIBasicType(tag: DW_TAG_base_type, name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed) +!29 = distinct !DILocalVariable(scope: !15, file: !3, line: 8, type: !28, flags: 64) +!30 = distinct !DILocalVariable(scope: !15, file: !3, line: 8, type: !19, flags: 64) +!31 = !DILocation(line: 10, column: 1, scope: !15) +!32 = !{ !23, !20 } +!33 = !DICompositeType(tag: DW_TAG_namelist, file: !3, name: "nml", elements: !32, scope: !15) +!34 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !33, flags: 64) + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) +declare signext i32 @f90io_nmlw_end_i8(...) #0 +declare signext i32 @f90io_nmlw_i8(...) #0 +declare signext i32 @f90io_nmlw_init_i8(...) #0 +declare void @f90io_src_info03a(...) #0 +declare void @llvm.dbg.declare(metadata, metadata, metadata) +declare void @fort_init(...) #0 +declare i32 @__atomic_compare_exchange(i64, i8* noalias, i8* noalias, i8* noalias, i32, i32) #0 +declare i64 @__tgt_fort_ptr_assn_i8(i8* noalias, i8* noalias, i8* noalias, i8* noalias, i8* noalias) #0 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,151 @@ +; 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 %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]]) +; +; Sample fortran testcase involving namelist declared inside a module. +; module mm +; integer :: aa=10, bb=20 +; namelist /nml/ aa, bb +; end module mm +; +; subroutine test() +; use mm, only: nml +; write(*,nml) +; end subroutine test +; +; Program namelist +; Call test() +; End Program + +source_filename = "namelist2.f90" +; ModuleID = 'namelist2.f90' +target datalayout = "e-p:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +define i32 @mm_() noinline { +.L.entry: + ret i32 undef + } +%struct_mm_7_ = type < { [8 x i8] , i8* , [16 x i8] , i8* , i8* , [32 x i8] , i8* , i8* , [24 x i8] } > +@_mm_7_ = global %struct_mm_7_ < { [8 x i8] [i8 3, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([3 x i8]* @.C354_mm_ to i8*), i32 0), [16 x i8] [i8 2, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([2 x i8]* @.C356_mm_ to i8*), i32 0), i8* getelementptr(i8, i8* bitcast (%struct_mm_8_* @_mm_8_ to i8*), i32 0), [32 x i8] [i8 25, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0], i8* getelementptr(i8, i8* bitcast ([2 x i8]* @.C358_mm_ to i8*), i32 0), i8* getelementptr(i8, i8* bitcast (%struct_mm_8_* @_mm_8_ to i8*), i32 4), [24 x i8] [i8 25, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0] } > , align 64 +%struct_mm_8_ = type < { [8 x i8] } > +@_mm_8_ = global %struct_mm_8_ < { [8 x i8] [i8 10, i8 0, i8 0, i8 0, i8 20, i8 0, i8 0, i8 0] } > , align 64, !dbg !16, !dbg !19 +%struct.STATICS1 = type <{ [120 x i8] }> +@.STATICS1 = internal global %struct.STATICS1 <{ [120 x i8] zeroinitializer }>, align 16 +@.C358_mm_ = internal constant [2 x i8] [i8 98,i8 98] +@.C356_mm_ = internal constant [2 x i8] [i8 97,i8 97] +@.C354_mm_ = internal constant [3 x i8] [i8 110,i8 109,i8 108] +@.C330_test_ = internal constant i32 0 +@.C331_test_ = internal constant i64 0 +@.C356_test_ = internal constant i32 6 +@.C357_test_ = internal constant [6 x i8] [i8 97,i8 50,i8 46,i8 102,i8 57,i8 48] +@.C359_test_ = internal constant i32 8 +define void @test_() #0 !dbg !27 { +L.entry: + %z_i_0_361 = alloca i64, align 8 + %z__io_362 = alloca i32, align 4 + + br label %L.LB2_368 +L.LB2_368: + %0 = bitcast i32* @.C359_test_ to i8*, !dbg !31 + %1 = bitcast [6 x i8]* @.C357_test_ to i8*, !dbg !31 + %2 = bitcast void (...)* @f90io_src_info03a to void (i8*, i8*, i64, ...)*, !dbg !31 + call void (i8*, i8*, i64, ...) %2 (i8* %0, i8* %1, i64 6), !dbg !31 + %3 = bitcast i32* @.C356_test_ to i8*, !dbg !31 + %4 = bitcast i32* @.C330_test_ to i8*, !dbg !31 + call void @llvm.dbg.declare (metadata i64* %z_i_0_361, metadata !33, metadata !15), !dbg !29 + %5 = bitcast i64* %z_i_0_361 to i8*, !dbg !31 + %6 = bitcast i32 (...)* @f90io_nmlw_init_i8 to i32 (i8*, i8*, i8*, i8*, ...)*, !dbg !31 + %7 = call i32 (i8*, i8*, i8*, i8*, ...) %6 (i8* %3, i8* null, i8* %4, i8* %5), !dbg !31 + call void @llvm.dbg.declare (metadata i32* %z__io_362, metadata !34, metadata !15), !dbg !29 + store i32 %7, i32* %z__io_362, align 4, !dbg !31 + %8 = bitcast %struct_mm_7_* @_mm_7_ to i8*, !dbg !31 + %9 = bitcast i32 (...)* @f90io_nmlw_i8 to i32 (i8*, ...)*, !dbg !31 + %10 = call i32 (i8*, ...) %9 (i8* %8), !dbg !31 + store i32 %10, i32* %z__io_362, align 4, !dbg !31 + %11 = call i32 (...) @f90io_nmlw_end_i8 (), !dbg !31 + store i32 %11, i32* %z__io_362, align 4, !dbg !31 + ret void, !dbg !35 +} +@.C330_MAIN_ = internal constant i32 0 +define void @MAIN_() #0 !dbg !38 { +L.entry: + + %0 = bitcast i32* @.C330_MAIN_ to i8* + %1 = bitcast void (...)* @fort_init to void (i8*, ...)* + call void (i8*, ...) %1 (i8* %0) + br label %L.LB3_354 +L.LB3_354: + call void @test_ (), !dbg !41 + ret void, !dbg !42 +} +attributes #0 = { "no-frame-pointer-elim-non-leaf" } + +; Named metadata +!llvm.module.flags = !{ !1, !2 } +!llvm.dbg.cu = !{ !11 } + +; Metadata +!1 = !{ i32 2, !"Dwarf Version", i32 4 } +!2 = !{ i32 2, !"Debug Info Version", i32 3 } +!3 = !DIFile(filename: "namelist2.f90", directory: "/dir") +; !4 = !DIFile(tag: DW_TAG_file_type, pair: !3) +!4 = !{ i32 41, !3 } +!5 = !{ } +!6 = !{ } +!7 = !{ !27, !38 } +!8 = !{ !16, !19, !23 } +!9 = !{ !28 } +!10 = !{ } +!11 = distinct !DICompileUnit(file: !3, language: DW_LANG_Fortran90, producer: " F90 Flang - 1.5 2017-05-01", flags: "'+flang -g namelist2.f90 -o out'", enums: !5, retainedTypes: !6, globals: !8, emissionKind: FullDebug, imports: !9, nameTableKind: None) +!12 = !DIModule(scope: !11, name: "mm", file: !3, line: 1) +!13 = !DIBasicType(tag: DW_TAG_base_type, name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!14 = distinct !DIGlobalVariable(scope: !12, name: "aa", file: !3, line: 2, type: !13, isDefinition: true) +!15 = !DIExpression() +!16 = !DIGlobalVariableExpression(var: !14, expr: !15) +!17 = distinct !DIGlobalVariable(scope: !12, name: "bb", file: !3, line: 2, type: !13, isDefinition: true) +!18 = !DIExpression(DW_OP_plus_uconst, 4) +!19 = !DIGlobalVariableExpression(var: !17, expr: !18) +!20 = !{ !14, !17 } +!21 = !DICompositeType(tag: DW_TAG_namelist, file: !3, name: "nml", elements: !20) +!22 = distinct !DIGlobalVariable(scope: !12, name: "nml", file: !3, line: 2, type: !21, isDefinition: true) +!23 = !DIGlobalVariableExpression(var: !22, expr: !15) +!24 = !{ null } +!25 = !DISubroutineType(types: !24) +!26 = !{ } +!27 = distinct !DISubprogram(file: !3, scope: !11, name: "test", line: 6, type: !25, flags: 536870912, spFlags: 8, unit: !11, scopeLine: 6) +!28 = !DIImportedEntity(tag: DW_TAG_imported_module, entity: !12, scope: !27, file: !3, line: 6) +!29 = !DILocation(scope: !27) +!30 = distinct !{ } +!31 = !DILocation(line: 8, column: 1, scope: !27) +!32 = !DIBasicType(tag: DW_TAG_base_type, name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed) +!33 = distinct !DILocalVariable(scope: !27, file: !3, line: 8, type: !32, flags: 64) +!34 = distinct !DILocalVariable(scope: !27, file: !3, line: 8, type: !13, flags: 64) +!35 = !DILocation(line: 9, column: 1, scope: !27) +!36 = !DISubroutineType(types: !24, cc: 2) +!37 = !{ } +!38 = distinct !DISubprogram(file: !3, scope: !11, name: "namelist", line: 10, type: !36, flags: 536870912, spFlags: 264, unit: !11, scopeLine: 10) +!39 = !DILocation(scope: !38) +!40 = !DILocation(line: 10, column: 1, scope: !38) +!41 = !DILocation(line: 11, column: 1, scope: !38) +!42 = !DILocation(line: 12, column: 1, scope: !38) + +declare void @fort_init(...) #0 +declare signext i32 @f90io_nmlw_end_i8(...) #0 +declare signext i32 @f90io_nmlw_i8(...) #0 +declare signext i32 @f90io_nmlw_init_i8(...) #0 +declare void @llvm.dbg.declare(metadata, metadata, metadata) +declare void @f90io_src_info03a(...) #0