diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -606,6 +606,7 @@ HANDLE_DW_AT(0x3e07, LLVM_apinotes, 0, APPLE) HANDLE_DW_AT(0x3e08, LLVM_ptrauth_isa_pointer, 0, LLVM) HANDLE_DW_AT(0x3e09, LLVM_ptrauth_authenticates_null_values, 0, LLVM) +HANDLE_DW_AT(0x3e0a, LLVM_preferred_name, 0, LLVM) // Apple extensions. 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 @@ -1113,14 +1113,15 @@ DITemplateParameterArray TemplateParams, StringRef Identifier, DIDerivedType *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - DINodeArray Annotations, StorageType Storage, + DINodeArray Annotations, DIType *PreferredNameTy, StorageType Storage, bool ShouldCreate = true) { - return getImpl( - Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, - BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), - RuntimeLang, VTableHolder, TemplateParams.get(), - getCanonicalMDString(Context, Identifier), Discriminator, DataLocation, - Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate); + return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, + Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, + Flags, Elements.get(), RuntimeLang, VTableHolder, + TemplateParams.get(), + getCanonicalMDString(Context, Identifier), Discriminator, + DataLocation, Associated, Allocated, Rank, Annotations.get(), + PreferredNameTy, Storage, ShouldCreate); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, @@ -1130,7 +1131,8 @@ Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); + Metadata *Annotations, Metadata *PreferredNameTy, StorageType Storage, + bool ShouldCreate = true); TempDICompositeType cloneImpl() const { return getTemporary( @@ -1139,7 +1141,7 @@ getFlags(), getElements(), getRuntimeLang(), getVTableHolder(), getTemplateParams(), getIdentifier(), getDiscriminator(), getRawDataLocation(), getRawAssociated(), getRawAllocated(), - getRawRank(), getAnnotations()); + getRawRank(), getAnnotations(), getPreferredName()); } public: @@ -1153,11 +1155,11 @@ StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, Metadata *Rank = nullptr, - DINodeArray Annotations = nullptr), + DINodeArray Annotations = nullptr, DIType *PreferredNameTy = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations)) + Annotations, PreferredNameTy)) DEFINE_MDNODE_GET( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -1167,11 +1169,12 @@ Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr, Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, - Metadata *Rank = nullptr, Metadata *Annotations = nullptr), + Metadata *Rank = nullptr, Metadata *Annotations = nullptr, + Metadata *PreferredNameTy = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations)) + Annotations, PreferredNameTy)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1190,7 +1193,7 @@ unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations); + Metadata *Rank, Metadata *Annotations, Metadata *PreferredNameTy); static DICompositeType *getODRTypeIfExists(LLVMContext &Context, MDString &Identifier); @@ -1203,15 +1206,14 @@ /// /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns /// nullptr. - static DICompositeType * - buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, - MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, - Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, - Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations); + static DICompositeType *buildODRType( + LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, + Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, + Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, + Metadata *Rank, Metadata *Annotations, Metadata *PreferredNameTy); DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } DINodeArray getElements() const { @@ -1271,6 +1273,11 @@ return cast_or_null(getRawAnnotations()); } + Metadata *getRawPreferredName() const { return getOperand(14); } + DIType *getPreferredName() const { + return cast_or_null(getRawPreferredName()); + } + /// Replace operands. /// /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision @@ -1293,6 +1300,10 @@ void replaceTemplateParams(DITemplateParameterArray TemplateParams) { replaceOperandWith(6, TemplateParams.get()); } + + void replacePreferredName(Metadata *PreferredName) { + replaceOperandWith(14, PreferredName); + } /// @} static bool classof(const Metadata *MD) { 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 @@ -5006,7 +5006,8 @@ OPTIONAL(associated, MDField, ); \ OPTIONAL(allocated, MDField, ); \ OPTIONAL(rank, MDSignedOrMDField, ); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(preferredName, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5024,7 +5025,7 @@ scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, - Rank, annotations.Val)) { + Rank, annotations.Val, preferredName.Val)) { Result = CT; return false; } @@ -5037,7 +5038,7 @@ size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank, - annotations.Val)); + annotations.Val, preferredName.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 @@ -1482,7 +1482,7 @@ break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 22) + if (Record.size() < 16 || Record.size() > 23) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1511,6 +1511,7 @@ Metadata *Allocated = nullptr; Metadata *Rank = nullptr; Metadata *Annotations = nullptr; + Metadata *PreferredNameTy = nullptr; auto *Identifier = getMDString(Record[15]); // If this module is being parsed so that it can be ThinLTO imported // into another module, composite types only need to be imported @@ -1554,6 +1555,9 @@ if (Record.size() > 21) { Annotations = getMDOrNull(Record[21]); } + if (Record.size() > 22) { + PreferredNameTy = getMDOrNull(Record[22]); + } } DICompositeType *CT = nullptr; if (Identifier) @@ -1561,7 +1565,7 @@ Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations); + Allocated, Rank, Annotations, PreferredNameTy); // Create a node if we didn't get a lazy ODR type. if (!CT) @@ -1570,7 +1574,7 @@ SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations)); + Allocated, Rank, Annotations, PreferredNameTy)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast(CT)); 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 @@ -1788,6 +1788,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated())); Record.push_back(VE.getMetadataOrNullID(N->getRawRank())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + Record.push_back(VE.getMetadataOrNullID(N->getPreferredName())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -298,6 +298,8 @@ /// Add DW_TAG_LLVM_annotation. void addAnnotation(DIE &Buffer, DINodeArray Annotations); + void addPreferredName(DIE &Buffer, DIType *PreferredNameTy); + /// Get context owner's DIE. DIE *createTypeDIE(const DICompositeType *Ty); 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 @@ -905,9 +905,16 @@ // Add template parameters to a class, structure or union types. if (Tag == dwarf::DW_TAG_class_type || - Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) + Tag == dwarf::DW_TAG_structure_type || + Tag == dwarf::DW_TAG_union_type) { addTemplateParams(Buffer, CTy->getTemplateParams()); + // A [[clang::preferred_name]] attribute can only live on class + // templates, so add it here if present. + if (auto const *PreferredNameTy = CTy->getPreferredName()) + addType(Buffer, PreferredNameTy, dwarf::DW_AT_LLVM_preferred_name); + } + // Add elements to structure type. DINodeArray Elements = CTy->getElements(); for (const auto *Element : Elements) { 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 @@ -2076,6 +2076,7 @@ else Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true); Printer.printMetadata("annotations", N->getRawAnnotations()); + Printer.printMetadata("preferredName", N->getRawPreferredName()); 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 @@ -689,8 +689,8 @@ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations, StorageType Storage, - bool ShouldCreate) { + Metadata *Rank, Metadata *Annotations, Metadata *PreferredNameTy, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. @@ -699,11 +699,11 @@ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations)); + Rank, Annotations, PreferredNameTy)); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations}; + Rank, Annotations, PreferredNameTy}; DEFINE_GETIMPL_STORE( DICompositeType, (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags), @@ -717,7 +717,7 @@ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations) { + Metadata *Rank, Metadata *Annotations, Metadata *PreferredNameTy) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -727,7 +727,8 @@ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, - DataLocation, Associated, Allocated, Rank, Annotations); + DataLocation, Associated, Allocated, Rank, Annotations, + PreferredNameTy); if (CT->getTag() != Tag) return nullptr; @@ -743,7 +744,7 @@ Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations}; + Rank, Annotations, PreferredNameTy}; assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && "Mismatched number of operands"); for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) @@ -759,7 +760,7 @@ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations) { + Metadata *Rank, Metadata *Annotations, Metadata *PreferredNameTy) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -769,7 +770,7 @@ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations); + Allocated, Rank, Annotations, PreferredNameTy); } else { if (CT->getTag() != Tag) return nullptr; 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 @@ -634,6 +634,7 @@ Metadata *Allocated; Metadata *Rank; Metadata *Annotations; + Metadata *PreferredNameTy; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, @@ -642,7 +643,8 @@ Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations) + Metadata *Allocated, Metadata *Rank, Metadata *Annotations, + Metadata *PreferredNameTy) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), @@ -650,7 +652,7 @@ TemplateParams(TemplateParams), Identifier(Identifier), Discriminator(Discriminator), DataLocation(DataLocation), Associated(Associated), Allocated(Allocated), Rank(Rank), - Annotations(Annotations) {} + Annotations(Annotations), PreferredNameTy(PreferredNameTy) {} MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), @@ -663,7 +665,8 @@ Discriminator(N->getRawDiscriminator()), DataLocation(N->getRawDataLocation()), Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), - Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {} + Rank(N->getRawRank()), Annotations(N->getRawAnnotations()), + PreferredNameTy(N->getRawPreferredName()) {} bool isKeyOf(const DICompositeType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && @@ -681,7 +684,8 @@ DataLocation == RHS->getRawDataLocation() && Associated == RHS->getRawAssociated() && Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && - Annotations == RHS->getRawAnnotations(); + Annotations == RHS->getRawAnnotations() && + PreferredNameTy == RHS->getRawPreferredName(); } unsigned getHashValue() const { @@ -690,7 +694,7 @@ // collision "most of the time". There is no correctness issue in case of // collision because of the full check above. return hash_combine(Name, File, Line, BaseType, Scope, Elements, - TemplateParams, Annotations); + TemplateParams, Annotations, PreferredNameTy); } }; diff --git a/llvm/test/Assembler/dicomposite-attr-preferred_name.ll b/llvm/test/Assembler/dicomposite-attr-preferred_name.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/dicomposite-attr-preferred_name.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s + +%struct.Foo = type { i8 } + +@var = global %struct.Foo zeroinitializer, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.linker.options = !{} +!llvm.module.flags = !{!11, !12, !13, !14, !15, !16} +!llvm.ident = !{!17} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "var", scope: !2, file: !3, line: 10, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None, sysroot: "/") +!3 = !DIFile(filename: "pref.cpp", directory: "/tmp") +!4 = !{!0} +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !3, line: 8, size: 8, flags: DIFlagTypePassByValue, elements: !6, templateParams: !7, identifier: "_ZTS3FooIiE", preferredName: !10) +!6 = !{} +!7 = !{!8} +!8 = !DITemplateTypeParameter(name: "T", type: !9) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar", file: !3, line: 5, baseType: !5) + +; CHECK: ![[BASE_TY:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" +; CHECK-SAME: preferredName: ![[NAME_TY:[0-9]+]] +; CHECK: ![[NAME_TY]] = !DIDerivedType(tag: DW_TAG_typedef, +; CHECK-SAME: baseType: ![[BASE_TY]] + +!11 = !{i32 7, !"Dwarf Version", i32 4} +!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, !"uwtable", i32 1} +!16 = !{i32 7, !"frame-pointer", i32 1} +!17 = !{!"clang version 17.0.0"} diff --git a/llvm/test/DebugInfo/attr-preferred_name.ll b/llvm/test/DebugInfo/attr-preferred_name.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/attr-preferred_name.ll @@ -0,0 +1,91 @@ +; REQUIRES: object-emission +; RUN: llc -filetype=obj -o %t %s +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s +; Source: +; template +; struct Foo; +; +; typedef Foo BarInt; +; typedef Foo BarDouble; +; typedef Foo BarChar; +; +; template +; struct [[clang::preferred_name(BarInt), +; clang::preferred_name(BarDouble)]] Foo {}; +; +; Foo varInt; +; Foo varDouble; +; Foo varChar; +; +; Compilation flag (on macOS): +; clang++ -glldb -S -emit-llvm -std=c++2a pref.cpp + +; ModuleID = 'pref.cpp' +source_filename = "pref.cpp" +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "arm64-apple-macosx13.0.0" + +%struct.Foo = type { i8 } +%struct.Foo.0 = type { i8 } +%struct.Foo.1 = type { i8 } + +@varInt = global %struct.Foo zeroinitializer, align 1, !dbg !0 +@varDouble = global %struct.Foo.0 zeroinitializer, align 1, !dbg !5 +@varChar = global %struct.Foo.1 zeroinitializer, align 1, !dbg !13 + +!llvm.module.flags = !{!24, !25, !26, !27, !28, !29, !30} +!llvm.dbg.cu = !{!2} +!llvm.linker.options = !{} +!llvm.ident = !{!31} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "varInt", scope: !2, file: !3, line: 12, type: !19, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "pref.cpp", directory: "/tmp") +!4 = !{!0, !5, !13} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "varDouble", scope: !2, file: !3, line: 13, type: !7, isLocal: false, isDefinition: true) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !3, line: 10, size: 8, flags: DIFlagTypePassByValue, elements: !8, templateParams: !9, identifier: "_ZTS3FooIdE", preferredName: !12) +!8 = !{} +!9 = !{!10} +!10 = !DITemplateTypeParameter(name: "T", type: !11) +!11 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble", file: !3, line: 5, baseType: !7) +!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) +!14 = distinct !DIGlobalVariable(name: "varChar", scope: !2, file: !3, line: 14, type: !15, isLocal: false, isDefinition: true) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !3, line: 10, size: 8, flags: DIFlagTypePassByValue, elements: !8, templateParams: !16, identifier: "_ZTS3FooIcE") +!16 = !{!17} +!17 = !DITemplateTypeParameter(name: "T", type: !18) +!18 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !3, line: 10, size: 8, flags: DIFlagTypePassByValue, elements: !8, templateParams: !20, identifier: "_ZTS3FooIiE", preferredName: !23) +!20 = !{!21} +!21 = !DITemplateTypeParameter(name: "T", type: !22) +!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", file: !3, line: 4, baseType: !19) + +; CHECK: 0x[[FOO_INT:[0-9a-f]+]]: DW_TAG_structure_type +; CHECK-DAG: DW_AT_LLVM_preferred_name (0x[[FOO_INT_PREF:[0-9a-f]+]]) +; CHECK-DAG: DW_AT_name ("Foo") +; CHECK-DAG: NULL + +; CHECK: 0x[[FOO_INT_PREF]]: DW_TAG_typedef +; CHECK-DAG: DW_AT_type (0x[[FOO_INT]] "Foo") +; CHECK-DAG: DW_AT_name ("BarInt") + +; CHECK: 0x[[FOO_INT:[0-9a-f]+]]: DW_TAG_structure_type +; CHECK-DAG: DW_AT_LLVM_preferred_name (0x[[FOO_DOUBLE_PREF:[0-9a-f]+]]) +; CHECK-DAG: DW_AT_name ("Foo") +; CHECK: NULL + +; CHECK: 0x[[FOO_DOUBLE_PREF]]: DW_TAG_typedef +; CHECK-DAG: DW_AT_type (0x[[FOO_INT]] "Foo") +; CHECK-DAG: DW_AT_name ("BarDouble") + +!24 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]} +!25 = !{i32 7, !"Dwarf Version", i32 4} +!26 = !{i32 2, !"Debug Info Version", i32 3} +!27 = !{i32 1, !"wchar_size", i32 4} +!28 = !{i32 8, !"PIC Level", i32 2} +!29 = !{i32 7, !"uwtable", i32 1} +!30 = !{i32 7, !"frame-pointer", i32 1} +!31 = !{!"clang version 17.0.0"}