Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -470,10 +470,12 @@ } std::string CGDebugInfo::remapDIPath(StringRef Path) const { + SmallString<256> p = Path; for (const auto &Entry : DebugPrefixMap) - if (Path.startswith(Entry.first)) - return (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); - return Path.str(); + if (llvm::sys::path::replace_path_prefix( + p, Entry.first, Entry.second, llvm::sys::path::Style::native, true)) + break; + return p.str().str(); } unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) { Index: clang/lib/Lex/PPMacroExpansion.cpp =================================================================== --- clang/lib/Lex/PPMacroExpansion.cpp +++ clang/lib/Lex/PPMacroExpansion.cpp @@ -1456,10 +1456,10 @@ const std::map> &MacroPrefixMap) { for (const auto &Entry : MacroPrefixMap) - if (Path.startswith(Entry.first)) { - Path = (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); + if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second, + llvm::sys::path::Style::native, + true)) break; - } } /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded @@ -1543,8 +1543,8 @@ } else { FN += PLoc.getFilename(); } - Lexer::Stringify(FN); remapMacroPath(FN, PPOpts->MacroPrefixMap); + Lexer::Stringify(FN); OS << '"' << FN << '"'; } Tok.setKind(tok::string_literal); Index: clang/test/Preprocessor/file_test.c =================================================================== --- clang/test/Preprocessor/file_test.c +++ clang/test/Preprocessor/file_test.c @@ -1,4 +1,4 @@ -// XFAIL: system-windows +// UNSUPPORTED: system-windows // RUN: %clang -E -ffile-prefix-map=%p=/UNLIKELY_PATH/empty -c -o - %s | FileCheck %s // RUN: %clang -E -fmacro-prefix-map=%p=/UNLIKELY_PATH/empty -c -o - %s | FileCheck %s // RUN: %clang -E -fmacro-prefix-map=%p=/UNLIKELY_PATH=empty -c -o - %s | FileCheck %s -check-prefix CHECK-EVIL @@ -7,14 +7,14 @@ filename: __FILE__ #include "file_test.h" -// CHECK: filename: "/UNLIKELY_PATH/empty{{/|\\\\}}file_test.c" -// CHECK: filename: "/UNLIKELY_PATH/empty{{/|\\\\}}file_test.h" -// CHECK: basefile: "/UNLIKELY_PATH/empty{{/|\\\\}}file_test.c" +// CHECK: filename: "/UNLIKELY_PATH/empty/file_test.c" +// CHECK: filename: "/UNLIKELY_PATH/empty/file_test.h" +// CHECK: basefile: "/UNLIKELY_PATH/empty/file_test.c" // CHECK-NOT: filename: -// CHECK-EVIL: filename: "/UNLIKELY_PATH=empty{{/|\\\\}}file_test.c" -// CHECK-EVIL: filename: "/UNLIKELY_PATH=empty{{/|\\\\}}file_test.h" -// CHECK-EVIL: basefile: "/UNLIKELY_PATH=empty{{/|\\\\}}file_test.c" +// CHECK-EVIL: filename: "/UNLIKELY_PATH=empty/file_test.c" +// CHECK-EVIL: filename: "/UNLIKELY_PATH=empty/file_test.h" +// CHECK-EVIL: basefile: "/UNLIKELY_PATH=empty/file_test.c" // CHECK-EVIL-NOT: filename: // CHECK-REMOVE: filename: "file_test.c" Index: clang/test/Preprocessor/file_test_windows.c =================================================================== --- /dev/null +++ clang/test/Preprocessor/file_test_windows.c @@ -0,0 +1,23 @@ +// REQUIRES: system-windows +// RUN: %clang -E -ffile-prefix-map=%p=A:\UNLIKELY_PATH\empty -c -o - %s | FileCheck %s +// RUN: %clang -E -fmacro-prefix-map=%p=A:\UNLIKELY_PATH\empty -c -o - %s | FileCheck %s +// RUN: %clang -E -fmacro-prefix-map=%p=A:\UNLIKELY_PATH=empty -c -o - %s | FileCheck %s -check-prefix CHECK-EVIL +// RUN: %clang -E -fmacro-prefix-map=%p\= -c -o - %s | FileCheck %s --check-prefix CHECK-REMOVE + +filename: __FILE__ +#include "file_test.h" + +// CHECK: filename: "A:\\UNLIKELY_PATH\\empty{{/|\\\\}}file_test_windows.c" +// CHECK: filename: "A:\\UNLIKELY_PATH\\empty{{/|\\\\}}file_test.h" +// CHECK: basefile: "A:\\UNLIKELY_PATH\\empty{{/|\\\\}}file_test_windows.c" +// CHECK-NOT: filename: + +// CHECK-EVIL: filename: "A:\\UNLIKELY_PATH=empty{{/|\\\\}}file_test_windows.c" +// CHECK-EVIL: filename: "A:\\UNLIKELY_PATH=empty{{/|\\\\}}file_test.h" +// CHECK-EVIL: basefile: "A:\\UNLIKELY_PATH=empty{{/|\\\\}}file_test_windows.c" +// CHECK-EVIL-NOT: filename: + +// CHECK-REMOVE: filename: "file_test_windows.c" +// CHECK-REMOVE: filename: "file_test.h" +// CHECK-REMOVE: basefile: "file_test_windows.c" +// CHECK-REMOVE-NOT: filename: Index: llvm/include/llvm/Support/Path.h =================================================================== --- llvm/include/llvm/Support/Path.h +++ llvm/include/llvm/Support/Path.h @@ -176,9 +176,9 @@ /// separators will only be matched and stripped when present /// in \a OldPrefix. /// @result true if \a Path begins with OldPrefix -bool replace_path_prefix(SmallVectorImpl &Path, - const StringRef &OldPrefix, const StringRef &NewPrefix, - Style style = Style::native, bool strict = false); +bool replace_path_prefix(SmallVectorImpl &Path, StringRef OldPrefix, + StringRef NewPrefix, Style style = Style::native, + bool strict = false); /// Append to path. /// Index: llvm/lib/DWARFLinker/DWARFLinker.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFLinker.cpp +++ llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1920,10 +1920,12 @@ static std::string remapPath(StringRef Path, const objectPrefixMap &ObjectPrefixMap) { + + SmallString<256> p = Path; for (const auto &Entry : ObjectPrefixMap) - if (Path.startswith(Entry.first)) - return (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); - return Path.str(); + if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second)) + break; + return p.str().str(); } bool DWARFLinker::registerModuleReference( Index: llvm/lib/MC/MCContext.cpp =================================================================== --- llvm/lib/MC/MCContext.cpp +++ llvm/lib/MC/MCContext.cpp @@ -589,13 +589,17 @@ void MCContext::RemapDebugPaths() { const auto &DebugPrefixMap = this->DebugPrefixMap; + if (DebugPrefixMap.empty()) + return; + const auto RemapDebugPath = [&DebugPrefixMap](std::string &Path) { - for (const auto &Entry : DebugPrefixMap) - if (StringRef(Path).startswith(Entry.first)) { - std::string RemappedPath = - (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); - Path.swap(RemappedPath); + SmallString<256> p(Path); + for (const auto &Entry : DebugPrefixMap) { + if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second)) { + Path = p.str().str(); + break; } + } }; // Remap compilation directory. Index: llvm/lib/Support/Path.cpp =================================================================== --- llvm/lib/Support/Path.cpp +++ llvm/lib/Support/Path.cpp @@ -496,9 +496,8 @@ path.append(ext.begin(), ext.end()); } -bool replace_path_prefix(SmallVectorImpl &Path, - const StringRef &OldPrefix, const StringRef &NewPrefix, - Style style, bool strict) { +bool replace_path_prefix(SmallVectorImpl &Path, StringRef OldPrefix, + StringRef NewPrefix, Style style, bool strict) { if (OldPrefix.empty() && NewPrefix.empty()) return false; @@ -533,8 +532,10 @@ if (!RelPath.empty()) { if (!is_separator(RelPath[0], style) || !strict) path::append(NewPath, style, RelPath); + else if (!NewPath.empty()) + NewPath += RelPath; // Use the separator from RelPath else - path::append(NewPath, style, relative_path(RelPath, style)); + NewPath = relative_path(RelPath, style); } Path.swap(NewPath);