yonghong-song updated this revision to Diff 377727.
yonghong-song added a comment.

- Instead of piggyback on existing AttributedType, create a new child class 
AttributedBTFType. The code is reorganized to avoid intrusive to existing 
AttributedType.
- Hack: the AttributedBTFType still not trivially destructible. Haven't find a 
best way how to fix it.
- Missing: With AttributedBTFType, we need to handle more things, 
serialization/deserialization, TypeProperties, etc.

It would be good if I can get some feedback on the overall approach before 
diving into more details.
cc @aaron.ballman


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111199/new/

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
@@ -265,6 +265,17 @@
       return T;
     }
 
+    QualType getAttributedBTFType(Attr *A, QualType ModifiedType,
+                                  QualType EquivType,
+                                  StringRef BTFTypeTag) {
+      QualType T =
+          sema.Context.getAttributedBTFType(A->getKind(), ModifiedType, EquivType,
+                                            BTFTypeTag);
+      AttrsForTypes.push_back({cast<AttributedBTFType>(T.getTypePtr()), A});
+      AttrsForTypesSorted = false;
+      return T;
+    }
+
     /// Completely replace the \c auto in \p TypeWithAuto by
     /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if
     /// necessary.
@@ -6500,6 +6511,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.getAttributedBTFType(
+      ::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 +8174,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 AttributedBTFTypes 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<AttributedBTFType>(BaseTy.getTypePtr())) {
+      StringRef BTFTypeTag = AT->getBTFTypeTag();
+      if (BTFTypeTag[0]) {
+        llvm::Metadata *Ops[2] = {
+              llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")),
+              llvm::MDString::get(CGM.getLLVMContext(), BTFTypeTag)};
+        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(\"" << cast<AttributedBTFType>(T)->getBTFTypeTag() << "\")";
+    break;
   }
   OS << "))";
 }
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -4641,6 +4641,27 @@
   return QualType(type, 0);
 }
 
+QualType ASTContext::getAttributedBTFType(attr::Kind attrKind,
+                                          QualType modifiedType,
+                                          QualType equivalentType,
+                                          StringRef BTFTypeTag) {
+  llvm::FoldingSetNodeID id;
+  AttributedBTFType::Profile(id, attrKind, modifiedType, equivalentType, BTFTypeTag);
+
+  void *insertPos = nullptr;
+  AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
+  if (type) return QualType(type, 0);
+
+  QualType canon = getCanonicalType(equivalentType);
+  type = new (*this, TypeAlignment)
+      AttributedBTFType(canon, attrKind, modifiedType, equivalentType, BTFTypeTag);
+
+  Types.push_back(type);
+  AttributedTypes.InsertNode(type, insertPos);
+
+  return QualType(type, 0);
+}
+
 /// Retrieve a substitution-result type.
 QualType
 ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
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
@@ -4675,6 +4675,7 @@
   QualType ModifiedType;
   QualType EquivalentType;
 
+protected:
   AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
                  QualType equivalent)
       : Type(Attributed, canon, equivalent->getDependence()),
@@ -4762,6 +4763,33 @@
   }
 };
 
+class AttributedBTFType : public AttributedType {
+private:
+  std::string BTFTypeTag;
+
+public:
+  AttributedBTFType(QualType canon, attr::Kind attrKind, QualType modified,
+                    QualType equivalent, StringRef BTFTypeTag)
+      : AttributedType(canon, attrKind, modified, equivalent) {
+    this->BTFTypeTag = BTFTypeTag.str();
+  }
+
+public:
+  StringRef getBTFTypeTag() const { return StringRef(BTFTypeTag); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getAttrKind(), getModifiedType(), getEquivalentType(),
+            StringRef(BTFTypeTag));
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
+                      QualType modified, QualType equivalent,
+                      StringRef BTFTypeTag) {
+    AttributedType::Profile(ID, attrKind, modified, equivalent);
+    ID.AddString(BTFTypeTag);
+  }
+};
+
 class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1558,6 +1558,11 @@
                              QualType modifiedType,
                              QualType equivalentType);
 
+  QualType getAttributedBTFType(attr::Kind attrKind,
+                                QualType modifiedType,
+                                QualType equivalentType,
+                                StringRef BTFTypeTag);
+
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                         QualType Replacement) const;
   QualType getSubstTemplateTypeParmPackType(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to