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

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 20 16:14:50 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Augusto Noronha (augusto2112)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/109490.diff


18 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+5) 
- (modified) clang/include/clang/Basic/Attr.td (+7) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+60) 
- (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (+3) 
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+27) 
- (added) clang/test/CodeGen/attr-debug-transparent-method.cpp (+16) 
- (added) clang/test/CodeGen/attr-debug-transparent-objc.m (+13) 
- (added) clang/test/CodeGen/attr-debug-transparent.c (+10) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (+1) 
- (added) clang/test/Sema/attr-debug-transparent.c (+7) 
- (added) clang/test/SemaCXX/attr-debug-transparent-method.cpp (+11) 
- (added) clang/test/SemaObjC/attr-debug-transparent-objc.m (+9) 
- (modified) llvm/include/llvm/IR/DebugInfoFlags.def (+2-1) 
- (modified) llvm/include/llvm/IR/DebugInfoMetadata.h (+3) 
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (+3) 
- (added) llvm/test/Assembler/disubprogram-debug-transparent.ll (+39) 
- (added) llvm/test/DebugInfo/AArch64/disubprogram-debug-transparent.ll (+42) 
- (modified) llvm/unittests/IR/MetadataTest.cpp (+7) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f4535db7356194..8a154a6563fe71 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -260,6 +260,11 @@ Attribute Changes in Clang
 - Introduced a new attribute ``[[clang::coro_await_elidable_argument]]`` on function parameters
   to propagate safe elide context to arguments if such function is also under a safe elide context.
 
+- 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/Attr.td b/clang/include/clang/Basic/Attr.td
index ce86116680d7a3..d0b885afa55afe 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -876,6 +876,13 @@ def Artificial : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def DebugTransparent: InheritableAttr {
+  let Spellings = [Clang<"debug_transparent">];
+  let Subjects = SubjectList<[Function, ObjCMethod]>;
+  let Documentation = [DebugTransparentDocs];
+  let SimpleHandler = 1;
+}
+
 def XRayInstrument : InheritableAttr {
   let Spellings = [Clang<"xray_always_instrument">,
                    Clang<"xray_never_instrument">];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 8ef151b3f2fddb..2074f16d83643b 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7846,6 +7846,66 @@ As such, this function attribute is currently only supported on X86 targets.
   }];
 }
 
+def DebugTransparentDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+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. This attribute is currently only supported by DWARF.
+
+For example:
+
+.. code-block:: c
+
+  int bar(void) {
+    return 42;
+  }
+
+  __attribute__((debug_transparent))
+  int foo(void) {
+    return bar();
+  }
+
+  int caller(void) {
+    return foo();
+  }
+
+Stepping into ``foo`` should step directly into ``bar`` instead, and stepping out of ``bar`` 
+should stop in ``caller``.
+
+Functions with the ``debug_transparent`` attribute can be chained together:
+
+.. code-block:: c
+
+  int baz(void) {
+    return 42;
+  }
+
+  __attribute__((debug_transparent))
+  int bar(void) {
+    return baz();
+  }
+
+  __attribute__((debug_transparent))
+  int foo(void) {
+    return bar();
+  }
+  
+  int caller(void) {
+    return foo();
+  }
+
+In this example, stepping into ``foo`` should step directly into ``baz``, and stepping out of 
+``baz`` should stop in ``caller``.
+  }];
+}
+
+
 def ReadOnlyPlacementDocs : Documentation {
   let Category = DocCatType;
   let Content = [{This attribute is attached to a structure, class or union declaration.
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index ae709e45a700a1..23c316f5ce6c71 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -467,4 +467,7 @@ 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">,
+  InGroup<OpenMPTargetException>;
 }
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2d2c280941bd64..d510dda07b5559 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -21,6 +21,7 @@
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/Attrs.inc"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
@@ -109,6 +110,21 @@ static bool IsArtificial(VarDecl const *VD) {
                               cast<Decl>(VD->getDeclContext())->isImplicit());
 }
 
+static bool usesDebugTransparent(const Decl *D, const CodeGenModule &CGM) {
+  if (!D)
+    return false;
+
+  if (auto *attr = D->getAttr<DebugTransparentAttr>()) {
+    auto opts = CGM.getCodeGenOpts();
+    if (opts.DwarfVersion == 0) {
+      auto &diags = CGM.getDiags();
+      diags.Report(attr->getLocation(), diag::warn_debug_transparent_ignored);
+    }
+    return true;
+  }
+  return false;
+}
+
 CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
     : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
       DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
@@ -2159,6 +2175,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
     SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
+  if (usesDebugTransparent(Method, CGM))
+    SPFlags |= llvm::DISubprogram::SPFlagIsDebugTransparent;
 
   // In this debug mode, emit type info for a class when its constructor type
   // info is emitted.
@@ -4160,6 +4178,8 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
   if (Stub) {
     Flags |= getCallSiteRelatedAttrs();
     SPFlags |= llvm::DISubprogram::SPFlagDefinition;
+    if (usesDebugTransparent(FD, CGM))
+      SPFlags |= llvm::DISubprogram::SPFlagIsDebugTransparent;
     return DBuilder.createFunction(
         DContext, Name, LinkageName, Unit, Line,
         getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,
@@ -4309,6 +4329,8 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
   if (It == TypeCache.end())
     return nullptr;
   auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
+  if (usesDebugTransparent(D, CGM))
+    SPFlags |= llvm::DISubprogram::SPFlagIsDebugTransparent;
   llvm::DISubprogram *FD = DBuilder.createFunction(
       InterfaceType, getObjCMethodName(OMD), StringRef(),
       InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
@@ -4476,6 +4498,8 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
     SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
+  if (usesDebugTransparent(D, CGM))
+    SPFlags |= llvm::DISubprogram::SPFlagIsDebugTransparent;
 
   llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
   llvm::DISubprogram::DISPFlags SPFlagsForDef =
@@ -4562,6 +4586,9 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
 
   llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
   llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
+  if (usesDebugTransparent(D, CGM))
+    SPFlags |= llvm::DISubprogram::SPFlagIsDebugTransparent;
+
   llvm::DISubprogram *SP = DBuilder.createFunction(
       FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
       SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);
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..330e2a965d710b
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-method.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | 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-objc.m b/clang/test/CodeGen/attr-debug-transparent-objc.m
new file mode 100644
index 00000000000000..a0da871848fb37
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent-objc.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | 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.c b/clang/test/CodeGen/attr-debug-transparent.c
new file mode 100644
index 00000000000000..19b74b0f769a53
--- /dev/null
+++ b/clang/test/CodeGen/attr-debug-transparent.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+
+void bar(void) {}
+
+__attribute__((debug_transparent))
+void foo(void) {
+  bar();
+}
+
+// CHECK: DISubprogram(name: "foo"{{.*}} DISPFlagIsDebugTransparent
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 914f94c08a9fd9..d5e8094ec6fe32 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -68,6 +68,7 @@
 // CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface)
+// CHECK-NEXT: DebugTransparent (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: Destructor (SubjectMatchRule_function)
 // CHECK-NEXT: DiagnoseAsBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: DisableSanitizerInstrumentation (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
diff --git a/clang/test/Sema/attr-debug-transparent.c b/clang/test/Sema/attr-debug-transparent.c
new file mode 100644
index 00000000000000..98b2d4357a99ee
--- /dev/null
+++ b/clang/test/Sema/attr-debug-transparent.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+__attribute__((debug_transparent))
+void correct(void) {}
+
+__attribute__((debug_transparent(1))) // expected-error {{'debug_transparent' attribute takes no arguments}}
+void wrong_arg(void) {}
diff --git a/clang/test/SemaCXX/attr-debug-transparent-method.cpp b/clang/test/SemaCXX/attr-debug-transparent-method.cpp
new file mode 100644
index 00000000000000..b19da619742f4e
--- /dev/null
+++ b/clang/test/SemaCXX/attr-debug-transparent-method.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+
+struct S {
+[[clang::debug_transparent]]
+void correct(void) {}
+
+[[clang::debug_transparent(1)]] // expected-error {{'debug_transparent' attribute takes no arguments}}
+void one_arg(void) {}
+};
+
diff --git a/clang/test/SemaObjC/attr-debug-transparent-objc.m b/clang/test/SemaObjC/attr-debug-transparent-objc.m
new file mode 100644
index 00000000000000..1fbde59ecb9350
--- /dev/null
+++ b/clang/test/SemaObjC/attr-debug-transparent-objc.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+
+
+ at interface ObjCClass
+- (void)correct __attribute__((debug_transparent));
+- (void)one_arg __attribute__((debug_transparent(1))); // expected-error {{'debug_transparent' attribute takes no arguments}}
+ at end
+
diff --git a/llvm/include/llvm/IR/DebugInfoFlags.def b/llvm/include/llvm/IR/DebugInfoFlags.def
index df375b6c68e810..9903580fb95502 100644
--- a/llvm/include/llvm/IR/DebugInfoFlags.def
+++ b/llvm/include/llvm/IR/DebugInfoFlags.def
@@ -91,11 +91,12 @@ HANDLE_DISP_FLAG((1u << 8), MainSubprogram)
 // for defaulted functions
 HANDLE_DISP_FLAG((1u << 9), Deleted)
 HANDLE_DISP_FLAG((1u << 11), ObjCDirect)
+HANDLE_DISP_FLAG((1u << 12), IsDebugTransparent)
 
 #ifdef DISP_FLAG_LARGEST_NEEDED
 // Intended to be used with ADT/BitmaskEnum.h.
 // NOTE: Always must be equal to largest flag, check this when adding new flags.
-HANDLE_DISP_FLAG((1 << 11), Largest)
+HANDLE_DISP_FLAG((1 << 12), Largest)
 #undef DISP_FLAG_LARGEST_NEEDED
 #endif
 
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index d2b4e900438d37..80d0c9e57b23de 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1830,6 +1830,9 @@ class DISubprogram : public DILocalScope {
   bool isElemental() const { return getSPFlags() & SPFlagElemental; }
   bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
   bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
+  bool isDebugTransparent() const {
+    return getSPFlags() & SPFlagIsDebugTransparent;
+  }
 
   /// Check if this is deleted member function.
   ///
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e76b0fe2081c07..d03a59e75bf7e9 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1379,6 +1379,9 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
   if (!SP->getTargetFuncName().empty())
     addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName());
 
+  if (SP->isDebugTransparent())
+    addFlag(SPDie, dwarf::DW_AT_trampoline);
+
   if (DD->getDwarfVersion() >= 5 && SP->isDeleted())
     addFlag(SPDie, dwarf::DW_AT_deleted);
 }
diff --git a/llvm/test/Assembler/disubprogram-debug-transparent.ll b/llvm/test/Assembler/disubprogram-debug-transparent.ll
new file mode 100644
index 00000000000000..316d6d367809cf
--- /dev/null
+++ b/llvm/test/Assembler/disubprogram-debug-transparent.ll
@@ -0,0 +1,39 @@
+; This test verifies that the DISPFlagIsDebugTransparent attribute in a DISubprogram
+; is assembled/disassembled correctly.
+;
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+;
+; CHECK: !DISubprogram(name: "baz",{{.*}} DISPFlagIsDebugTransparent
+;
+; ModuleID = 't.c'
+source_filename = "t.c"
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-macosx13.0.0"
+
+; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
+define void @baz() #0 !dbg !10 {
+entry:
+  ret void, !dbg !14
+}
+
+attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
+!llvm.dbg.cu = !{!7}
+!llvm.ident = !{!9}
+
+!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 2]}
+!1 = !{i32 7, !"Dwarf Version", i32 4}
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !{i32 1, !"wchar_size", i32 4}
+!4 = !{i32 8, !"PIC Level", i32 2}
+!5 = !{i32 7, !"uwtable", i32 1}
+!6 = !{i32 7, !"frame-pointer", i32 1}
+!7 = distinct !DICompileUnit(language: DW_LANG_C11, file: !8, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!8 = !DIFile(filename: "t.c", directory: "/")
+!9 = !{!"clang version 17.0.0"}
+!10 = distinct !DISubprogram(name: "baz", scope: !8, file: !8, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagIsDebugTransparent, unit: !7, retainedNodes: !13)
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!13 = !{}
+!14 = !DILocation(line: 4, column: 1, scope: !10)
diff --git a/llvm/test/DebugInfo/AArch64/disubprogram-debug-transparent.ll b/llvm/test/DebugInfo/AArch64/disubprogram-debug-transparent.ll
new file mode 100644
index 00000000000000..65facbb4a36955
--- /dev/null
+++ b/llvm/test/DebugInfo/AArch64/disubprogram-debug-transparent.ll
@@ -0,0 +1,42 @@
+; This test verifies that the proper DWARF debug info is emitted
+; for a trampoline function with no target.
+;
+; RUN: llc -filetype=obj  %s -o - | llvm-dwarfdump - | FileCheck %s
+;
+; CHECK: DW_TAG_subprogram
+; CHECK:   DW_AT_name	("baz")
+; CHECK:   DW_AT_trampoline  (true)
+;
+; ModuleID = 't.c'
+source_filename = "t.c"
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-macosx13.0.0"
+
+; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
+define void @baz() #0 !dbg !10 {
+entry:
+  ret void, !dbg !14
+}
+
+attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
+!llvm.dbg.cu = !{!7}
+!llvm.ident = !{!9}
+
+!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 2]}
+!1 = !{i32 7, !"Dwarf Version", i32 4}
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !{i32 1, !"wchar_size", i32 4}
+!4 = !{i32 8, !"PIC Level", i32 2}
+!5 = !{i32 7, !"uwtable", i32 1}
+!6 = !{i32 7, !"frame-pointer", i32 1}
+!7 = distinct !DICompileUnit(language: DW_LANG_C11, file: !8, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!8 = !DIFile(filename: "t.c", directory: "/")
+!9 = !{!"clang version 17.0.0"}
+!10 = distinct !DISubprogram(name: "baz", scope: !8, file: !8, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagIsDebugTransparent, unit: !7, retainedNodes: !13)
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!13 = !{}
+!14 = !DILocation(line: 4, column: 1, scope: !10)
+
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 4572ec622ef624..4ccdea7f8dabea 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -2553,6 +2553,7 @@ TEST_F(DISubprogramTest, get) {
   assert(!IsLocalToUnit && IsDefinition && !IsOptimized &&
          "bools and SPFlags have to match");
   SPFlags |= DISubprogram::SPFlagDefinition;
+  SPFlags |= DISubprogram::SPFlagIsDebugTransparent;
 
   auto *N = DISubprogram::get(
       Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine,
@@ -2636,6 +2637,12 @@ TEST_F(DISubprogramTest, get) {
                    Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit,
                    TemplateParams, Declaration, RetainedNodes, ThrownTypes,
                    Annotations, TargetFuncName));
+  EXPECT_NE(N, DISubprogram::get(
+                   Context, Scope, Name, LinkageName, File, Line, Type,
+                   ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
+                   Flags, SPFlags ^ DISubprogram::SPFlagIsDebugTransparent,
+                   Unit, TemplateParams, Declaration, RetainedNodes,
+                   ThrownTypes, Annotations, TargetFuncName));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine + 1, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,

``````````

</details>


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


More information about the cfe-commits mailing list