yonghong-song created this revision.
yonghong-song added a reviewer: aaron.ballman.
Herald added subscribers: dexonsmith, hiraditya.
yonghong-song requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

Commit [1] introduced btf_tag attribute which
is used for declarations. Later we tried to compile
linux kernel by simply replacing __user definition
from attribute address_space to attribute btf_tag,
we hit two major issues:

  (1). btf_tag won't support type conversion, and 
  (2). btf_tag is not supported for typedef.

Commit [2] changed btf_tag attribute to be a
decl or type, i.e., can be applied to either declaration
or type, but actually does not do anything meaningful
for those type conversions. But typedef is still not 
resolved.

Patch [3] intended to address typedef issue. But through
discussion making btf_tag for both declaration and type
is not desirable. For example, making attributes in

  typedef int __user *__intp;
  int foo(int __user *arg, ...)

applying to declaration (__intp or arg) is not really
desirable. Further, we have code in kernel like:

  static int do_execve(struct filename *filename,
          const char __user *const __user *__argv,
          const char __user *const __user *__envp)

If __user is applied to declaration, we will lose
information that second-level dereference is also
user memory.

So it looks like it is good idea to introduce
a new type attribute. This patch introduced
btf_type_tag applying to type only. In the current
implementation, I only focus on pointers which is what
kernel is needed. Please see an dwarf generation example
in the patch.

If this approach is desirable, we can do the following:

  step 1: revert commit [2].
  step 2: I would like to rename current btf_tag
     to be btf_decl_tag to make it clear it is for 
     declaration.
  step 3: Introduce btf_type_tag as a type attribute.

This patch contains a hack in AttributedType to store
the btf_type_tag string. It is certainly not an acceptable
way. It would be great if I can get some advice on
where to store btf_type_tag string in AST.

  [1] https://reviews.llvm.org/D106614
  [2] https://reviews.llvm.org/D110116
  [3] https://reviews.llvm.org/D110127


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111199

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/Attr.td
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/attr-btf_type_tag-conv-var.c
  clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
  clang/test/Sema/attr-btf_type_tag.c
  llvm/include/llvm/IR/DIBuilder.h
  llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
  llvm/lib/IR/DIBuilder.cpp
  llvm/test/DebugInfo/attr-btf_type_tag.ll

Index: llvm/test/DebugInfo/attr-btf_type_tag.ll
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/attr-btf_type_tag.ll
@@ -0,0 +1,62 @@
+; REQUIRES: x86-registered-target
+; RUN: llc -filetype=obj -o %t %s
+; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
+; Source:
+;   #define __tag1 __attribute__((btf_type_tag("tag1")))
+;   #define __tag2 __attribute__((btf_type_tag("tag2")))
+;
+;   int * __tag1 * __tag2 *g;
+; Compilation flag:
+;   clang -target x86_64 -g -S -emit-llvm t.c
+
+@g = dso_local global i32*** null, align 8, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!13, !14, !15, !16, !17}
+!llvm.ident = !{!18}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !5, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 2c240a5eefae1a945dfd36cdaa0c677eca90dd82)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "t.c", directory: "/home/yhs/work/tests/llvm/btf_tag_type")
+!4 = !{!0}
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !11)
+!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !9)
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!9 = !{!10}
+!10 = !{!"btf_tag", !"tag1"}
+!11 = !{!12}
+!12 = !{!"btf_tag", !"tag2"}
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name      ("g")
+; CHECK-NEXT:   DW_AT_type      (0x[[T1:[0-9]+]] "int ***")
+
+; CHECK:      0x[[T1]]: DW_TAG_pointer_type
+; CHECK-NEXT:   DW_AT_type      (0x[[T2:[0-9]+]] "int **")
+
+; CHECK:        DW_TAG_LLVM_annotation
+; CHECK-NEXT:     DW_AT_name    ("btf_tag")
+; CHECK-NEXT:     DW_AT_const_value     ("tag2")
+
+; CHECK:        NULL
+
+; CHECK:      0x[[T2]]: DW_TAG_pointer_type
+; CHECK-NEXT:   DW_AT_type      (0x[[T3:[0-9]+]] "int *")
+
+; CHECK:        DW_TAG_LLVM_annotation
+; CHECK-NEXT:     DW_AT_name    ("btf_tag")
+; CHECK-NEXT:     DW_AT_const_value     ("tag1")
+
+; CHECK:        NULL
+
+; CHECK:      0x[[T3]]: DW_TAG_pointer_type
+; CHECK-NEXT:   DW_AT_type      (0x[[#]] "int")
+
+!13 = !{i32 7, !"Dwarf Version", i32 4}
+!14 = !{i32 2, !"Debug Info Version", i32 3}
+!15 = !{i32 1, !"wchar_size", i32 4}
+!16 = !{i32 7, !"uwtable", i32 1}
+!17 = !{i32 7, !"frame-pointer", i32 2}
+!18 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 2c240a5eefae1a945dfd36cdaa0c677eca90dd82)"}
Index: llvm/lib/IR/DIBuilder.cpp
===================================================================
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -292,12 +292,13 @@
     uint64_t SizeInBits,
     uint32_t AlignInBits,
     Optional<unsigned> DWARFAddressSpace,
-    StringRef Name) {
+    StringRef Name,
+    DINodeArray Annotations) {
   // FIXME: Why is there a name here?
   return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,
                             nullptr, 0, nullptr, PointeeTy, SizeInBits,
                             AlignInBits, 0, DWARFAddressSpace,
-                            DINode::FlagZero);
+                            DINode::FlagZero, nullptr, Annotations);
 }
 
 DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,
Index: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -754,6 +754,8 @@
   if (!Name.empty())
     addString(Buffer, dwarf::DW_AT_name, Name);
 
+  addAnnotation(Buffer, DTy->getAnnotations());
+
   // If alignment is specified for a typedef , create and insert DW_AT_alignment
   // attribute in DW_TAG_typedef DIE.
   if (Tag == dwarf::DW_TAG_typedef && DD->getDwarfVersion() >= 5) {
Index: llvm/include/llvm/IR/DIBuilder.h
===================================================================
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -219,11 +219,13 @@
     /// \param AlignInBits       Alignment. (optional)
     /// \param DWARFAddressSpace DWARF address space. (optional)
     /// \param Name              Pointer type name. (optional)
+    /// \param Annotations       Member annotations.
     DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
                                      uint32_t AlignInBits = 0,
                                      Optional<unsigned> DWARFAddressSpace =
                                          None,
-                                     StringRef Name = "");
+                                     StringRef Name = "",
+                                     DINodeArray Annotations = nullptr);
 
     /// Create debugging information entry for a pointer to member.
     /// \param PointeeTy Type pointed to by this pointer.
Index: clang/test/Sema/attr-btf_type_tag.c
===================================================================
--- /dev/null
+++ clang/test/Sema/attr-btf_type_tag.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -x c -triple x86_64-pc-linux-gnu -dwarf-version=4 -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+#define __tag1 __attribute__((btf_type_tag("tag1")))
+#define __tag2 __attribute__((btf_type_tag("tag2")))
+
+int * __tag1 * __tag2 *g;
+
+typedef void __fn_t(int);
+typedef __fn_t __tag1 __tag2 *__fn2_t;
+struct t {
+  int __tag1 * __tag2 *a;
+  __fn2_t b;
+  long c;
+};
+int __tag1 *foo1(struct t __tag1 * __tag2 *a1) {
+  return (int __tag1 *)a1[0]->c;
+}
+int * foo2(struct t * __tag1 a1) {
+  return (int *)a1->c;
+}
Index: clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_type_tag("tag1")))
+#define __tag2 __attribute__((btf_type_tag("tag2")))
+
+typedef void __fn_t(int);
+typedef __fn_t __tag1 __tag2 *__fn2_t;
+struct t {
+  int __tag1 * __tag2 *a;
+  __fn2_t b;
+  long c;
+};
+int *foo1(struct t *a1) {
+  return (int *)a1->c;
+}
+
+// CHECK: ![[L4:[0-9]+]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L16:[0-9]+]])
+// CHECK: ![[L16]] = !{![[L17:[0-9]+]], ![[L24:[0-9]+]], ![[L31:[0-9]+]]}
+// CHECK: ![[L17]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L18:[0-9]+]], size: [[#]])
+// CHECK: ![[L18]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L19:[0-9]+]], size: [[#]], annotations: ![[L22:[0-9]+]])
+// CHECK: ![[L19]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L4]], size: [[#]], annotations: ![[L20:[0-9]+]])
+// CHECK: ![[L20]] = !{![[L21:[0-9]+]]}
+// CHECK: ![[L21]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[L22]] = !{![[L23:[0-9]+]]}
+// CHECK: ![[L23]] = !{!"btf_tag", !"tag2"}
+// CHECK: ![[L24]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L25:[0-9]+]]
+// CHECK: ![[L25]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn2_t", file: ![[#]], line: [[#]], baseType: ![[L26:[0-9]+]])
+// CHECK: ![[L26]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L27:[0-9]+]], size: [[#]], annotations: ![[L30:[0-9]+]])
+// CHECK: ![[L27]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn_t", file: ![[#]], line: [[#]], baseType: ![[L28:[0-9]+]])
+// CHECK: ![[L28]] = !DISubroutineType(types: ![[L29:[0-9]+]])
+// CHECK: ![[L29]] = !{null, ![[L4]]}
+// CHECK: ![[L30]] = !{![[L21]], ![[L23]]}
+// CHECK: ![[L31]] = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[#]], file: ![[#]], line: [[#]]1, baseType: ![[L32:[0-9]+]]
+// CHECK: ![[L32]] = !DIBasicType(name: "long int", size: [[#]], encoding: DW_ATE_signed)
Index: clang/test/CodeGen/attr-btf_type_tag-conv-var.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-btf_type_tag-conv-var.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_type_tag("tag1")))
+#define __tag2 __attribute__((btf_type_tag("tag2")))
+#define __tag3 __attribute__((btf_type_tag("tag3")))
+
+struct t {
+  long c;
+};
+struct t * __tag1 * __tag2 *g;
+int __tag3 *foo(struct t *a1) {
+  return (int __tag3 *)a1->c;
+}
+
+// CHECK:      distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L10:[0-9]+]]
+// CHECK:      distinct !DICompileUnit(language: DW_LANG_C99
+// CHECK-SAME: retainedTypes: ![[L4:[0-9]+]]
+// CHECK:      ![[L4]] = !{![[L5:[0-9]+]]}
+// CHECK:      ![[L5]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L6:[0-9]+]], size: [[#]], annotations: ![[L7:[0-9]+]])
+// CHECK:      ![[L6]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed)
+// CHECK:      ![[L7]] = !{![[L8:[0-9]+]]}
+// CHECK:      ![[L8]] = !{!"btf_tag", !"tag3"}
+// CHECK:      ![[L10]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L11:[0-9]+]], size: [[#]], annotations: ![[L19:[0-9]+]])
+// CHECK:      ![[L11]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L12:[0-9]+]], size: [[#]], annotations: ![[L17:[0-9]+]])
+// CHECK:      ![[L12]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L13:[0-9]+]], size: [[#]])
+// CHECK:      ![[L13]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t"
+// CHECK:      ![[L17]] = !{![[L18:[0-9]+]]}
+// CHECK:      ![[L18]] = !{!"btf_tag", !"tag1"}
+// CHECK:      ![[L19]] = !{![[L20:[0-9]+]]}
+// CHECK:      ![[L20]] = !{!"btf_tag", !"tag2"}
+// CHECK:      distinct !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L28:[0-9]+]]
+// CHECK:      ![[L28]] = !DISubroutineType(types: ![[L29:[0-9]+]])
+// CHECK:      ![[L29]] = !{![[L5]], ![[L12]]}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -257,9 +257,11 @@
     /// Get an attributed type for the given attribute, and remember the Attr
     /// object so that we can attach it to the AttributedTypeLoc.
     QualType getAttributedType(Attr *A, QualType ModifiedType,
-                               QualType EquivType) {
+                               QualType EquivType,
+                               StringRef BTFTypeTag = StringRef()) {
       QualType T =
-          sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);
+          sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType,
+                                         BTFTypeTag);
       AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
       AttrsForTypesSorted = false;
       return T;
@@ -6500,6 +6502,36 @@
   return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
 }
 
+static void HandleBTFTypeTagAttribute(QualType &Type,
+                                      const ParsedAttr &Attr,
+                                      TypeProcessingState &State) {
+  Sema &S = State.getSema();
+
+  // Check the number of attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
+                                                                      << 1;
+    Attr.setInvalid();
+    return;
+  }
+
+  // Ensure the argument is a string.
+  auto *StrLiteral = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0));
+  if (!StrLiteral) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr
+        << AANT_ArgumentString;
+    Attr.setInvalid();
+    return;
+  }
+
+  ASTContext &Ctx = S.Context;
+  StringRef BTFTypeTag = StrLiteral->getString();
+  Type = State.getAttributedType(
+      ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type, Type,
+      BTFTypeTag);
+  return;
+}
+
 /// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
 /// specified type.  The attribute contains 1 argument, the id of the address
 /// space for the type.
@@ -8133,6 +8165,10 @@
       // build won't break.
       attr.setUsedAsTypeAttr();
       break;
+    case ParsedAttr::AT_BTFTypeTag:
+      HandleBTFTypeTagAttribute(type, attr, state);
+      attr.setUsedAsTypeAttr();
+      break;
     case ParsedAttr::AT_MayAlias:
       // FIXME: This attribute needs to actually be handled, but if we ignore
       // it it breaks large amounts of Linux software.
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1157,13 +1157,38 @@
   Optional<unsigned> DWARFAddressSpace =
       CGM.getTarget().getDWARFAddressSpace(AddressSpace);
 
+  // Find all AttributedTypes for this pointer.
+  SmallVector<llvm::Metadata *, 4> Annots;
+  QualType BaseTy = PointeeTy;
+  while (true) {
+    if (auto *MT = dyn_cast<MacroQualifiedType>(BaseTy.getTypePtr())) {
+      BaseTy = MT->getUnderlyingType();
+    } else if (auto *AT = dyn_cast<AttributedType>(BaseTy.getTypePtr())) {
+      const char *BTFTypeTag = AT->getBTFTypeTag();
+      if (BTFTypeTag[0]) {
+        llvm::Metadata *Ops[2] = {
+              llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")),
+              llvm::MDString::get(CGM.getLLVMContext(), AT->getBTFTypeTag())};
+        Annots.insert(Annots.begin(), llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+      }
+      BaseTy = AT->getModifiedType();
+    } else {
+      break;
+    }
+  }
+
+  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)
     return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
                                         Size, Align, DWARFAddressSpace);
   else
     return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
-                                      Align, DWARFAddressSpace);
+                                      Align, DWARFAddressSpace, StringRef(),
+                                      Annotations);
 }
 
 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1753,6 +1753,9 @@
   case attr::ArmMveStrictPolymorphism:
     OS << "__clang_arm_mve_strict_polymorphism";
     break;
+  case attr::BTFTypeTag:
+    OS << "btf_type_tag(\"" << T->getBTFTypeTag() << "\")";
+    break;
   }
   OS << "))";
 }
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -4623,9 +4623,10 @@
 
 QualType ASTContext::getAttributedType(attr::Kind attrKind,
                                        QualType modifiedType,
-                                       QualType equivalentType) {
+                                       QualType equivalentType,
+                                       StringRef BTFTypeTag) {
   llvm::FoldingSetNodeID id;
-  AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
+  AttributedType::Profile(id, attrKind, modifiedType, equivalentType, BTFTypeTag);
 
   void *insertPos = nullptr;
   AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
@@ -4633,7 +4634,7 @@
 
   QualType canon = getCanonicalType(equivalentType);
   type = new (*this, TypeAlignment)
-      AttributedType(canon, attrKind, modifiedType, equivalentType);
+      AttributedType(canon, attrKind, modifiedType, equivalentType, BTFTypeTag);
 
   Types.push_back(type);
   AttributedTypes.InsertNode(type, insertPos);
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1843,6 +1843,13 @@
   let LangOpts = [COnly];
 }
 
+def BTFTypeTag : TypeAttr {
+  let Spellings = [Clang<"btf_type_tag">];
+  let Args = [StringArgument<"BTFTypeTag">];
+  let Documentation = [Undocumented];
+  let LangOpts = [COnly];
+}
+
 def WebAssemblyExportName : InheritableAttr,
                             TargetSpecificAttr<TargetWebAssembly> {
   let Spellings = [Clang<"export_name">];
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -4674,12 +4674,18 @@
 
   QualType ModifiedType;
   QualType EquivalentType;
+  // HACK: using std::string will trigger
+  //   error: static assertion failed: AttributedType should be trivially destructible!
+  // so let use char array here.
+  char BTFTypeTag[100];
 
   AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
-                 QualType equivalent)
+                 QualType equivalent, StringRef BTFTypeTag = StringRef())
       : Type(Attributed, canon, equivalent->getDependence()),
         ModifiedType(modified), EquivalentType(equivalent) {
     AttributedTypeBits.AttrKind = attrKind;
+    strncpy(this->BTFTypeTag, BTFTypeTag.str().c_str(), sizeof(BTFTypeTag));
+    this->BTFTypeTag[99] = '\0'; // HACK, maybe we should error and bail out earlier?
   }
 
 public:
@@ -4687,6 +4693,7 @@
     return static_cast<Kind>(AttributedTypeBits.AttrKind);
   }
 
+  const char *getBTFTypeTag() const { return BTFTypeTag; }
   QualType getModifiedType() const { return ModifiedType; }
   QualType getEquivalentType() const { return EquivalentType; }
 
@@ -4747,14 +4754,16 @@
   static Optional<NullabilityKind> stripOuterNullability(QualType &T);
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
+    Profile(ID, getAttrKind(), ModifiedType, EquivalentType, StringRef());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
-                      QualType modified, QualType equivalent) {
+                      QualType modified, QualType equivalent,
+                      StringRef BTFTypeTag) {
     ID.AddInteger(attrKind);
     ID.AddPointer(modified.getAsOpaquePtr());
     ID.AddPointer(equivalent.getAsOpaquePtr());
+    ID.AddString(BTFTypeTag);
   }
 
   static bool classof(const Type *T) {
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1556,7 +1556,8 @@
 
   QualType getAttributedType(attr::Kind attrKind,
                              QualType modifiedType,
-                             QualType equivalentType);
+                             QualType equivalentType,
+                             StringRef BTFTypeTag = StringRef());
 
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                         QualType Replacement) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to