Index: include/clang/Basic/ConvertUTF.h
===================================================================
--- include/clang/Basic/ConvertUTF.h	(revision 145028)
+++ include/clang/Basic/ConvertUTF.h	(working copy)
@@ -135,11 +135,12 @@
   const UTF8** sourceStart, const UTF8* sourceEnd,
   UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
 
-#ifdef CLANG_NEEDS_THESE_ONE_DAY
 ConversionResult ConvertUTF16toUTF8 (
   const UTF16** sourceStart, const UTF16* sourceEnd,
   UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
 
+#ifdef CLANG_NEEDS_THESE_ONE_DAY
+
 ConversionResult ConvertUTF32toUTF8 (
   const UTF32** sourceStart, const UTF32* sourceEnd,
   UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
Index: lib/Basic/ConvertUTF.c
===================================================================
--- lib/Basic/ConvertUTF.c	(revision 145028)
+++ lib/Basic/ConvertUTF.c	(working copy)
@@ -218,74 +218,7 @@
 #endif
     return result;
 }
-ConversionResult ConvertUTF16toUTF8 (
-        const UTF16** sourceStart, const UTF16* sourceEnd, 
-        UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
-    ConversionResult result = conversionOK;
-    const UTF16* source = *sourceStart;
-    UTF8* target = *targetStart;
-    while (source < sourceEnd) {
-        UTF32 ch;
-        unsigned short bytesToWrite = 0;
-        const UTF32 byteMask = 0xBF;
-        const UTF32 byteMark = 0x80; 
-        const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
-        ch = *source++;
-        /* If we have a surrogate pair, convert to UTF32 first. */
-        if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
-            /* If the 16 bits following the high surrogate are in the source buffer... */
-            if (source < sourceEnd) {
-                UTF32 ch2 = *source;
-                /* If it's a low surrogate, convert to UTF32. */
-                if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
-                    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
-                        + (ch2 - UNI_SUR_LOW_START) + halfBase;
-                    ++source;
-                } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
-                    --source; /* return to the illegal value itself */
-                    result = sourceIllegal;
-                    break;
-                }
-            } else { /* We don't have the 16 bits following the high surrogate. */
-                --source; /* return to the high surrogate */
-                result = sourceExhausted;
-                break;
-            }
-        } else if (flags == strictConversion) {
-            /* UTF-16 surrogate values are illegal in UTF-32 */
-            if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
-                --source; /* return to the illegal value itself */
-                result = sourceIllegal;
-                break;
-            }
-        }
-        /* Figure out how many bytes the result will require */
-        if (ch < (UTF32)0x80) {      bytesToWrite = 1;
-        } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
-        } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
-        } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
-        } else {                            bytesToWrite = 3;
-                                            ch = UNI_REPLACEMENT_CHAR;
-        }
 
-        target += bytesToWrite;
-        if (target > targetEnd) {
-            source = oldSource; /* Back up source pointer! */
-            target -= bytesToWrite; result = targetExhausted; break;
-        }
-        switch (bytesToWrite) { /* note: everything falls through. */
-            case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-            case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-            case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-            case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
-        }
-        target += bytesToWrite;
-    }
-    *sourceStart = source;
-    *targetStart = target;
-    return result;
-}
-
 /* --------------------------------------------------------------------- */
 
 ConversionResult ConvertUTF32toUTF8 (
@@ -546,3 +479,76 @@
     similarly unrolled loops.
 
    --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (
+  const UTF16** sourceStart, const UTF16* sourceEnd, 
+  UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+      UTF32 ch;
+      unsigned short bytesToWrite = 0;
+      const UTF32 byteMask = 0xBF;
+      const UTF32 byteMark = 0x80; 
+      const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+      ch = *source++;
+      /* If we have a surrogate pair, convert to UTF32 first. */
+      if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+        /* If the 16 bits following the high surrogate are in the source buffer... */
+        if (source < sourceEnd) {
+          UTF32 ch2 = *source;
+          /* If it's a low surrogate, convert to UTF32. */
+          if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+            ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+              + (ch2 - UNI_SUR_LOW_START) + halfBase;
+            ++source;
+          } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+            --source; /* return to the illegal value itself */
+            result = sourceIllegal;
+            break;
+          }
+        } else { /* We don't have the 16 bits following the high surrogate. */
+          --source; /* return to the high surrogate */
+          result = sourceExhausted;
+          break;
+        }
+      } else if (flags == strictConversion) {
+        /* UTF-16 surrogate values are illegal in UTF-32 */
+        if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+          --source; /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        }
+      }
+      /* Figure out how many bytes the result will require */
+      if (ch < (UTF32)0x80)
+        bytesToWrite = 1;
+      else if (ch < (UTF32)0x800)
+        bytesToWrite = 2;
+      else if (ch < (UTF32)0x10000)
+        bytesToWrite = 3;
+      else if (ch < (UTF32)0x110000)
+        bytesToWrite = 4;
+      else {
+        bytesToWrite = 3;
+        ch = UNI_REPLACEMENT_CHAR;
+      }
+
+      target += bytesToWrite;
+      if (target > targetEnd) {
+        source = oldSource; /* Back up source pointer! */
+        target -= bytesToWrite; result = targetExhausted; break;
+      }
+      switch (bytesToWrite) { /* note: everything falls through. */
+      case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+      case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+      case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+      case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+      }
+      target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
Index: lib/Basic/FileManager.cpp
===================================================================
--- lib/Basic/FileManager.cpp	(revision 145028)
+++ lib/Basic/FileManager.cpp	(working copy)
@@ -17,6 +17,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/ConvertUTF.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemStatCache.h"
 #include "llvm/ADT/SmallString.h"
@@ -26,6 +27,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/system_error.h"
 #include "llvm/Config/config.h"
+#include <locale>
 #include <map>
 #include <set>
 #include <string>
@@ -64,14 +66,43 @@
 #ifdef LLVM_ON_WIN32
 
 namespace {
-  static std::string GetFullPath(const char *relPath) {
-    char *absPathStrPtr = _fullpath(NULL, relPath, 0);
-    assert(absPathStrPtr && "_fullpath() returned NULL!");
+  static std::string GetFullPath(const char *relPath, bool convertToLowercase) {
+    StringRef String(relPath);
+    unsigned NumBytes = String.size() + 1;
+    SmallVector<UTF16, 128> utf16(NumBytes);
+    const UTF8 *FromUTF8Ptr = (UTF8 *)String.data();
+    UTF16 *ToUTF16Ptr = &utf16[0];
 
-    std::string absPath(absPathStrPtr);
+    ConversionResult Result = ConvertUTF8toUTF16(&FromUTF8Ptr,
+                                                 FromUTF8Ptr + NumBytes,
+                                                 &ToUTF16Ptr,
+                                                 ToUTF16Ptr + NumBytes,
+                                                 strictConversion);
+    assert(Result == conversionOK);
+    
+    wchar_t *absPath = _wfullpath(NULL, (wchar_t *)utf16.data(), utf16.size());
+    assert(absPath && "_wfullpath() returned NULL!");
 
-    free(absPathStrPtr);
-    return absPath;
+    unsigned NumWChars = ::wcslen(absPath);
+    if (convertToLowercase)
+    {
+      for (int i = 0; i != NumWChars; ++i)
+        absPath[i] = std::tolower(absPath[i], std::locale());
+    }
+     
+    SmallVector<UTF8, 128> utf8(NumBytes);
+    const UTF16 *FromUTF16Ptr = (UTF16 *)absPath;
+    UTF8 *ToUTF8Ptr = &utf8[0];
+
+    Result = ConvertUTF16toUTF8(&FromUTF16Ptr, FromUTF16Ptr + NumWChars,
+                                &ToUTF8Ptr, ToUTF8Ptr + NumBytes,
+                                strictConversion);
+
+    assert(Result == conversionOK);
+
+    free(absPath);
+
+    return std::string((char *)utf8.data());
   }
 }
 
@@ -86,7 +117,7 @@
   /// default-constructed DirectoryEntry.
   DirectoryEntry &getDirectory(const char *Name,
                                const struct stat & /*StatBuf*/) {
-    std::string FullPath(GetFullPath(Name));
+    std::string FullPath(GetFullPath(Name, false));
     return UniqueDirs.GetOrCreateValue(FullPath).getValue();
   }
 
@@ -103,10 +134,8 @@
   /// there is already one; otherwise create and return a
   /// default-constructed FileEntry.
   FileEntry &getFile(const char *Name, const struct stat & /*StatBuf*/) {
-    std::string FullPath(GetFullPath(Name));
-
     // Lowercase string because Windows filesystem is case insensitive.
-    FullPath = StringRef(FullPath).lower();
+    std::string FullPath(GetFullPath(Name, true));
     return UniqueFiles.GetOrCreateValue(FullPath).getValue();
   }
 
@@ -561,7 +590,7 @@
   llvm::SmallString<128> FilePath(Path);
   FixupRelativePath(FilePath);
 
-  return ::stat(FilePath.c_str(), &StatBuf) != 0;
+  return llvm::sys::fs::Stat(FilePath.c_str(), &StatBuf) != 0;
 }
 
 void FileManager::GetUniqueIDMapping(
Index: lib/Basic/FileSystemStatCache.cpp
===================================================================
--- lib/Basic/FileSystemStatCache.cpp	(revision 145028)
+++ lib/Basic/FileSystemStatCache.cpp	(working copy)
@@ -13,6 +13,7 @@
 
 #include "clang/Basic/FileSystemStatCache.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/FileSystem.h"
 #include <fcntl.h>
 
 // FIXME: This is terrible, we need this for ::close.
@@ -47,7 +48,7 @@
     R = Cache->getStat(Path, StatBuf, FileDescriptor);
   else if (isForDir) {
     // If this is a directory and we have no cache, just go to the file system.
-    R = ::stat(Path, &StatBuf) != 0 ? CacheMissing : CacheExists;
+    R = llvm::sys::fs::Stat(Path, &StatBuf) != 0 ? CacheMissing : CacheExists;
   } else {
     // Otherwise, we have to go to the filesystem.  We can always just use
     // 'stat' here, but (for files) the client is asking whether the file exists
@@ -60,7 +61,7 @@
 #ifdef O_BINARY
     OpenFlags |= O_BINARY;  // Open input file in binary mode on win32.
 #endif
-    *FileDescriptor = ::open(Path, OpenFlags);
+    *FileDescriptor = llvm::sys::fs::Open(Path, OpenFlags);
     
     if (*FileDescriptor == -1) {
       // If the open fails, our "stat" fails.
Index: lib/Basic/SourceManager.cpp
===================================================================
--- lib/Basic/SourceManager.cpp	(revision 145028)
+++ lib/Basic/SourceManager.cpp	(working copy)
@@ -19,6 +19,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Path.h"
@@ -1332,7 +1333,7 @@
     return llvm::Optional<ino_t>();
   
   struct stat StatBuf;
-  if (::stat(File->getName(), &StatBuf))
+  if (llvm::sys::fs::Stat(File->getName(), &StatBuf))
     return llvm::Optional<ino_t>();
     
   return StatBuf.st_ino;
Index: lib/Driver/Compilation.cpp
===================================================================
--- lib/Driver/Compilation.cpp	(revision 145028)
+++ lib/Driver/Compilation.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include "clang/Driver/ToolChain.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Program.h"
 #include <sys/stat.h>
@@ -124,7 +125,8 @@
 
       // FIXME: Grumble, P.exists() is broken. PR3837.
       struct stat buf;
-      if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
+      if (llvm::sys::fs::Stat(P.c_str(), &buf) == 0 ? 
+                                         (buf.st_mode & S_IFMT) == S_IFREG :
                                          (errno != ENOENT)) {
         if (IssueErrors)
           getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp	(revision 145028)
+++ lib/Serialization/ASTReader.cpp	(working copy)
@@ -2389,7 +2389,7 @@
       // The stat info from the FileEntry came from the cached stat
       // info of the PCH, so we cannot trust it.
       struct stat StatBuf;
-      if (::stat(File->getName(), &StatBuf) != 0) {
+      if (llvm::sys::fs::Stat(File->getName(), &StatBuf) != 0) {
         StatBuf.st_size = File->getSize();
         StatBuf.st_mtime = File->getModificationTime();
       }
Index: tools/driver/driver.cpp
===================================================================
--- tools/driver/driver.cpp	(revision 145028)
+++ tools/driver/driver.cpp	(working copy)
@@ -241,17 +241,17 @@
   }
 }
 
-static void ExpandArgv(int argc, const char **argv,
+static void ExpandArgv(const std::vector<std::string> &argv,
                        SmallVectorImpl<const char*> &ArgVector,
                        std::set<std::string> &SavedStrings) {
-  for (int i = 0; i < argc; ++i) {
-    const char *Arg = argv[i];
-    if (Arg[0] != '@') {
-      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
+  for (std::vector<std::string>::const_iterator I = argv.begin(),
+       E = argv.end(); I != E; ++I) {
+    if (I->front() != '@') {
+      ArgVector.push_back(SaveStringInSet(SavedStrings, *I));
       continue;
     }
 
-    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
+    ExpandArgsFromBuf(I->c_str(), ArgVector, SavedStrings);
   }
 }
 
@@ -343,7 +343,7 @@
   std::set<std::string> SavedStrings;
   SmallVector<const char*, 256> argv;
 
-  ExpandArgv(argc_, argv_, argv, SavedStrings);
+  ExpandArgv(llvm::sys::fs::GetArgvAsUTF8(argc_, argv_), argv, SavedStrings);
 
   // Handle -cc1 integrated tools.
   if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) {
