diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -817,40 +817,45 @@ static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate = true) { + DIFlags Flags, DINodeArray Annotations, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), - SizeInBits, AlignInBits, Encoding, Flags, Storage, - ShouldCreate); + SizeInBits, AlignInBits, Encoding, Flags, Annotations.get(), + Storage, ShouldCreate); } static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate = true); + DIFlags Flags, Metadata *Annotations, + StorageType Storage, bool ShouldCreate = true); TempDIBasicType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), - getAlignInBits(), getEncoding(), getFlags()); + getAlignInBits(), getEncoding(), getFlags(), + getAnnotations()); } public: DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name), - (Tag, Name, 0, 0, 0, FlagZero)) + (Tag, Name, 0, 0, 0, FlagZero, {})) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) + (Tag, Name, SizeInBits, 0, 0, FlagZero, {})) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, MDString *Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) + (Tag, Name, SizeInBits, 0, 0, FlagZero, {})) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + DINodeArray Annotations = {}), + (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, + Annotations)) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + Metadata *Annotations), + (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, + Annotations)) TempDIBasicType clone() const { return cloneImpl(); } @@ -862,6 +867,16 @@ /// neither signed nor unsigned. std::optional getSignedness() const; + Metadata *getRawAnnotations() const { return getOperand(3); } + + DINodeArray getAnnotations() const { + return cast_or_null(getRawAnnotations()); + } + + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(3, Annotations.get()); + } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIBasicTypeKind; } @@ -1054,6 +1069,10 @@ } Metadata *getRawAnnotations() const { return getOperand(5); } + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(5, Annotations.get()); + } + /// Get casted version of extra data. /// @{ DIType *getClassType() const; @@ -1271,6 +1290,10 @@ return cast_or_null(getRawAnnotations()); } + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(13, Annotations.get()); + } + /// Replace operands. /// /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision @@ -1317,26 +1340,30 @@ static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray, - StorageType Storage, + DINodeArray Annotations, StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate); + return getImpl(Context, Flags, CC, TypeArray.get(), Annotations.get(), + Storage, ShouldCreate); } static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags, uint8_t CC, Metadata *TypeArray, - StorageType Storage, + Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); TempDISubroutineType cloneImpl() const { - return getTemporary(getContext(), getFlags(), getCC(), getTypeArray()); + return getTemporary(getContext(), getFlags(), getCC(), getTypeArray(), + getAnnotations()); } public: DEFINE_MDNODE_GET(DISubroutineType, - (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray), - (Flags, CC, TypeArray)) + (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray, + DINodeArray Annotations = nullptr), + (Flags, CC, TypeArray, Annotations)) DEFINE_MDNODE_GET(DISubroutineType, - (DIFlags Flags, uint8_t CC, Metadata *TypeArray), - (Flags, CC, TypeArray)) + (DIFlags Flags, uint8_t CC, Metadata *TypeArray, + Metadata *Annotations = nullptr), + (Flags, CC, TypeArray, Annotations)) TempDISubroutineType clone() const { return cloneImpl(); } // Returns a new temporary DISubroutineType with updated CC @@ -1354,6 +1381,15 @@ Metadata *getRawTypeArray() const { return getOperand(3); } + Metadata *getRawAnnotations() const { return getOperand(4); } + DINodeArray getAnnotations() const { + return cast_or_null(getRawAnnotations()); + } + + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(4, Annotations.get()); + } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DISubroutineTypeKind; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4906,7 +4906,7 @@ /// parseDIBasicType: /// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, -/// encoding: DW_ATE_encoding, flags: 0) +/// encoding: DW_ATE_encoding, flags: 0, annotations: !1) bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ @@ -4914,12 +4914,14 @@ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); \ - OPTIONAL(flags, DIFlagField, ); + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(annotations, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val, - align.Val, encoding.Val, flags.Val)); + Result = GET_OR_DISTINCT(DIBasicType, + (Context, tag.Val, name.Val, size.Val, align.Val, + encoding.Val, flags.Val, annotations.Val)); return false; } @@ -5041,12 +5043,13 @@ #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(cc, DwarfCCField, ); \ - REQUIRED(types, MDField, ); + REQUIRED(types, MDField, ); \ + OPTIONAL(annotations, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DISubroutineType, - (Context, flags.Val, cc.Val, types.Val)); + Result = GET_OR_DISTINCT(DISubroutineType, (Context, flags.Val, cc.Val, + types.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1417,7 +1417,7 @@ break; } case bitc::METADATA_BASIC_TYPE: { - if (Record.size() < 6 || Record.size() > 7) + if (Record.size() < 6 || Record.size() > 8) return error("Invalid record"); IsDistinct = Record[0]; @@ -1425,10 +1425,14 @@ ? static_cast(Record[6]) : DINode::FlagZero; + Metadata *Annotations = nullptr; + if (Record.size() > 7 && Record[7]) + Annotations = getMDOrNull(Record[7]); + MetadataList.assignValue( GET_OR_DISTINCT(DIBasicType, (Context, Record[1], getMDString(Record[2]), Record[3], - Record[4], Record[5], Flags)), + Record[4], Record[5], Flags, Annotations)), NextMetadataNo); NextMetadataNo++; break; @@ -1579,7 +1583,7 @@ break; } case bitc::METADATA_SUBROUTINE_TYPE: { - if (Record.size() < 3 || Record.size() > 4) + if (Record.size() < 3 || Record.size() > 5) return error("Invalid record"); bool IsOldTypeRefArray = Record[0] < 2; unsigned CC = (Record.size() > 3) ? Record[3] : 0; @@ -1589,9 +1593,13 @@ Metadata *Types = getMDOrNull(Record[2]); if (LLVM_UNLIKELY(IsOldTypeRefArray)) Types = MetadataList.upgradeTypeRefArray(Types); + Metadata *Annotations = nullptr; + if (Record.size() > 4 && Record[4]) + Annotations = getMDOrNull(Record[4]); MetadataList.assignValue( - GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)), + GET_OR_DISTINCT(DISubroutineType, + (Context, Flags, CC, Types, Annotations)), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1711,6 +1711,7 @@ Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); Record.push_back(N->getFlags()); + Record.push_back(VE.getMetadataOrNullID(N->getRawAnnotations())); Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev); Record.clear(); @@ -1801,6 +1802,7 @@ Record.push_back(N->getFlags()); Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get())); Record.push_back(N->getCC()); + Record.push_back(VE.getMetadataOrNullID(N->getRawAnnotations())); Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -695,9 +695,11 @@ if (!Name.empty()) addString(Buffer, dwarf::DW_AT_name, Name); - // An unspecified type only has a name attribute. - if (BTy->getTag() == dwarf::DW_TAG_unspecified_type) + // An unspecified type only has a name attribute & annotations. + if (BTy->getTag() == dwarf::DW_TAG_unspecified_type) { + addAnnotation(Buffer, BTy->getAnnotations()); return; + } if (BTy->getTag() != dwarf::DW_TAG_string_type) addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, @@ -710,6 +712,8 @@ addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big); else if (BTy->isLittleEndian()) addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little); + + addAnnotation(Buffer, BTy->getAnnotations()); } void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) { @@ -847,6 +851,8 @@ if (CTy->isRValueReference()) addFlag(Buffer, dwarf::DW_AT_rvalue_reference); + + addAnnotation(Buffer, CTy->getAnnotations()); } void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1987,9 +1987,9 @@ } static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, - AsmWriterContext &) { + AsmWriterContext &WriterCtx) { Out << "!DIBasicType("; - MDFieldPrinter Printer(Out); + MDFieldPrinter Printer(Out, WriterCtx); if (N->getTag() != dwarf::DW_TAG_base_type) Printer.printTag(N); Printer.printString("name", N->getName()); @@ -1998,6 +1998,7 @@ Printer.printDwarfEnum("encoding", N->getEncoding(), dwarf::AttributeEncodingString); Printer.printDIFlags("flags", N->getFlags()); + Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; } @@ -2083,6 +2084,7 @@ Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString); Printer.printMetadata("types", N->getRawTypeArray(), /* ShouldSkipNull */ false); + Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -592,12 +592,12 @@ DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate) { + DIFlags Flags, Metadata *Annotations, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIBasicType, - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)); - Metadata *Ops[] = {nullptr, nullptr, Name}; + DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits, + Encoding, Flags, Annotations)); + Metadata *Ops[] = {nullptr, nullptr, Name, Annotations}; DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops); } @@ -793,10 +793,11 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, uint8_t CC, Metadata *TypeArray, + Metadata *Annotations, StorageType Storage, bool ShouldCreate) { - DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray)); - Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray}; + DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray, Annotations)); + Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray, Annotations}; DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -465,25 +465,29 @@ uint32_t AlignInBits; unsigned Encoding; unsigned Flags; + Metadata *Annotations; MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, unsigned Flags) + uint32_t AlignInBits, unsigned Encoding, unsigned Flags, + Metadata *Annotations) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), - Encoding(Encoding), Flags(Flags) {} + Encoding(Encoding), Flags(Flags), Annotations(Annotations) {} MDNodeKeyImpl(const DIBasicType *N) : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), - Flags(N->getFlags()) {} + Flags(N->getFlags()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIBasicType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && - Encoding == RHS->getEncoding() && Flags == RHS->getFlags(); + Encoding == RHS->getEncoding() && Flags == RHS->getFlags() && + Annotations == RHS->getRawAnnotations(); } unsigned getHashValue() const { - return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding); + return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding, + Annotations); } }; @@ -698,18 +702,24 @@ unsigned Flags; uint8_t CC; Metadata *TypeArray; + Metadata *Annotations; - MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray) - : Flags(Flags), CC(CC), TypeArray(TypeArray) {} + MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray, + Metadata *Annotations) + : Flags(Flags), CC(CC), TypeArray(TypeArray), Annotations(Annotations) {} MDNodeKeyImpl(const DISubroutineType *N) - : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {} + : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()), + Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DISubroutineType *RHS) const { return Flags == RHS->getFlags() && CC == RHS->getCC() && - TypeArray == RHS->getRawTypeArray(); + TypeArray == RHS->getRawTypeArray() && + Annotations == RHS->getRawAnnotations(); } - unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); } + unsigned getHashValue() const { + return hash_combine(Flags, CC, TypeArray, Annotations); + } }; template <> struct MDNodeKeyImpl { diff --git a/llvm/test/Bitcode/attr-btf_tag-dibasic.ll b/llvm/test/Bitcode/attr-btf_tag-dibasic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/attr-btf_tag-dibasic.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; int __tag1 g; +; Compilation flag: +; clang -S -g -emit-llvm test.c + +@g = dso_local global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10, !11, !12, !13, !14} +!llvm.ident = !{!15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 2, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git c15ba1bb9498fa04f6c374337313df43486c9713)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "79feb01d60b549b43abc493c324fe2a8") +!4 = !{!0} +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !6) +!6 = !{!7} +!7 = !{!"btf_type_tag", !"tag1", i16 24577} + +; CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L1:[0-9]+]], isLocal: false, isDefinition: true) +; CHECK: ![[L1]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L2:[0-9]+]]) +; CHECK: ![[L2]] = !{![[L3:[0-9]+]]} +; CHECK: ![[L3]] = !{!"btf_type_tag", !"tag1", i16 24577} + +!8 = !{i32 7, !"Dwarf Version", i32 5} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{i32 8, !"PIC Level", i32 2} +!12 = !{i32 7, !"PIE Level", i32 2} +!13 = !{i32 7, !"uwtable", i32 2} +!14 = !{i32 7, !"frame-pointer", i32 2} +!15 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git c15ba1bb9498fa04f6c374337313df43486c9713)"} diff --git a/llvm/test/Bitcode/attr-btf_tag-disubroutine.ll b/llvm/test/Bitcode/attr-btf_tag-disubroutine.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/attr-btf_tag-disubroutine.ll @@ -0,0 +1,41 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; int (__tag1 * g)(void); + +; Compilation flag: +; clang -S -g -emit-llvm test.c + +@g = dso_local global ptr null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13, !14, !15, !16, !17} +!llvm.ident = !{!18} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 2, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git c15ba1bb9498fa04f6c374337313df43486c9713)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "2ed8742fd12b44b948de1ac5e433bd63") +!4 = !{!0} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) +!6 = !DISubroutineType(types: !7, annotations: !9) +!7 = !{!8} +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !{!"btf_type_tag", !"tag1", i16 24577} + +; CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L1:[0-9]+]], isLocal: false, isDefinition: true) +; CHECK: ![[L1]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L2:[0-9]+]], size: [[#]]) +; CHECK: ![[L2]] = !DISubroutineType(types: ![[#]], annotations: ![[L3:[0-9]+]]) +; CHECK: ![[L3]] = !{![[L4:[0-9]+]]} +; CHECK: ![[L4]] = !{!"btf_type_tag", !"tag1", i16 24577} + +!11 = !{i32 7, !"Dwarf Version", i32 5} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{i32 8, !"PIC Level", i32 2} +!15 = !{i32 7, !"PIE Level", i32 2} +!16 = !{i32 7, !"uwtable", i32 2} +!17 = !{i32 7, !"frame-pointer", i32 2} +!18 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git c15ba1bb9498fa04f6c374337313df43486c9713)"} diff --git a/llvm/test/DebugInfo/attr-btf_type_tag.ll b/llvm/test/DebugInfo/attr-btf_type_tag.ll --- a/llvm/test/DebugInfo/attr-btf_type_tag.ll +++ b/llvm/test/DebugInfo/attr-btf_type_tag.ll @@ -4,59 +4,121 @@ ; Source: ; #define __tag1 __attribute__((btf_type_tag("tag1"))) ; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; #define __tag3 __attribute__((btf_type_tag("tag3"))) +; #define __tag4 __attribute__((btf_type_tag("tag4"))) +; +; int __tag1 a; +; int * __tag2 b; +; void __tag3 *c; +; void (__tag4 *d)(void); +; ; -; int * __tag1 * __tag2 *g; ; Compilation flag: ; clang -target x86_64 -g -S -emit-llvm t.c +; +; Note: only "btf_type_tag:v2" annotations are checked for brevity. -@g = dso_local global ptr null, align 8, !dbg !0 +@a = dso_local global i32 0, align 4, !dbg !0 +@b = dso_local global ptr null, align 8, !dbg !5 +@c = dso_local global ptr null, align 8, !dbg !11 +@d = dso_local global ptr null, align 8, !dbg !19 !llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!13, !14, !15, !16, !17} -!llvm.ident = !{!18} +!llvm.module.flags = !{!31, !32, !33, !34, !35} +!llvm.ident = !{!36} !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) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 6, type: !28, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git ffde01565bce81795ba0442108742557a9a4562d)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "71845c02e58f6b1a8b0162797b4d3f37") +!4 = !{!0, !5, !11, !19} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name ("a") +; CHECK-NEXT: DW_AT_type (0x[[T1:[0-9a-f]+]] "int") + +; CHECK: 0x[[T1]]: DW_TAG_base_type +; CHECK-NEXT: DW_AT_name ("int") + +; CHECK: DW_TAG_LLVM_annotation +; CHECK-NEXT: DW_AT_name ("btf_type_tag:v2") +; CHECK-NEXT: DW_AT_const_value ("tag1") + +!6 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 7, type: !7, isLocal: false, isDefinition: true) +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64, annotations: !9) !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) !9 = !{!10} -!10 = !{!"btf_type_tag", !"tag1"} -!11 = !{!12} -!12 = !{!"btf_type_tag", !"tag2"} +!10 = !{!"btf_type_tag:v2", !"tag2"} +!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression()) + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name ("b") +; CHECK-NEXT: DW_AT_type (0x[[T2:[0-9a-f]+]] "int *") + +; CHECK: 0x[[T2]]: DW_TAG_pointer_type +; CHECK-NEXT: DW_AT_type (0x[[T3:[0-9a-f]+]] "int") + +; CHECK: DW_TAG_LLVM_annotation +; CHECK-NEXT: DW_AT_name ("btf_type_tag:v2") +; CHECK-NEXT: DW_AT_const_value ("tag2") + +; CHECK: 0x[[T3]]: DW_TAG_base_type +; CHECK-NEXT: DW_AT_name ("int") +; CHECK-NEXT: DW_AT_encoding (DW_ATE_signed) + +!12 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !3, line: 8, type: !13, isLocal: false, isDefinition: true) +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64, annotations: !17) +!14 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "void", annotations: !15) +!15 = !{!16} +!16 = !{!"btf_type_tag:v2", !"tag3"} +!17 = !{!18} +!18 = !{!"btf_type_tag", !"tag3"} + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name ("c") +; CHECK-NEXT: DW_AT_type (0x[[T4:[0-9a-f]+]] "void *") -; CHECK: DW_TAG_variable -; CHECK-NEXT: DW_AT_name ("g") -; CHECK-NEXT: DW_AT_type (0x[[T1:[0-9a-f]+]] "int ***") +; CHECK: 0x[[T4]]: DW_TAG_pointer_type +; CHECK-NEXT: DW_AT_type (0x[[T5:[0-9a-f]+]] "void") -; CHECK: 0x[[T1]]: DW_TAG_pointer_type -; CHECK-NEXT: DW_AT_type (0x[[T2:[0-9a-f]+]] "int **") +; CHECK: 0x[[T5]]: DW_TAG_unspecified_type +; CHECK-NEXT: DW_AT_name ("void") -; CHECK: DW_TAG_LLVM_annotation -; CHECK-NEXT: DW_AT_name ("btf_type_tag") -; CHECK-NEXT: DW_AT_const_value ("tag2") +; CHECK: DW_TAG_LLVM_annotation +; CHECK-NEXT: DW_AT_name ("btf_type_tag:v2") +; CHECK-NEXT: DW_AT_const_value ("tag3") -; CHECK: NULL +!19 = !DIGlobalVariableExpression(var: !20, expr: !DIExpression()) +!20 = distinct !DIGlobalVariable(name: "d", scope: !2, file: !3, line: 9, type: !21, isLocal: false, isDefinition: true) +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64, annotations: !26) +!22 = !DISubroutineType(types: !23, annotations: !24) +!23 = !{null} +!24 = !{!25} +!25 = !{!"btf_type_tag:v2", !"tag4"} +!26 = !{!27} +!27 = !{!"btf_type_tag", !"tag4"} +!28 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !29) +!29 = !{!30} +!30 = !{!"btf_type_tag:v2", !"tag1"} -; CHECK: 0x[[T2]]: DW_TAG_pointer_type -; CHECK-NEXT: DW_AT_type (0x[[T3:[0-9a-f]+]] "int *") +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name ("d") +; CHECK-NEXT: DW_AT_type (0x[[T6:[0-9a-f]+]] "void (*)(") -; CHECK: DW_TAG_LLVM_annotation -; CHECK-NEXT: DW_AT_name ("btf_type_tag") -; CHECK-NEXT: DW_AT_const_value ("tag1") +; CHECK: 0x[[T6]]: DW_TAG_pointer_type +; CHECK-NEXT: DW_AT_type (0x[[T7:[0-9a-f]+]] "void (") -; CHECK: NULL +; CHECK: 0x[[T7]]: DW_TAG_subroutine_type +; CHECK-NEXT: DW_AT_prototyped (true) -; CHECK: 0x[[T3]]: DW_TAG_pointer_type -; CHECK-NEXT: DW_AT_type (0x{{[0-9a-f]+}} "int") +; CHECK: DW_TAG_LLVM_annotation +; CHECK-NEXT: DW_AT_name ("btf_type_tag:v2") +; CHECK-NEXT: DW_AT_const_value ("tag4") -!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)"} +!31 = !{i32 7, !"Dwarf Version", i32 5} +!32 = !{i32 2, !"Debug Info Version", i32 3} +!33 = !{i32 1, !"wchar_size", i32 4} +!34 = !{i32 7, !"uwtable", i32 2} +!35 = !{i32 7, !"frame-pointer", i32 2} +!36 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git ffde01565bce81795ba0442108742557a9a4562d)"}