Index: llvm/include/llvm/Support/FileSystem.h =================================================================== --- llvm/include/llvm/Support/FileSystem.h +++ llvm/include/llvm/Support/FileSystem.h @@ -349,6 +349,13 @@ std::error_code real_path(const Twine &path, SmallVectorImpl &output, bool expand_tilde = false); +/// Expands ~ expressions to the user's home directory. +/// +/// @param path The path to resolve. +/// @returns errc::success if the current path has been resolved in output, +/// otherwise a platform-specific error_code. +std::error_code expand_tilde(const Twine &path, SmallVectorImpl &output); + /// Get the current path. /// /// @param result Holds the current path on return. Index: llvm/lib/Support/Unix/Path.inc =================================================================== --- llvm/lib/Support/Unix/Path.inc +++ llvm/lib/Support/Unix/Path.inc @@ -550,6 +550,18 @@ llvm::sys::path::append(Path, Storage); } + +std::error_code expand_tilde(const Twine &path, SmallVectorImpl &dest) { + dest.clear(); + if (path.isTriviallyEmpty()) + return std::error_code(); + + path.toVector(dest); + expandTildeExpr(dest); + + return std::error_code(); +} + static file_type typeForMode(mode_t Mode) { if (S_ISDIR(Mode)) return file_type::directory_file; Index: llvm/lib/Support/Windows/Path.inc =================================================================== --- llvm/lib/Support/Windows/Path.inc +++ llvm/lib/Support/Windows/Path.inc @@ -1253,6 +1253,17 @@ Path.insert(Path.begin() + 1, HomeDir.begin() + 1, HomeDir.end()); } +std::error_code expand_tilde(const Twine &path, SmallVectorImpl &dest) { + dest.clear(); + if (path.isTriviallyEmpty()) + return std::error_code(); + + path.toVector(dest); + expandTildeExpr(dest); + + return std::error_code(); +} + std::error_code real_path(const Twine &path, SmallVectorImpl &dest, bool expand_tilde) { dest.clear(); Index: llvm/unittests/Support/Path.cpp =================================================================== --- llvm/unittests/Support/Path.cpp +++ llvm/unittests/Support/Path.cpp @@ -528,6 +528,28 @@ ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1")); } +TEST_F(FileSystemTest, ExpandTilde) { + ASSERT_NO_ERROR( + fs::create_directories(Twine(TestDirectory) + "/test1/test2/test3")); + ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/test1/test2/test3")); + + SmallString<64> RealBase; + SmallString<64> Expected; + SmallString<64> Actual; + + SmallString<64> HomeDir; + bool Result = llvm::sys::path::home_directory(HomeDir); + if (Result) { + ASSERT_NO_ERROR(fs::expand_tilde(HomeDir, Expected)); + ASSERT_NO_ERROR(fs::expand_tilde("~", Actual)); + EXPECT_EQ(Expected, Actual); + ASSERT_NO_ERROR(fs::expand_tilde("~/", Actual)); + EXPECT_EQ(Expected, Actual); + } + + ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1")); +} + #ifdef LLVM_ON_UNIX TEST_F(FileSystemTest, RealPathNoReadPerm) { SmallString<64> Expanded;