yonghong-song updated this revision to Diff 413219.
yonghong-song edited the summary of this revision.
yonghong-song added a comment.
Herald added subscribers: dexonsmith, arphaman, martong.
Herald added a project: All.

- Create a separate type BTFTagAttributed instead of using Attributed type 
based on previous discussion


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120296

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTNodeTraverser.h
  clang/include/clang/AST/PropertiesBase.td
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeLoc.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/TypeNodes.td
  clang/include/clang/Serialization/ASTRecordReader.h
  clang/include/clang/Serialization/ASTRecordWriter.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CodeGen/attr-btf_type_tag-similar-type.c
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXType.cpp

Index: clang/tools/libclang/CXType.cpp
===================================================================
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -116,6 +116,7 @@
     TKCASE(Elaborated);
     TKCASE(Pipe);
     TKCASE(Attributed);
+    TKCASE(BTFTagAttributed);
     TKCASE(Atomic);
     default:
       return CXType_Unexposed;
@@ -136,6 +137,10 @@
         return MakeCXType(ATT->getEquivalentType(), TU);
       }
     }
+    if (auto *ATT = T->getAs<BTFTagAttributedType>()) {
+      if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes))
+        return MakeCXType(ATT->getEquivalentType(), TU);
+    }
     // Handle paren types as the original type
     if (auto *PTT = T->getAs<ParenType>()) {
       return MakeCXType(PTT->getInnerType(), TU);
@@ -610,6 +615,7 @@
     TKIND(Elaborated);
     TKIND(Pipe);
     TKIND(Attributed);
+    TKIND(BTFTagAttributed);
     TKIND(BFloat16);
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
 #include "clang/Basic/OpenCLImageTypes.def"
@@ -1051,6 +1057,9 @@
   if (auto *ATT = T->getAs<AttributedType>())
     return MakeCXType(ATT->getModifiedType(), GetTU(CT));
 
+  if (auto *ATT = T->getAs<BTFTagAttributedType>())
+    return MakeCXType(ATT->getModifiedType(), GetTU(CT));
+
   return MakeCXType(QualType(), GetTU(CT));
 }
 
Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -1672,6 +1672,10 @@
   return Visit(TL.getModifiedLoc());
 }
 
+bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
+  return Visit(TL.getModifiedLoc());
+}
+
 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
                                          bool SkipResultType) {
   if (!SkipResultType && Visit(TL.getReturnLoc()))
Index: clang/test/CodeGen/attr-btf_type_tag-similar-type.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-btf_type_tag-similar-type.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
+
+struct map_value {
+        int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *a;
+        int __attribute__((btf_type_tag("tag2"))) __attribute__((btf_type_tag("tag4"))) *b;
+};
+
+struct map_value *func(void);
+
+int test(struct map_value *arg)
+{
+        return *arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L14:[0-9]+]]
+// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L20:[0-9]+]]}
+// CHECK: ![[L15]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L16:[0-9]+]]
+// CHECK: ![[L16]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L17:[0-9]+]]
+// CHECK: ![[L17]] = !{![[L18:[0-9]+]], ![[L19:[0-9]+]]}
+// CHECK: ![[L18]] = !{!"btf_type_tag", !"tag1"}
+// CHECK: ![[L19]] = !{!"btf_type_tag", !"tag3"}
+// CHECK: ![[L20]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L21:[0-9]+]]
+// CHECK: ![[L21:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L22:[0-9]+]]
+// CHECK: ![[L22]] = !{![[L23:[0-9]+]], ![[L24:[0-9]+]]}
+// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag2"}
+// CHECK: ![[L24]] = !{!"btf_type_tag", !"tag4"}
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -474,6 +474,10 @@
   Record.AddAttr(TL.getAttr());
 }
 
+void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
+  Record.AddAttr(TL.getAttr());
+}
+
 void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
   Record.AddSourceLocation(TL.getNameLoc());
 }
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -6695,6 +6695,10 @@
   TL.setAttr(ReadAttr());
 }
 
+void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
+  TL.setAttr(ReadAttr());
+}
+
 void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
   TL.setNameLoc(readSourceLocation());
 }
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -6865,6 +6865,42 @@
   return result;
 }
 
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
+    TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
+  const BTFTagAttributedType *oldType = TL.getTypePtr();
+  StringRef Tag = oldType->getTag();
+  QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
+  if (modifiedType.isNull())
+    return QualType();
+
+  // oldAttr can be null if we started with a QualType rather than a TypeLoc.
+  const Attr *oldAttr = TL.getAttr();
+  const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
+  if (oldAttr && !newAttr)
+    return QualType();
+
+  QualType result = TL.getType();
+
+  // FIXME: dependent operand expressions?
+  if (getDerived().AlwaysRebuild() ||
+      modifiedType != oldType->getModifiedType()) {
+    // TODO: this is really lame; we should really be rebuilding the
+    // equivalent type from first principles.
+    QualType equivalentType =
+      getDerived().TransformType(oldType->getEquivalentType());
+    if (equivalentType.isNull())
+      return QualType();
+
+    result = SemaRef.Context.getBTFTagAttributedType(modifiedType,
+                                                     equivalentType, Tag);
+  }
+
+  BTFTagAttributedTypeLoc newTL = TLB.push<BTFTagAttributedTypeLoc>(result);
+  newTL.setAttr(newAttr);
+  return result;
+}
+
 template<typename Derived>
 QualType
 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -189,6 +189,11 @@
     SmallVector<TypeAttrPair, 8> AttrsForTypes;
     bool AttrsForTypesSorted = true;
 
+    using BTFTagTypeAttrPair =
+        std::pair<const BTFTagAttributedType*, const Attr*>;
+    SmallVector<BTFTagTypeAttrPair, 8> AttrsForBTFTagTypes;
+    bool AttrsForBTFTagTypesSorted = true;
+
     /// MacroQualifiedTypes mapping to macro expansion locations that will be
     /// stored in a MacroQualifiedTypeLoc.
     llvm::DenseMap<const MacroQualifiedType *, SourceLocation> LocsForMacros;
@@ -266,6 +271,19 @@
       return T;
     }
 
+    /// Get a BTFTagAttributed type for the btf_type_tag attribute, and
+    /// remember the Attr object so that we can attach it to the
+    /// BTFTagAttributedTypeLoc.
+    QualType getBTFTagAttributedType(Attr *A, QualType ModifiedType,
+                                     QualType EquivType, StringRef Tag) {
+      QualType T =
+          sema.Context.getBTFTagAttributedType(ModifiedType, EquivType, Tag);
+      AttrsForBTFTagTypes.push_back(
+          {cast<BTFTagAttributedType>(T.getTypePtr()), A});
+      AttrsForBTFTagTypesSorted = false;
+      return T;
+    }
+
     /// Completely replace the \c auto in \p TypeWithAuto by
     /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if
     /// necessary.
@@ -273,12 +291,21 @@
       QualType T = sema.ReplaceAutoType(TypeWithAuto, Replacement);
       if (auto *AttrTy = TypeWithAuto->getAs<AttributedType>()) {
         // Attributed type still should be an attributed type after replacement.
-        auto *NewAttrTy = cast<AttributedType>(T.getTypePtr());
-        for (TypeAttrPair &A : AttrsForTypes) {
-          if (A.first == AttrTy)
-            A.first = NewAttrTy;
+        if (auto *NewAttrTy = cast<AttributedType>(T.getTypePtr())) {
+          for (TypeAttrPair &A : AttrsForTypes) {
+            if (A.first == AttrTy)
+              A.first = NewAttrTy;
+          }
+          AttrsForTypesSorted = false;
+        }
+      } else if (auto *AttrTy = TypeWithAuto->getAs<BTFTagAttributedType>()) {
+        if (auto *NewAttrTy = cast<BTFTagAttributedType>(T.getTypePtr())) {
+          for (BTFTagTypeAttrPair &A : AttrsForBTFTagTypes) {
+            if (A.first == AttrTy)
+              A.first = NewAttrTy;
+          }
+          AttrsForBTFTagTypesSorted = false;
         }
-        AttrsForTypesSorted = false;
       }
       return T;
     }
@@ -306,6 +333,28 @@
       llvm_unreachable("no Attr* for AttributedType*");
     }
 
+    const Attr *takeAttrForBTFTagAttributedType(const BTFTagAttributedType *AT) {
+      if (!AttrsForBTFTagTypesSorted) {
+        llvm::stable_sort(AttrsForBTFTagTypes, llvm::less_first());
+        AttrsForBTFTagTypesSorted = true;
+      }
+
+      // FIXME: This is quadratic if we have lots of reuses of the same
+      // attributed type.
+      for (auto It = std::partition_point(
+               AttrsForBTFTagTypes.begin(), AttrsForBTFTagTypes.end(),
+               [=](const BTFTagTypeAttrPair &A) { return A.first < AT; });
+           It != AttrsForBTFTagTypes.end() && It->first == AT; ++It) {
+        if (It->second) {
+          const Attr *Result = It->second;
+          It->second = nullptr;
+          return Result;
+        }
+      }
+
+      llvm_unreachable("no Attr* for BTFTagAttributedType*");
+    }
+
     SourceLocation
     getExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT) const {
       auto FoundLoc = LocsForMacros.find(MQT);
@@ -5899,6 +5948,11 @@
   TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
 }
 
+static void fillBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL,
+                                        TypeProcessingState &State) {
+  TL.setAttr(State.takeAttrForBTFTagAttributedType(TL.getTypePtr()));
+}
+
 namespace {
   class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
     Sema &SemaRef;
@@ -5915,6 +5969,10 @@
       Visit(TL.getModifiedLoc());
       fillAttributedTypeLoc(TL, State);
     }
+    void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
+      Visit(TL.getModifiedLoc());
+      fillBTFTagAttributedTypeLoc(TL, State);
+    }
     void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
       Visit(TL.getInnerLoc());
       TL.setExpansionLoc(
@@ -6141,6 +6199,9 @@
     void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
       fillAttributedTypeLoc(TL, State);
     }
+    void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
+      fillBTFTagAttributedTypeLoc(TL, State);
+    }
     void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
       // nothing
     }
@@ -6556,8 +6617,9 @@
 
   ASTContext &Ctx = S.Context;
   StringRef BTFTypeTag = StrLiteral->getString();
-  Type = State.getAttributedType(
-      ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type, Type);
+  Type = State.getBTFTagAttributedType(
+      ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type, Type,
+      BTFTypeTag);
 }
 
 /// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4469,6 +4469,7 @@
     case Type::TypeOf:
     case Type::UnaryTransform:
     case Type::Attributed:
+    case Type::BTFTagAttributed:
     case Type::SubstTemplateTypeParm:
     case Type::MacroQualified:
       // Keep walking after single level desugaring.
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2310,6 +2310,7 @@
     case Type::TypeOf:
     case Type::UnaryTransform:
     case Type::Attributed:
+    case Type::BTFTagAttributed:
     case Type::SubstTemplateTypeParm:
     case Type::MacroQualified:
       // Keep walking after single level desugaring.
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -177,19 +177,16 @@
   llvm::DIType *CreateType(const ComplexType *Ty);
   llvm::DIType *CreateType(const AutoType *Ty);
   llvm::DIType *CreateType(const BitIntType *Ty);
-  llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg,
-                                    TypeLoc TL = TypeLoc());
+  llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg);
   llvm::DIType *CreateQualifiedType(const FunctionProtoType *Ty,
                                     llvm::DIFile *Fg);
   llvm::DIType *CreateType(const TypedefType *Ty, llvm::DIFile *Fg);
   llvm::DIType *CreateType(const TemplateSpecializationType *Ty,
                            llvm::DIFile *Fg);
   llvm::DIType *CreateType(const ObjCObjectPointerType *Ty, llvm::DIFile *F);
-  llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F,
-                           TypeLoc TL = TypeLoc());
+  llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F);
   llvm::DIType *CreateType(const BlockPointerType *Ty, llvm::DIFile *F);
-  llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F,
-                           TypeLoc TL = TypeLoc());
+  llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F);
   /// Get structure or union type.
   llvm::DIType *CreateType(const RecordType *Tyg);
   llvm::DIType *CreateTypeDefinition(const RecordType *Ty);
@@ -244,8 +241,7 @@
   /// \return namespace descriptor for the given namespace decl.
   llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N);
   llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
-                                      QualType PointeeTy, llvm::DIFile *F,
-                                      TypeLoc TL = TypeLoc());
+                                      QualType PointeeTy, llvm::DIFile *F);
   llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
 
   /// A helper function to create a subprogram for a single member
@@ -311,8 +307,7 @@
                                 uint64_t offsetInBits, uint32_t AlignInBits,
                                 llvm::DIFile *tunit, llvm::DIScope *scope,
                                 const RecordDecl *RD = nullptr,
-                                llvm::DINodeArray Annotations = nullptr,
-                                TypeLoc TL = TypeLoc());
+                                llvm::DINodeArray Annotations = nullptr);
 
   llvm::DIType *createFieldType(StringRef name, QualType type,
                                 SourceLocation loc, AccessSpecifier AS,
@@ -640,8 +635,7 @@
              Optional<StringRef> Source);
 
   /// Get the type from the cache or create a new type if necessary.
-  llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg,
-                                TypeLoc TL = TypeLoc());
+  llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg);
 
   /// Get a reference to a clang module.  If \p CreateSkeletonCU is true,
   /// this also creates a split dwarf skeleton compile unit.
@@ -656,8 +650,7 @@
   llvm::DICompositeType *getOrCreateLimitedType(const RecordType *Ty);
 
   /// Create type metadata for a source language type.
-  llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg,
-                               TypeLoc TL = TypeLoc());
+  llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg);
 
   /// Create new member and increase Offset by FType's size.
   llvm::DIType *CreateMemberType(llvm::DIFile *Unit, QualType FType,
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -927,28 +927,8 @@
   return (llvm::dwarf::Tag)0;
 }
 
-// Strip MacroQualifiedTypeLoc and AttributedTypeLoc
-// as their corresponding types will be ignored
-// during code generation. Stripping them allows
-// to maintain proper TypeLoc for a given type
-// during code generation.
-static TypeLoc StripMacroAttributed(TypeLoc TL) {
-  if (!TL)
-    return TL;
-
-  while (true) {
-    if (auto MTL = TL.getAs<MacroQualifiedTypeLoc>())
-      TL = MTL.getInnerLoc();
-    else if (auto ATL = TL.getAs<AttributedTypeLoc>())
-      TL = ATL.getModifiedLoc();
-    else
-      break;
-  }
-  return TL;
-}
-
-llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit,
-                                               TypeLoc TL) {
+llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
+                                               llvm::DIFile *Unit) {
   QualifierCollector Qc;
   const Type *T = Qc.strip(Ty);
 
@@ -962,15 +942,7 @@
     return getOrCreateType(QualType(T, 0), Unit);
   }
 
-  QualType NextTy = Qc.apply(CGM.getContext(), T);
-  TypeLoc NextTL;
-  if (NextTy.hasQualifiers())
-    NextTL = TL;
-  else if (TL) {
-    if (auto QTL = TL.getAs<QualifiedTypeLoc>())
-      NextTL = StripMacroAttributed(QTL.getNextTypeLoc());
-  }
-  auto *FromTy = getOrCreateType(NextTy, Unit, NextTL);
+  auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
 
   // No need to fill in the Name, Line, Size, Alignment, Offset in case of
   // CVR derived types.
@@ -1014,10 +986,10 @@
                                Ty->getPointeeType(), Unit);
 }
 
-llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIFile *Unit,
-                                      TypeLoc TL) {
+llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
+                                      llvm::DIFile *Unit) {
   return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
-                               Ty->getPointeeType(), Unit, TL);
+                               Ty->getPointeeType(), Unit);
 }
 
 /// \return whether a C++ mangling exists for the type defined by TD.
@@ -1158,8 +1130,7 @@
 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
                                                  const Type *Ty,
                                                  QualType PointeeTy,
-                                                 llvm::DIFile *Unit,
-                                                 TypeLoc TL) {
+                                                 llvm::DIFile *Unit) {
   // Bit size, align and offset of the type.
   // Size is always the size of a pointer. We can't use getTypeSize here
   // because that does not return the correct value for references.
@@ -1169,52 +1140,33 @@
   Optional<unsigned> DWARFAddressSpace =
       CGM.getTarget().getDWARFAddressSpace(AddressSpace);
 
-  llvm::DINodeArray Annotations = nullptr;
-  TypeLoc NextTL;
-  if (TL) {
-    SmallVector<llvm::Metadata *, 4> Annots;
-    NextTL = TL.getNextTypeLoc();
-    if (NextTL) {
-      // Traverse all MacroQualifiedTypeLoc, QualifiedTypeLoc and
-      // AttributedTypeLoc type locations so we can collect
-      // BTFTypeTag attributes for this pointer.
-      while (true) {
-        if (auto MTL = NextTL.getAs<MacroQualifiedTypeLoc>()) {
-          NextTL = MTL.getInnerLoc();
-        } else if (auto QTL = NextTL.getAs<QualifiedTypeLoc>()) {
-          NextTL = QTL.getNextTypeLoc();
-        } else if (auto ATL = NextTL.getAs<AttributedTypeLoc>()) {
-          if (const auto *A = ATL.getAttrAs<BTFTypeTagAttr>()) {
-            StringRef BTFTypeTag = A->getBTFTypeTag();
-            if (!BTFTypeTag.empty()) {
-              llvm::Metadata *Ops[2] = {
-                  llvm::MDString::get(CGM.getLLVMContext(),
-                                      StringRef("btf_type_tag")),
-                  llvm::MDString::get(CGM.getLLVMContext(), BTFTypeTag)};
-              Annots.insert(Annots.begin(),
-                            llvm::MDNode::get(CGM.getLLVMContext(), Ops));
-            }
-          }
-          NextTL = ATL.getModifiedLoc();
-        } else {
-          break;
-        }
-      }
+  SmallVector<llvm::Metadata *, 4> Annots;
+  auto BTFTagAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
+  while (BTFTagAttrTy) {
+    StringRef Tag = BTFTagAttrTy->getTag();
+    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));
     }
-
-    NextTL = StripMacroAttributed(TL.getNextTypeLoc());
-    if (Annots.size() > 0)
-      Annotations = DBuilder.getOrCreateArray(Annots);
+    BTFTagAttrTy =
+        dyn_cast<BTFTagAttributedType>(BTFTagAttrTy->getEquivalentType());
   }
 
+  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, NextTL),
-                                      Size, Align, DWARFAddressSpace,
-                                      StringRef(), Annotations);
+    return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
+                                      Align, DWARFAddressSpace, StringRef(),
+                                      Annotations);
 }
 
 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -1331,11 +1283,8 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
                                       llvm::DIFile *Unit) {
-  TypeLoc TL;
-  if (const TypeSourceInfo *TSI = Ty->getDecl()->getTypeSourceInfo())
-    TL = TSI->getTypeLoc();
   llvm::DIType *Underlying =
-      getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, TL);
+      getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
 
   if (Ty->getDecl()->hasAttr<NoDebugAttr>())
     return Underlying;
@@ -1409,7 +1358,7 @@
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
-                                      llvm::DIFile *Unit, TypeLoc TL) {
+                                      llvm::DIFile *Unit) {
   const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
   if (FPT) {
     if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
@@ -1421,12 +1370,7 @@
   SmallVector<llvm::Metadata *, 16> EltTys;
 
   // Add the result type at least.
-  TypeLoc RetTL;
-  if (TL) {
-    if (auto FTL = TL.getAs<FunctionTypeLoc>())
-      RetTL = FTL.getReturnLoc();
-  }
-  EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit, RetTL));
+  EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit));
 
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   // Set up remainder of arguments if there is a prototype.
@@ -1435,30 +1379,8 @@
     EltTys.push_back(DBuilder.createUnspecifiedParameter());
   } else {
     Flags = getRefFlags(FPT);
-    bool DoneWithTL = false;
-    if (TL) {
-      if (auto FTL = TL.getAs<FunctionTypeLoc>()) {
-        DoneWithTL = true;
-        unsigned Idx = 0;
-        unsigned FTL_NumParams = FTL.getNumParams();
-        for (const QualType &ParamType : FPT->param_types()) {
-          TypeLoc ParamTL;
-          if (Idx < FTL_NumParams) {
-            if (ParmVarDecl *Param = FTL.getParam(Idx)) {
-              if (const TypeSourceInfo *TSI = Param->getTypeSourceInfo())
-                ParamTL = TSI->getTypeLoc();
-            }
-          }
-          EltTys.push_back(getOrCreateType(ParamType, Unit, ParamTL));
-          Idx++;
-        }
-      }
-    }
-
-    if (!DoneWithTL) {
-      for (const QualType &ParamType : FPT->param_types())
-        EltTys.push_back(getOrCreateType(ParamType, Unit));
-    }
+    for (const QualType &ParamType : FPT->param_types())
+      EltTys.push_back(getOrCreateType(ParamType, Unit));
     if (FPT->isVariadic())
       EltTys.push_back(DBuilder.createUnspecifiedParameter());
   }
@@ -1534,8 +1456,8 @@
                              AccessSpecifier AS, uint64_t offsetInBits,
                              uint32_t AlignInBits, llvm::DIFile *tunit,
                              llvm::DIScope *scope, const RecordDecl *RD,
-                             llvm::DINodeArray Annotations, TypeLoc TL) {
-  llvm::DIType *debugType = getOrCreateType(type, tunit, TL);
+                             llvm::DINodeArray Annotations) {
+  llvm::DIType *debugType = getOrCreateType(type, tunit);
 
   // Get the location for the field.
   llvm::DIFile *file = getOrCreateFile(loc);
@@ -1643,12 +1565,9 @@
   } else {
     auto Align = getDeclAlignIfRequired(field, CGM.getContext());
     llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
-    TypeLoc TL;
-    if (const TypeSourceInfo *TSI = field->getTypeSourceInfo())
-      TL = TSI->getTypeLoc();
     FieldType = createFieldType(name, type, field->getLocation(),
                                 field->getAccess(), OffsetInBits, Align, tunit,
-                                RecordTy, RD, Annotations, TL);
+                                RecordTy, RD, Annotations);
   }
 
   elements.push_back(FieldType);
@@ -3348,6 +3267,9 @@
     case Type::Attributed:
       T = cast<AttributedType>(T)->getEquivalentType();
       break;
+    case Type::BTFTagAttributed:
+      T = cast<BTFTagAttributedType>(T)->getEquivalentType();
+      break;
     case Type::Elaborated:
       T = cast<ElaboratedType>(T)->getNamedType();
       break;
@@ -3409,8 +3331,7 @@
   RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
 }
 
-llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit,
-                                           TypeLoc TL) {
+llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {
   if (Ty.isNull())
     return nullptr;
 
@@ -3427,7 +3348,7 @@
   if (auto *T = getTypeOrNull(Ty))
     return T;
 
-  llvm::DIType *Res = CreateTypeNode(Ty, Unit, TL);
+  llvm::DIType *Res = CreateTypeNode(Ty, Unit);
   void *TyPtr = Ty.getAsOpaquePtr();
 
   // And update the type cache.
@@ -3471,11 +3392,10 @@
   return nullptr;
 }
 
-llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit,
-                                          TypeLoc TL) {
+llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
   // Handle qualifiers, which recursively handles what they refer to.
   if (Ty.hasLocalQualifiers())
-    return CreateQualifiedType(Ty, Unit, TL);
+    return CreateQualifiedType(Ty, Unit);
 
   // Work out details of type.
   switch (Ty->getTypeClass()) {
@@ -3504,7 +3424,7 @@
   case Type::Complex:
     return CreateType(cast<ComplexType>(Ty));
   case Type::Pointer:
-    return CreateType(cast<PointerType>(Ty), Unit, TL);
+    return CreateType(cast<PointerType>(Ty), Unit);
   case Type::BlockPointer:
     return CreateType(cast<BlockPointerType>(Ty), Unit);
   case Type::Typedef:
@@ -3515,7 +3435,7 @@
     return CreateEnumType(cast<EnumType>(Ty));
   case Type::FunctionProto:
   case Type::FunctionNoProto:
-    return CreateType(cast<FunctionType>(Ty), Unit, TL);
+    return CreateType(cast<FunctionType>(Ty), Unit);
   case Type::ConstantArray:
   case Type::VariableArray:
   case Type::IncompleteArray:
@@ -3542,6 +3462,7 @@
 
   case Type::Auto:
   case Type::Attributed:
+  case Type::BTFTagAttributed:
   case Type::Adjusted:
   case Type::Decayed:
   case Type::DeducedTemplateSpecialization:
@@ -4064,12 +3985,7 @@
                                            getDwarfCC(CC));
     }
 
-  TypeLoc TL;
-  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
-    if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo())
-      TL = TSI->getTypeLoc();
-  }
-  return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F, TL));
+  return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
 }
 
 QualType
@@ -4471,12 +4387,8 @@
   uint64_t XOffset = 0;
   if (VD->hasAttr<BlocksAttr>())
     Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
-  else {
-    TypeLoc TL;
-    if (const TypeSourceInfo *TSI = VD->getTypeSourceInfo())
-      TL = TSI->getTypeLoc();
-    Ty = getOrCreateType(VD->getType(), Unit, TL);
-  }
+  else
+    Ty = getOrCreateType(VD->getType(), Unit);
 
   // If there is no debug info for this type then do not emit debug info
   // for this variable.
@@ -5347,14 +5259,10 @@
     }
     AppendAddressSpaceXDeref(AddressSpace, Expr);
 
-    TypeLoc TL;
-    if (const TypeSourceInfo *TSI = D->getTypeSourceInfo())
-      TL = TSI->getTypeLoc();
-
     llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
     GVE = DBuilder.createGlobalVariableExpression(
         DContext, DeclName, LinkageName, Unit, LineNo,
-        getOrCreateType(T, Unit, TL), Var->hasLocalLinkage(), true,
+        getOrCreateType(T, Unit), Var->hasLocalLinkage(), true,
         Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
         getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
         Align, Annotations);
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -235,6 +235,7 @@
     case Type::Pipe:
     case Type::BitInt:
     case Type::DependentBitInt:
+    case Type::BTFTagAttributed:
       CanPrefixQualifiers = true;
       break;
 
@@ -1689,6 +1690,9 @@
 #include "clang/Basic/AttrList.inc"
     llvm_unreachable("non-type attribute attached to type");
 
+  case attr::BTFTypeTag:
+    llvm_unreachable("BTFTypeTag attribute handled separately");
+
   case attr::OpenCLPrivateAddressSpace:
   case attr::OpenCLGlobalAddressSpace:
   case attr::OpenCLGlobalDeviceAddressSpace:
@@ -1763,13 +1767,21 @@
   case attr::ArmMveStrictPolymorphism:
     OS << "__clang_arm_mve_strict_polymorphism";
     break;
-  case attr::BTFTypeTag:
-    OS << "btf_type_tag";
-    break;
   }
   OS << "))";
 }
 
+void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
+                                        raw_ostream &OS) {
+  printBefore(T->getEquivalentType(), OS);
+  OS << " btf_type_tag(" << T->getTag() << ")";
+}
+
+void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
+                                        raw_ostream &OS) {
+  printAfter(T->getEquivalentType(), OS);
+}
+
 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
                                            raw_ostream &OS) {
   OS << T->getDecl()->getName();
Index: clang/lib/AST/TypeLoc.cpp
===================================================================
--- clang/lib/AST/TypeLoc.cpp
+++ clang/lib/AST/TypeLoc.cpp
@@ -507,6 +507,10 @@
   return getAttr() ? getAttr()->getRange() : SourceRange();
 }
 
+SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {
+  return getAttr() ? getAttr()->getRange() : SourceRange();
+}
+
 void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
                                        SourceLocation Loc) {
   TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
@@ -683,6 +687,10 @@
       return Visit(T.getModifiedLoc());
     }
 
+    TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {
+      return Visit(T.getModifiedLoc());
+    }
+
     TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
       return Visit(T.getInnerLoc());
     }
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -2286,6 +2286,7 @@
   case Type::FunctionNoProto:
   case Type::Paren:
   case Type::Attributed:
+  case Type::BTFTagAttributed:
   case Type::Auto:
   case Type::DeducedTemplateSpecialization:
   case Type::PackExpansion:
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===================================================================
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -932,6 +932,17 @@
       return false;
     break;
 
+  case Type::BTFTagAttributed:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<BTFTagAttributedType>(T1)->getModifiedType(),
+                                  cast<BTFTagAttributedType>(T2)->getModifiedType()))
+      return false;
+    if (!IsStructurallyEquivalent(
+            Context, cast<BTFTagAttributedType>(T1)->getEquivalentType(),
+            cast<BTFTagAttributedType>(T2)->getEquivalentType()))
+      return false;
+    break;
+
   case Type::Paren:
     if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
                                   cast<ParenType>(T2)->getInnerType()))
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2377,6 +2377,10 @@
     return getTypeInfo(
                   cast<AttributedType>(T)->getEquivalentType().getTypePtr());
 
+  case Type::BTFTagAttributed:
+    return getTypeInfo(
+                  cast<BTFTagAttributedType>(T)->getEquivalentType().getTypePtr());
+
   case Type::Atomic: {
     // Start with the base type information.
     TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());
@@ -4683,6 +4687,28 @@
   return QualType(type, 0);
 }
 
+QualType ASTContext::getBTFTagAttributedType(QualType modifiedType,
+                                             QualType equivalentType,
+                                             StringRef tag) {
+  llvm::FoldingSetNodeID id;
+  BTFTagAttributedType::Profile(id, modifiedType, equivalentType, tag);
+
+  void *insertPos = nullptr;
+  BTFTagAttributedType *type =
+      BTFTagAttributedTypes.FindNodeOrInsertPos(id, insertPos);
+  if (type)
+    return QualType(type, 0);
+
+  QualType canon = getCanonicalType(equivalentType);
+  type = new (*this, TypeAlignment)
+      BTFTagAttributedType(canon, modifiedType, equivalentType, tag);
+
+  Types.push_back(type);
+  BTFTagAttributedTypes.InsertNode(type, insertPos);
+
+  return QualType(type, 0);
+}
+
 /// Retrieve a substitution-result type.
 QualType
 ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
Index: clang/include/clang/Serialization/TypeBitCodes.def
===================================================================
--- clang/include/clang/Serialization/TypeBitCodes.def
+++ clang/include/clang/Serialization/TypeBitCodes.def
@@ -63,5 +63,6 @@
 TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52)
 TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53)
 TYPE_BIT_CODE(Using, USING, 54)
+TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55)
 
 #undef TYPE_BIT_CODE
Index: clang/include/clang/Serialization/ASTRecordWriter.h
===================================================================
--- clang/include/clang/Serialization/ASTRecordWriter.h
+++ clang/include/clang/Serialization/ASTRecordWriter.h
@@ -123,6 +123,8 @@
     AddStmt(const_cast<Stmt*>(S));
   }
 
+  void writeStringRef(const StringRef Str) { AddString(Str); }
+
   /// Add a definition for the given function to the queue of statements
   /// to emit.
   void AddFunctionDefinition(const FunctionDecl *FD);
Index: clang/include/clang/Serialization/ASTRecordReader.h
===================================================================
--- clang/include/clang/Serialization/ASTRecordReader.h
+++ clang/include/clang/Serialization/ASTRecordReader.h
@@ -128,6 +128,8 @@
   Stmt *readStmt() { return Reader->ReadStmt(*F); }
   Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
 
+  StringRef readStringRef() { return readString(); }
+
   /// Reads an expression.
   Expr *readExpr() { return Reader->ReadExpr(*F); }
 
Index: clang/include/clang/Basic/TypeNodes.td
===================================================================
--- clang/include/clang/Basic/TypeNodes.td
+++ clang/include/clang/Basic/TypeNodes.td
@@ -91,6 +91,7 @@
 def EnumType : TypeNode<TagType>, LeafType;
 def ElaboratedType : TypeNode<Type>, NeverCanonical;
 def AttributedType : TypeNode<Type>, NeverCanonical;
+def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
 def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
 def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
 def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
Index: clang/include/clang/AST/TypeProperties.td
===================================================================
--- clang/include/clang/AST/TypeProperties.td
+++ clang/include/clang/AST/TypeProperties.td
@@ -619,6 +619,22 @@
   }]>;
 }
 
+let Class = BTFTagAttributedType in {
+  def : Property<"modifiedType", QualType> {
+    let Read = [{ node->getModifiedType() }];
+  }
+  def : Property<"equivalentType", QualType> {
+    let Read = [{ node->getEquivalentType() }];
+  }
+  def : Property<"tag", StringRef> {
+    let Read = [{ node->getTag() }];
+  }
+
+  def : Creator<[{
+    return ctx.getBTFTagAttributedType(modifiedType, equivalentType, tag);
+  }]>;
+}
+
 let Class = DependentAddressSpaceType in {
   def : Property<"pointeeType", QualType> {
     let Read = [{ node->getPointeeType() }];
Index: clang/include/clang/AST/TypeLoc.h
===================================================================
--- clang/include/clang/AST/TypeLoc.h
+++ clang/include/clang/AST/TypeLoc.h
@@ -901,6 +901,34 @@
   }
 };
 
+struct BTFTagAttributedLocInfo {
+  const Attr *TypeAttr;
+};
+
+/// Type source information for an btf_tag attributed type.
+class BTFTagAttributedTypeLoc
+    : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc,
+                             BTFTagAttributedType, BTFTagAttributedLocInfo> {
+public:
+  TypeLoc getModifiedLoc() const { return getInnerTypeLoc(); }
+
+  /// The type attribute.
+  const Attr *getAttr() const { return getLocalData()->TypeAttr; }
+  void setAttr(const Attr *A) { getLocalData()->TypeAttr = A; }
+
+  template<typename T> const T *getAttrAs() {
+    return dyn_cast_or_null<T>(getAttr());
+  }
+
+  SourceRange getLocalSourceRange() const;
+
+  void initializeLocal(ASTContext &Context, SourceLocation loc) {
+    setAttr(nullptr);
+  }
+
+  QualType getInnerType() const { return getTypePtr()->getModifiedType(); }
+};
+
 struct ObjCObjectTypeLocInfo {
   SourceLocation TypeArgsLAngleLoc;
   SourceLocation TypeArgsRAngleLoc;
@@ -2589,6 +2617,8 @@
       Cur = PTL.getInnerLoc();
     else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
       Cur = ATL.getModifiedLoc();
+    else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
+      Cur = ATL.getModifiedLoc();
     else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
       Cur = ETL.getNamedTypeLoc();
     else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -4786,6 +4786,43 @@
   }
 };
 
+class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
+private:
+  friend class ASTContext; // ASTContext creates these
+
+  QualType ModifiedType;
+  QualType EquivalentType;
+  StringRef Tag;
+
+  BTFTagAttributedType(QualType canon, QualType modified, QualType equivalent,
+                       StringRef tag)
+      : Type(BTFTagAttributed, canon, equivalent->getDependence()),
+        ModifiedType(modified), EquivalentType(equivalent), Tag(tag) {}
+
+public:
+  QualType getModifiedType() const { return ModifiedType; }
+  QualType getEquivalentType() const { return EquivalentType; }
+  StringRef getTag() const { return Tag; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return getEquivalentType(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, ModifiedType, EquivalentType, Tag);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType modified,
+                      QualType equivalent, StringRef Tag) {
+    ID.AddPointer(modified.getAsOpaquePtr());
+    ID.AddPointer(equivalent.getAsOpaquePtr());
+    ID.AddString(Tag);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == BTFTagAttributed;
+  }
+};
+
 class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
@@ -7220,6 +7257,8 @@
   while (Ty) {
     if (const auto *A = dyn_cast<AttributedType>(Ty))
       Ty = A->getModifiedType().getTypePtr();
+    else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
+      Ty = A->getModifiedType().getTypePtr();
     else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
       Ty = E->desugar().getTypePtr();
     else if (const auto *P = dyn_cast<ParenType>(Ty))
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1036,6 +1036,9 @@
 DEF_TRAVERSE_TYPE(AttributedType,
                   { TRY_TO(TraverseType(T->getModifiedType())); })
 
+DEF_TRAVERSE_TYPE(BTFTagAttributedType,
+                  { TRY_TO(TraverseType(T->getModifiedType())); })
+
 DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
 
 DEF_TRAVERSE_TYPE(MacroQualifiedType,
@@ -1322,6 +1325,9 @@
 DEF_TRAVERSE_TYPELOC(AttributedType,
                      { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
 
+DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+
 DEF_TRAVERSE_TYPELOC(ElaboratedType, {
   if (TL.getQualifierLoc()) {
     TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
Index: clang/include/clang/AST/PropertiesBase.td
===================================================================
--- clang/include/clang/AST/PropertiesBase.td
+++ clang/include/clang/AST/PropertiesBase.td
@@ -133,6 +133,7 @@
 def SourceLocation : PropertyType;
 def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
   def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
+def StringRef : PropertyType<"llvm::StringRef">;
 def TemplateArgument : PropertyType;
 def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
 def TemplateName : DefaultValuePropertyType;
Index: clang/include/clang/AST/ASTNodeTraverser.h
===================================================================
--- clang/include/clang/AST/ASTNodeTraverser.h
+++ clang/include/clang/AST/ASTNodeTraverser.h
@@ -386,6 +386,9 @@
     // FIXME: AttrKind
     Visit(T->getModifiedType());
   }
+  void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
+    Visit(T->getModifiedType());
+  }
   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
     Visit(T->getReplacedParameter());
   }
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -264,6 +264,7 @@
   mutable llvm::FoldingSet<PipeType> PipeTypes;
   mutable llvm::FoldingSet<BitIntType> BitIntTypes;
   mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;
+  llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
 
   mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
   mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -1592,6 +1593,9 @@
                              QualType modifiedType,
                              QualType equivalentType);
 
+  QualType getBTFTagAttributedType(QualType modifiedType,
+                                   QualType equivalentType, StringRef Tag);
+
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                         QualType Replacement) const;
   QualType getSubstTemplateTypeParmPackType(
Index: clang/include/clang-c/Index.h
===================================================================
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3401,7 +3401,8 @@
   CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175,
 
   CXType_ExtVector = 176,
-  CXType_Atomic = 177
+  CXType_Atomic = 177,
+  CXType_BTFTagAttributed = 178
 };
 
 /**
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to