Author: yonghong-song
Date: 2026-06-15T10:51:02-07:00
New Revision: 5754a48780f516cbc06eeb2a31b1e445ddd9c935

URL: 
https://github.com/llvm/llvm-project/commit/5754a48780f516cbc06eeb2a31b1e445ddd9c935
DIFF: 
https://github.com/llvm/llvm-project/commit/5754a48780f516cbc06eeb2a31b1e445ddd9c935.diff

LOG: [Clang][BPF] Support btf_type_tag on typedef underlying types (#203089)

Emil Tsalapatis suggested to add type tag for typedef like below:
```
  $ cat tag.c
  #define __type_tag(x) __attribute__((btf_type_tag(x)))

  struct bar { int c; int d; };
  typedef struct bar __type_tag("a") bar_t;
  int use(bar_t *v)
  {
    return v->c + v->d;
  }
```
This makes the code simpler -- using `bar_t *v` instead of the longer
form `struct bar __type_tag("a") *v`.

So the goal is to allow type tag for typedef underlying types. The
following describes the main changes:

- CGDebugInfo: factor the btf_type_tag walk out of CreatePointerLikeType
into a new CollectBTFTypeTagAnnotations() helper, and use it when
emitting a typedef's DIDerivedType so the typedef carries both its
btf_decl_tag annotations (on the declaration) and the btf_type_tag
annotations (on the underlying type).

- BPF BTFDebug: emit type tags for DW_TAG_typedef the same way they are
emitted for DW_TAG_pointer_type, building the intermediate
BTF_KIND_TYPE_TAG chain. The BTFTypeDerived constructor now selects
BTF_KIND_PTR or BTF_KIND_TYPEDEF based on the DWARF tag.

Added: 
    clang/test/DebugInfo/Generic/attr-btf_type_tag-typedef-no-ptr.c
    llvm/test/CodeGen/BPF/BTF/type-tag-typedef-noptr.ll

Modified: 
    clang/include/clang/Basic/AttrDocs.td
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/CodeGen/CGDebugInfo.h
    llvm/lib/Target/BPF/BTFDebug.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 59d4b7ef63d9e..04362de2d5be2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3042,8 +3042,35 @@ def BTFTypeTagDocs : Documentation {
   let Category = DocCatType;
   let Content = [{
 Clang supports the ``__attribute__((btf_type_tag("ARGUMENT")))`` attribute for
-all targets. It only has effect when ``-g`` is specified on the command line 
and
-is currently silently ignored when not applied to a pointer type (note: this
+all targets. It only has effect when ``-g`` is specified on the command line.
+
+The attribute can be applied to a pointer type, in which case the tag is
+associated with the pointee type, e.g.:
+
+.. code-block:: c
+
+  int __attribute__((btf_type_tag("tag"))) *p;
+
+It can also be applied to the underlying type of a typedef, in which case the
+tag follows the typedef down to its base type, e.g.:
+
+.. code-block:: c
+
+  typedef struct foo __attribute__((btf_type_tag("tag"))) foo_t;
+
+The following is the corresponding btf:
+
+.. code-block::
+
+  ...
+  [2] TYPE_TAG 'tag' type_id=4
+  [3] TYPEDEF 'foo_t' type_id=2
+  [4] STRUCT 'foo' size=4 vlen=1
+      'c' type_id=5 bits_offset=0
+  [5] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+  ...
+
+The attribute is currently silently ignored in any other position (note: this
 scenario may be diagnosed in the future).
 
 The ``ARGUMENT`` string will be preserved in IR and emitted to DWARF for the

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3d429d0d78e82..7421733efcc24 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1531,36 +1531,21 @@ llvm::DIType 
*CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
       CGM.getTarget().getDWARFAddressSpace(
           CGM.getTypes().getTargetAddressSpace(PointeeTy));
 
-  const BTFTagAttributedType *BTFAttrTy;
-  if (auto *Atomic = PointeeTy->getAs<AtomicType>())
-    BTFAttrTy = dyn_cast<BTFTagAttributedType>(Atomic->getValueType());
-  else
-    BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
-  SmallVector<llvm::Metadata *, 4> Annots;
-  while (BTFAttrTy) {
-    StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
-    if (!Tag.empty()) {
-      llvm::Metadata *Ops[2] = {
-          llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")),
-          llvm::MDString::get(CGM.getLLVMContext(), Tag)};
-      Annots.insert(Annots.begin(),
-                    llvm::MDNode::get(CGM.getLLVMContext(), Ops));
-    }
-    BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
-  }
-
-  llvm::DINodeArray Annotations = nullptr;
-  if (Annots.size() > 0)
-    Annotations = DBuilder.getOrCreateArray(Annots);
-
   if (Tag == llvm::dwarf::DW_TAG_reference_type ||
-      Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
+      Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) {
     return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
                                         Size, Align, DWARFAddressSpace);
-  else
+  } else {
+    SmallVector<llvm::Metadata *, 4> Annots;
+    CollectBTFTypeTagAnnotations(PointeeTy, Annots);
+
+    llvm::DINodeArray Annotations = nullptr;
+    if (Annots.size() > 0)
+      Annotations = DBuilder.getOrCreateArray(Annots);
     return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
                                       Align, DWARFAddressSpace, StringRef(),
                                       Annotations);
+  }
 }
 
 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -1780,8 +1765,17 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType 
*Ty,
   SourceLocation Loc = Ty->getDecl()->getLocation();
 
   uint32_t Align = getDeclAlignIfRequired(Ty->getDecl(), CGM.getContext());
-  // Typedefs are derived from some other type.
-  llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->getDecl());
+
+  // Typedefs are derived from some other type. Collect both btf_decl_tag
+  // annotations on the typedef declaration and btf_type_tag annotations on
+  // the (possibly non-pointer) underlying type, e.g.
+  //   typedef struct foo __attribute__((btf_type_tag("tag"))) foo_t;
+  SmallVector<llvm::Metadata *, 4> Annots;
+  llvm::DINodeArray Annotations;
+  CollectBTFTypeTagAnnotations(Ty->getDecl()->getUnderlyingType(), Annots);
+  CollectBTFDeclTagAnnotations(Ty->getDecl(), Annots);
+  if (!Annots.empty())
+    Annotations = DBuilder.getOrCreateArray(Annots);
 
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   const DeclContext *DC = Ty->getDecl()->getDeclContext();
@@ -2844,20 +2838,46 @@ llvm::DINodeArray 
CGDebugInfo::CollectCXXTemplateParams(const RecordDecl *RD,
   return CollectTemplateParams(GetTemplateArgs(RD), Unit);
 }
 
-llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(const Decl *D) {
-  if (!D->hasAttr<BTFDeclTagAttr>())
-    return nullptr;
-
-  SmallVector<llvm::Metadata *, 4> Annotations;
+void CGDebugInfo::CollectBTFDeclTagAnnotations(
+    const Decl *D, SmallVectorImpl<llvm::Metadata *> &Annotations) {
   for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
     llvm::Metadata *Ops[2] = {
         llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_decl_tag")),
         llvm::MDString::get(CGM.getLLVMContext(), I->getBTFDeclTag())};
     Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
   }
+}
+
+llvm::DINodeArray CGDebugInfo::CollectBTFDeclTagAnnotations(const Decl *D) {
+  if (!D->hasAttr<BTFDeclTagAttr>())
+    return nullptr;
+
+  SmallVector<llvm::Metadata *, 4> Annotations;
+  CollectBTFDeclTagAnnotations(D, Annotations);
   return DBuilder.getOrCreateArray(Annotations);
 }
 
+void CGDebugInfo::CollectBTFTypeTagAnnotations(
+    QualType Ty, SmallVectorImpl<llvm::Metadata *> &Annotations) {
+  const BTFTagAttributedType *BTFAttrTy;
+  if (auto *Atomic = Ty->getAs<AtomicType>())
+    BTFAttrTy = dyn_cast<BTFTagAttributedType>(Atomic->getValueType());
+  else
+    BTFAttrTy = dyn_cast<BTFTagAttributedType>(Ty);
+
+  while (BTFAttrTy) {
+    StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag();
+    if (!Tag.empty()) {
+      llvm::Metadata *Ops[2] = {
+          llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")),
+          llvm::MDString::get(CGM.getLLVMContext(), Tag)};
+      Annotations.insert(Annotations.begin(),
+                         llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+    }
+    BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType());
+  }
+}
+
 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
   if (VTablePtrType)
     return VTablePtrType;

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 4c385c26efc4e..a818d6471ff3e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -349,6 +349,18 @@ class CGDebugInfo {
   /// A helper function to collect debug info for btf_decl_tag annotations.
   llvm::DINodeArray CollectBTFDeclTagAnnotations(const Decl *D);
 
+  /// A helper function to collect debug info for btf_decl_tag annotations and
+  /// append them to Annotations.
+  void
+  CollectBTFDeclTagAnnotations(const Decl *D,
+                               SmallVectorImpl<llvm::Metadata *> &Annotations);
+
+  /// A helper function to collect debug info for btf_type_tag annotations and
+  /// append them to Annotations.
+  void
+  CollectBTFTypeTagAnnotations(QualType Ty,
+                               SmallVectorImpl<llvm::Metadata *> &Annotations);
+
   llvm::DIType *createFieldType(StringRef name, QualType type,
                                 SourceLocation loc, AccessSpecifier AS,
                                 uint64_t offsetInBits, uint32_t AlignInBits,

diff  --git a/clang/test/DebugInfo/Generic/attr-btf_type_tag-typedef-no-ptr.c 
b/clang/test/DebugInfo/Generic/attr-btf_type_tag-typedef-no-ptr.c
new file mode 100644
index 0000000000000..52616ae2e5de5
--- /dev/null
+++ b/clang/test/DebugInfo/Generic/attr-btf_type_tag-typedef-no-ptr.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -DDOUBLE_BRACKET_ATTRS=1 
-debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+
+#if DOUBLE_BRACKET_ATTRS
+#define __tag1 [[clang::btf_type_tag("tag1")]]
+#define __tag2 [[clang::btf_type_tag("tag2")]]
+#else
+#define __tag1 __attribute__((btf_type_tag("tag1")))
+#define __tag2 __attribute__((btf_type_tag("tag2")))
+#endif
+
+struct bar {
+  int c;
+};
+typedef struct bar __tag1 __tag2 bar_t1;
+typedef const struct bar __tag1 __tag2 bar_t2;
+typedef volatile struct bar __tag1 __tag2 bar_t3;
+typedef volatile struct bar * __tag1 __tag2 bar_t4;
+
+typedef const int __tag1 __tag2 int_v;
+
+int use(bar_t1 *v1, bar_t2 *v2, bar_t3 *v3, bar_t4 v4, int_v v5)
+{
+  return v1->c + v2->c + v3->c + v4->c + v5;
+}
+
+// CHECK: ![[L4:[0-9]+]] = !DIBasicType(name: "int", size: 32, encoding: 
DW_ATE_signed)
+// CHECK: ![[L10:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: 
"bar_t1", file: ![[#]], line: [[#]], baseType: ![[L11:[0-9]+]], annotations: 
![[L14:[0-9]+]])
+// CHECK: ![[L11]] = distinct !DICompositeType(tag: DW_TAG_structure_type, 
name: "bar", file: ![[#]], line: [[#]], size: [[#]], elements: ![[#]])
+// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L16:[0-9]+]]}
+// CHECK: ![[L15]] = !{!"btf_type_tag", !"tag1"}
+// CHECK: ![[L16]] = !{!"btf_type_tag", !"tag2"}
+// CHECK: ![[L18:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: 
"bar_t2", file: ![[#]], line: [[#]], baseType: ![[L19:[0-9]+]], annotations: 
![[L14]])
+// CHECK: ![[L19]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L11]])
+// CHECK: ![[L21:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: 
"bar_t3", file: ![[#]], line: [[#]], baseType: ![[L22:[0-9]+]], annotations: 
![[L14]])
+// CHECK: ![[L22]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: 
![[L11]])
+// CHECK: ![[L23:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: 
"bar_t4", file: ![[#]], line: [[#]], baseType: ![[L24:[0-9]+]], annotations: 
![[L14]])
+// CHECK: ![[L24]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: 
![[L22]], size: [[#]])
+// CHECK: ![[L25:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "int_v", 
file: ![[#]], line: [[#]], baseType: ![[L26:[0-9]+]], annotations: ![[L14]])
+// CHECK: ![[L26]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L4]])

diff  --git a/llvm/lib/Target/BPF/BTFDebug.cpp 
b/llvm/lib/Target/BPF/BTFDebug.cpp
index 1b7a1cbc561b0..3a9d461bc5b93 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -284,11 +284,21 @@ BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, 
unsigned Tag,
   BTFType.Info = Kind << 24;
 }
 
-/// Used by DW_TAG_pointer_type only.
+/// Used by DW_TAG_pointer_type and DW_TAG_typedef only.
 BTFTypeDerived::BTFTypeDerived(unsigned NextTypeId, unsigned Tag,
                                StringRef Name)
     : DTy(nullptr), NeedsFixup(false), Name(Name) {
-  Kind = BTF::BTF_KIND_PTR;
+  switch (Tag) {
+  case dwarf::DW_TAG_pointer_type:
+    Kind = BTF::BTF_KIND_PTR;
+    break;
+  case dwarf::DW_TAG_typedef:
+    Kind = BTF::BTF_KIND_TYPEDEF;
+    break;
+  default:
+    llvm_unreachable("Tag must be pointer or typedef");
+  }
+
   BTFType.Info = Kind << 24;
   BTFType.Type = NextTypeId;
 }
@@ -1167,7 +1177,7 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, 
uint32_t &TypeId,
     }
   }
 
-  if (Tag == dwarf::DW_TAG_pointer_type) {
+  if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef) {
     int TmpTypeId = genBTFTypeTags(DTy, -1);
     if (TmpTypeId >= 0) {
       auto TypeDEntry =
@@ -1177,13 +1187,13 @@ void BTFDebug::visitDerivedType(const DIDerivedType 
*DTy, uint32_t &TypeId,
       auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
       TypeId = addType(std::move(TypeEntry), DTy);
     }
-  } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type ||
+    if (Tag == dwarf::DW_TAG_typedef)
+      processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);
+  } else if (Tag == dwarf::DW_TAG_const_type ||
              Tag == dwarf::DW_TAG_volatile_type ||
              Tag == dwarf::DW_TAG_restrict_type) {
     auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
     TypeId = addType(std::move(TypeEntry), DTy);
-    if (Tag == dwarf::DW_TAG_typedef)
-      processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);
   } else if (Tag != dwarf::DW_TAG_member) {
     return;
   }

diff  --git a/llvm/test/CodeGen/BPF/BTF/type-tag-typedef-noptr.ll 
b/llvm/test/CodeGen/BPF/BTF/type-tag-typedef-noptr.ll
new file mode 100644
index 0000000000000..fc4a965f2ee70
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/type-tag-typedef-noptr.ll
@@ -0,0 +1,137 @@
+; RUN: llc -mtriple=bpfel -filetype=obj -o %t1 %s
+; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
+; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
+; RUN: llc -mtriple=bpfeb -filetype=obj -o %t1 %s
+; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
+; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
+;
+; Source:
+;  #define __tag1 __attribute__((btf_type_tag("tag1")))
+;  #define __tag2 __attribute__((btf_type_tag("tag2")))
+;
+;  struct bar {
+;    int c;
+;  };
+;  typedef struct bar __tag1 __tag2 bar_t1;
+;  typedef const struct bar __tag1 __tag2 bar_t2;
+;  typedef volatile struct bar __tag1 __tag2 bar_t3;
+;  typedef volatile struct bar * __tag1 __tag2 bar_t4;
+;
+;  typedef const int __tag1 __tag2 int_v;
+;
+;  int use(bar_t1 *v1, bar_t2 *v2, bar_t3 *v3, bar_t4 v4, int_v v5)
+;  {
+;    return v1->c + v2->c + v3->c + v4.c + v5;
+;  }
+; Compilation flag:
+;  clang -target bpf -O2 -g -S -emit-llvm t.c
+
+; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite, 
inaccessiblemem: readwrite)
+define dso_local i32 @use(ptr nofree noundef readonly captures(none) %0, ptr 
nofree noundef readonly captures(none) %1, ptr nofree noundef captures(address) 
%2, ptr nofree noundef captures(address) %3, i32 noundef %4) local_unnamed_addr 
#0 !dbg !11 {
+    #dbg_value(ptr %0, !34, !DIExpression(), !39)
+    #dbg_value(ptr %1, !35, !DIExpression(), !39)
+    #dbg_value(ptr %2, !36, !DIExpression(), !39)
+    #dbg_value(ptr %3, !37, !DIExpression(), !39)
+    #dbg_value(i32 %4, !38, !DIExpression(), !39)
+  %6 = load i32, ptr %0, align 4, !dbg !40, !tbaa !41
+  %7 = load i32, ptr %1, align 4, !dbg !43, !tbaa !41
+  %8 = load volatile i32, ptr %2, align 4, !dbg !44, !tbaa !41
+  %9 = load volatile i32, ptr %3, align 4, !dbg !45, !tbaa !41
+  %10 = add i32 %6, %4, !dbg !46
+  %11 = add i32 %10, %7, !dbg !47
+  %12 = add i32 %11, %8, !dbg !48
+  %13 = add i32 %12, %9, !dbg !49
+  ret i32 %13, !dbg !50
+}
+
+; CHECK-BTF: [1] PTR '(anon)' type_id=4
+; CHECK-BTF: [2] TYPE_TAG 'tag1' type_id=5
+; CHECK-BTF: [3] TYPE_TAG 'tag2' type_id=2
+; CHECK-BTF: [4] TYPEDEF 'bar_t1' type_id=3
+; CHECK-BTF: [5] STRUCT 'bar' size=4 vlen=1
+; CHECK-BTF:   'c' type_id=6 bits_offset=0
+; CHECK-BTF: [6] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+; CHECK-BTF: [7] PTR '(anon)' type_id=10
+; CHECK-BTF: [8] TYPE_TAG 'tag1' type_id=11
+; CHECK-BTF: [9] TYPE_TAG 'tag2' type_id=8
+; CHECK-BTF: [10] TYPEDEF 'bar_t2' type_id=9
+; CHECK-BTF: [11] CONST '(anon)' type_id=5
+; CHECK-BTF: [12] PTR '(anon)' type_id=15
+; CHECK-BTF: [13] TYPE_TAG 'tag1' type_id=16
+; CHECK-BTF: [14] TYPE_TAG 'tag2' type_id=13
+; CHECK-BTF: [15] TYPEDEF 'bar_t3' type_id=14
+; CHECK-BTF: [16] VOLATILE '(anon)' type_id=5
+; CHECK-BTF: [17] TYPE_TAG 'tag1' type_id=20
+; CHECK-BTF: [18] TYPE_TAG 'tag2' type_id=17
+; CHECK-BTF: [19] TYPEDEF 'bar_t4' type_id=18
+; CHECK-BTF: [20] PTR '(anon)' type_id=16
+; CHECK-BTF: [21] TYPE_TAG 'tag1' type_id=24
+; CHECK-BTF: [22] TYPE_TAG 'tag2' type_id=21
+; CHECK-BTF: [23] TYPEDEF 'int_v' type_id=22
+; CHECK-BTF: [24] CONST '(anon)' type_id=6
+; CHECK-BTF: [25] FUNC_PROTO '(anon)' ret_type_id=6 vlen=5
+; CHECK-BTF:   'v1' type_id=1
+; CHECK-BTF:   'v2' type_id=7
+; CHECK-BTF:   'v3' type_id=12
+; CHECK-BTF:   'v4' type_id=19
+; CHECK-BTF:   'v5' type_id=23
+; CHECK-BTF: [26] FUNC 'use' type_id=25 linkage=global
+
+attributes #0 = { nofree norecurse nosync nounwind memory(argmem: readwrite, 
inaccessiblemem: readwrite) "frame-pointer"="all" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!llvm.ident = !{!6}
+!llvm.errno.tbaa = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang 
version 23.0.0git ([email protected]:yonghong-song/llvm-project.git 
19865cd9403e3a25d2ab36f87d28f3d212342a7e)", isOptimized: true, runtimeVersion: 
0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "t.c", directory: 
"/tmp/home/yhs/tests/typedef-tag-noptr", checksumkind: CSK_MD5, checksum: 
"837ae8c69aac4a5303c9a401fdefea04")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 7, !"frame-pointer", i32 2}
+!5 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!6 = !{!"clang version 23.0.0git 
([email protected]:yonghong-song/llvm-project.git 
19865cd9403e3a25d2ab36f87d28f3d212342a7e)"}
+!7 = !{!8, !8, i64 0}
+!8 = !{!"int", !9, i64 0}
+!9 = !{!"omnipotent char", !10, i64 0}
+!10 = !{!"Simple C/C++ TBAA"}
+!11 = distinct !DISubprogram(name: "use", scope: !1, file: !1, line: 14, type: 
!12, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !33, 
keyInstructions: true)
+!12 = !DISubroutineType(types: !13)
+!13 = !{!14, !15, !23, !26, !29, !31}
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64)
+!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "bar_t1", file: !1, line: 7, 
baseType: !17, annotations: !20)
+!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: 
!1, line: 4, size: 32, elements: !18)
+!18 = !{!19}
+!19 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !17, file: !1, 
line: 5, baseType: !14, size: 32)
+!20 = !{!21, !22}
+!21 = !{!"btf_type_tag", !"tag1"}
+!22 = !{!"btf_type_tag", !"tag2"}
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64)
+!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "bar_t2", file: !1, line: 8, 
baseType: !25, annotations: !20)
+!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !17)
+!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !27, size: 64)
+!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "bar_t3", file: !1, line: 9, 
baseType: !28, annotations: !20)
+!28 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !17)
+!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "bar_t4", file: !1, line: 10, 
baseType: !30, annotations: !20)
+!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !28, size: 64)
+!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "int_v", file: !1, line: 12, 
baseType: !32, annotations: !20)
+!32 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14)
+!33 = !{!34, !35, !36, !37, !38}
+!34 = !DILocalVariable(name: "v1", arg: 1, scope: !11, file: !1, line: 14, 
type: !15)
+!35 = !DILocalVariable(name: "v2", arg: 2, scope: !11, file: !1, line: 14, 
type: !23)
+!36 = !DILocalVariable(name: "v3", arg: 3, scope: !11, file: !1, line: 14, 
type: !26)
+!37 = !DILocalVariable(name: "v4", arg: 4, scope: !11, file: !1, line: 14, 
type: !29)
+!38 = !DILocalVariable(name: "v5", arg: 5, scope: !11, file: !1, line: 14, 
type: !31)
+!39 = !DILocation(line: 0, scope: !11)
+!40 = !DILocation(line: 16, column: 20, scope: !11)
+!41 = !{!42, !8, i64 0}
+!42 = !{!"bar", !8, i64 0}
+!43 = !DILocation(line: 16, column: 28, scope: !11)
+!44 = !DILocation(line: 16, column: 36, scope: !11)
+!45 = !DILocation(line: 16, column: 44, scope: !11)
+!46 = !DILocation(line: 16, column: 22, scope: !11)
+!47 = !DILocation(line: 16, column: 30, scope: !11)
+!48 = !DILocation(line: 16, column: 38, scope: !11)
+!49 = !DILocation(line: 16, column: 46, scope: !11, atomGroup: 1, atomRank: 2)
+!50 = !DILocation(line: 16, column: 9, scope: !11, atomGroup: 1, atomRank: 1)


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to