[flang-commits] [flang] 1ba2f49 - [flang][debug] Use lowercase name for the main program. (#217340)
via flang-commits
flang-commits at lists.llvm.org
Thu Aug 20 01:57:42 PDT 2026
Author: Abid Qadeer
Date: 2026-08-20T09:57:38+01:00
New Revision: 1ba2f495294571c385a3ad61e508545bc6b3c568
URL: https://github.com/llvm/llvm-project/commit/1ba2f495294571c385a3ad61e508545bc6b3c568
DIFF: https://github.com/llvm/llvm-project/commit/1ba2f495294571c385a3ad61e508545bc6b3c568.diff
LOG: [flang][debug] Use lowercase name for the main program. (#217340)
Since #149169, the main program symbol name is uppercased in the cooked
character stream so that it cannot clash with any other symbol. That
made DW_AT_name for the main program uppercase, unlike every other
function, which is emitted in lowercase.
Route the main program through fir::getPresentableFunctionName(), which
already undoes this for diagnostics and remarks, so the PROGRAM name is
spelled the same way as all the other names.
Fixes #205868
---------
Co-authored-by: Cursor <cursoragent at cursor.com>
Added:
flang/test/Integration/debug-main-program-name.f90
flang/test/Integration/debug-main-program-unnamed.f90
Modified:
flang/docs/Extensions.md
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
flang/test/Integration/debug-common-block-1.f90
flang/test/Integration/debug-local-var-2.f90
flang/test/Integration/debug-use-stmt-order.f90
flang/test/Integration/debug-use-stmt.f90
flang/test/Transforms/debug-module-use-imports.fir
flang/test/Transforms/debug-use-stmt.fir
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 65ecd21bf71c9..d00397ce2f227 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -176,7 +176,9 @@ end
```
Note that internally the main program symbol name is all uppercase, unlike
the names of all other symbols, which are usually all lowercase. This
- may make a
diff erence in testing/debugging.
+ may make a
diff erence in testing. It is not visible in the debug
+ information, which spells the main program name in lowercase like every
+ other name.
* A `PROCEDURE()` with no interface name or type may be called as an
subroutine with an implicit interface, F'2023 15.4.3.6 paragraph 4 and
C1525 notwithstanding.
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index b9df44a92290b..869dac5dd31df 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -20,6 +20,7 @@
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/Support/InternalNames.h"
+#include "flang/Optimizer/Support/Utils.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Support/Version.h"
#include "mlir/Dialect/DLTI/DLTI.h"
@@ -585,10 +586,12 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
bool isMain = false;
if (funcName == fir::NameUniquer::doProgramEntry()) {
isMain = true;
- mlir::StringAttr bindcName =
- funcOp->getAttrOfType<mlir::StringAttr>(fir::getSymbolAttrName());
- if (bindcName)
- funcName = bindcName;
+ // The main program symbol name is uppercased in the cooked character stream
+ // so that it cannot clash with any other symbol. Go through the presentable
+ // name so that the PROGRAM name is spelled the same way here as every other
+ // name in the debug information.
+ funcName =
+ mlir::StringAttr::get(context, fir::getPresentableFunctionName(funcOp));
}
llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
diff --git a/flang/test/Integration/debug-common-block-1.f90 b/flang/test/Integration/debug-common-block-1.f90
index 926879a7490aa..2a4e6932309fd 100644
--- a/flang/test/Integration/debug-common-block-1.f90
+++ b/flang/test/Integration/debug-common-block-1.f90
@@ -89,7 +89,7 @@ program test
! CHECK-DAG: ![[CBF3]] = !DICommonBlock(scope: ![[F3]], declaration: null, name: "__BLNK__"{{.*}})
! CHECK-DAG: ![[CBAF3]] = !DICommonBlock(scope: ![[F3]], declaration: null, name: "a"{{.*}})
-! CHECK-DAG: ![[MAIN:[0-9]+]] = {{.*}}!DISubprogram(name: "TEST"{{.*}})
+! CHECK-DAG: ![[MAIN:[0-9]+]] = {{.*}}!DISubprogram(name: "test"{{.*}})
! CHECK-DAG: ![[CBM]] = !DICommonBlock(scope: ![[MAIN]], declaration: null, name: "__BLNK__"{{.*}})
! CHECK-DAG: ![[CBAM]] = !DICommonBlock(scope: ![[MAIN]], declaration: null, name: "a"{{.*}})
diff --git a/flang/test/Integration/debug-local-var-2.f90 b/flang/test/Integration/debug-local-var-2.f90
index c2bc2d9a9896d..b595eb2597e94 100644
--- a/flang/test/Integration/debug-local-var-2.f90
+++ b/flang/test/Integration/debug-local-var-2.f90
@@ -37,7 +37,7 @@
! BOTH-LABEL: }
program mn
-! BOTH-DAG: ![[MAIN:.*]] = distinct !DISubprogram(name: "MN", {{.*}})
+! BOTH-DAG: ![[MAIN:.*]] = distinct !DISubprogram(name: "mn", {{.*}})
! BOTH-DAG: ![[TYI32:.*]] = !DIBasicType(name: "integer(kind=4)", size: 32, encoding: DW_ATE_signed)
! BOTH-DAG: ![[TYI64:.*]] = !DIBasicType(name: "integer(kind=8)", size: 64, encoding: DW_ATE_signed)
diff --git a/flang/test/Integration/debug-main-program-name.f90 b/flang/test/Integration/debug-main-program-name.f90
new file mode 100644
index 0000000000000..7b66d8b092c04
--- /dev/null
+++ b/flang/test/Integration/debug-main-program-name.f90
@@ -0,0 +1,17 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+! Test that the main program name is emitted in lowercase, like the name of any
+! other subprogram.
+
+subroutine Example_Function()
+ print *, "in the subroutine"
+end subroutine Example_Function
+
+program Example
+ call Example_Function
+end program Example
+
+! CHECK-DAG: !DISubprogram(name: "example_function", linkageName: "example_function_"
+! CHECK-DAG: !DISubprogram(name: "example", linkageName: "_QQmain"
+
+! CHECK-NOT: !DISubprogram(name: "EXAMPLE"
diff --git a/flang/test/Integration/debug-main-program-unnamed.f90 b/flang/test/Integration/debug-main-program-unnamed.f90
new file mode 100644
index 0000000000000..cfd74e3a854d7
--- /dev/null
+++ b/flang/test/Integration/debug-main-program-unnamed.f90
@@ -0,0 +1,14 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+! Test a main program without a PROGRAM statement. There is no name to spell, so
+! the entry symbol is used as it is.
+
+subroutine Example_Function()
+ print *, "in the subroutine"
+end subroutine Example_Function
+
+call Example_Function
+end
+
+! CHECK-DAG: !DISubprogram(name: "example_function", linkageName: "example_function_"
+! CHECK-DAG: !DISubprogram(name: "_QQmain", linkageName: "_QQmain"{{.*}}DISPFlagMainSubprogram
diff --git a/flang/test/Integration/debug-use-stmt-order.f90 b/flang/test/Integration/debug-use-stmt-order.f90
index 83cb310089a3b..8adb10d32bd7a 100644
--- a/flang/test/Integration/debug-use-stmt-order.f90
+++ b/flang/test/Integration/debug-use-stmt-order.f90
@@ -31,7 +31,7 @@ program test_order
! CHECK-DAG: [[M3:![0-9]+]] = !DIModule(scope: !{{.*}}, name: "m3"
! CHECK-DAG: [[A3:![0-9]+]] = distinct !DIGlobalVariable(name: "a3"
! CHECK-DAG: [[B3:![0-9]+]] = distinct !DIGlobalVariable(name: "b3"
-! CHECK-DAG: [[SP:![0-9]+]] = distinct !DISubprogram(name: "TEST_ORDER"{{.*}}retainedNodes: [[NODES:![0-9]+]]
+! CHECK-DAG: [[SP:![0-9]+]] = distinct !DISubprogram(name: "test_order"{{.*}}retainedNodes: [[NODES:![0-9]+]]
! CHECK: [[NODES]] = !{[[E1:![0-9]+]], [[E2:![0-9]+]], [[E3:![0-9]+]], [[E4:![0-9]+]], [[E5:![0-9]+]]}
! CHECK-NEXT: [[E1]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[SP]], entity: [[A1]],
diff --git a/flang/test/Integration/debug-use-stmt.f90 b/flang/test/Integration/debug-use-stmt.f90
index 50a70da3941f8..d55c381deadf0 100644
--- a/flang/test/Integration/debug-use-stmt.f90
+++ b/flang/test/Integration/debug-use-stmt.f90
@@ -24,7 +24,7 @@ program test_use
! CHECK-DAG: [[VAR_C:![0-9]+]] = distinct !DIGlobalVariable(name: "var_c", linkageName: "_QMtestmodEvar_c"
! CHECK-DAG: [[VAR_Y:![0-9]+]] = distinct !DIGlobalVariable(name: "var_y", linkageName: "_QMtestmod2Evar_y"
-! CHECK-DAG: [[SP:![0-9]+]] = distinct !DISubprogram(name: "TEST_USE", linkageName: "_QQmain"{{.*}}retainedNodes:
+! CHECK-DAG: [[SP:![0-9]+]] = distinct !DISubprogram(name: "test_use", linkageName: "_QQmain"{{.*}}retainedNodes:
! Check that the full testmod module is not imported
! CHECK-NOT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[SP]], entity: [[TESTMOD]]
diff --git a/flang/test/Transforms/debug-module-use-imports.fir b/flang/test/Transforms/debug-module-use-imports.fir
index e3127c888e806..8f0d6090a96c3 100644
--- a/flang/test/Transforms/debug-module-use-imports.fir
+++ b/flang/test/Transforms/debug-module-use-imports.fir
@@ -25,7 +25,7 @@ module {
// CHECK-DAG: #[[MOD_CHILD:.+]] = #llvm.di_module<{{.*}}name = "child"{{.*}}>
// CHECK-DAG: #[[MOD_PARENT:.+]] = #llvm.di_module<{{.*}}name = "parent"{{.*}}>
-// CHECK-DAG: #[[SP_REC:.+]] = #llvm.di_subprogram<recId = distinct[[[RECID:[0-9]+]]]<>, isRecSelf = true{{.*}}name = "MAIN_USE"
+// CHECK-DAG: #[[SP_REC:.+]] = #llvm.di_subprogram<recId = distinct[[[RECID:[0-9]+]]]<>, isRecSelf = true{{.*}}name = "main_use"
// CHECK-DAG: #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #[[SP_REC]], entity = #[[MOD_CHILD]],{{.*}}>
// CHECK-DAG: #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #[[SP_REC]], entity = #[[MOD_PARENT]],{{.*}}>
-// CHECK-DAG: #llvm.di_subprogram<recId = distinct[[[RECID]]]<>{{.*}}name = "MAIN_USE"{{.*}}retainedNodes = {{.+}}>
+// CHECK-DAG: #llvm.di_subprogram<recId = distinct[[[RECID]]]<>{{.*}}name = "main_use"{{.*}}retainedNodes = {{.+}}>
diff --git a/flang/test/Transforms/debug-use-stmt.fir b/flang/test/Transforms/debug-use-stmt.fir
index c1db92af072f4..5f0b32265254d 100644
--- a/flang/test/Transforms/debug-use-stmt.fir
+++ b/flang/test/Transforms/debug-use-stmt.fir
@@ -50,7 +50,7 @@ module {
// CHECK-DAG: #[[GVAR_Y:.+]] = #llvm.di_global_variable<scope = #[[MOD_TESTMOD2]], name = "var_y", linkageName = "_QMtestmod2Evar_y"
// DISubprogram placeholder (for recursive reference)
-// CHECK-DAG: #[[SP_REC:.+]] = #llvm.di_subprogram<recId = distinct[[[RECID:[0-9]+]]]<>, isRecSelf = true{{.*}}name = "TEST_USE"
+// CHECK-DAG: #[[SP_REC:.+]] = #llvm.di_subprogram<recId = distinct[[[RECID:[0-9]+]]]<>, isRecSelf = true{{.*}}name = "test_use"
// 1. Imported declaration without rename (var_b) - has entity but NO name attribute
// CHECK-DAG: #llvm.di_imported_entity<tag = DW_TAG_imported_declaration, scope = #[[SP_REC]], entity = #[[GVAR_B]],{{.*}}>
@@ -66,4 +66,4 @@ module {
// Verify final DISubprogram has retainedNodes (non-empty)
// We don't check the exact order since retainedNodes comes from an unordered collection
-// CHECK-DAG: #llvm.di_subprogram<recId = distinct[[[RECID]]]<>{{.*}}name = "TEST_USE"{{.*}}retainedNodes = {{.+}}>
+// CHECK-DAG: #llvm.di_subprogram<recId = distinct[[[RECID]]]<>{{.*}}name = "test_use"{{.*}}retainedNodes = {{.+}}>
More information about the flang-commits
mailing list