[clang] [llvm] [clang] Add "debug_transparent" attribute (PR #109490)

Augusto Noronha via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 26 16:26:46 PDT 2024


https://github.com/augusto2112 updated https://github.com/llvm/llvm-project/pull/109490

>From b7271f2f4a638a5c03cb28b05bb836ca245acb41 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <augusto2112 at me.com>
Date: Thu, 30 Mar 2023 14:01:36 -0700
Subject: [PATCH] [clang] Add "debug_transparent" attribute

The `debug_transparent` attribute is intended as a hint for
debuggers that this function itself is not interesting, but it calls a
function that might be.  So, when stepping in arrives at a function
with this attribute, debuggers should transparently step-in through it
into the functions called by the annotated function (but not by
subsequent calls made by those functions), stopping at the first one its
normal rules for whether to stop says to stop at - or stepping out again
if none qualify. Also, when stepping out arrives at a function with this
attribute, the debugger should continue stepping out to its caller.
---
 clang/docs/ReleaseNotes.rst                      |  4 ++++
 .../include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 .../attr-debug-transparent-method-warning.cpp    | 14 ++++++++++++++
 .../CodeGen/attr-debug-transparent-method.cpp    | 16 ++++++++++++++++
 .../CodeGen/attr-debug-transparent-no-warning.c  | 10 ++++++++++
 .../attr-debug-transparent-objc-warning.m        | 12 ++++++++++++
 clang/test/CodeGen/attr-debug-transparent-objc.m | 13 +++++++++++++
 .../CodeGen/attr-debug-transparent-warning.c     |  9 +++++++++
 clang/test/CodeGen/attr-debug-transparent.c      | 10 ++++++++++
 llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp        |  5 +++++
 10 files changed, 95 insertions(+)
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-method-warning.cpp
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-method.cpp
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-no-warning.c
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-objc-warning.m
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-objc.m
 create mode 100644 clang/test/CodeGen/attr-debug-transparent-warning.c
 create mode 100644 clang/test/CodeGen/attr-debug-transparent.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1fbcac807d0b30..52c6fd27415688 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -293,6 +293,10 @@ Attribute Changes in Clang
 
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. (#GH109442)
+- Introduced a new function attribute ``__attribute__((debug_transparent))``
+  which is intended as a hint to debuggers that they should not stop at the annotated
+  function, but instead step through it when stepping in, and continuing directly to 
+  its caller when stepping out.
 
 Improvements to Clang's diagnostics
 -----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index ae709e45a700a1..e9cb8a9aaadfe2 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -467,4 +467,6 @@ def warn_try_not_valid_on_target : Warning<
   "target '%0' does not support exception handling;"
   " 'catch' block is ignored">,
   InGroup<OpenMPTargetException>;
+def warn_debug_transparent_ignored : Warning<
+  "'debug_transparent' attribute is ignored since it is only supported by DWARF">;
 }
diff --git a/clang/test/CodeGen/attr-debug-transparent-method-warning.cpp b/clang/test/CodeGen/attr-debug-transparent-method-warning.cpp
new file mode 100644
index 00000000000000..71b8617d46bd2c
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-method-warning.cpp
@@ -0,0 +1,14 @@
+// Pipe stderr to FileCheck since we're checking for a warning
+// RUN: %clang -gcodeview -g -emit-llvm -S %s -o - 2>&1 | FileCheck %s
+
+
+struct S {
+[[clang::debug_transparent]] 
+void foo(void) {}
+};
+
+int main() {
+  S s;
+  s.foo();
+}
+// CHECK: warning: 'debug_transparent' attribute is ignored since it is only supported by DWARF
diff --git a/clang/test/CodeGen/attr-debug-transparent-method.cpp b/clang/test/CodeGen/attr-debug-transparent-method.cpp
new file mode 100644
index 00000000000000..300e46535576de
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-method.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang -gdwarf -emit-llvm -S %s -o - | FileCheck %s
+
+void bar(void) {}
+
+struct A {
+[[clang::debug_transparent()]]
+void foo(void) {
+  bar();
+}
+};
+
+int main() {
+  A().foo();
+}
+
+// CHECK: DISubprogram(name: "foo"{{.*}} DISPFlagIsDebugTransparent
diff --git a/clang/test/CodeGen/attr-debug-transparent-no-warning.c b/clang/test/CodeGen/attr-debug-transparent-no-warning.c
new file mode 100644
index 00000000000000..d49f1ce0bb4a82
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-no-warning.c
@@ -0,0 +1,10 @@
+// Pipe stderr to FileCheck since we're checking for a warning
+// RUN: %clang -gcodeview -emit-llvm -S %s -o - 2>&1 | FileCheck %s
+
+
+__attribute__((debug_transparent)) 
+void foo(void) {}
+
+// Check that the warning is NOT printed when compiling without debug information.
+// CHECK-NOT: warning: 'debug_transparent' attribute is ignored since it is only supported by DWARF
+
diff --git a/clang/test/CodeGen/attr-debug-transparent-objc-warning.m b/clang/test/CodeGen/attr-debug-transparent-objc-warning.m
new file mode 100644
index 00000000000000..ff43bd46c5975c
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-objc-warning.m
@@ -0,0 +1,12 @@
+// Pipe stderr to FileCheck since we're checking for a warning
+// RUN: %clang -gcodeview -g -emit-llvm -S %s -o - 2>&1 | FileCheck %s
+
+ at interface ObjCClass
+- (void)foo __attribute__((debug_transparent));
+ at end
+
+ at implementation ObjCClass
+- (void)foo {}
+ at end
+
+// CHECK: warning: 'debug_transparent' attribute is ignored since it is only supported by DWARF
diff --git a/clang/test/CodeGen/attr-debug-transparent-objc.m b/clang/test/CodeGen/attr-debug-transparent-objc.m
new file mode 100644
index 00000000000000..4b1450ff4311c7
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-objc.m
@@ -0,0 +1,13 @@
+// RUN: %clang -gdwarf -emit-llvm -S %s -o - | FileCheck %s
+
+
+ at interface ObjCClass
+- (void)foo __attribute__((debug_transparent));
+ at end
+
+ at implementation ObjCClass
+- (void)foo {}
+ at end
+
+
+// CHECK: DISubprogram(name: "-[ObjCClass foo]"{{.*}} DISPFlagIsDebugTransparent
diff --git a/clang/test/CodeGen/attr-debug-transparent-warning.c b/clang/test/CodeGen/attr-debug-transparent-warning.c
new file mode 100644
index 00000000000000..ef3e931e3bab82
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-warning.c
@@ -0,0 +1,9 @@
+// Pipe stderr to FileCheck since we're checking for a warning
+// RUN: %clang -gcodeview -g -emit-llvm -S %s -o - 2>&1 | FileCheck %s
+
+
+__attribute__((debug_transparent)) 
+void foo(void) {}
+
+// CHECK: warning: 'debug_transparent' attribute is ignored since it is only supported by DWARF
+
diff --git a/clang/test/CodeGen/attr-debug-transparent.c b/clang/test/CodeGen/attr-debug-transparent.c
new file mode 100644
index 00000000000000..03af1366723af7
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent.c
@@ -0,0 +1,10 @@
+// RUN: %clang -gdwarf -emit-llvm -S %s -o - | FileCheck %s
+
+void bar(void) {}
+
+__attribute__((debug_transparent))
+void foo(void) {
+  bar();
+}
+
+// CHECK: DISubprogram(name: "foo"{{.*}} DISPFlagIsDebugTransparent
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e76b0fe2081c07..bde716c862036c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1260,6 +1260,9 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
       (DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP)))
     addLinkageName(SPDie, LinkageName);
 
+  if (SP->isDebugTransparent())
+    addFlag(SPDie, dwarf::DW_AT_trampoline);
+
   if (!DeclDie)
     return false;
 
@@ -1378,6 +1381,8 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
 
   if (!SP->getTargetFuncName().empty())
     addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName());
+  else if (SP->isDebugTransparent())
+    addFlag(SPDie, dwarf::DW_AT_trampoline);
 
   if (DD->getDwarfVersion() >= 5 && SP->isDeleted())
     addFlag(SPDie, dwarf::DW_AT_deleted);



More information about the llvm-commits mailing list