Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -181,8 +181,7 @@ SourceManager &SM = CGM.getContext().getSourceManager(); auto *Scope = cast(LexicalBlockStack.back()); PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc); - - if (PCLoc.isInvalid() || Scope->getFilename() == PCLoc.getFilename()) + if (PCLoc.isInvalid() || Scope->getFile() == getOrCreateFile(CurLoc)) return; if (auto *LBF = dyn_cast(Scope)) { @@ -410,13 +409,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. @@ -431,11 +430,41 @@ 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 (if it is more than just "/") 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); + if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) { + // The common prefix only the root; stripping it would cause + // LLVM diagnostic locations to be more confusing. + Dir = {}; + File = RemappedFile; + } else { + 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: lib/CodeGen/CodeGenAction.cpp =================================================================== --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -549,12 +549,16 @@ SourceLocation DILoc; if (D.isLocationAvailable()) { - D.getLocation(&Filename, &Line, &Column); - const FileEntry *FE = FileMgr.getFile(Filename); - if (FE && Line > 0) { - // If -gcolumn-info was not used, Column will be 0. This upsets the - // source manager, so pass 1 if Column is not set. - DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); + D.getLocation(Filename, Line, Column); + if (Line > 0) { + const FileEntry *FE = FileMgr.getFile(Filename); + if (!FE) + FE = FileMgr.getFile(D.getAbsolutePath()); + if (FE) { + // If -gcolumn-info was not used, Column will be 0. This upsets the + // source manager, so pass 1 if Column is not set. + DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); + } } BadDebugInfo = DILoc.isInvalid(); } Index: test/CodeGen/debug-info-abspath.c =================================================================== --- test/CodeGen/debug-info-abspath.c +++ 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: Index: test/Modules/module-debuginfo-prefix.m =================================================================== --- test/Modules/module-debuginfo-prefix.m +++ test/Modules/module-debuginfo-prefix.m @@ -20,4 +20,4 @@ @import DebugObjC; #endif -// CHECK: !DIFile({{.*}}"/OVERRIDE/DebugObjC.h" +// CHECK: !DIFile(filename: "/OVERRIDE/DebugObjC.h", directory: "")