return CollectTemplateParams(TPList, TAList.asArray(), Unit);
}
+llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) {
+ SmallVector<llvm::Metadata *, 4> Annotations;
+ for (const auto *I : D->specific_attrs<BTFTagAttr>()) {
+ 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;
Flags |= llvm::DINode::FlagExportSymbols;
}
+ llvm::DINodeArray Annotations = nullptr;
+ if (D->hasAttr<BTFTagAttr>())
+ 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.
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,
--- /dev/null
+// 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
--- /dev/null
+// 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]])