yonghong-song updated this revision to Diff 379772.
yonghong-song retitled this revision from "[POC][BTF] support btf_type_tag
attribute" to "[Clang][LLVM][Attr] support btf_type_tag attribute".
yonghong-song edited the summary of this revision.
yonghong-song added a comment.
Herald added subscribers: arphaman, martong.
- remove POC tag and now the implementation is complete
- in this patch, AttributedBTFType is created as a subclass of AttributedType.
This makes quite some changes in the codebase for processing or handling
AttributedBTFType. Alternatively, we could amend existing AttributedType to
have a StringRef to store btf_tag. We can discuss which way is better.
- I may have missed some testing. Let me know what I have missed and I can add
them.
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/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/Attr.td
clang/include/clang/Basic/TypeNodes.td
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/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-conv-var.c
clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
clang/test/Sema/attr-btf_type_tag.c
clang/tools/libclang/CIndex.cpp
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_type_tag", !"tag1"}
+!11 = !{!12}
+!12 = !{!"btf_type_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_type_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_type_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/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -1670,6 +1670,10 @@
return Visit(TL.getModifiedLoc());
}
+bool CursorVisitor::VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc TL) {
+ return Visit(TL.getModifiedLoc());
+}
+
bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
bool SkipResultType) {
if (!SkipResultType && Visit(TL.getReturnLoc()))
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_type_tag", !"tag1"}
+// CHECK: ![[L22]] = !{![[L23:[0-9]+]]}
+// CHECK: ![[L23]] = !{!"btf_type_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", 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_type_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_type_tag", !"tag1"}
+// CHECK: ![[L19]] = !{![[L20:[0-9]+]]}
+// CHECK: ![[L20]] = !{!"btf_type_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/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -413,6 +413,10 @@
Record.AddAttr(TL.getAttr());
}
+void TypeLocWriter::VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc 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
@@ -6670,6 +6670,10 @@
TL.setAttr(ReadAttr());
}
+void TypeLocReader::VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc 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
@@ -6800,6 +6800,42 @@
return result;
}
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformAttributedBTFType(
+ TypeLocBuilder &TLB,
+ AttributedBTFTypeLoc TL) {
+ const AttributedBTFType *oldType = TL.getTypePtr();
+ 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();
+
+ // Handle similar to TransformAttributedType().
+ if (getDerived().AlwaysRebuild() ||
+ modifiedType != oldType->getModifiedType()) {
+ QualType equivalentType
+ = getDerived().TransformType(oldType->getEquivalentType());
+ if (equivalentType.isNull())
+ return QualType();
+
+ result = SemaRef.Context.getAttributedBTFType(TL.getAttrKind(),
+ modifiedType,
+ equivalentType,
+ oldType->getBTFTypeTag());
+ }
+
+ AttributedBTFTypeLoc newTL = TLB.push<AttributedBTFTypeLoc>(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
@@ -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<AttributedType>(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.
@@ -5876,6 +5887,11 @@
TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
}
+static void fillAttributedBTFTypeLoc(AttributedBTFTypeLoc TL,
+ TypeProcessingState &State) {
+ TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
+}
+
namespace {
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
Sema &SemaRef;
@@ -5892,6 +5908,10 @@
Visit(TL.getModifiedLoc());
fillAttributedTypeLoc(TL, State);
}
+ void VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc TL) {
+ Visit(TL.getModifiedLoc());
+ fillAttributedBTFTypeLoc(TL, State);
+ }
void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
Visit(TL.getInnerLoc());
TL.setExpansionLoc(
@@ -6108,6 +6128,9 @@
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
fillAttributedTypeLoc(TL, State);
}
+ void VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc TL) {
+ fillAttributedBTFTypeLoc(TL, State);
+ }
void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
// nothing
}
@@ -6500,6 +6523,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.
@@ -8127,6 +8180,11 @@
case ParsedAttr::IgnoredAttribute:
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/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4433,6 +4433,7 @@
case Type::TypeOf:
case Type::UnaryTransform:
case Type::Attributed:
+ case Type::AttributedBTF:
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
@@ -2258,6 +2258,7 @@
case Type::TypeOf:
case Type::UnaryTransform:
case Type::Attributed:
+ case Type::AttributedBTF:
case Type::SubstTemplateTypeParm:
case Type::MacroQualified:
// Keep walking after single level desugaring.
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1141,13 +1141,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_type_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,
@@ -3242,6 +3267,7 @@
T = cast<UnaryTransformType>(T)->getUnderlyingType();
break;
case Type::Attributed:
+ case Type::AttributedBTF:
T = cast<AttributedType>(T)->getEquivalentType();
break;
case Type::Elaborated:
@@ -3433,6 +3459,7 @@
case Type::Auto:
case Type::Attributed:
+ case Type::AttributedBTF:
case Type::Adjusted:
case Type::Decayed:
case Type::DeducedTemplateSpecialization:
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -234,6 +234,7 @@
case Type::Pipe:
case Type::ExtInt:
case Type::DependentExtInt:
+ case Type::AttributedBTF:
CanPrefixQualifiers = true;
break;
@@ -1704,6 +1705,7 @@
case attr::UPtr:
case attr::AddressSpace:
case attr::CmseNSCall:
+ case attr::BTFTypeTag:
llvm_unreachable("This attribute should have been handled already");
case attr::NSReturnsRetained:
@@ -1756,6 +1758,14 @@
OS << "))";
}
+void TypePrinter::printAttributedBTFBefore(const AttributedBTFType *T,
+ raw_ostream &OS) {
+ OS << " __attribute__((btf_type_tag(\"" << T->getBTFTypeTag() << "\")))";
+}
+
+void TypePrinter::printAttributedBTFAfter(const AttributedBTFType *T,
+ raw_ostream &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
@@ -673,6 +673,10 @@
return Visit(T.getModifiedLoc());
}
+ TypeLoc VisitAttributedBTFTypeLoc(AttributedBTFTypeLoc 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
@@ -2253,6 +2253,7 @@
case Type::FunctionNoProto:
case Type::Paren:
case Type::Attributed:
+ case Type::AttributedBTF:
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
@@ -922,6 +922,7 @@
break;
case Type::Attributed:
+ case Type::AttributedBTF:
if (!IsStructurallyEquivalent(Context,
cast<AttributedType>(T1)->getModifiedType(),
cast<AttributedType>(T2)->getModifiedType()))
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2363,6 +2363,7 @@
return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
case Type::Attributed:
+ case Type::AttributedBTF:
return getTypeInfo(
cast<AttributedType>(T)->getEquivalentType().getTypePtr());
@@ -4632,6 +4633,25 @@
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;
+ AttributedBTFType *type = AttributedBTFTypes.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);
+ AttributedBTFTypes.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
@@ -62,5 +62,6 @@
TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51)
TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52)
TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53)
+TYPE_BIT_CODE(AttributedBTF, ATTRIBUTED_BTF, 54)
#undef TYPE_BIT_CODE
Index: clang/include/clang/Serialization/ASTRecordWriter.h
===================================================================
--- clang/include/clang/Serialization/ASTRecordWriter.h
+++ clang/include/clang/Serialization/ASTRecordWriter.h
@@ -283,6 +283,10 @@
return Writer->AddString(Str, *Record);
}
+ void writeString(StringRef Str) {
+ return AddString(Str);
+ }
+
/// Emit a path.
void AddPath(StringRef Path) {
return Writer->AddPath(Path, *Record);
Index: clang/include/clang/Basic/TypeNodes.td
===================================================================
--- clang/include/clang/Basic/TypeNodes.td
+++ clang/include/clang/Basic/TypeNodes.td
@@ -90,6 +90,7 @@
def EnumType : TypeNode<TagType>, LeafType;
def ElaboratedType : TypeNode<Type>, NeverCanonical;
def AttributedType : TypeNode<Type>, NeverCanonical;
+def AttributedBTFType : TypeNode<AttributedType>, NeverCanonical;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1844,6 +1844,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/TypeProperties.td
===================================================================
--- clang/include/clang/AST/TypeProperties.td
+++ clang/include/clang/AST/TypeProperties.td
@@ -606,6 +606,15 @@
}]>;
}
+let Class = AttributedBTFType in {
+ def : Property<"tag", String> {
+ let Read = [{ node->getBTFTypeTag().str() }];
+ }
+ def : Creator<[{
+ return ctx.getAttributedBTFType(attribute, 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
@@ -891,6 +891,10 @@
}
};
+class AttributedBTFTypeLoc
+ : public InheritingConcreteTypeLoc<AttributedTypeLoc, AttributedBTFTypeLoc,
+ AttributedBTFType> {};
+
struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -4682,6 +4682,13 @@
AttributedTypeBits.AttrKind = attrKind;
}
+protected:
+ AttributedType(TypeClass tc, QualType canon, attr::Kind attrKind,
+ QualType modified, QualType equivalent)
+ : Type(tc, canon, equivalent->getDependence()),
+ ModifiedType(modified), EquivalentType(equivalent) {
+ AttributedTypeBits.AttrKind = attrKind;
+ }
public:
Kind getAttrKind() const {
return static_cast<Kind>(AttributedTypeBits.AttrKind);
@@ -4758,7 +4765,38 @@
}
static bool classof(const Type *T) {
- return T->getTypeClass() == Attributed;
+ return T->getTypeClass() == Attributed ||
+ T->getTypeClass() == AttributedBTF;
+ }
+};
+
+class AttributedBTFType : public AttributedType {
+private:
+ StringRef BTFTypeTag;
+
+public:
+ AttributedBTFType(QualType canon, attr::Kind attrKind, QualType modified,
+ QualType equivalent, StringRef BTFTypeTag)
+ : AttributedType(AttributedBTF, canon, attrKind, modified, equivalent) {
+ this->BTFTypeTag = BTFTypeTag;
+ }
+
+ StringRef getBTFTypeTag() const { return BTFTypeTag; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getAttrKind(), getModifiedType(), getEquivalentType(),
+ BTFTypeTag);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
+ QualType modified, QualType equivalent,
+ StringRef BTFTypeTag) {
+ AttributedType::Profile(ID, attrKind, modified, equivalent);
+ ID.AddString(BTFTypeTag);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == AttributedBTF;
}
};
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1029,6 +1029,9 @@
DEF_TRAVERSE_TYPE(AttributedType,
{ TRY_TO(TraverseType(T->getModifiedType())); })
+DEF_TRAVERSE_TYPE(AttributedBTFType,
+ { TRY_TO(TraverseType(T->getModifiedType())); })
+
DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(MacroQualifiedType,
@@ -1314,6 +1317,9 @@
DEF_TRAVERSE_TYPELOC(AttributedType,
{ TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+DEF_TRAVERSE_TYPELOC(AttributedBTFType,
+ { 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
@@ -131,6 +131,7 @@
def SourceLocation : PropertyType;
def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
+def String : PropertyType<"std::string">;
def TemplateArgument : PropertyType;
def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
def TemplateName : DefaultValuePropertyType;
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -263,6 +263,7 @@
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
llvm::FoldingSet<AttributedType> AttributedTypes;
+ llvm::FoldingSet<AttributedBTFType> AttributedBTFTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes;
mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
@@ -1558,6 +1559,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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits