Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -407,13 +407,13 @@ SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(Loc); - if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty()) + StringRef FileName = PLoc.getFilename(); + if (PLoc.isInvalid() || FileName.empty()) // If the location is not valid then use main input file. return getOrCreateMainFile(); // Cache the results. - const char *fname = PLoc.getFilename(); - auto It = DIFileCache.find(fname); + auto It = DIFileCache.find(FileName.data()); if (It != DIFileCache.end()) { // Verify that the information still exists. @@ -428,11 +428,34 @@ if (CSKind) CSInfo.emplace(*CSKind, Checksum); - llvm::DIFile *F = DBuilder.createFile( - remapDIPath(PLoc.getFilename()), remapDIPath(getCurrentDirname()), CSInfo, - getSource(SM, SM.getFileID(Loc))); + StringRef Dir; + StringRef File; + std::string RemappedFile = remapDIPath(FileName); + std::string CurDir = remapDIPath(getCurrentDirname()); + SmallString<128> DirBuf; + SmallString<128> FileBuf; + if (llvm::sys::path::is_absolute(RemappedFile)) { + // Strip the common prefix from current directory and FileName for + // a more space-efficient encoding. + auto FileIt = llvm::sys::path::begin(RemappedFile); + auto FileE = llvm::sys::path::end(RemappedFile); + auto CurDirIt = llvm::sys::path::begin(CurDir); + auto CurDirE = llvm::sys::path::end(CurDir); + for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt) + llvm::sys::path::append(DirBuf, *CurDirIt); + for (; FileIt != FileE; ++FileIt) + llvm::sys::path::append(FileBuf, *FileIt); + Dir = DirBuf; + File = FileBuf; + } else { + Dir = CurDir; + File = RemappedFile; + } + llvm::DIFile *F = + DBuilder.createFile(File, Dir, CSInfo, + getSource(SM, SM.getFileID(Loc))); - DIFileCache[fname].reset(F); + DIFileCache[FileName.data()].reset(F); return F; } Index: test/CodeGen/debug-info-abspath.c =================================================================== --- /dev/null +++ test/CodeGen/debug-info-abspath.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \ +// RUN: %s -emit-llvm -o - | FileCheck %s + +// RUN: cp %s %t.c +// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \ +// RUN: %t.c -emit-llvm -o - | FileCheck %s --check-prefix=INTREE +void foo() {} + +// Since %s is an absolute path, directory should be a nonempty +// prefix, but the CodeGen part should be part of the filename. + +// CHECK: DIFile(filename: "{{.*}}CodeGen{{.*}}debug-info-abspath.c" +// CHECK-SAME: directory: "{{.+}}") + +// INTREE: DIFile({{.*}}directory: "{{.+}}CodeGen{{.*}}") Index: test/CodeGen/debug-prefix-map.c =================================================================== --- test/CodeGen/debug-prefix-map.c +++ test/CodeGen/debug-prefix-map.c @@ -17,18 +17,22 @@ } // CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{/|\\5C}}" -// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}" -// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h" +// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "var/empty{{[/\\]}}{{.*}}", +// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "/") +// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "var/empty{{[/\\]}}Inputs/stdio.h", +// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "/") // CHECK-NO-MAIN-FILE-NAME-NOT: !DIFile(filename: // CHECK-EVIL: !DIFile(filename: "/var=empty{{[/\\]}}{{.*}}" -// CHECK-EVIL: !DIFile(filename: "/var=empty{{[/\\]}}Inputs/stdio.h" +// CHECK-EVIL: !DIFile(filename: "var=empty{{[/\\]}}{{.*}}Inputs/stdio.h", +// CHECK-EVIL-SAME: directory: "/") // CHECK-EVIL-NOT: !DIFile(filename: // CHECK: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}" -// CHECK: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h" +// CHECK: !DIFile(filename: "var/empty{{[/\\]}}{{.*}}Inputs/stdio.h", +// CHECK-SAME: directory: "/") // CHECK-NOT: !DIFile(filename: -// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}", directory: "/var/empty") -// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h", directory: "/var/empty") +// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}", directory: "/var/empty") +// CHECK-COMPILATION-DIR: !DIFile(filename: "Inputs/stdio.h", directory: "/var/empty") // CHECK-COMPILATION-DIR-NOT: !DIFile(filename: