DebugInfo: Test DW_AT_prototyped and generalize it to handle C11 and C17
authorDavid Blaikie <dblaikie@gmail.com>
Mon, 12 Dec 2022 22:18:45 +0000 (22:18 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Mon, 12 Dec 2022 22:34:49 +0000 (22:34 +0000)
llvm/include/llvm/BinaryFormat/Dwarf.h
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/test/DebugInfo/X86/prototyped.ll [new file with mode: 0644]

index fedf98a..d990485 100644 (file)
@@ -338,6 +338,68 @@ inline bool isFortran(SourceLanguage S) {
   return result;
 }
 
+inline bool isC(SourceLanguage S) {
+  // Deliberately enumerate all the language options so we get a warning when
+  // new language options are added (-Wswitch) that'll hopefully help keep this
+  // switch up-to-date when new C++ versions are added.
+  switch (S) {
+  case DW_LANG_C11:
+  case DW_LANG_C17:
+  case DW_LANG_C89:
+  case DW_LANG_C99:
+  case DW_LANG_C:
+  case DW_LANG_ObjC:
+    return true;
+  case DW_LANG_C_plus_plus:
+  case DW_LANG_C_plus_plus_03:
+  case DW_LANG_C_plus_plus_11:
+  case DW_LANG_C_plus_plus_14:
+  case DW_LANG_C_plus_plus_17:
+  case DW_LANG_C_plus_plus_20:
+  case DW_LANG_Ada83:
+  case DW_LANG_Cobol74:
+  case DW_LANG_Cobol85:
+  case DW_LANG_Fortran77:
+  case DW_LANG_Fortran90:
+  case DW_LANG_Pascal83:
+  case DW_LANG_Modula2:
+  case DW_LANG_Java:
+  case DW_LANG_Ada95:
+  case DW_LANG_Fortran95:
+  case DW_LANG_PLI:
+  case DW_LANG_ObjC_plus_plus:
+  case DW_LANG_UPC:
+  case DW_LANG_D:
+  case DW_LANG_Python:
+  case DW_LANG_OpenCL:
+  case DW_LANG_Go:
+  case DW_LANG_Modula3:
+  case DW_LANG_Haskell:
+  case DW_LANG_OCaml:
+  case DW_LANG_Rust:
+  case DW_LANG_Swift:
+  case DW_LANG_Julia:
+  case DW_LANG_Dylan:
+  case DW_LANG_Fortran03:
+  case DW_LANG_Fortran08:
+  case DW_LANG_RenderScript:
+  case DW_LANG_BLISS:
+  case DW_LANG_Mips_Assembler:
+  case DW_LANG_GOOGLE_RenderScript:
+  case DW_LANG_BORLAND_Delphi:
+  case DW_LANG_lo_user:
+  case DW_LANG_hi_user:
+  case DW_LANG_Kotlin:
+  case DW_LANG_Zig:
+  case DW_LANG_Crystal:
+  case DW_LANG_Fortran18:
+  case DW_LANG_Ada2005:
+  case DW_LANG_Ada2012:
+    return false;
+  }
+  llvm_unreachable("Unknown language kind.");
+}
+
 inline TypeKind getArrayIndexTypeEncoding(SourceLanguage S) {
   return isFortran(S) ? DW_ATE_signed : DW_ATE_unsigned;
 }
index bdb3fd9..aad00c8 100644 (file)
@@ -834,10 +834,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {
 
   // Add prototype flag if we're dealing with a C language and the function has
   // been prototyped.
-  uint16_t Language = getLanguage();
-  if (isPrototyped &&
-      (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
-       Language == dwarf::DW_LANG_ObjC))
+  if (isPrototyped && dwarf::isC((dwarf::SourceLanguage)getLanguage()))
     addFlag(Buffer, dwarf::DW_AT_prototyped);
 
   // Add a DW_AT_calling_convention if this has an explicit convention.
@@ -1263,10 +1260,7 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
 
   // Add the prototype if we have a prototype and we have a C like
   // language.
-  uint16_t Language = getLanguage();
-  if (SP->isPrototyped() &&
-      (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
-       Language == dwarf::DW_LANG_ObjC))
+  if (SP->isPrototyped() && dwarf::isC((dwarf::SourceLanguage)getLanguage()))
     addFlag(SPDie, dwarf::DW_AT_prototyped);
 
   if (SP->isObjCDirect())
diff --git a/llvm/test/DebugInfo/X86/prototyped.ll b/llvm/test/DebugInfo/X86/prototyped.ll
new file mode 100644 (file)
index 0000000..532f5d3
--- /dev/null
@@ -0,0 +1,67 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+
+; RUN: llc -mtriple x86_64-unknown-linux-gnu -O0 -filetype=obj -o %t.o %s
+; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s
+
+; RUN: sed -e "s/LANG_C/LANG_C89/" %s > %t/test.ll
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj -o %t/test.o < %t/test.ll
+; RUN: llvm-dwarfdump -debug-info %t/test.o | FileCheck %s
+
+; RUN: sed -e "s/LANG_C/LANG_C99/" %s > %t/test.ll
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj -o %t/test.o < %t/test.ll
+; RUN: llvm-dwarfdump -debug-info %t/test.o | FileCheck %s
+
+; RUN: sed -e "s/LANG_C/LANG_C11/" %s > %t/test.ll
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj -o %t/test.o < %t/test.ll
+; RUN: llvm-dwarfdump -debug-info %t/test.o | FileCheck %s
+
+; RUN: sed -e "s/LANG_C/LANG_ObjC/" %s > %t/test.ll
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj -o %t/test.o < %t/test.ll
+; RUN: llvm-dwarfdump -debug-info %t/test.o | FileCheck %s
+
+; Generated from this simple example, compiled as C code:
+; void (*x)(void);
+; void y(void) { }
+
+; CHECK: DW_TAG_subroutine_type
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK:   DW_AT_prototyped (true)
+
+; CHECK: DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK:   DW_AT_prototyped (true)
+
+@x = dso_local global ptr null, align 8, !dbg !0
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @y() #0 !dbg !16 {
+entry:
+  ret void, !dbg !18
+}
+
+attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!8, !9, !10, !11, !12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "clang version 16.0.0 (git@github.com:llvm/llvm-project.git 4ffde47ab8c2790c8ee2867eccb9f41c329c9e99)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "test.c", directory: "/usr/local/google/home/blaikie/dev/scratch", checksumkind: CSK_MD5, checksum: "02049edb47c3f3ebb7dfd6ed0658ec6b")
+!4 = !{!0}
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !{i32 7, !"Dwarf Version", i32 5}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !{i32 1, !"wchar_size", i32 4}
+!11 = !{i32 8, !"PIC Level", i32 2}
+!12 = !{i32 7, !"PIE Level", i32 2}
+!13 = !{i32 7, !"uwtable", i32 2}
+!14 = !{i32 7, !"frame-pointer", i32 2}
+!15 = !{!"clang version 16.0.0 (git@github.com:llvm/llvm-project.git 4ffde47ab8c2790c8ee2867eccb9f41c329c9e99)"}
+!16 = distinct !DISubprogram(name: "y", scope: !3, file: !3, line: 2, type: !6, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
+!17 = !{}
+!18 = !DILocation(line: 2, column: 16, scope: !16)