[llvm] 87e22bd - Allow for mixing source/no-source DIFiles in one CU
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 15:09:43 PST 2023
Author: Adrian Prantl
Date: 2023-11-30T15:09:24-08:00
New Revision: 87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d
URL: https://github.com/llvm/llvm-project/commit/87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d
DIFF: https://github.com/llvm/llvm-project/commit/87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d.diff
LOG: Allow for mixing source/no-source DIFiles in one CU
The DWARF proposal that the DW_LNCT_LLVM_source extension is based on
(https://dwarfstd.org/issues/180201.1.html) allows to mix source and
non-source files in the same CU by storing an empty string as a
sentinel value.
This patch implements this feature.
Review in https://github.com/llvm/llvm-project/pull/73877
Added:
llvm/test/DebugInfo/Generic/mixed-source.ll
Modified:
llvm/include/llvm/MC/MCDwarf.h
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
llvm/lib/MC/MCDwarf.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 715714f8e55dbb5..18056c5fdf816ae 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -265,7 +265,8 @@ struct MCDwarfLineTableHeader {
StringMap<unsigned> SourceIdMap;
std::string CompilationDir;
MCDwarfFile RootFile;
- bool HasSource = false;
+ bool HasAnySource = false;
+
private:
bool HasAllMD5 = true;
bool HasAnyMD5 = false;
@@ -305,7 +306,7 @@ struct MCDwarfLineTableHeader {
RootFile.Checksum = Checksum;
RootFile.Source = Source;
trackMD5Usage(Checksum.has_value());
- HasSource = Source.has_value();
+ HasAnySource |= Source.has_value();
}
void resetFileTable() {
@@ -313,7 +314,7 @@ struct MCDwarfLineTableHeader {
MCDwarfFiles.clear();
RootFile.Name.clear();
resetMD5Usage();
- HasSource = false;
+ HasAnySource = false;
}
private:
@@ -385,7 +386,7 @@ class MCDwarfLineTable {
Header.RootFile.Checksum = Checksum;
Header.RootFile.Source = Source;
Header.trackMD5Usage(Checksum.has_value());
- Header.HasSource = Source.has_value();
+ Header.HasAnySource |= Source.has_value();
}
void resetFileTable() { Header.resetFileTable(); }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 6f2afe5d50e9c81..78792cf83891670 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -170,9 +170,14 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
if (ContentTypes.HasLength)
OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
if (ContentTypes.HasSource) {
- OS << " source: ";
- FileEntry.Source.dump(OS, DumpOptions);
- OS << '\n';
+ auto Source = FileEntry.Source.getAsCString();
+ if (!Source)
+ consumeError(Source.takeError());
+ else if ((*Source)[0]) {
+ OS << " source: ";
+ FileEntry.Source.dump(OS, DumpOptions);
+ OS << '\n';
+ }
}
}
}
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 7925fba876f86cf..f94fc48a033d4e4 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -386,7 +386,7 @@ void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
}
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
- bool EmitMD5, bool HasSource,
+ bool EmitMD5, bool HasAnySource,
std::optional<MCDwarfLineStr> &LineStr) {
assert(!DwarfFile.Name.empty());
if (LineStr)
@@ -401,7 +401,7 @@ static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
MCOS->emitBinaryData(
StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));
}
- if (HasSource) {
+ if (HasAnySource) {
if (LineStr)
LineStr->emitRef(MCOS, DwarfFile.Source.value_or(StringRef()));
else {
@@ -452,7 +452,7 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
uint64_t Entries = 2;
if (HasAllMD5)
Entries += 1;
- if (HasSource)
+ if (HasAnySource)
Entries += 1;
MCOS->emitInt8(Entries);
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
@@ -464,7 +464,7 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
MCOS->emitULEB128IntValue(dwarf::DW_FORM_data16);
}
- if (HasSource) {
+ if (HasAnySource) {
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
: dwarf::DW_FORM_string);
@@ -479,9 +479,9 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
"No root file and no .file directives");
emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
- HasAllMD5, HasSource, LineStr);
+ HasAllMD5, HasAnySource, LineStr);
for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
- emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasSource, LineStr);
+ emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasAnySource, LineStr);
}
std::pair<MCSymbol *, MCSymbol *>
@@ -598,7 +598,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
// If any files have embedded source, they all must.
if (MCDwarfFiles.empty()) {
trackMD5Usage(Checksum.has_value());
- HasSource = (Source != std::nullopt);
+ HasAnySource |= Source.has_value();
}
if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
return 0;
@@ -625,11 +625,6 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
return make_error<StringError>("file number already allocated",
inconvertibleErrorCode());
- // If any files have embedded source, they all must.
- if (HasSource != (Source != std::nullopt))
- return make_error<StringError>("inconsistent use of embedded source",
- inconvertibleErrorCode());
-
if (Directory.empty()) {
// Separate the directory part from the basename of the FileName.
StringRef tFileName = sys::path::filename(FileName);
@@ -662,8 +657,8 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
File.Checksum = Checksum;
trackMD5Usage(Checksum.has_value());
File.Source = Source;
- if (Source)
- HasSource = true;
+ if (Source.has_value())
+ HasAnySource = true;
// return the allocated FileNumber.
return FileNumber;
diff --git a/llvm/test/DebugInfo/Generic/mixed-source.ll b/llvm/test/DebugInfo/Generic/mixed-source.ll
new file mode 100644
index 000000000000000..46ea05c975f1544
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/mixed-source.ll
@@ -0,0 +1,37 @@
+; RUN: %llc_dwarf -O0 -filetype=obj -o - < %s | llvm-dwarfdump -debug-line - | FileCheck %s
+
+; CHECK: include_directories[ 0] = "dir"
+; CHECK-NEXT: file_names[ 0]:
+; CHECK-NEXT: name: "foo.c"
+; CHECK-NEXT: dir_index: 0
+; CHECK-NEXT: source: "void foo() { }\n"
+; CHECK-NEXT: file_names[ 1]:
+; CHECK-NEXT: name: "bar.h"
+; CHECK-NEXT: dir_index: 0
+; CHECK-NOT: source:
+
+; Test that DIFiles mixing source and no-source within a DICompileUnit works.
+
+define dso_local void @foo() !dbg !5 {
+ ret void, !dbg !7
+}
+
+define dso_local void @bar() !dbg !6 {
+ ret void, !dbg !8
+}
+
+!llvm.dbg.cu = !{!4}
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 2, !"Dwarf Version", i32 5}
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+
+!2 = !DIFile(filename: "foo.c", directory: "dir", source: "void foo() { }\0A")
+!3 = !DIFile(filename: "bar.h", directory: "dir")
+
+!4 = distinct !DICompileUnit(language: DW_LANG_C99, emissionKind: FullDebug, file: !2)
+!5 = distinct !DISubprogram(name: "foo", file: !2, line: 1, type: !9, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !4)
+!6 = distinct !DISubprogram(name: "bar", file: !3, line: 1, type: !9, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !4)
+!7 = !DILocation(line: 1, scope: !5)
+!8 = !DILocation(line: 1, scope: !6)
+!9 = !DISubroutineType(types: !{})
More information about the llvm-commits
mailing list