From 2a2bd988b47e8772312c22681f97bbf528898f88 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 7 Oct 2025 11:56:22 +0100 Subject: [PATCH 1/4] [llvm][DebugInfo] [llvm][DebugInfo] Add 'sourceLanguageVersion' field support to DICompileUnit --- llvm/lib/AsmParser/LLParser.cpp | 8 +++++- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 6 +++-- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 + llvm/lib/IR/AsmWriter.cpp | 11 +++++--- .../dicompileunit-invalid-language-version.ll | 25 +++++++++++++++++++ .../Bitcode/dwarf-source-language-version.ll | 17 +++++++++++++ 6 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 llvm/test/Assembler/dicompileunit-invalid-language-version.ll create mode 100644 llvm/test/Bitcode/dwarf-source-language-version.ll diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 380b19296a3c4..bb9f8442610d8 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5865,6 +5865,7 @@ bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) { REQUIRED(file, MDField, (/* AllowNull */ false)); \ OPTIONAL(language, DwarfLangField, ); \ OPTIONAL(sourceLanguageName, DwarfSourceLangNameField, ); \ + OPTIONAL(sourceLanguageVersion, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(producer, MDStringField, ); \ OPTIONAL(isOptimized, MDBoolField, ); \ OPTIONAL(flags, MDStringField, ); \ @@ -5894,10 +5895,15 @@ bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) { return error(Loc, "can only specify one of 'language' and " "'sourceLanguageName' on !DICompileUnit"); + if (sourceLanguageVersion.Seen && !sourceLanguageName.Seen) + return error(Loc, "'sourceLanguageVersion' requires an associated " + "'sourceLanguageName' on !DICompileUnit"); + Result = DICompileUnit::getDistinct( Context, language.Seen ? DISourceLanguageName(language.Val) - : DISourceLanguageName(sourceLanguageName.Val, 0), + : DISourceLanguageName(sourceLanguageName.Val, + sourceLanguageVersion.Val), file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, splitDebugInlining.Val, diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index cdcf7a80ffac7..ed0443f599a44 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1860,7 +1860,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 22) + if (Record.size() < 14 || Record.size() > 23) return error("Invalid record"); // Ignore Record[0], which indicates whether this compile unit is @@ -1869,11 +1869,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( const auto LangVersionMask = (uint64_t(1) << 63); const bool HasVersionedLanguage = Record[1] & LangVersionMask; + const uint32_t LanguageVersion = Record.size() > 22 ? Record[22] : 0; auto *CU = DICompileUnit::getDistinct( Context, HasVersionedLanguage - ? DISourceLanguageName(Record[1] & ~LangVersionMask, 0) + ? DISourceLanguageName(Record[1] & ~LangVersionMask, + LanguageVersion) : DISourceLanguageName(Record[1]), getMDOrNull(Record[2]), getMDString(Record[3]), Record[4], getMDString(Record[5]), Record[6], getMDString(Record[7]), Record[8], diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 54e916e2dcfe1..8ff3aa9817571 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2142,6 +2142,7 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, Record.push_back(N->getRangesBaseAddress()); Record.push_back(VE.getMetadataOrNullID(N->getRawSysRoot())); Record.push_back(VE.getMetadataOrNullID(N->getRawSDK())); + Record.push_back(Lang.hasVersionedName() ? Lang.getVersion() : 0); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 2430d988ddb04..3908a78f48412 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2374,16 +2374,21 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, Out << "!DICompileUnit("; MDFieldPrinter Printer(Out, WriterCtx); - auto Lang = N->getSourceLanguage(); - if (Lang.hasVersionedName()) + DISourceLanguageName Lang = N->getSourceLanguage(); + + if (Lang.hasVersionedName()) { Printer.printDwarfEnum( "sourceLanguageName", static_cast(Lang.getName()), dwarf::SourceLanguageNameString, /* ShouldSkipZero */ false); - else + + Printer.printInt("sourceLanguageVersion", Lang.getVersion(), + /*ShouldSkipZero=*/true); + } else { Printer.printDwarfEnum("language", Lang.getName(), dwarf::LanguageString, /* ShouldSkipZero */ false); + } Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false); Printer.printString("producer", N->getProducer()); diff --git a/llvm/test/Assembler/dicompileunit-invalid-language-version.ll b/llvm/test/Assembler/dicompileunit-invalid-language-version.ll new file mode 100644 index 0000000000000..b3794ac749f60 --- /dev/null +++ b/llvm/test/Assembler/dicompileunit-invalid-language-version.ll @@ -0,0 +1,25 @@ +; RUN: split-file %s %t +; RUN: not llvm-as < %t/dw_lang_with_version.ll -disable-output 2>&1 | FileCheck %s --check-prefix=WRONG-ATTR +; RUN: not llvm-as < %t/overflow.ll -disable-output 2>&1 | FileCheck %s --check-prefix=OVERFLOW +; RUN: not llvm-as < %t/version_without_name.ll -disable-output 2>&1 | FileCheck %s --check-prefix=NO-NAME +; RUN: not llvm-as < %t/negative.ll -disable-output 2>&1 | FileCheck %s --check-prefix=NEGATIVE + +; WRONG-ATTR: error: 'sourceLanguageVersion' requires an associated 'sourceLanguageName' on !DICompileUnit +; OVERFLOW: error: value for 'sourceLanguageVersion' too large, limit is 4294967295 +; NEGATIVE: error: expected unsigned integer +; NO-NAME: error: missing one of 'language' or 'sourceLanguageName', required for !DICompileUnit + +;--- dw_lang_with_version.ll +!0 = distinct !DICompileUnit(language: DW_LANG_C, sourceLanguageVersion: 1, + file: !DIFile(filename: "", directory: "")) + +;--- overflow.ll +!0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 4294967298) + +;--- negative.ll +!0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: -1, + file: !DIFile(filename: "", directory: "")) + +;--- version_without_name.ll +!0 = distinct !DICompileUnit(sourceLanguageVersion: 1, + file: !DIFile(filename: "", directory: "")) diff --git a/llvm/test/Bitcode/dwarf-source-language-version.ll b/llvm/test/Bitcode/dwarf-source-language-version.ll new file mode 100644 index 0000000000000..311afd5a99afe --- /dev/null +++ b/llvm/test/Bitcode/dwarf-source-language-version.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s --implicit-check-not "sourceLanguageVersion: 0" + +; CHECK: sourceLanguageVersion: 120 + +source_filename = "cu.cpp" +target triple = "arm64-apple-macosx" + +!llvm.dbg.cu = !{!0, !5} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC_plus_plus, sourceLanguageVersion: 120, file: !1, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +!1 = !DIFile(filename: "cu.cpp", directory: "/tmp") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC_plus_plus, sourceLanguageVersion: 0, file: !6, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +!6 = !DIFile(filename: "cu2.cpp", directory: "/tmp") From 831f6b93083ca81aa072d804e349d1704802150b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 15 Oct 2025 00:17:43 +0100 Subject: [PATCH 2/4] fixup! add dedicated bitcode upgrade test --- .../compile-unit-no-versioned-language.bc | Bin 0 -> 1760 bytes ...e-DICompileUnit-no-versioned-language.test | 21 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 llvm/test/Bitcode/Inputs/compile-unit-no-versioned-language.bc create mode 100644 llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test diff --git a/llvm/test/Bitcode/Inputs/compile-unit-no-versioned-language.bc b/llvm/test/Bitcode/Inputs/compile-unit-no-versioned-language.bc new file mode 100644 index 0000000000000000000000000000000000000000..461a34d02ffb1efc010fc02b221777157ac848e3 GIT binary patch literal 1760 zcmXw4e@q+K9e?&2pA(!rlhT5lyW1Jlh*fEFIRo)=wgf&#+&0rpHdR#W6l{Y-wuKzV z0Yj(C&N0r}T*-|r)qi9YtkKly5>RS_GpW9^H!2cQ69d;zk=B)WBK9&Nct=^}qh%{I~NzI#h1% zHt{vcWk={86GF9S7c#@0CV23)`<@U>VoQ&l+k(BKR=D?NOK(~Xh z_u3j?-Oo2=g2e%sG@Y@Wr1(JdNZD4`{Qb`9tm9P^KQLvxLb2{ZW*a%{0v6|sEidMJ z-(cMzbxzxz8h-OxXHz!Yj63!IViw1T zflHSir(w#CEQNym_Z<$b)C8Ii+osYf!OS7_%r!Zujuo+vAw^E%$$m9Hq>S0rk)%4Y zh`;TaZndm7{O)8#>Fm9UQ0j;S=s`SFusiEc<+A$@pIos>A5gE%+E(Fwt`VV6VD;Ei z)N+-I)tmeo$vdTG11WqWiH{aW>~|6Qxr5kC5gvPhSt`-DW~mrg^W>UxNXPtT$)Cmi zdNP}k@i%SwL{ODwd{V~7lB&$APQ8xU$q`kK9OlT)U1B#xcpS_0hKsu6qL;!I>M-bOWEP$vrM zBM*0phZW+hMPi4;BIQ|XYnIZV%D93H-#JMrOG4qvd_(i*C2s~3^V%`^ z=;KS`zc8_=+5dJU| z>SAuYsP#0nUZJ+C^k*g}*4XPUN*z}fQ4cl$4@kc{p2U-d-cx%y(qMr38M7Lu?z`xX z68)BmF%ovsyJ723ex-PIO)N@&Ams6qZ%Yz0u+_33?+2vnIOJo)CtL7%A^patgV+Ao*`#LS7N{z6DSpz)nJ*L3LbKoj30hk2tbgAs%#+4`$#inh6_y z9|tUF3Sbq3;lvt9nV#wrDjHDd2c`7RGV_|f=fDbB7aTQ9 zy_IIZFoBLMb5?L5!~rcl2iqG}sLILr@rf3YtTf-{En?z==6!7TFK8WkMMM)ULdT)z zt}sDX%GjOz1_sK1XVX~=-_z6cOgb==`_FROCIqIlzfbQ$zp~C*-nPK~=*6Q^Sw5CH zFAs%>2gc*)5{bd#W8LH7c#M5*Fg|+j!f^LsA!xLBgs2Nc2Vmilg$tQ1W~3vXqiT39*ZAwK<#0Pn=v8G*JkkPQ zz75d;!#^FsF<`)T-!(llZm~&VF literal 0 HcmV?d00001 diff --git a/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test new file mode 100644 index 0000000000000..733d50c0217d2 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test @@ -0,0 +1,21 @@ +; Test loading metadata which was not aware of versioned language names. +; +; RUN: llvm-dis -o - %p/Inputs/compile-unit-no-versioned-language.bc \ +; RUN: | FileCheck %s --implicit-check-not "sourceLanguageName" --implicit-check-not "sourceLanguageVersion" + +; Input bitcode file was compiled from following source on +; LLVM commit `fc22b58c25963ece6b041cadbdc931c2338955e4`: +; +; source_filename = "cu.cpp" +; target triple = "arm64-apple-macosx" +; +; !llvm.dbg.cu = !{!0} +; !llvm.module.flags = !{!3, !4} +; +; !0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC_plus_plus, file: !1, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +; !1 = !DIFile(filename: "cu.cpp", directory: "/tmp") +; !2 = !{} +; !3 = !{i32 7, !"Dwarf Version", i32 5} +; !4 = !{i32 2, !"Debug Info Version", i32 3} + +; CHECK: distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") From 8ecd4bc55d4b55ad3e877d8faa1f6b4771d01767 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 15 Oct 2025 10:20:27 +0100 Subject: [PATCH 3/4] fixup! relax test assertion --- .../Bitcode/upgrade-DICompileUnit-no-versioned-language.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test index 733d50c0217d2..0cfb7b5ad1587 100644 --- a/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test +++ b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test @@ -18,4 +18,4 @@ ; !3 = !{i32 7, !"Dwarf Version", i32 5} ; !4 = !{i32 2, !"Debug Info Version", i32 3} -; CHECK: distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +; CHECK: distinct !DICompileUnit(language: DW_LANG_C, From f55cca0f6a7f7d643c59ad5a7b81e8dc48ba1e9a Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 15 Oct 2025 11:25:23 +0100 Subject: [PATCH 4/4] fixup! fix test assertion --- .../Bitcode/upgrade-DICompileUnit-no-versioned-language.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test index 0cfb7b5ad1587..9475f9b1134fa 100644 --- a/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test +++ b/llvm/test/Bitcode/upgrade-DICompileUnit-no-versioned-language.test @@ -12,10 +12,10 @@ ; !llvm.dbg.cu = !{!0} ; !llvm.module.flags = !{!3, !4} ; -; !0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC_plus_plus, file: !1, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +; !0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "handwritten", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") ; !1 = !DIFile(filename: "cu.cpp", directory: "/tmp") ; !2 = !{} ; !3 = !{i32 7, !"Dwarf Version", i32 5} ; !4 = !{i32 2, !"Debug Info Version", i32 3} -; CHECK: distinct !DICompileUnit(language: DW_LANG_C, +; CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC,