diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 81c910f40bf84b..967fa7f1493a2b 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2063,6 +2063,17 @@ llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams( return CollectTemplateParams(TPList, TAList.asArray(), Unit); } +llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) { + SmallVector Annotations; + for (const auto *I : D->specific_attrs()) { + llvm::Metadata *Ops[2] = { + llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")), + llvm::MDString::get(CGM.getLLVMContext(), I->getBTFTag())}; + Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops)); + } + return DBuilder.getOrCreateArray(Annotations); +} + llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) { if (VTablePtrType) return VTablePtrType; @@ -3435,9 +3446,13 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { Flags |= llvm::DINode::FlagExportSymbols; } + llvm::DINodeArray Annotations = nullptr; + if (D->hasAttr()) + Annotations = CollectBTFTagAnnotations(D); + llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType( getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align, - Flags, Identifier); + Flags, Identifier, Annotations); // Elements of composite types usually have back to the type, creating // uniquing cycles. Distinct nodes are more efficient. diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index b01165f85a6c82..c0674b4511c79d 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -292,6 +292,9 @@ class CGDebugInfo { CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS, llvm::DIFile *F); + /// A helper function to collect debug info for btf_tag annotations. + llvm::DINodeArray CollectBTFTagAnnotations(const Decl *D); + llvm::DIType *createFieldType(StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS, uint64_t offsetInBits, uint32_t AlignInBits, diff --git a/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c b/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c new file mode 100644 index 00000000000000..ed937ec28c37a1 --- /dev/null +++ b/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c @@ -0,0 +1,14 @@ +// REQUIRES: x86-registered-target +// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s + +#define __tag1 __attribute__((btf_tag("tag1"))) +#define __tag2 __attribute__((btf_tag("tag2"))) + +struct __tag1 __tag2 t1; + +int foo(struct t1 *arg) { + return (int)(long)arg; +} + +// CHECK: define dso_local i32 @foo( +// CHECK-NOT: annotations diff --git a/clang/test/CodeGen/attr-btf_tag-dicomposite.c b/clang/test/CodeGen/attr-btf_tag-dicomposite.c new file mode 100644 index 00000000000000..514dc4e0ccc108 --- /dev/null +++ b/clang/test/CodeGen/attr-btf_tag-dicomposite.c @@ -0,0 +1,52 @@ +// REQUIRES: x86-registered-target +// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s + +#define __tag1 __attribute__((btf_tag("tag1"))) +#define __tag2 __attribute__((btf_tag("tag2"))) + +struct __tag1 __tag2 t1; +struct t1 { + int a; +}; + +int foo(struct t1 *arg) { + return arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT:[0-9]+]]) +// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]} +// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"} +// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"} + +struct __tag1 t2; +struct __tag2 t2 { + int a; +}; + +int foo2(struct t2 *arg) { + return arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]]) + +struct __tag1 t3; +struct t3 { + int a; +} __tag2; + +int foo3(struct t3 *arg) { + return arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]]) + +struct t4; +struct t4 { + int a; +} __tag1 __tag2; + +int foo4(struct t4 *arg) { + return arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t4", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]])