Skip to content

Commit 21f2c3d

Browse files
committed
Bring the Swift frontend's handling of DIFiles in synch with CFE.
This applies the same changes from Clang CFE r349065 to the Swift frontend to unify how filenames, cmpilation directories and absolute paths in filenames and path remappings are handled.
1 parent 824ab89 commit 21f2c3d

11 files changed

+86
-45
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -348,28 +348,66 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
348348
}
349349

350350
// Detect the main file.
351-
if (MainFile && Filename.endswith(MainFile->getFilename())) {
351+
StringRef MainFileName = MainFile->getFilename();
352+
if (MainFile && Filename.endswith(MainFileName)) {
352353
SmallString<256> AbsThisFile, AbsMainFile;
353354
AbsThisFile = Filename;
354355
llvm::sys::fs::make_absolute(AbsThisFile);
355-
llvm::sys::path::append(AbsMainFile, MainFile->getDirectory(),
356-
MainFile->getFilename());
357-
if (AbsThisFile == AbsMainFile) {
356+
if (llvm::sys::path::is_absolute(MainFileName))
357+
AbsMainFile = MainFileName;
358+
else
359+
llvm::sys::path::append(AbsMainFile, MainFile->getDirectory(),
360+
MainFileName);
361+
if (AbsThisFile == DebugPrefixMap.remapPath(AbsMainFile)) {
358362
DIFileCache[Filename] = llvm::TrackingMDNodeRef(MainFile);
359363
return MainFile;
360364
}
361365
}
362366

363-
// Create a new one.
364-
StringRef File = llvm::sys::path::filename(Filename);
365-
llvm::SmallString<512> Path(Filename);
366-
llvm::sys::path::remove_filename(Path);
367-
llvm::sys::path::remove_dots(Path);
368-
llvm::DIFile *F = DBuilder.createFile(DebugPrefixMap.remapPath(File),
369-
DebugPrefixMap.remapPath(Path));
370-
371-
// Cache it.
372-
DIFileCache[Filename] = llvm::TrackingMDNodeRef(F);
367+
return createFile(Filename, None, None);
368+
}
369+
370+
/// This is effectively \p clang::CGDebugInfo::createFile().
371+
llvm::DIFile *
372+
createFile(StringRef FileName,
373+
Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
374+
Optional<StringRef> Source) {
375+
StringRef Dir;
376+
StringRef File;
377+
SmallString<128> DirBuf;
378+
SmallString<128> FileBuf;
379+
std::string RemappedFileString = DebugPrefixMap.remapPath(FileName);
380+
SmallString<128> RemappedFile = StringRef(RemappedFileString);
381+
llvm::sys::path::remove_dots(RemappedFile);
382+
std::string CurDir = DebugPrefixMap.remapPath(Opts.DebugCompilationDir);
383+
if (llvm::sys::path::is_absolute(RemappedFile)) {
384+
// Strip the common prefix (if it is more than just "/") from current
385+
// directory and FileName for a more space-efficient encoding.
386+
auto FileIt = llvm::sys::path::begin(RemappedFile);
387+
auto FileE = llvm::sys::path::end(RemappedFile);
388+
auto CurDirIt = llvm::sys::path::begin(CurDir);
389+
auto CurDirE = llvm::sys::path::end(CurDir);
390+
for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
391+
llvm::sys::path::append(DirBuf, *CurDirIt);
392+
if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) {
393+
// Don't strip the common prefix if it is only the root "/"
394+
// since that would make LLVM diagnostic locations confusing.
395+
Dir = {};
396+
File = RemappedFile;
397+
} else {
398+
for (; FileIt != FileE; ++FileIt)
399+
llvm::sys::path::append(FileBuf, *FileIt);
400+
Dir = DirBuf;
401+
File = FileBuf;
402+
}
403+
} else {
404+
File = RemappedFile;
405+
// Leave <compiler-generated> & friends as is, without directory.
406+
if (!(File.startswith("<") && File.endswith(">")))
407+
Dir = CurDir;
408+
}
409+
llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source);
410+
DIFileCache[FileName.data()].reset(F);
373411
return F;
374412
}
375413

@@ -1562,16 +1600,17 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
15621600
// No split DWARF on Darwin.
15631601
StringRef SplitName = StringRef();
15641602
// Note that File + Dir need not result in a valid path.
1565-
// Clang is doing the same thing here.
1603+
// The directory part of the main file is the current working directory.
1604+
MainFile =
1605+
DBuilder.createFile(DebugPrefixMap.remapPath(SourcePath),
1606+
DebugPrefixMap.remapPath(Opts.DebugCompilationDir));
1607+
15661608
TheCU = DBuilder.createCompileUnit(
1567-
Lang, DBuilder.createFile(
1568-
DebugPrefixMap.remapPath(SourcePath),
1569-
DebugPrefixMap.remapPath(Opts.DebugCompilationDir)),
1609+
Lang, MainFile,
15701610
Producer, Opts.shouldOptimize(), Flags, MajorRuntimeVersion, SplitName,
15711611
Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
15721612
? llvm::DICompileUnit::FullDebug
15731613
: llvm::DICompileUnit::LineTablesOnly);
1574-
MainFile = getOrCreateFile(SourcePath);
15751614

15761615
// Because the swift compiler relies on Clang to setup the Module,
15771616
// the clang CU is always created first. Several dwarf-reading

test/DebugInfo/ClangPathDots.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
// RUN: %target-swift-frontend -emit-ir %s -g -I %S/Inputs -o - \
66
// RUN: -module-cache-path %t.cache | %FileCheck %s --check-prefix=CACHED
77

8-
// FIRST: !DIFile(filename: "NSObject.h", directory: {{.*}}/include/objc")
9-
// CACHED: !DIFile(filename: "NSObject.h", directory: {{.*}}/include/objc")
8+
// Test that the paths have no extra "./" components on rebuild.
9+
10+
// FIRST: !DIFile(filename: "{{.*}}/include/objc/NSObject.h",
11+
// CACHED: !DIFile(filename: "{{.*}}/include/objc/NSObject.h",
1012

1113
import ObjectiveC
1214

test/DebugInfo/Imports.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
// CHECK-DAG: ![[FOOMODULE:[0-9]+]] = !DIModule({{.*}}, name: "Foo", includePath: "{{.*}}test{{.*}}DebugInfo{{.*}}"
99
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE:[0-9]+]], entity: ![[FOOMODULE]]
10-
// CHECK-DAG: ![[THISFILE]] = !DIFile(filename: "Imports.swift", directory: "{{.*}}test{{/|\\5C}}DebugInfo")
11-
// CHECK-DAG: ![[SWIFTFILE:[0-9]+]] = !DIFile(filename: "Swift.swiftmodule"
10+
// CHECK-DAG: ![[THISFILE]] = !DIFile(filename: "{{.*}}test{{/|\\5C}}DebugInfo{{/|\\5C}}Imports.swift",
11+
// CHECK-DAG: ![[SWIFTFILE:[0-9]+]] = !DIFile(filename: "{{.*}}Swift.swiftmodule"
1212
// CHECK-DAG: ![[SWIFTMODULE:[0-9]+]] = !DIModule({{.*}}, name: "Swift"
1313
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE]], entity: ![[SWIFTMODULE]]
1414
// CHECK-DAG: ![[BASICMODULE:[0-9]+]] = !DIModule({{.*}}, name: "basic"

test/DebugInfo/ImportsStdlib.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
// CHECK-DAG: ![[MODULE:[0-9]+]] = !DIModule({{.*}}, name: "NotTheStdlib", includePath: "{{.*}}test{{.*}}DebugInfo{{.*}}"
1313
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE:[0-9]+]], entity: ![[MODULE]]
14-
// CHECK-DAG: ![[THISFILE]] = !DIFile(filename: "ImportsStdlib.swift", directory: "{{.*}}test{{/|\\5C}}DebugInfo")
14+
// CHECK-DAG: ![[THISFILE]] = !DIFile(filename: "{{.*}}test{{/|\\5C}}DebugInfo{{/|\\5C}}ImportsStdlib.swift"
1515

16-
// NEGATIVE-NOT: !DIFile(filename: "Swift.swiftmodule"
16+
// NEGATIVE-NOT: !DIFile(filename: "{{.*}}Swift.swiftmodule"
1717
// NEGATIVE-NOT: !DIModule({{.*}}, name: "Swift"
1818

1919
// DWARF: .debug_info

test/DebugInfo/basic.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// Verify that we don't emit any debug info by default.
44
// RUN: %target-swift-frontend %s -emit-ir -o - \
55
// RUN: | %FileCheck %s --check-prefix NDEBUG
6+
// NDEBUG: source_filename
67
// NDEBUG-NOT: !dbg
7-
// NDEBUG-NOT: DW_TAG
8+
// NDEBUG-NOT: DICompileUnit
89
// --------------------------------------------------------------------
910
// Verify that we don't emit any debug info with -gnone.
1011
// RUN: %target-swift-frontend %s -emit-ir -gnone -o - \
@@ -14,9 +15,9 @@
1415
// RUN: %target-swift-frontend %s -emit-ir -gline-tables-only -o - \
1516
// RUN: | %FileCheck %s --check-prefix CHECK-LINETABLES
1617
// CHECK: !dbg
17-
// CHECK-LINETABLES-NOT: DW_TAG_{{.*}}variable
18+
// CHECK-LINETABLES-NOT: DI{{.*}}Variable
1819
// CHECK-LINETABLES-NOT: DW_TAG_structure_type
19-
// CHECK-LINETABLES-NOT: DW_TAG_basic_type
20+
// CHECK-LINETABLES-NOT: DIBasicType
2021
// --------------------------------------------------------------------
2122
// Now check that we do generate line+scope info with -g.
2223
// RUN: %target-swift-frontend %/s -emit-ir -g -o - \
@@ -71,9 +72,8 @@ func foo(_ a: Int64, _ b: Int64) -> Int64 {
7172
}
7273
}
7374

74-
// CHECK-DAG: ![[FILE_CWD:[0-9]+]] = !DIFile(filename: "{{.*}}DebugInfo/basic.swift", directory: "{{.*}}")
75-
// CHECK-DAG: ![[MAINFILE:[0-9]+]] = !DIFile(filename: "basic.swift", directory: "{{.*}}DebugInfo")
76-
// CHECK-DAG: !DICompileUnit(language: DW_LANG_Swift, file: ![[FILE_CWD]],{{.*}} producer: "{{.*}}Swift version{{.*}},{{.*}}
75+
// CHECK-DAG: ![[MAINFILE:[0-9]+]] = !DIFile(filename: "{{.*}}DebugInfo/basic.swift", directory: "{{.*}}")
76+
// CHECK-DAG: !DICompileUnit(language: DW_LANG_Swift, file: ![[MAINFILE]],{{.*}} producer: "{{.*}}Swift version{{.*}},{{.*}}
7777
// CHECK-DAG: !DISubprogram(name: "main", {{.*}}file: ![[MAINFILE]],
7878

7979
// Function type for foo.

test/DebugInfo/gsil.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %FileCheck %s < %t/out.ir
44
// RUN: %FileCheck %s --check-prefix=CHECK_OUT_SIL < %t/out.ir.gsil_0.sil
55

6-
// CHECK: [[F:![0-9]+]] = !DIFile(filename: "out.ir.gsil_0.sil", directory: "{{.+}}")
6+
// CHECK: [[F:![0-9]+]] = !DIFile(filename: "{{.+}}out.ir.gsil_0.sil",
77
// CHECK: !DISubprogram(linkageName: "$s3out6testityyF", scope: !{{[0-9]+}}, file: [[F]], line: {{[1-9][0-9]+}},
88

99
// CHECK_OUT_SIL: sil @$s3out6testityyF : $@convention(thin) () -> () {

test/DebugInfo/inlinescopes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
// CHECK: define{{( dllexport)?}}{{( protected)?( signext)?}} i32 @main
99
// CHECK: call {{.*}}noinline{{.*}}, !dbg ![[CALL:.*]]
10-
// CHECK-DAG: ![[TOPLEVEL:.*]] = !DIFile(filename: "inlinescopes.swift"
10+
// CHECK-DAG: ![[TOPLEVEL:.*]] = !DIFile(filename: "{{.*}}inlinescopes.swift"
1111

1212
import FooBar
1313

test/DebugInfo/line-directive.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ func f() {
88
markUsed("Test")
99
#sourceLocation(file: "abc.swift", line: 142)
1010
markUsed("abc again")
11-
#sourceLocation(file: "def.swift", line: 142)
11+
#sourceLocation(file: "/absolute/path/def.swift", line: 142)
1212
markUsed("jump directly to def")
1313
}
1414

1515
// RUN: %target-swift-frontend -primary-file %s -S -g -o - | %FileCheck %s
1616
// CHECK: .file [[MAIN:.*]] "{{.*}}line-directive.swift"
1717
// CHECK: .loc [[MAIN]] 1
18-
// CHECK: .file [[ABC:.*]] "abc.swift"
18+
// CHECK: .file [[ABC:.*]] "{{.*}}abc.swift"
1919
// CHECK: .loc [[ABC]] 42
2020
// CHECK: .loc [[MAIN]] 8
2121
// CHECK: .loc [[ABC]] 142
22-
// CHECK: .file [[DEF:.*]] "def.swift"
22+
// CHECK: .file [[DEF:.*]] "/absolute/path/def.swift"
2323
// CHECK: .loc [[DEF]] 142
2424
// CHECK: .asciz "{{.*}}test/DebugInfo"
2525

@@ -28,10 +28,10 @@ func f() {
2828
// RUN: %target-swift-frontend -vfsoverlay %t/overlay.yaml -primary-file %S/vfs-relocated-line-directive.swift -S -g -o - | %FileCheck -check-prefix=VFS %s
2929
// VFS: .file [[MAIN:.*]] "{{.*}}vfs-relocated-line-directive.swift"
3030
// VFS: .loc [[MAIN]] 1
31-
// VFS: .file [[ABC:.*]] "abc.swift"
31+
// VFS: .file [[ABC:.*]] "{{.*}}abc.swift"
3232
// VFS: .loc [[ABC]] 42
3333
// VFS: .loc [[MAIN]] 8
3434
// VFS: .loc [[ABC]] 142
35-
// VFS: .file [[DEF:.*]] "def.swift"
35+
// VFS: .file [[DEF:.*]] "/absolute/path/def.swift"
3636
// VFS: .loc [[DEF]] 142
3737
// VFS: .asciz "{{.*}}test/DebugInfo"

test/DebugInfo/test-foundation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class MyObject : NSObject {
1717
// LOC-CHECK: ret {{.*}}, !dbg ![[DBG:.*]]
1818
// LOC-CHECK: ret
1919
@objc var MyArr = NSArray()
20-
// IMPORT-CHECK: filename: "test-foundation.swift"
20+
// IMPORT-CHECK: filename: "{{.*}}test-foundation.swift"
2121
// IMPORT-CHECK-DAG: [[FOUNDATION:[0-9]+]] = !DIModule({{.*}} name: "Foundation",{{.*}} includePath: {{.*}}Foundation.framework
2222
// IMPORT-CHECK-DAG: [[OVERLAY:[0-9]+]] = !DIModule({{.*}} name: "Foundation",{{.*}} includePath: {{.*}}Foundation.swiftmodule
2323
// IMPORT-CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "NSArray", scope: ![[NSARRAY:[0-9]+]]

test/DebugInfo/variables.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ print(", \(glob_b)", terminator: "")
4141
print(", \(glob_s)", terminator: "")
4242
var unused: Int32 = -1
4343

44-
// CHECK-DAG: ![[RT:[0-9]+]] ={{.*}}"Swift.swiftmodule"
44+
// CHECK-DAG: ![[RT:[0-9]+]] ={{.*}}"{{.*}}Swift.swiftmodule"
4545

4646

4747
// Stack variables.
@@ -114,4 +114,4 @@ func myprint(_ value: TriValue) {
114114
}
115115
myprint(unknown)
116116

117-
// CHECK-DAG: !DIFile(filename: "variables.swift"
117+
// CHECK-DAG: !DIFile(filename: "{{.*}}variables.swift"

test/IRGen/multithread_module.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ func callproto(_ p: MyProto) {
6262

6363
// Check if the DI filename is correct and not "<unknown>".
6464

65-
// CHECK-MAINLL: DICompileUnit(language: DW_LANG_Swift, file: [[F:![0-9]+]]
66-
// CHECK-MAINLL: [[F]] = !DIFile(filename: "{{.*}}IRGen/Inputs/multithread_module/main.swift", directory: "{{.*}}")
65+
// CHECK-MAINLL: [[F:![0-9]+]] = !DIFile(filename: "{{.*}}IRGen/Inputs/multithread_module/main.swift", directory: "{{.*}}")
66+
// CHECK-MAINLL: DICompileUnit(language: DW_LANG_Swift, file: [[F]],
6767

68-
// CHECK-MODULELL: DICompileUnit(language: DW_LANG_Swift, file: [[F:![0-9]+]]
69-
// CHECK-MODULELL: [[F]] = !DIFile(filename: "{{.*}}IRGen/multithread_module.swift", directory: "{{.*}}")
68+
// CHECK-MODULELL: [[F:![0-9]]] = !DIFile(filename: "{{.*}}IRGen/multithread_module.swift", directory: "{{.*}}")
69+
// CHECK-MODULELL: DICompileUnit(language: DW_LANG_Swift, file: [[F]],

0 commit comments

Comments
 (0)