Index: include/llvm/Support/Path.h =================================================================== --- include/llvm/Support/Path.h +++ include/llvm/Support/Path.h @@ -160,7 +160,8 @@ /// start with \a NewPrefix. /// @param OldPrefix The path prefix to strip from \a Path. /// @param NewPrefix The path prefix to replace \a NewPrefix with. -void replace_path_prefix(SmallVectorImpl &Path, +/// @result true if \a Path begins with OldPrefix +bool replace_path_prefix(SmallVectorImpl &Path, const StringRef &OldPrefix, const StringRef &NewPrefix, Style style = Style::native); Index: lib/Support/Path.cpp =================================================================== --- lib/Support/Path.cpp +++ lib/Support/Path.cpp @@ -521,27 +521,43 @@ path.append(ext.begin(), ext.end()); } -void replace_path_prefix(SmallVectorImpl &Path, +bool replace_path_prefix(SmallVectorImpl &Path, const StringRef &OldPrefix, const StringRef &NewPrefix, Style style) { if (OldPrefix.empty() && NewPrefix.empty()) - return; + return false; StringRef OrigPath(Path.begin(), Path.size()); - if (!OrigPath.startswith(OldPrefix)) - return; + if ((is_separator(OldPrefix.back(), style) && + !OrigPath.startswith(parent_path(OldPrefix, style))) || + (!is_separator(OldPrefix.back(), style) && + !OrigPath.startswith(OldPrefix))) + return false; + + if (!is_separator(OldPrefix.back(), style) && + !(OldPrefix == OrigPath || + is_separator(OrigPath[OldPrefix.size()], style))) + return false; + // If prefixes have the same size we can simply copy the new one over. if (OldPrefix.size() == NewPrefix.size()) { llvm::copy(NewPrefix, Path.begin()); - return; + return true; } StringRef RelPath = OrigPath.substr(OldPrefix.size()); SmallString<256> NewPath; path::append(NewPath, style, NewPrefix); - path::append(NewPath, style, RelPath); + if (!is_separator(RelPath[0], style)) + path::append(NewPath, style, RelPath); + else + path::append(NewPath, style, relative_path(RelPath, style)); + while (is_separator(NewPath.back(), style)) + NewPath.set_size(NewPath.size() - 1); Path.swap(NewPath); + + return true; } void native(const Twine &path, SmallVectorImpl &result, Style style) {