[llvm] Emit DW_AT_identifier_case for compile units (PR #216197)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 15:05:54 PDT 2026


https://github.com/timsmith78 created https://github.com/llvm/llvm-project/pull/216197

DWARF compile unit tags can contain an attribute that indicates the case sensitivity of symbols in the source language.  This attribute will be useful in supporting Fortran in lldb (issue# 205872)

Co-developed with Claude Opus 4.6

>From 4ce144e92cac2b5daab8ae7a7f0e24f6c9d0bb4e Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Thu, 13 Aug 2026 11:19:57 -0500
Subject: [PATCH] Emit DW_AT_identifier_case for compile units

DWARF compile unit tags can contain an attribute that indicates the case
sensitivity of symbols in the source language.  This attribute will be
useful in supporting Fortran in lldb (issue# 205872)

Co-developed with Claude Opus 4.6
---
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    | 32 +++++++++++++++
 .../Generic/compileunit-identifier-case.ll    | 41 +++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 llvm/test/DebugInfo/Generic/compileunit-identifier-case.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 88e75e3c96106..566cc34476e26 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1094,6 +1094,35 @@ void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const {
   U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
 }
 
+static bool isLangCaseSensitive(const DISourceLanguageName &Lang) {
+  if (!Lang.hasVersionedName()) {
+    switch (Lang.getName()) {
+    case dwarf::DW_LANG_Cobol74:
+    case dwarf::DW_LANG_Cobol85:
+    case dwarf::DW_LANG_Fortran77:
+    case dwarf::DW_LANG_Fortran90:
+    case dwarf::DW_LANG_Fortran95:
+    case dwarf::DW_LANG_Fortran03:
+    case dwarf::DW_LANG_Fortran08:
+    case dwarf::DW_LANG_Fortran18:
+    case dwarf::DW_LANG_Fortran23:
+    case dwarf::DW_LANG_Pascal83:
+      return false;
+    default:
+      return true;
+    }
+  } else {
+    switch (Lang.getName()) {
+    case dwarf::DW_LNAME_Fortran:
+    case dwarf::DW_LNAME_Cobol:
+    case dwarf::DW_LNAME_Pascal:
+      return false;
+    default:
+      return true;
+    }
+  }
+}
+
 void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
                                       DwarfCompileUnit &NewCU) {
   DIE &Die = NewCU.getUnitDie();
@@ -1119,6 +1148,9 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
                   Lang.getName());
   }
 
+  if (!isLangCaseSensitive(DIUnit->getSourceLanguage()))
+    NewCU.addUInt(Die, dwarf::DW_AT_identifier_case, dwarf::DW_FORM_data1,
+                  dwarf::DW_ID_case_insensitive);
   NewCU.addString(Die, dwarf::DW_AT_name, FN);
 
   finishTargetUnitAttributes(*DIUnit, NewCU);
diff --git a/llvm/test/DebugInfo/Generic/compileunit-identifier-case.ll b/llvm/test/DebugInfo/Generic/compileunit-identifier-case.ll
new file mode 100644
index 0000000000000..754e1d759836f
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/compileunit-identifier-case.ll
@@ -0,0 +1,41 @@
+; AIX and zOS don't support DWARF 6 DW_AT_language_name
+; XFAIL: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
+; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s
+
+; Test that DW_AT_identifier_case is emitted for case-insensitive languages
+; (Fortran) and omitted for case-sensitive languages (C++).
+
+; Fortran via old-style language field
+; CHECK:      DW_AT_language (DW_LANG_Fortran90)
+; CHECK-NEXT: DW_AT_identifier_case (DW_ID_case_insensitive)
+
+; C++ via old-style language field — no DW_AT_identifier_case emitted
+; CHECK:      DW_AT_language (DW_LANG_C_plus_plus)
+; CHECK-NOT:  DW_AT_identifier_case
+; CHECK:      DW_AT_name
+
+; Fortran via sourceLanguageName
+; CHECK:      DW_AT_language_name (DW_LNAME_Fortran)
+; CHECK:      DW_AT_identifier_case (DW_ID_case_insensitive)
+
+; C++ via sourceLanguageName — no DW_AT_identifier_case emitted
+; CHECK:      DW_AT_language_name (DW_LNAME_C_plus_plus)
+; CHECK-NOT:  DW_AT_identifier_case
+; CHECK:      DW_AT_name
+
+ at x = global i32 0, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2, !8, !9, !10}
+!llvm.module.flags = !{!6, !7}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!3 = !DIFile(filename: "test.f90", directory: "/tmp")
+!4 = !{!0}
+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!6 = !{i32 7, !"Dwarf Version", i32 5}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!9 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_Fortran, sourceLanguageVersion: 1990, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!10 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 201100, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")



More information about the llvm-commits mailing list