Index: clang/include/clang/Basic/JsonSupport.h =================================================================== --- clang/include/clang/Basic/JsonSupport.h +++ clang/include/clang/Basic/JsonSupport.h @@ -12,6 +12,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include @@ -98,18 +99,19 @@ if (AddBraces) Out << "{ "; std::string filename(PLoc.getFilename()); -#ifdef _WIN32 - // Remove forbidden Windows path characters - auto RemoveIt = - std::remove_if(filename.begin(), filename.end(), [](auto Char) { - static const char ForbiddenChars[] = "<>*?\"|"; - return std::find(std::begin(ForbiddenChars), std::end(ForbiddenChars), - Char) != std::end(ForbiddenChars); - }); - filename.erase(RemoveIt, filename.end()); - // Handle windows-specific path delimiters. - std::replace(filename.begin(), filename.end(), '\\', '/'); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) { + // Remove forbidden Windows path characters + auto RemoveIt = + std::remove_if(filename.begin(), filename.end(), [](auto Char) { + static const char ForbiddenChars[] = "<>*?\"|"; + return std::find(std::begin(ForbiddenChars), + std::end(ForbiddenChars), + Char) != std::end(ForbiddenChars); + }); + filename.erase(RemoveIt, filename.end()); + // Handle windows-specific path delimiters. + std::replace(filename.begin(), filename.end(), '\\', '/'); + } Out << "\"line\": " << PLoc.getLine() << ", \"column\": " << PLoc.getColumn() << ", \"file\": \"" << filename << "\""; Index: clang/lib/Basic/FileManager.cpp =================================================================== --- clang/lib/Basic/FileManager.cpp +++ clang/lib/Basic/FileManager.cpp @@ -123,16 +123,16 @@ DirName != llvm::sys::path::root_path(DirName) && llvm::sys::path::is_separator(DirName.back())) DirName = DirName.substr(0, DirName.size()-1); -#ifdef _WIN32 - // Fixing a problem with "clang C:test.c" on Windows. - // Stat("C:") does not recognize "C:" as a valid directory - std::string DirNameStr; - if (DirName.size() > 1 && DirName.back() == ':' && - DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) { - DirNameStr = DirName.str() + '.'; - DirName = DirNameStr; + if (is_style_windows(llvm::sys::path::Style::native)) { + // Fixing a problem with "clang C:test.c" on Windows. + // Stat("C:") does not recognize "C:" as a valid directory + std::string DirNameStr; + if (DirName.size() > 1 && DirName.back() == ':' && + DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) { + DirNameStr = DirName.str() + '.'; + DirName = DirNameStr; + } } -#endif ++NumDirLookups; Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -4890,11 +4890,11 @@ bool MultipleArchs, StringRef OffloadingPrefix) const { std::string BoundArch = OrigBoundArch.str(); -#if defined(_WIN32) - // BoundArch may contains ':', which is invalid in file names on Windows, - // therefore replace it with '%'. - std::replace(BoundArch.begin(), BoundArch.end(), ':', '@'); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) { + // BoundArch may contains ':', which is invalid in file names on Windows, + // therefore replace it with '%'. + std::replace(BoundArch.begin(), BoundArch.end(), ':', '@'); + } llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? Index: clang/lib/Driver/ToolChain.cpp =================================================================== --- clang/lib/Driver/ToolChain.cpp +++ clang/lib/Driver/ToolChain.cpp @@ -169,10 +169,11 @@ /// present and lower-casing the string on Windows. static std::string normalizeProgramName(llvm::StringRef Argv0) { std::string ProgName = std::string(llvm::sys::path::stem(Argv0)); -#ifdef _WIN32 - // Transform to lowercase for case insensitive file systems. - std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) { + // Transform to lowercase for case insensitive file systems. + std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), + ::tolower); + } return ProgName; } Index: clang/lib/Lex/PPDirectives.cpp =================================================================== --- clang/lib/Lex/PPDirectives.cpp +++ clang/lib/Lex/PPDirectives.cpp @@ -2012,20 +2012,16 @@ SourceLocation FilenameLoc = FilenameTok.getLocation(); StringRef LookupFilename = Filename; -#ifdef _WIN32 - llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::windows; -#else // Normalize slashes when compiling with -fms-extensions on non-Windows. This // is unnecessary on Windows since the filesystem there handles backslashes. SmallString<128> NormalizedPath; - llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::posix; - if (LangOpts.MicrosoftExt) { + llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native; + if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) { NormalizedPath = Filename.str(); llvm::sys::path::native(NormalizedPath); LookupFilename = NormalizedPath; BackslashStyle = llvm::sys::path::Style::windows; } -#endif Optional File = LookupHeaderIncludeOrImport( CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok, Index: clang/unittests/Basic/FileManagerTest.cpp =================================================================== --- clang/unittests/Basic/FileManagerTest.cpp +++ clang/unittests/Basic/FileManagerTest.cpp @@ -31,18 +31,18 @@ void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile, const char *StatPath) { -#ifndef _WIN32 SmallString<128> NormalizedPath(Path); - llvm::sys::path::native(NormalizedPath); - Path = NormalizedPath.c_str(); - SmallString<128> NormalizedStatPath; - if (StatPath) { - NormalizedStatPath = StatPath; - llvm::sys::path::native(NormalizedStatPath); - StatPath = NormalizedStatPath.c_str(); + if (is_style_windows(llvm::sys::path::Style::native)) { + llvm::sys::path::native(NormalizedPath); + Path = NormalizedPath.c_str(); + + if (StatPath) { + NormalizedStatPath = StatPath; + llvm::sys::path::native(NormalizedStatPath); + StatPath = NormalizedStatPath.c_str(); + } } -#endif if (!StatPath) StatPath = Path; @@ -74,11 +74,11 @@ bool isFile, std::unique_ptr *F, llvm::vfs::FileSystem &FS) override { -#ifndef _WIN32 SmallString<128> NormalizedPath(Path); - llvm::sys::path::native(NormalizedPath); - Path = NormalizedPath.c_str(); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) { + llvm::sys::path::native(NormalizedPath); + Path = NormalizedPath.c_str(); + } if (StatCalls.count(Path) != 0) { Status = StatCalls[Path]; @@ -436,13 +436,16 @@ #endif // !_WIN32 +static StringRef getSystemRoot() { + return is_style_windows(llvm::sys::path::Style::native) ? "C:/" : "/"; +} + TEST_F(FileManagerTest, makeAbsoluteUsesVFS) { - SmallString<64> CustomWorkingDir; -#ifdef _WIN32 - CustomWorkingDir = "C:"; -#else - CustomWorkingDir = "/"; -#endif + // FIXME: Should this be using a root path / call getSystemRoot()? For now, + // avoiding that and leaving the test as-is. + SmallString<64> CustomWorkingDir = + is_style_windows(llvm::sys::path::Style::native) ? StringRef("C:") + : StringRef("/"); llvm::sys::path::append(CustomWorkingDir, "some", "weird", "path"); auto FS = IntrusiveRefCntPtr( @@ -464,12 +467,7 @@ // getVirtualFile should always fill the real path. TEST_F(FileManagerTest, getVirtualFileFillsRealPathName) { - SmallString<64> CustomWorkingDir; -#ifdef _WIN32 - CustomWorkingDir = "C:/"; -#else - CustomWorkingDir = "/"; -#endif + SmallString<64> CustomWorkingDir = getSystemRoot(); auto FS = IntrusiveRefCntPtr( new llvm::vfs::InMemoryFileSystem); @@ -497,12 +495,7 @@ } TEST_F(FileManagerTest, getFileDontOpenRealPath) { - SmallString<64> CustomWorkingDir; -#ifdef _WIN32 - CustomWorkingDir = "C:/"; -#else - CustomWorkingDir = "/"; -#endif + SmallString<64> CustomWorkingDir = getSystemRoot(); auto FS = IntrusiveRefCntPtr( new llvm::vfs::InMemoryFileSystem); Index: clang/unittests/Driver/ToolChainTest.cpp =================================================================== --- clang/unittests/Driver/ToolChainTest.cpp +++ clang/unittests/Driver/ToolChainTest.cpp @@ -85,9 +85,8 @@ llvm::raw_string_ostream OS(S); C->getDefaultToolChain().printVerboseInfo(OS); } -#if _WIN32 - std::replace(S.begin(), S.end(), '\\', '/'); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) + std::replace(S.begin(), S.end(), '\\', '/'); EXPECT_EQ( "Found candidate GCC installation: " "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" @@ -110,9 +109,8 @@ llvm::raw_string_ostream OS(S); C->getDefaultToolChain().printVerboseInfo(OS); } -#if _WIN32 - std::replace(S.begin(), S.end(), '\\', '/'); -#endif + if (is_style_windows(llvm::sys::path::Style::native)) + std::replace(S.begin(), S.end(), '\\', '/'); // Test that 4.5.3 from --sysroot is not overridden by 4.6.3 (larger // version) from /usr. EXPECT_EQ("Found candidate GCC installation: " @@ -153,9 +151,8 @@ llvm::raw_string_ostream OS(S); C->getDefaultToolChain().printVerboseInfo(OS); } -#if _WIN32 - std::replace(S.begin(), S.end(), '\\', '/'); -#endif + if (is_style_windows(llvm::sys::path::Style::windows)) + std::replace(S.begin(), S.end(), '\\', '/'); EXPECT_EQ("Found candidate GCC installation: " "/home/test/bin/../lib/gcc/arm-linux-gnueabi/4.6.1\n" "Selected GCC installation: " Index: clang/unittests/Lex/HeaderSearchTest.cpp =================================================================== --- clang/unittests/Lex/HeaderSearchTest.cpp +++ clang/unittests/Lex/HeaderSearchTest.cpp @@ -188,11 +188,11 @@ std::string HeaderDirName = "/tmp/Sources/Foo/Headers/"; std::string HeaderName = "Foo.h"; -#ifdef _WIN32 - // Force header path to be absolute on windows. - // As headermap content should represent absolute locations. - HeaderDirName = "C:" + HeaderDirName; -#endif /*_WIN32*/ + if (is_style_windows(llvm::sys::path::Style::native)) { + // Force header path to be absolute on windows. + // As headermap content should represent absolute locations. + HeaderDirName = "C:" + HeaderDirName; + } test::HMapFileMockMaker Maker(File); auto a = Maker.addString("Foo/Foo.h"); Index: clang/unittests/Tooling/RefactoringTest.cpp =================================================================== --- clang/unittests/Tooling/RefactoringTest.cpp +++ clang/unittests/Tooling/RefactoringTest.cpp @@ -1031,18 +1031,17 @@ toReplacements({{"", 0, 3, "cc"}, {"", 3, 3, "dd"}})); } +static constexpr bool usesWindowsPaths() { + return is_style_windows(llvm::sys::path::Style::native); +} + TEST(DeduplicateByFileTest, PathsWithDots) { std::map FileToReplaces; llvm::IntrusiveRefCntPtr VFS( new llvm::vfs::InMemoryFileSystem()); FileManager FileMgr(FileSystemOptions(), VFS); -#if !defined(_WIN32) - StringRef Path1 = "a/b/.././c.h"; - StringRef Path2 = "a/c.h"; -#else - StringRef Path1 = "a\\b\\..\\.\\c.h"; - StringRef Path2 = "a\\c.h"; -#endif + StringRef Path1 = usesWindowsPaths() ? "a\\b\\..\\.\\c.h" : "a/b/.././c.h"; + StringRef Path2 = usesWindowsPaths() ? "a\\c.h" : "a/c.h"; EXPECT_TRUE(VFS->addFile(Path1, 0, llvm::MemoryBuffer::getMemBuffer(""))); EXPECT_TRUE(VFS->addFile(Path2, 0, llvm::MemoryBuffer::getMemBuffer(""))); FileToReplaces[std::string(Path1)] = Replacements(); @@ -1057,13 +1056,8 @@ llvm::IntrusiveRefCntPtr VFS( new llvm::vfs::InMemoryFileSystem()); FileManager FileMgr(FileSystemOptions(), VFS); -#if !defined(_WIN32) - StringRef Path1 = "./a/b/c.h"; - StringRef Path2 = "a/b/c.h"; -#else - StringRef Path1 = ".\\a\\b\\c.h"; - StringRef Path2 = "a\\b\\c.h"; -#endif + StringRef Path1 = usesWindowsPaths() ? ".\\a\\b\\c.h" : "./a/b/c.h"; + StringRef Path2 = usesWindowsPaths() ? "a\\b\\c.h" : "a/b/c.h"; EXPECT_TRUE(VFS->addFile(Path1, 0, llvm::MemoryBuffer::getMemBuffer(""))); EXPECT_TRUE(VFS->addFile(Path2, 0, llvm::MemoryBuffer::getMemBuffer(""))); FileToReplaces[std::string(Path1)] = Replacements(); @@ -1078,13 +1072,8 @@ llvm::IntrusiveRefCntPtr VFS( new llvm::vfs::InMemoryFileSystem()); FileManager FileMgr(FileSystemOptions(), VFS); -#if !defined(_WIN32) - StringRef Path1 = "./a/b/c.h"; - StringRef Path2 = "a/b/c.h"; -#else - StringRef Path1 = ".\\a\\b\\c.h"; - StringRef Path2 = "a\\b\\c.h"; -#endif + StringRef Path1 = usesWindowsPaths() ? ".\\a\\b\\c.h" : "./a/b/c.h"; + StringRef Path2 = usesWindowsPaths() ? "a\\b\\c.h" : "a/b/c.h"; FileToReplaces[std::string(Path1)] = Replacements(); FileToReplaces[std::string(Path2)] = Replacements(); FileToReplaces = groupReplacementsByFile(FileMgr, FileToReplaces); Index: llvm/include/llvm/Support/VirtualFileSystem.h =================================================================== --- llvm/include/llvm/Support/VirtualFileSystem.h +++ llvm/include/llvm/Support/VirtualFileSystem.h @@ -788,12 +788,7 @@ /// Whether to perform case-sensitive comparisons. /// /// Currently, case-insensitive matching only works correctly with ASCII. - bool CaseSensitive = -#ifdef _WIN32 - false; -#else - true; -#endif + bool CaseSensitive = is_style_posix(sys::path::Style::native); /// IsRelativeOverlay marks whether a ExternalContentsPrefixDir path must /// be prefixed in every 'external-contents' when reading from YAML files. Index: llvm/lib/Support/GraphWriter.cpp =================================================================== --- llvm/lib/Support/GraphWriter.cpp +++ llvm/lib/Support/GraphWriter.cpp @@ -23,11 +23,12 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" #include -#include #include +#include #include using namespace llvm; @@ -94,11 +95,8 @@ static std::string replaceIllegalFilenameChars(std::string Filename, const char ReplacementChar) { -#ifdef _WIN32 - std::string IllegalChars = "\\/:?\"<>|"; -#else - std::string IllegalChars = "/"; -#endif + std::string IllegalChars = + is_style_windows(sys::path::Style::native) ? "\\/:?\"<>|" : "/"; for (char IllegalChar : IllegalChars) { std::replace(Filename.begin(), Filename.end(), IllegalChar, Index: llvm/lib/Support/Path.cpp =================================================================== --- llvm/lib/Support/Path.cpp +++ llvm/lib/Support/Path.cpp @@ -64,7 +64,7 @@ if (path.empty()) return path; - if (real_style(style) == Style::windows) { + if (is_style_windows(style)) { // C: if (path.size() >= 2 && std::isalpha(static_cast(path[0])) && path[1] == ':') @@ -96,7 +96,7 @@ size_t pos = str.find_last_of(separators(style), str.size() - 1); - if (real_style(style) == Style::windows) { + if (is_style_windows(style)) { if (pos == StringRef::npos) pos = str.find_last_of(':', str.size() - 2); } @@ -111,7 +111,7 @@ // directory in str, it returns StringRef::npos. size_t root_dir_start(StringRef str, Style style) { // case "c:/" - if (real_style(style) == Style::windows) { + if (is_style_windows(style)) { if (str.size() > 2 && str[1] == ':' && is_separator(str[2], style)) return 2; } @@ -257,7 +257,7 @@ // Root dir. if (was_net || // c:/ - (real_style(S) == Style::windows && Component.endswith(":"))) { + (is_style_windows(S) && Component.endswith(":"))) { Component = Path.substr(Position, 1); return *this; } @@ -346,7 +346,7 @@ if (b != e) { bool has_net = b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; - bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); + bool has_drive = is_style_windows(style) && b->endswith(":"); if (has_net || has_drive) { if ((++pos != e) && is_separator((*pos)[0], style)) { @@ -371,7 +371,7 @@ if (b != e) { bool has_net = b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; - bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); + bool has_drive = is_style_windows(style) && b->endswith(":"); if (has_net || has_drive) { // just {C:,//net}, return the first component. @@ -388,7 +388,7 @@ if (b != e) { bool has_net = b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; - bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); + bool has_drive = is_style_windows(style) && b->endswith(":"); if ((has_net || has_drive) && // {C:,//net}, skip to the next component. @@ -495,7 +495,7 @@ static bool starts_with(StringRef Path, StringRef Prefix, Style style = Style::native) { // Windows prefix matching : case and separator insensitive - if (real_style(style) == Style::windows) { + if (is_style_windows(style)) { if (Path.size() < Prefix.size()) return false; for (size_t I = 0, E = Prefix.size(); I != E; ++I) { @@ -595,7 +595,7 @@ bool is_separator(char value, Style style) { if (value == '/') return true; - if (real_style(style) == Style::windows) + if (is_style_windows(style)) return value == '\\'; return false; } @@ -667,8 +667,7 @@ StringRef p = path.toStringRef(path_storage); bool rootDir = has_root_directory(p, style); - bool rootName = - (real_style(style) != Style::windows) || has_root_name(p, style); + bool rootName = is_style_posix(style) || has_root_name(p, style); return rootDir && rootName; } @@ -682,7 +681,7 @@ if (!p.empty() && is_separator(p.front(), style)) return true; - if (real_style(style) == Style::windows) { + if (is_style_windows(style)) { // Handle drive letter pattern (a character followed by ':') on Windows. if (p.size() >= 2 && (p[0] && p[1] == ':')) return true; @@ -902,8 +901,7 @@ bool rootName = path::has_root_name(p); // Already absolute. - if ((rootName || real_style(Style::native) != Style::windows) && - rootDirectory) + if ((rootName || is_style_posix(Style::native)) && rootDirectory) return; // All of the following conditions will need the current directory. Index: llvm/tools/lli/lli.cpp =================================================================== --- llvm/tools/lli/lli.cpp +++ llvm/tools/lli/lli.cpp @@ -355,13 +355,12 @@ return false; std::string CacheSubdir = ModID.substr(PrefixLength); -#if defined(_WIN32) - // Transform "X:\foo" => "/X\foo" for convenience. - if (isalpha(CacheSubdir[0]) && CacheSubdir[1] == ':') { + // Transform "X:\foo" => "/X\foo" for convenience on Windows. + if (is_style_windows(llvm::sys::path::Style::native) && + isalpha(CacheSubdir[0]) && CacheSubdir[1] == ':') { CacheSubdir[1] = CacheSubdir[0]; CacheSubdir[0] = '/'; } -#endif CacheName = CacheDir + CacheSubdir; size_t pos = CacheName.rfind('.'); Index: llvm/unittests/Support/Path.cpp =================================================================== --- llvm/unittests/Support/Path.cpp +++ llvm/unittests/Support/Path.cpp @@ -101,8 +101,7 @@ EXPECT_TRUE(path::is_separator('\\', path::Style::windows)); EXPECT_FALSE(path::is_separator('\\', path::Style::posix)); - EXPECT_EQ(path::is_style_windows(path::Style::native), - path::is_separator('\\')); + EXPECT_EQ(is_style_windows(path::Style::native), path::is_separator('\\')); } TEST(is_absolute_gnu, Works) {