-
Notifications
You must be signed in to change notification settings - Fork 15k
[llvm][DebugInfo] Add 'sourceLanguageVersion' field support to DICompileUnit #162632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm][DebugInfo] Add 'sourceLanguageVersion' field support to DICompileUnit #162632
Conversation
2cf20c8 to
dc6391f
Compare
… support to DICompileUnit
dc6391f to
2a2bd98
Compare
|
@llvm/pr-subscribers-llvm-ir Author: Michael Buch (Michael137) ChangesDepends on: In preparation to emit DWARFv6's Full diff: https://github.com/llvm/llvm-project/pull/162632.diff 6 Files Affected:
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<llvm::dwarf::SourceLanguageName>(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")
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm that there is a .bc file checked in with RecordSize == 22 that tests the upgrade code?
There probably isn't. Do we have raw bitcode files that test the upgrade code for other metadata? Happy to add one if checking in bitcode is fine |
|
Added. Turns out there were a couple already there that exercise this upgrade codepath, but I added a dedicated test just in case. |
|
Failing tests in CI is a LLDB-DAP test. Unrelated |
…163208) Depends on: * #163348 * #162632 With this patch Clang will start emitting `DW_AT_language_{name, version}` for C++/C/Objective-C/Objective-C++ when using `-gdwarf-6`. We adjust the `DISourceLanguageName` (which we pass to `DICompileUnit`) to hold a `DW_AT_language_name_` and version code when in DWARFv6. Otherwise we continue using the `DW_LANG_` version of `DISourceLanguageName`. We didn't back-port emitting `DW_AT_language_name`/`DW_AT_language_version` to DWARFv5 (unlike GCC, which emits both the new and old language attributes in DWARFv5) because there wasn't a compelling reason to do so (yet).
… DWARFv6 (#163208) Depends on: * llvm/llvm-project#163348 * llvm/llvm-project#162632 With this patch Clang will start emitting `DW_AT_language_{name, version}` for C++/C/Objective-C/Objective-C++ when using `-gdwarf-6`. We adjust the `DISourceLanguageName` (which we pass to `DICompileUnit`) to hold a `DW_AT_language_name_` and version code when in DWARFv6. Otherwise we continue using the `DW_LANG_` version of `DISourceLanguageName`. We didn't back-port emitting `DW_AT_language_name`/`DW_AT_language_version` to DWARFv5 (unlike GCC, which emits both the new and old language attributes in DWARFv5) because there wasn't a compelling reason to do so (yet).
…version (#163147) Depends on: * llvm/llvm-project#162632 Emit `DW_AT_language_version` (new in DWARFv6) if DICompileUnit has a `sourceLanguageVersion` field. Omit it if it has the default value of `0` (since it's the default lower bound of any language without a version scheme).
Depends on:
In preparation to emit DWARFv6's
DW_AT_language_version.