Define string16 in terms of std::u16string.

This can be done now that we have C++17 support. The typedef is left for
simplicity. It will be replaced in a separate pass.

Remove wstring completely. On Windows we now use explicit 16-bit strings
and cast to make syscalls work. A new helper is added to support this.

Remove some unnecessary conversion functions and NACL defines.

Change-Id: I30c5b35c31e59510474fff71dc7256fb56cda641
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/6020
Commit-Queue: Brett Wilson <brettw@chromium.org>
Reviewed-by: Scott Graham <scottmg@chromium.org>
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 0dc59e6..510fcea 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -7,6 +7,7 @@
 
 #include <stddef.h>
 
+#include <tuple>
 #include <type_traits>
 #include <utility>
 
diff --git a/base/command_line.cc b/base/command_line.cc
index 792d322..b2bf5a8 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <ostream>
+#include <string_view>
 
 #include "base/files/file_path.h"
 #include "base/logging.h"
@@ -38,7 +39,7 @@
 // By putting slash last, we can control whether it is treaded as a switch
 // value by changing the value of switch_prefix_count to be one less than
 // the array size.
-const CommandLine::CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"};
+const CommandLine::CharType* const kSwitchPrefixes[] = {u"--", u"-", u"/"};
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
 // Unixes don't use slash as a switch.
 const CommandLine::CharType* const kSwitchPrefixes[] = {"--", "-"};
@@ -110,18 +111,18 @@
                                     bool quote_placeholders) {
   // We follow the quoting rules of CommandLineToArgvW.
   // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
-  string16 quotable_chars(L" \\\"");
+  string16 quotable_chars(u" \\\"");
   // We may also be required to quote '%', which is commonly used in a command
   // line as a placeholder. (It may be substituted for a string with spaces.)
   if (quote_placeholders)
-    quotable_chars.push_back(L'%');
+    quotable_chars.push_back('%');
   if (arg.find_first_of(quotable_chars) == string16::npos) {
     // No quoting necessary.
     return arg;
   }
 
   string16 out;
-  out.push_back(L'"');
+  out.push_back('"');
   for (size_t i = 0; i < arg.size(); ++i) {
     if (arg[i] == '\\') {
       // Find the extent of this run of backslashes.
@@ -185,7 +186,8 @@
 // static
 void CommandLine::set_slash_is_not_a_switch() {
   // The last switch prefix should be slash, so adjust the size to skip it.
-  DCHECK_EQ(wcscmp(kSwitchPrefixes[arraysize(kSwitchPrefixes) - 1], L"/"), 0);
+  DCHECK(std::u16string_view(kSwitchPrefixes[arraysize(kSwitchPrefixes) - 1]) ==
+         std::u16string_view(u"/"));
   switch_prefix_count = arraysize(kSwitchPrefixes) - 1;
 }
 
@@ -212,7 +214,8 @@
 
   current_process_commandline_ = new CommandLine(NO_PROGRAM);
 #if defined(OS_WIN)
-  current_process_commandline_->ParseFromString(::GetCommandLineW());
+  current_process_commandline_->ParseFromString(
+      reinterpret_cast<const char16_t*>(::GetCommandLineW()));
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
   current_process_commandline_->InitFromArgv(argc, argv);
 #else
@@ -380,7 +383,7 @@
 void CommandLine::AppendArg(const std::string& value) {
 #if defined(OS_WIN)
   DCHECK(IsStringUTF8(value));
-  AppendArgNative(UTF8ToWide(value));
+  AppendArgNative(UTF8ToUTF16(value));
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
   AppendArgNative(value);
 #else
@@ -428,8 +431,9 @@
     return;
 
   int num_args = 0;
-  wchar_t** args = NULL;
-  args = ::CommandLineToArgvW(command_line_string.c_str(), &num_args);
+  char16_t** args = NULL;
+  args = reinterpret_cast<char16_t**>(::CommandLineToArgvW(
+      reinterpret_cast<LPCWSTR>(command_line_string.c_str()), &num_args));
 
   DPLOG_IF(FATAL, !args) << "CommandLineToArgvW failed on command line: "
                          << UTF16ToUTF8(command_line);
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 4224197..78fcbaf 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -159,7 +159,7 @@
 #endif
 
 // MemorySanitizer annotations.
-#if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
+#if defined(MEMORY_SANITIZER)
 #include <sanitizer/msan_interface.h>
 
 // Mark a memory region fully initialized.
diff --git a/base/containers/vector_buffer.h b/base/containers/vector_buffer.h
index a72c1ed..d40438d 100644
--- a/base/containers/vector_buffer.h
+++ b/base/containers/vector_buffer.h
@@ -39,7 +39,7 @@
  public:
   constexpr VectorBuffer() = default;
 
-#if defined(__clang__) && !defined(__native_client__)
+#if defined(__clang__)
   // This constructor converts an uninitialized void* to a T* which triggers
   // clang Control Flow Integrity. Since this is as-designed, disable.
   __attribute__((no_sanitize("cfi-unrelated-cast", "vptr")))
diff --git a/base/environment.cc b/base/environment.cc
index 7f0e5d9..41951b7 100644
--- a/base/environment.cc
+++ b/base/environment.cc
@@ -57,15 +57,17 @@
  private:
   bool GetVarImpl(StringPiece variable_name, std::string* result) {
 #if defined(OS_WIN)
-    DWORD value_length =
-        ::GetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), nullptr, 0);
+    DWORD value_length = ::GetEnvironmentVariable(
+        reinterpret_cast<LPCWSTR>(UTF8ToUTF16(variable_name).c_str()), nullptr,
+        0);
     if (value_length == 0)
       return false;
     if (result) {
-      std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]);
-      ::GetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), value.get(),
-                               value_length);
-      *result = WideToUTF8(value.get());
+      std::unique_ptr<char16_t[]> value(new char16_t[value_length]);
+      ::GetEnvironmentVariable(
+          reinterpret_cast<LPCWSTR>(UTF8ToUTF16(variable_name).c_str()),
+          reinterpret_cast<LPWSTR>(value.get()), value_length);
+      *result = UTF16ToUTF8(value.get());
     }
     return true;
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -82,8 +84,9 @@
   bool SetVarImpl(StringPiece variable_name, const std::string& new_value) {
 #if defined(OS_WIN)
     // On success, a nonzero value is returned.
-    return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(),
-                                    UTF8ToWide(new_value).c_str());
+    return !!SetEnvironmentVariable(
+        reinterpret_cast<LPCWSTR>(UTF8ToUTF16(variable_name).c_str()),
+        reinterpret_cast<LPCWSTR>(UTF8ToUTF16(new_value).c_str()));
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
     // On success, zero is returned.
     return !setenv(variable_name.data(), new_value.c_str(), 1);
@@ -93,7 +96,8 @@
   bool UnSetVarImpl(StringPiece variable_name) {
 #if defined(OS_WIN)
     // On success, a nonzero value is returned.
-    return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), nullptr);
+    return !!SetEnvironmentVariable(
+        reinterpret_cast<LPCWSTR>(UTF8ToUTF16(variable_name).c_str()), nullptr);
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
     // On success, zero is returned.
     return !unsetenv(variable_name.data());
@@ -143,14 +147,14 @@
 
 #if defined(OS_WIN)
 
-string16 AlterEnvironment(const wchar_t* env, const EnvironmentMap& changes) {
+string16 AlterEnvironment(const char16_t* env, const EnvironmentMap& changes) {
   string16 result;
 
   // First copy all unmodified values to the output.
   size_t cur_env = 0;
   string16 key;
   while (env[cur_env]) {
-    const wchar_t* line = &env[cur_env];
+    const char16_t* line = &env[cur_env];
     size_t line_length = ParseEnvLine(line, &key);
 
     // Keep only values not specified in the change vector.
diff --git a/base/environment.h b/base/environment.h
index 82af987..201b1a8 100644
--- a/base/environment.h
+++ b/base/environment.h
@@ -61,7 +61,7 @@
 // which is a concatenated list of null-terminated 16-bit strings. The end is
 // marked by a double-null terminator. The size of the returned string will
 // include the terminators.
-string16 AlterEnvironment(const wchar_t* env, const EnvironmentMap& changes);
+string16 AlterEnvironment(const char16_t* env, const EnvironmentMap& changes);
 
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
 
diff --git a/base/files/file.cc b/base/files/file.cc
index 98fa3a6..8c04016 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -19,12 +19,10 @@
 File::File()
     : error_details_(FILE_ERROR_FAILED), created_(false), async_(false) {}
 
-#if !defined(OS_NACL)
 File::File(const FilePath& path, uint32_t flags)
     : error_details_(FILE_OK), created_(false), async_(false) {
   Initialize(path, flags);
 }
-#endif
 
 File::File(PlatformFile platform_file)
     : file_(platform_file),
@@ -68,7 +66,6 @@
   return *this;
 }
 
-#if !defined(OS_NACL)
 void File::Initialize(const FilePath& path, uint32_t flags) {
   if (path.ReferencesParent()) {
 #if defined(OS_WIN)
@@ -83,7 +80,6 @@
   }
   DoInitialize(path, flags);
 }
-#endif
 
 std::string File::ErrorToString(Error error) {
   switch (error) {
diff --git a/base/files/file.h b/base/files/file.h
index 61239ad..3355030 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -22,7 +22,7 @@
 
 namespace base {
 
-#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
+#if defined(OS_BSD) || defined(OS_MACOSX) || \
     defined(OS_ANDROID) && __ANDROID_API__ < 21
 typedef struct stat stat_wrapper_t;
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
diff --git a/base/files/file_enumerator_win.cc b/base/files/file_enumerator_win.cc
index 803b7bd..aa884ea 100644
--- a/base/files/file_enumerator_win.cc
+++ b/base/files/file_enumerator_win.cc
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include "base/logging.h"
+#include "base/win/win_util.h"
 
 namespace base {
 
@@ -23,7 +24,7 @@
     case FileEnumerator::FolderSearchPolicy::MATCH_ONLY:
       return root_path.Append(pattern);
     case FileEnumerator::FolderSearchPolicy::ALL:
-      return root_path.Append(L"*");
+      return root_path.Append(u"*");
   }
   NOTREACHED();
   return {};
@@ -42,7 +43,7 @@
 }
 
 FilePath FileEnumerator::FileInfo::GetName() const {
-  return FilePath(find_data_.cFileName);
+  return FilePath(reinterpret_cast<const char16_t*>(find_data_.cFileName));
 }
 
 int64_t FileEnumerator::FileInfo::GetSize() const {
@@ -86,7 +87,7 @@
                                FolderSearchPolicy folder_search_policy)
     : recursive_(recursive),
       file_type_(file_type),
-      pattern_(!pattern.empty() ? pattern : L"*"),
+      pattern_(!pattern.empty() ? pattern : u"*"),
       folder_search_policy_(folder_search_policy) {
   // INCLUDE_DOT_DOT must not be specified if recursive.
   DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
@@ -119,7 +120,7 @@
       // Start a new find operation.
       const FilePath src =
           BuildSearchFilter(folder_search_policy_, root_path_, pattern_);
-      find_handle_ = FindFirstFileEx(src.value().c_str(),
+      find_handle_ = FindFirstFileEx(ToWCharT(&src.value()),
                                      FindExInfoBasic,  // Omit short name.
                                      &find_data_, FindExSearchNameMatch,
                                      nullptr, FIND_FIRST_EX_LARGE_FETCH);
@@ -143,13 +144,13 @@
         // files in the root search directory, but for those directories which
         // were matched, we want to enumerate all files inside them. This will
         // happen when the handle is empty.
-        pattern_ = L"*";
+        pattern_ = u"*";
       }
 
       continue;
     }
 
-    const FilePath filename(find_data_.cFileName);
+    const FilePath filename(reinterpret_cast<char16_t*>(find_data_.cFileName));
     if (ShouldSkip(filename))
       continue;
 
@@ -163,7 +164,7 @@
       // add it to pending_paths_ so we scan it after we finish scanning this
       // directory. However, don't do recursion through reparse points or we
       // may end up with an infinite cycle.
-      DWORD attributes = GetFileAttributes(abs_path.value().c_str());
+      DWORD attributes = GetFileAttributes(ToWCharT(&abs_path.value()));
       if (!(attributes & FILE_ATTRIBUTE_REPARSE_POINT))
         pending_paths_.push(abs_path);
     }
@@ -183,7 +184,7 @@
     case FolderSearchPolicy::ALL:
       // ALL policy enumerates all files, we need to check pattern match
       // manually.
-      return PathMatchSpec(src.value().c_str(), pattern_.c_str()) == TRUE;
+      return PathMatchSpec(ToWCharT(&src.value()), ToWCharT(&pattern_)) == TRUE;
   }
   NOTREACHED();
   return false;
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index 014bc9e..f0e1acb 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -199,10 +199,6 @@
 #endif  // defined(FILE_PATH_USES_DRIVE_LETTERS)
 }
 
-std::ostream& operator<<(std::ostream& out, const FilePath& file_path) {
-  return out << file_path.value();
-}
-
 // static
 bool FilePath::IsSeparator(CharType character) {
   for (size_t i = 0; i < kSeparatorsLength - 1; ++i) {
@@ -578,22 +574,8 @@
   return std::string();
 }
 
-std::string FilePath::AsUTF8Unsafe() const {
-  return WideToUTF8(value());
-}
-
-string16 FilePath::AsUTF16Unsafe() const {
-  return value();
-}
-
-// static
-FilePath FilePath::FromUTF8Unsafe(StringPiece utf8) {
-  return FilePath(UTF8ToWide(utf8));
-}
-
-// static
-FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
-  return FilePath(utf16);
+std::string FilePath::As8Bit() const {
+  return UTF16ToUTF8(value());
 }
 
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -607,24 +589,10 @@
   return std::string();
 }
 
-std::string FilePath::AsUTF8Unsafe() const {
+std::string FilePath::As8Bit() const {
   return value();
 }
 
-string16 FilePath::AsUTF16Unsafe() const {
-  return UTF8ToUTF16(value());
-}
-
-// static
-FilePath FilePath::FromUTF8Unsafe(StringPiece utf8) {
-  return FilePath(utf8);
-}
-
-// static
-FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
-  return FilePath(UTF16ToUTF8(utf16));
-}
-
 #endif  // defined(OS_WIN)
 
 void FilePath::StripTrailingSeparatorsInternal() {
diff --git a/base/files/file_path.h b/base/files/file_path.h
index 1717cba..a85c1aa 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -9,7 +9,7 @@
 //
 //                   POSIX            Windows
 //                   ---------------  ----------------------------------
-// Fundamental type  char[]           wchar_t[]
+// Fundamental type  char[]           char16_t[]
 // Encoding          unspecified*     UTF-16
 // Separator         /                \, tolerant of /
 // Drive letters     no               case-insensitive A-Z followed by :
@@ -50,7 +50,7 @@
 //
 // To aid in initialization of FilePath objects from string literals, a
 // FILE_PATH_LITERAL macro is provided, which accounts for the difference
-// between char[]-based pathnames on POSIX systems and wchar_t[]-based
+// between char[]-based pathnames on POSIX systems and char16_t[]-based
 // pathnames on Windows.
 //
 // As a precaution against premature truncation, paths can't contain NULs.
@@ -142,9 +142,9 @@
 class FilePath {
  public:
 #if defined(OS_WIN)
-  // On Windows, for Unicode-aware applications, native pathnames are wchar_t
+  // On Windows, for Unicode-aware applications, native pathnames are char16_t
   // arrays encoded in UTF-16.
-  typedef std::wstring StringType;
+  typedef std::u16string StringType;
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
   // On most platforms, native pathnames are char arrays, and the encoding
   // may or may not be specified.  On Mac OS X, native pathnames are encoded
@@ -306,10 +306,10 @@
   FilePath Append(StringPieceType component) const WARN_UNUSED_RESULT;
   FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT;
 
-  // Although Windows StringType is std::wstring, since the encoding it uses for
-  // paths is well defined, it can handle ASCII path components as well.
-  // Mac uses UTF8, and since ASCII is a subset of that, it works there as well.
-  // On Linux, although it can use any 8-bit encoding for paths, we assume that
+  // Although Windows StringType is std::u16string, since the encoding it uses
+  // for paths is well defined, it can handle ASCII path components as well. Mac
+  // uses UTF8, and since ASCII is a subset of that, it works there as well. On
+  // Linux, although it can use any 8-bit encoding for paths, we assume that
   // ASCII is a valid subset, regardless of the encoding, since many operating
   // system paths will always be ASCII.
   FilePath AppendASCII(StringPiece component) const WARN_UNUSED_RESULT;
@@ -346,36 +346,8 @@
   // known-ASCII filename.
   std::string MaybeAsASCII() const;
 
-  // Return the path as UTF-8.
-  //
-  // This function is *unsafe* as there is no way to tell what encoding is
-  // used in file names on POSIX systems other than Mac and Chrome OS,
-  // although UTF-8 is practically used everywhere these days. To mitigate
-  // the encoding issue, this function internally calls
-  // SysNativeMBToWide() on POSIX systems other than Mac and Chrome OS,
-  // per assumption that the current locale's encoding is used in file
-  // names, but this isn't a perfect solution.
-  //
-  // Once it becomes safe to to stop caring about non-UTF-8 file names,
-  // the SysNativeMBToWide() hack will be removed from the code, along
-  // with "Unsafe" in the function name.
-  std::string AsUTF8Unsafe() const;
-
-  // Similar to AsUTF8Unsafe, but returns UTF-16 instead.
-  string16 AsUTF16Unsafe() const;
-
-  // Returns a FilePath object from a path name in UTF-8. This function
-  // should only be used for cases where you are sure that the input
-  // string is UTF-8.
-  //
-  // Like AsUTF8Unsafe(), this function is unsafe. This function
-  // internally calls SysWideToNativeMB() on POSIX systems other than Mac
-  // and Chrome OS, to mitigate the encoding issue. See the comment at
-  // AsUTF8Unsafe() for details.
-  static FilePath FromUTF8Unsafe(StringPiece utf8);
-
-  // Similar to FromUTF8Unsafe, but accepts UTF-16 instead.
-  static FilePath FromUTF16Unsafe(StringPiece16 utf16);
+  // Return the path as 8-bit. On Linux this isn't guaranteed to be UTF-8.
+  std::string As8Bit() const;
 
   // Normalize all path separators to backslash on Windows
   // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems.
@@ -396,18 +368,13 @@
   StringType path_;
 };
 
-std::ostream& operator<<(std::ostream& out, const FilePath& file_path);
-
 }  // namespace base
 
-// Macros for string literal initialization of FilePath::CharType[], and for
-// using a FilePath::CharType[] in a printf-style format string.
+// Macros for string literal initialization of FilePath::CharType[].
 #if defined(OS_WIN)
-#define FILE_PATH_LITERAL(x) L##x
-#define PRFilePath "ls"
+#define FILE_PATH_LITERAL(x) u##x
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
 #define FILE_PATH_LITERAL(x) x
-#define PRFilePath "s"
 #endif  // OS_WIN
 
 namespace std {
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index ed9a5e2..90b80d0 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -24,7 +24,7 @@
 
 namespace {
 
-#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
+#if defined(OS_BSD) || defined(OS_MACOSX) || \
     defined(OS_ANDROID) && __ANDROID_API__ < 21
 int CallFstat(int fd, stat_wrapper_t* sb) {
   return fstat(fd, sb);
@@ -35,9 +35,9 @@
 }
 #endif
 
-// NaCl doesn't provide the following system calls, so either simulate them or
-// wrap them in order to minimize the number of #ifdef's in this file.
-#if !defined(OS_NACL) && !defined(OS_AIX)
+// Some systems don't provide the following system calls, so either simulate
+// them or wrap them in order to minimize the number of #ifdef's in this file.
+#if !defined(OS_AIX)
 bool IsOpenAppend(PlatformFile file) {
   return (fcntl(file, F_GETFL) & O_APPEND) != 0;
 }
@@ -59,7 +59,7 @@
 }
 #endif
 
-#else   // defined(OS_NACL) && !defined(OS_AIX)
+#else   // !defined(OS_AIX)
 
 bool IsOpenAppend(PlatformFile file) {
   // NaCl doesn't implement fcntl. Since NaCl's write conforms to the POSIX
@@ -77,7 +77,7 @@
   NOTIMPLEMENTED();  // NaCl doesn't implement flock struct.
   return File::FILE_ERROR_INVALID_OPERATION;
 }
-#endif  // defined(OS_NACL)
+#endif  // defined(OS_AIX)
 
 }  // namespace
 
@@ -303,9 +303,7 @@
     case EPERM:
       return FILE_ERROR_ACCESS_DENIED;
     case EBUSY:
-#if !defined(OS_NACL)  // ETXTBSY not defined by NaCl.
     case ETXTBSY:
-#endif
       return FILE_ERROR_IN_USE;
     case EEXIST:
       return FILE_ERROR_EXISTS;
@@ -329,8 +327,6 @@
   }
 }
 
-// NaCl doesn't implement system calls to open files directly.
-#if !defined(OS_NACL)
 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
 void File::DoInitialize(const FilePath& path, uint32_t flags) {
   DCHECK(!IsValid());
@@ -409,7 +405,6 @@
   error_details_ = FILE_OK;
   file_.reset(descriptor);
 }
-#endif  // !defined(OS_NACL)
 
 bool File::Flush() {
   DCHECK(IsValid());
diff --git a/base/files/file_util.cc b/base/files/file_util.cc
index 9a98a0b..25b7aab 100644
--- a/base/files/file_util.cc
+++ b/base/files/file_util.cc
@@ -23,7 +23,6 @@
 
 namespace base {
 
-#if !defined(OS_NACL_NONSFI)
 namespace {
 
 // The maximum number of 'uniquified' files we will try to create.
@@ -47,9 +46,9 @@
   // We open the file in binary format even if they are text files because
   // we are just comparing that bytes are exactly same in both files and not
   // doing anything smart with text formatting.
-  std::ifstream file1(filename1.value().c_str(),
+  std::ifstream file1(filename1.As8Bit().c_str(),
                       std::ios::in | std::ios::binary);
-  std::ifstream file2(filename2.value().c_str(),
+  std::ifstream file2(filename2.As8Bit().c_str(),
                       std::ios::in | std::ios::binary);
 
   // Even if both files aren't openable (and thus, in some sense, "equal"),
@@ -77,8 +76,8 @@
 }
 
 bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) {
-  std::ifstream file1(filename1.value().c_str(), std::ios::in);
-  std::ifstream file2(filename2.value().c_str(), std::ios::in);
+  std::ifstream file1(filename1.As8Bit().c_str(), std::ios::in);
+  std::ifstream file2(filename2.As8Bit().c_str(), std::ios::in);
 
   // Even if both files aren't openable (and thus, in some sense, "equal"),
   // any unusable file yields a result of "false".
@@ -114,7 +113,6 @@
 
   return true;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 bool ReadFileToStringWithMaxSize(const FilePath& path,
                                  std::string* contents,
@@ -133,15 +131,11 @@
   // file size as a hint for chunk size if available.
   constexpr int64_t kDefaultChunkSize = 1 << 16;
   int64_t chunk_size;
-#if !defined(OS_NACL_NONSFI)
   if (!GetFileSize(path, &chunk_size) || chunk_size <= 0)
     chunk_size = kDefaultChunkSize - 1;
   // We need to attempt to read at EOF for feof flag to be set so here we
   // use |chunk_size| + 1.
   chunk_size = std::min<uint64_t>(chunk_size, max_size) + 1;
-#else
-  chunk_size = kDefaultChunkSize;
-#endif  // !defined(OS_NACL_NONSFI)
   size_t bytes_read_this_pass;
   size_t bytes_read_so_far = 0;
   bool read_status = true;
@@ -183,7 +177,6 @@
                                      std::numeric_limits<size_t>::max());
 }
 
-#if !defined(OS_NACL_NONSFI)
 bool IsDirectoryEmpty(const FilePath& dir_path) {
   FileEnumerator files(dir_path, false,
                        FileEnumerator::FILES | FileEnumerator::DIRECTORIES);
@@ -212,15 +205,12 @@
   return true;
 }
 
-#endif  // !defined(OS_NACL_NONSFI)
-
 bool CloseFile(FILE* file) {
   if (file == nullptr)
     return true;
   return fclose(file) == 0;
 }
 
-#if !defined(OS_NACL_NONSFI)
 bool TruncateFile(FILE* file) {
   if (file == nullptr)
     return false;
@@ -258,6 +248,5 @@
 
   return -1;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 }  // namespace base
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index eb07e64..966abc0 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -55,7 +55,7 @@
 
 namespace {
 
-#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
+#if defined(OS_BSD) || defined(OS_MACOSX) || \
     defined(OS_ANDROID) && __ANDROID_API__ < 21
 int CallStat(const char* path, stat_wrapper_t* sb) {
   return stat(path, sb);
@@ -72,7 +72,6 @@
 }
 #endif
 
-#if !defined(OS_NACL_NONSFI)
 // Helper for VerifyPathControlledByUser.
 bool VerifySpecificPathControlledByUser(const FilePath& path,
                                         uid_t owner_uid,
@@ -179,7 +178,6 @@
   NOTREACHED();
   return false;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 #if !defined(OS_MACOSX)
 // Appends |mode_char| to |mode| before the optional character set encoding; see
@@ -196,7 +194,6 @@
 
 }  // namespace
 
-#if !defined(OS_NACL_NONSFI)
 FilePath MakeAbsoluteFilePath(const FilePath& input) {
   char full_path[PATH_MAX];
   if (realpath(input.value().c_str(), full_path) == nullptr)
@@ -251,7 +248,6 @@
     *error = File::GetLastFileError();
   return false;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 bool CreateLocalNonBlockingPipe(int fds[2]) {
 #if defined(OS_LINUX)
@@ -288,15 +284,11 @@
 }
 
 bool SetCloseOnExec(int fd) {
-#if defined(OS_NACL_NONSFI)
-  const int flags = 0;
-#else
   const int flags = fcntl(fd, F_GETFD);
   if (flags == -1)
     return false;
   if (flags & FD_CLOEXEC)
     return true;
-#endif  // defined(OS_NACL_NONSFI)
   if (HANDLE_EINTR(fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1)
     return false;
   return true;
@@ -306,11 +298,9 @@
   return access(path.value().c_str(), F_OK) == 0;
 }
 
-#if !defined(OS_NACL_NONSFI)
 bool PathIsWritable(const FilePath& path) {
   return access(path.value().c_str(), W_OK) == 0;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 bool DirectoryExists(const FilePath& path) {
   stat_wrapper_t file_info;
@@ -331,8 +321,6 @@
   return total_read == bytes;
 }
 
-#if !defined(OS_NACL_NONSFI)
-
 int CreateAndOpenFdForTemporaryFileInDir(const FilePath& directory,
                                          FilePath* path) {
   *path = directory.Append(TempFileName());
@@ -575,7 +563,6 @@
   results->FromStat(file_info);
   return true;
 }
-#endif  // !defined(OS_NACL_NONSFI)
 
 FILE* OpenFile(const FilePath& filename, const char* mode) {
   // 'e' is unconditionally added below, so be sure there is not one already
@@ -603,15 +590,12 @@
   return result;
 }
 
-// NaCl doesn't implement system calls to open files directly.
-#if !defined(OS_NACL)
 FILE* FileToFILE(File file, const char* mode) {
   FILE* stream = fdopen(file.GetPlatformFile(), mode);
   if (stream)
     file.TakePlatformFile();
   return stream;
 }
-#endif  // !defined(OS_NACL)
 
 int ReadFile(const FilePath& filename, char* data, int max_size) {
   int fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY));
@@ -649,8 +633,6 @@
   return true;
 }
 
-#if !defined(OS_NACL_NONSFI)
-
 bool AppendToFile(const FilePath& filename, const char* data, int size) {
   bool ret = true;
   int fd = HANDLE_EINTR(open(filename.value().c_str(), O_WRONLY | O_APPEND));
@@ -783,5 +765,4 @@
 }
 #endif  // !defined(OS_MACOSX)
 
-#endif  // !defined(OS_NACL_NONSFI)
 }  // namespace base
diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc
index 34d328b..8fba87a 100644
--- a/base/files/file_util_win.cc
+++ b/base/files/file_util_win.cc
@@ -29,6 +29,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_handle.h"
+#include "base/win/win_util.h"
 
 // #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036.  See the
 // "Community Additions" comment on MSDN here:
@@ -61,7 +62,7 @@
     if ((info.find_data().dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
         (recursive || !info.IsDirectory())) {
       ::SetFileAttributes(
-          current.value().c_str(),
+          ToWCharT(&current.value()),
           info.find_data().dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
     }
 
@@ -70,11 +71,11 @@
       if (recursive) {
         this_result = DeleteFileRecursive(current, pattern, true);
         if (this_result == ERROR_SUCCESS &&
-            !::RemoveDirectory(current.value().c_str())) {
+            !::RemoveDirectory(ToWCharT(&current.value()))) {
           this_result = ::GetLastError();
         }
       }
-    } else if (!::DeleteFile(current.value().c_str())) {
+    } else if (!::DeleteFile(ToWCharT(&current.value()))) {
       this_result = ::GetLastError();
     }
     if (result == ERROR_SUCCESS)
@@ -100,14 +101,14 @@
     return ERROR_BAD_PATHNAME;
 
   // Handle any path with wildcards.
-  if (path.BaseName().value().find_first_of(L"*?") !=
+  if (path.BaseName().value().find_first_of(u"*?") !=
       FilePath::StringType::npos) {
     return DeleteFileRecursive(path.DirName(), path.BaseName().value(),
                                recursive);
   }
 
   // Report success if the file or path does not exist.
-  const DWORD attr = ::GetFileAttributes(path.value().c_str());
+  const DWORD attr = ::GetFileAttributes(ToWCharT(&path.value()));
   if (attr == INVALID_FILE_ATTRIBUTES) {
     const DWORD error_code = ::GetLastError();
     return (error_code == ERROR_FILE_NOT_FOUND ||
@@ -118,24 +119,24 @@
 
   // Clear the read-only bit if it is set.
   if ((attr & FILE_ATTRIBUTE_READONLY) &&
-      !::SetFileAttributes(path.value().c_str(),
+      !::SetFileAttributes(ToWCharT(&path.value()),
                            attr & ~FILE_ATTRIBUTE_READONLY)) {
     return ::GetLastError();
   }
 
   // Perform a simple delete on anything that isn't a directory.
   if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
-    return ::DeleteFile(path.value().c_str()) ? ERROR_SUCCESS
-                                              : ::GetLastError();
+    return ::DeleteFile(ToWCharT(&path.value())) ? ERROR_SUCCESS
+                                                 : ::GetLastError();
   }
 
   if (recursive) {
-    const DWORD error_code = DeleteFileRecursive(path, L"*", true);
+    const DWORD error_code = DeleteFileRecursive(path, u"*", true);
     if (error_code != ERROR_SUCCESS)
       return error_code;
   }
-  return ::RemoveDirectory(path.value().c_str()) ? ERROR_SUCCESS
-                                                 : ::GetLastError();
+  return ::RemoveDirectory(ToWCharT(&path.value())) ? ERROR_SUCCESS
+                                                    : ::GetLastError();
 }
 
 std::string RandomDataToGUIDString(const uint64_t bytes[2]) {
@@ -185,8 +186,8 @@
 }  // namespace
 
 FilePath MakeAbsoluteFilePath(const FilePath& input) {
-  wchar_t file_path[MAX_PATH];
-  if (!_wfullpath(file_path, input.value().c_str(), MAX_PATH))
+  char16_t file_path[MAX_PATH];
+  if (!_wfullpath(ToWCharT(file_path), ToWCharT(&input.value()), MAX_PATH))
     return FilePath();
   return FilePath(file_path);
 }
@@ -208,7 +209,7 @@
   if (path.value().length() >= MAX_PATH)
     return false;
 
-  return MoveFileEx(path.value().c_str(), NULL,
+  return MoveFileEx(ToWCharT(&path.value()), NULL,
                     MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING) !=
          FALSE;
 }
@@ -218,7 +219,7 @@
                  File::Error* error) {
   // Try a simple move first.  It will only succeed when |to_path| doesn't
   // already exist.
-  if (::MoveFile(from_path.value().c_str(), to_path.value().c_str()))
+  if (::MoveFile(ToWCharT(&from_path.value()), ToWCharT(&to_path.value())))
     return true;
   File::Error move_error = File::OSErrorToFileError(GetLastError());
 
@@ -226,8 +227,8 @@
   // succeed when |to_path| does exist. When writing to a network share, we may
   // not be able to change the ACLs. Ignore ACL errors then
   // (REPLACEFILE_IGNORE_MERGE_ERRORS).
-  if (::ReplaceFile(to_path.value().c_str(), from_path.value().c_str(), NULL,
-                    REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) {
+  if (::ReplaceFile(ToWCharT(&to_path.value()), ToWCharT(&from_path.value()),
+                    NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) {
     return true;
   }
   // In the case of FILE_ERROR_NOT_FOUND from ReplaceFile, it is likely that
@@ -242,12 +243,13 @@
 }
 
 bool PathExists(const FilePath& path) {
-  return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES);
+  return (GetFileAttributes(ToWCharT(&path.value())) !=
+          INVALID_FILE_ATTRIBUTES);
 }
 
 bool PathIsWritable(const FilePath& path) {
   HANDLE dir =
-      CreateFile(path.value().c_str(), FILE_ADD_FILE, kFileShareAll, NULL,
+      CreateFile(ToWCharT(&path.value()), FILE_ADD_FILE, kFileShareAll, NULL,
                  OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
   if (dir == INVALID_HANDLE_VALUE)
@@ -258,15 +260,15 @@
 }
 
 bool DirectoryExists(const FilePath& path) {
-  DWORD fileattr = GetFileAttributes(path.value().c_str());
+  DWORD fileattr = GetFileAttributes(ToWCharT(&path.value()));
   if (fileattr != INVALID_FILE_ATTRIBUTES)
     return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
   return false;
 }
 
 bool GetTempDir(FilePath* path) {
-  wchar_t temp_path[MAX_PATH + 1];
-  DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
+  char16_t temp_path[MAX_PATH + 1];
+  DWORD path_len = ::GetTempPath(MAX_PATH, ToWCharT(temp_path));
   if (path_len >= MAX_PATH || path_len <= 0)
     return false;
   // TODO(evanm): the old behavior of this function was to always strip the
@@ -318,7 +320,7 @@
   // Although it is nearly impossible to get a duplicate name with GUID, we
   // still use a loop here in case it happens.
   for (int i = 0; i < 100; ++i) {
-    temp_name = dir.Append(ASCIIToUTF16(base::GenerateGUID()) + L".tmp");
+    temp_name = dir.Append(ASCIIToUTF16(base::GenerateGUID()) + u".tmp");
     File file(temp_name,
               File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
     if (file.IsValid()) {
@@ -334,9 +336,9 @@
     return false;
   }
 
-  wchar_t long_temp_name[MAX_PATH + 1];
-  DWORD long_name_len =
-      GetLongPathName(temp_name.value().c_str(), long_temp_name, MAX_PATH);
+  char16_t long_temp_name[MAX_PATH + 1];
+  DWORD long_name_len = GetLongPathName(ToWCharT(&temp_name.value()),
+                                        ToWCharT(long_temp_name), MAX_PATH);
   if (long_name_len > MAX_PATH || long_name_len == 0) {
     // GetLongPathName() failed, but we still have a temporary file.
     *temp_file = std::move(temp_name);
@@ -364,7 +366,7 @@
     new_dir_name.append(UTF8ToUTF16(GenerateGUID()));
 
     path_to_create = base_dir.Append(new_dir_name);
-    if (::CreateDirectory(path_to_create.value().c_str(), NULL)) {
+    if (::CreateDirectory(ToWCharT(&path_to_create.value()), NULL)) {
       *new_dir = path_to_create;
       return true;
     }
@@ -384,13 +386,13 @@
 
 bool CreateDirectoryAndGetError(const FilePath& full_path, File::Error* error) {
   // If the path exists, we've succeeded if it's a directory, failed otherwise.
-  const wchar_t* full_path_str = full_path.value().c_str();
-  DWORD fileattr = ::GetFileAttributes(full_path_str);
+  DWORD fileattr = ::GetFileAttributes(ToWCharT(&full_path.value()));
   if (fileattr != INVALID_FILE_ATTRIBUTES) {
     if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
       return true;
     }
-    DLOG(WARNING) << "CreateDirectory(" << full_path_str << "), "
+    DLOG(WARNING) << "CreateDirectory(" << UTF16ToUTF8(full_path.value())
+                  << "), "
                   << "conflicts with existing file.";
     if (error) {
       *error = File::FILE_ERROR_NOT_A_DIRECTORY;
@@ -418,7 +420,7 @@
     return false;
   }
 
-  if (!::CreateDirectory(full_path_str, NULL)) {
+  if (!::CreateDirectory(ToWCharT(&full_path.value()), NULL)) {
     DWORD error_code = ::GetLastError();
     if (error_code == ERROR_ALREADY_EXISTS && DirectoryExists(full_path)) {
       // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we
@@ -429,8 +431,9 @@
     } else {
       if (error)
         *error = File::OSErrorToFileError(error_code);
-      DLOG(WARNING) << "Failed to create directory " << full_path_str
-                    << ", last error is " << error_code << ".";
+      DLOG(WARNING) << "Failed to create directory "
+                    << UTF16ToUTF8(full_path.value()) << ", last error is "
+                    << error_code << ".";
       return false;
     }
   } else {
@@ -453,17 +456,18 @@
                                  FilePath* out_drive_letter_path) {
   // Get the mapping of drive letters to device paths.
   const int kDriveMappingSize = 1024;
-  wchar_t drive_mapping[kDriveMappingSize] = {'\0'};
-  if (!::GetLogicalDriveStrings(kDriveMappingSize - 1, drive_mapping)) {
+  char16_t drive_mapping[kDriveMappingSize] = {'\0'};
+  if (!::GetLogicalDriveStrings(kDriveMappingSize - 1,
+                                ToWCharT(drive_mapping))) {
     DLOG(ERROR) << "Failed to get drive mapping.";
     return false;
   }
 
   // The drive mapping is a sequence of null terminated strings.
   // The last string is empty.
-  wchar_t* drive_map_ptr = drive_mapping;
-  wchar_t device_path_as_string[MAX_PATH];
-  wchar_t drive[] = L" :";
+  char16_t* drive_map_ptr = drive_mapping;
+  char16_t device_path_as_string[MAX_PATH];
+  char16_t drive[] = u" :";
 
   // For each string in the drive mapping, get the junction that links
   // to it.  If that junction is a prefix of |device_path|, then we
@@ -471,13 +475,14 @@
   while (*drive_map_ptr) {
     drive[0] = drive_map_ptr[0];  // Copy the drive letter.
 
-    if (QueryDosDevice(drive, device_path_as_string, MAX_PATH)) {
+    if (QueryDosDevice(ToWCharT(drive), ToWCharT(device_path_as_string),
+                       MAX_PATH)) {
       FilePath device_path(device_path_as_string);
       if (device_path == nt_device_path ||
           device_path.IsParent(nt_device_path)) {
         *out_drive_letter_path =
             FilePath(drive + nt_device_path.value().substr(
-                                 wcslen(device_path_as_string)));
+                                 wcslen(ToWCharT(device_path_as_string))));
         return true;
       }
     }
@@ -499,9 +504,9 @@
   // code below to a call to GetFinalPathNameByHandle().  The method this
   // function uses is explained in the following msdn article:
   // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
-  win::ScopedHandle file_handle(::CreateFile(path.value().c_str(), GENERIC_READ,
-                                             kFileShareAll, NULL, OPEN_EXISTING,
-                                             FILE_ATTRIBUTE_NORMAL, NULL));
+  win::ScopedHandle file_handle(
+      ::CreateFile(ToWCharT(&path.value()), GENERIC_READ, kFileShareAll, NULL,
+                   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
   if (!file_handle.IsValid())
     return false;
 
@@ -528,10 +533,11 @@
   // not return kMaxPathLength.  This would mean that only part of the
   // path fit in |mapped_file_path|.
   const int kMaxPathLength = MAX_PATH + 10;
-  wchar_t mapped_file_path[kMaxPathLength];
+  char16_t mapped_file_path[kMaxPathLength];
   bool success = false;
   HANDLE cp = GetCurrentProcess();
-  if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) {
+  if (::GetMappedFileNameW(cp, file_view, ToWCharT(mapped_file_path),
+                           kMaxPathLength)) {
     *nt_path = FilePath(mapped_file_path);
     success = true;
   }
@@ -547,7 +553,7 @@
 
 bool GetFileInfo(const FilePath& file_path, File::Info* results) {
   WIN32_FILE_ATTRIBUTE_DATA attr;
-  if (!GetFileAttributesEx(file_path.value().c_str(), GetFileExInfoStandard,
+  if (!GetFileAttributesEx(ToWCharT(&file_path.value()), GetFileExInfoStandard,
                            &attr)) {
     return false;
   }
@@ -574,7 +580,7 @@
       (strchr(mode, ',') != nullptr && strchr(mode, 'N') > strchr(mode, ',')));
   string16 w_mode = ASCIIToUTF16(mode);
   AppendModeCharacter(L'N', &w_mode);
-  return _wfsopen(filename.value().c_str(), w_mode.c_str(), _SH_DENYNO);
+  return _wfsopen(ToWCharT(&filename.value()), ToWCharT(&w_mode), _SH_DENYNO);
 }
 
 FILE* FileToFILE(File file, const char* mode) {
@@ -592,7 +598,7 @@
 }
 
 int ReadFile(const FilePath& filename, char* data, int max_size) {
-  win::ScopedHandle file(CreateFile(filename.value().c_str(), GENERIC_READ,
+  win::ScopedHandle file(CreateFile(ToWCharT(&filename.value()), GENERIC_READ,
                                     FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                                     OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
                                     NULL));
@@ -607,9 +613,9 @@
 }
 
 int WriteFile(const FilePath& filename, const char* data, int size) {
-  win::ScopedHandle file(CreateFile(filename.value().c_str(), GENERIC_WRITE, 0,
-                                    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
-                                    NULL));
+  win::ScopedHandle file(CreateFile(ToWCharT(&filename.value()), GENERIC_WRITE,
+                                    0, NULL, CREATE_ALWAYS,
+                                    FILE_ATTRIBUTE_NORMAL, NULL));
   if (!file.IsValid()) {
     DPLOG(WARNING) << "CreateFile failed for path "
                    << UTF16ToUTF8(filename.value());
@@ -634,8 +640,9 @@
 }
 
 bool AppendToFile(const FilePath& filename, const char* data, int size) {
-  win::ScopedHandle file(CreateFile(filename.value().c_str(), FILE_APPEND_DATA,
-                                    0, NULL, OPEN_EXISTING, 0, NULL));
+  win::ScopedHandle file(CreateFile(ToWCharT(&filename.value()),
+                                    FILE_APPEND_DATA, 0, NULL, OPEN_EXISTING, 0,
+                                    NULL));
   if (!file.IsValid()) {
     return false;
   }
@@ -649,33 +656,33 @@
 }
 
 bool GetCurrentDirectory(FilePath* dir) {
-  wchar_t system_buffer[MAX_PATH];
+  char16_t system_buffer[MAX_PATH];
   system_buffer[0] = 0;
-  DWORD len = ::GetCurrentDirectory(MAX_PATH, system_buffer);
+  DWORD len = ::GetCurrentDirectory(MAX_PATH, ToWCharT(system_buffer));
   if (len == 0 || len > MAX_PATH)
     return false;
   // TODO(evanm): the old behavior of this function was to always strip the
   // trailing slash.  We duplicate this here, but it shouldn't be necessary
   // when everyone is using the appropriate FilePath APIs.
-  std::wstring dir_str(system_buffer);
+  std::u16string dir_str(system_buffer);
   *dir = FilePath(dir_str).StripTrailingSeparators();
   return true;
 }
 
 bool SetCurrentDirectory(const FilePath& directory) {
-  return ::SetCurrentDirectory(directory.value().c_str()) != 0;
+  return ::SetCurrentDirectory(ToWCharT(&directory.value())) != 0;
 }
 
 int GetMaximumPathComponentLength(const FilePath& path) {
-  wchar_t volume_path[MAX_PATH];
-  if (!GetVolumePathNameW(path.NormalizePathSeparators().value().c_str(),
-                          volume_path, arraysize(volume_path))) {
+  char16_t volume_path[MAX_PATH];
+  if (!GetVolumePathNameW(ToWCharT(&path.NormalizePathSeparators().value()),
+                          ToWCharT(volume_path), arraysize(volume_path))) {
     return -1;
   }
 
   DWORD max_length = 0;
-  if (!GetVolumeInformationW(volume_path, NULL, 0, NULL, &max_length, NULL,
-                             NULL, 0)) {
+  if (!GetVolumeInformationW(ToWCharT(volume_path), NULL, 0, NULL, &max_length,
+                             NULL, NULL, 0)) {
     return -1;
   }
 
diff --git a/base/files/file_win.cc b/base/files/file_win.cc
index 7ca4461..9aae162 100644
--- a/base/files/file_win.cc
+++ b/base/files/file_win.cc
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include "base/logging.h"
+#include "base/win/win_util.h"
 
 #include <windows.h>
 
@@ -348,8 +349,8 @@
   if (flags & FLAG_SEQUENTIAL_SCAN)
     create_flags |= FILE_FLAG_SEQUENTIAL_SCAN;
 
-  file_.Set(CreateFile(path.value().c_str(), access, sharing, NULL, disposition,
-                       create_flags, NULL));
+  file_.Set(CreateFile(ToWCharT(&path.value()), access, sharing, NULL,
+                       disposition, create_flags, NULL));
 
   if (file_.IsValid()) {
     error_details_ = FILE_OK;
diff --git a/base/logging.cc b/base/logging.cc
index c2c243f..1144d61 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -324,7 +324,3 @@
 }
 
 }  // namespace logging
-
-std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) {
-  return out << (wstr ? base::WideToUTF8(wstr) : std::string());
-}
diff --git a/base/logging.h b/base/logging.h
index 2edad38..95c96ed 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -304,13 +304,13 @@
 // - Don't cause too much binary bloat.
 #if defined(COMPILER_GCC)
 
-#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_NACL)
+#if defined(ARCH_CPU_X86_FAMILY)
 // int 3 will generate a SIGTRAP.
 #define TRAP_SEQUENCE() \
   asm volatile(         \
       "int3; ud2; push %0;" ::"i"(static_cast<unsigned char>(__COUNTER__)))
 
-#elif defined(ARCH_CPU_ARMEL) && !defined(OS_NACL)
+#elif defined(ARCH_CPU_ARMEL)
 // bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running
 // as a 32 bit userspace app on arm64. There doesn't seem to be any way to
 // cause a SIGTRAP from userspace without using a syscall (which would be a
@@ -318,7 +318,7 @@
 #define TRAP_SEQUENCE() \
   asm volatile("bkpt #0; udf %0;" ::"i"(__COUNTER__ % 256))
 
-#elif defined(ARCH_CPU_ARM64) && !defined(OS_NACL)
+#elif defined(ARCH_CPU_ARM64)
 // This will always generate a SIGTRAP on arm64.
 #define TRAP_SEQUENCE() \
   asm volatile("brk #0; hlt %0;" ::"i"(__COUNTER__ % 65536))
@@ -901,32 +901,11 @@
 bool IsLoggingToFileEnabled();
 
 // Returns the default log file path.
-std::wstring GetLogFileFullPath();
+std::u16string GetLogFileFullPath();
 #endif
 
 }  // namespace logging
 
-// Note that "The behavior of a C++ program is undefined if it adds declarations
-// or definitions to namespace std or to a namespace within namespace std unless
-// otherwise specified." --C++11[namespace.std]
-//
-// We've checked that this particular definition has the intended behavior on
-// our implementations, but it's prone to breaking in the future, and please
-// don't imitate this in your own definitions without checking with some
-// standard library experts.
-namespace std {
-// These functions are provided as a convenience for logging, which is where we
-// use streams (it is against Google style to use streams in other places). It
-// is designed to allow you to emit non-ASCII Unicode strings to the log file,
-// which is normally ASCII. It is relatively slow, so try not to use it for
-// common cases. Non-ASCII characters will be converted to UTF-8 by these
-// operators.
-std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
-inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
-  return out << wstr.c_str();
-}
-}  // namespace std
-
 // The NOTIMPLEMENTED() macro annotates codepaths which have not been
 // implemented yet. If output spam is a serious concern,
 // NOTIMPLEMENTED_LOG_ONCE can be used.
diff --git a/base/numerics/safe_math_shared_impl.h b/base/numerics/safe_math_shared_impl.h
index 583c487..8518b45 100644
--- a/base/numerics/safe_math_shared_impl.h
+++ b/base/numerics/safe_math_shared_impl.h
@@ -18,8 +18,7 @@
 #include "base/numerics/safe_conversions.h"
 
 // Where available use builtin math overflow support on Clang and GCC.
-#if !defined(__native_client__) &&                         \
-    ((defined(__clang__) &&                                \
+#if ((defined(__clang__) &&                                \
       ((__clang_major__ > 3) ||                            \
        (__clang_major__ == 3 && __clang_minor__ >= 4))) || \
      (defined(__GNUC__) && __GNUC__ >= 5))
diff --git a/base/posix/safe_strerror.cc b/base/posix/safe_strerror.cc
index 3e3bb15..252b5df 100644
--- a/base/posix/safe_strerror.cc
+++ b/base/posix/safe_strerror.cc
@@ -20,7 +20,7 @@
 
 namespace base {
 
-#if defined(__GLIBC__) || defined(OS_NACL)
+#if defined(__GLIBC__)
 #define USE_HISTORICAL_STRERRO_R 1
 #else
 #define USE_HISTORICAL_STRERRO_R 0
diff --git a/base/strings/string16.cc b/base/strings/string16.cc
deleted file mode 100644
index 997ab20..0000000
--- a/base/strings/string16.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/string16.h"
-
-#if defined(WCHAR_T_IS_UTF16) && !defined(_AIX)
-
-#error This file should not be used on 2-byte wchar_t systems
-// If this winds up being needed on 2-byte wchar_t systems, either the
-// definitions below can be used, or the host system's wide character
-// functions like wmemcmp can be wrapped.
-
-#elif defined(WCHAR_T_IS_UTF32)
-
-#include <ostream>
-
-#include "base/strings/utf_string_conversions.h"
-
-namespace base {
-
-int c16memcmp(const char16* s1, const char16* s2, size_t n) {
-  // We cannot call memcmp because that changes the semantics.
-  while (n-- > 0) {
-    if (*s1 != *s2) {
-      // We cannot use (*s1 - *s2) because char16 is unsigned.
-      return ((*s1 < *s2) ? -1 : 1);
-    }
-    ++s1;
-    ++s2;
-  }
-  return 0;
-}
-
-size_t c16len(const char16* s) {
-  const char16* s_orig = s;
-  while (*s) {
-    ++s;
-  }
-  return s - s_orig;
-}
-
-const char16* c16memchr(const char16* s, char16 c, size_t n) {
-  while (n-- > 0) {
-    if (*s == c) {
-      return s;
-    }
-    ++s;
-  }
-  return nullptr;
-}
-
-char16* c16memmove(char16* s1, const char16* s2, size_t n) {
-  return static_cast<char16*>(memmove(s1, s2, n * sizeof(char16)));
-}
-
-char16* c16memcpy(char16* s1, const char16* s2, size_t n) {
-  return static_cast<char16*>(memcpy(s1, s2, n * sizeof(char16)));
-}
-
-char16* c16memset(char16* s, char16 c, size_t n) {
-  char16* s_orig = s;
-  while (n-- > 0) {
-    *s = c;
-    ++s;
-  }
-  return s_orig;
-}
-
-namespace string16_internals {
-
-std::ostream& operator<<(std::ostream& out, const string16& str) {
-  return out << UTF16ToUTF8(str);
-}
-
-void PrintTo(const string16& str, std::ostream* out) {
-  *out << str;
-}
-
-}  // namespace string16_internals
-
-}  // namespace base
-
-template class std::
-    basic_string<base::char16, base::string16_internals::string16_char_traits>;
-
-#endif  // WCHAR_T_IS_UTF32
diff --git a/base/strings/string16.h b/base/strings/string16.h
index 59bf6d7..a8e6ae3 100644
--- a/base/strings/string16.h
+++ b/base/strings/string16.h
@@ -5,199 +5,15 @@
 #ifndef BASE_STRINGS_STRING16_H_
 #define BASE_STRINGS_STRING16_H_
 
-// WHAT:
-// A version of std::basic_string that provides 2-byte characters even when
-// wchar_t is not implemented as a 2-byte type. You can access this class as
-// string16. We also define char16, which string16 is based upon.
-//
-// WHY:
-// On Windows, wchar_t is 2 bytes, and it can conveniently handle UTF-16/UCS-2
-// data. Plenty of existing code operates on strings encoded as UTF-16.
-//
-// On many other platforms, sizeof(wchar_t) is 4 bytes by default. We can make
-// it 2 bytes by using the GCC flag -fshort-wchar. But then std::wstring fails
-// at run time, because it calls some functions (like wcslen) that come from
-// the system's native C library -- which was built with a 4-byte wchar_t!
-// It's wasteful to use 4-byte wchar_t strings to carry UTF-16 data, and it's
-// entirely improper on those systems where the encoding of wchar_t is defined
-// as UTF-32.
-//
-// Here, we define string16, which is similar to std::wstring but replaces all
-// libc functions with custom, 2-byte-char compatible routines. It is capable
-// of carrying UTF-16-encoded data.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include <functional>
 #include <string>
 
-#include "util/build_config.h"
-
-#if defined(WCHAR_T_IS_UTF16)
-
 namespace base {
 
-typedef wchar_t char16;
-typedef std::wstring string16;
+// Temporary definitions. These should be removed and code using the standard
+// ones.
+using char16 = char16_t;
+using string16 = std::u16string;
 
 }  // namespace base
 
-#elif defined(WCHAR_T_IS_UTF32)
-
-#include <wchar.h>  // for mbstate_t
-
-namespace base {
-
-typedef uint16_t char16;
-
-// char16 versions of the functions required by string16_char_traits; these
-// are based on the wide character functions of similar names ("w" or "wcs"
-// instead of "c16").
-int c16memcmp(const char16* s1, const char16* s2, size_t n);
-size_t c16len(const char16* s);
-const char16* c16memchr(const char16* s, char16 c, size_t n);
-char16* c16memmove(char16* s1, const char16* s2, size_t n);
-char16* c16memcpy(char16* s1, const char16* s2, size_t n);
-char16* c16memset(char16* s, char16 c, size_t n);
-
-// This namespace contains the implementation of base::string16 along with
-// things that need to be found via argument-dependent lookup from a
-// base::string16.
-namespace string16_internals {
-
-struct string16_char_traits {
-  typedef char16 char_type;
-  typedef int int_type;
-
-  // int_type needs to be able to hold each possible value of char_type, and in
-  // addition, the distinct value of eof().
-  static_assert(sizeof(int_type) > sizeof(char_type),
-                "int must be larger than 16 bits wide");
-
-  typedef std::streamoff off_type;
-  typedef mbstate_t state_type;
-  typedef std::fpos<state_type> pos_type;
-
-  static void assign(char_type& c1, const char_type& c2) { c1 = c2; }
-
-  static bool eq(const char_type& c1, const char_type& c2) { return c1 == c2; }
-  static bool lt(const char_type& c1, const char_type& c2) { return c1 < c2; }
-
-  static int compare(const char_type* s1, const char_type* s2, size_t n) {
-    return c16memcmp(s1, s2, n);
-  }
-
-  static size_t length(const char_type* s) { return c16len(s); }
-
-  static const char_type* find(const char_type* s,
-                               size_t n,
-                               const char_type& a) {
-    return c16memchr(s, a, n);
-  }
-
-  static char_type* move(char_type* s1, const char_type* s2, size_t n) {
-    return c16memmove(s1, s2, n);
-  }
-
-  static char_type* copy(char_type* s1, const char_type* s2, size_t n) {
-    return c16memcpy(s1, s2, n);
-  }
-
-  static char_type* assign(char_type* s, size_t n, char_type a) {
-    return c16memset(s, a, n);
-  }
-
-  static int_type not_eof(const int_type& c) {
-    return eq_int_type(c, eof()) ? 0 : c;
-  }
-
-  static char_type to_char_type(const int_type& c) { return char_type(c); }
-
-  static int_type to_int_type(const char_type& c) { return int_type(c); }
-
-  static bool eq_int_type(const int_type& c1, const int_type& c2) {
-    return c1 == c2;
-  }
-
-  static int_type eof() { return static_cast<int_type>(EOF); }
-};
-
-}  // namespace string16_internals
-
-typedef std::basic_string<char16,
-                          base::string16_internals::string16_char_traits>
-    string16;
-
-namespace string16_internals {
-
-extern std::ostream& operator<<(std::ostream& out, const string16& str);
-
-// This is required by googletest to print a readable output on test failures.
-extern void PrintTo(const string16& str, std::ostream* out);
-
-}  // namespace string16_internals
-
-}  // namespace base
-
-// The string class will be explicitly instantiated only once, in string16.cc.
-//
-// std::basic_string<> in GNU libstdc++ contains a static data member,
-// _S_empty_rep_storage, to represent empty strings.  When an operation such
-// as assignment or destruction is performed on a string, causing its existing
-// data member to be invalidated, it must not be freed if this static data
-// member is being used.  Otherwise, it counts as an attempt to free static
-// (and not allocated) data, which is a memory error.
-//
-// Generally, due to C++ template magic, _S_empty_rep_storage will be marked
-// as a coalesced symbol, meaning that the linker will combine multiple
-// instances into a single one when generating output.
-//
-// If a string class is used by multiple shared libraries, a problem occurs.
-// Each library will get its own copy of _S_empty_rep_storage.  When strings
-// are passed across a library boundary for alteration or destruction, memory
-// errors will result.  GNU libstdc++ contains a configuration option,
-// --enable-fully-dynamic-string (_GLIBCXX_FULLY_DYNAMIC_STRING), which
-// disables the static data member optimization, but it's a good optimization
-// and non-STL code is generally at the mercy of the system's STL
-// configuration.  Fully-dynamic strings are not the default for GNU libstdc++
-// libstdc++ itself or for the libstdc++ installations on the systems we care
-// about, such as Mac OS X and relevant flavors of Linux.
-//
-// See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24196 .
-//
-// To avoid problems, string classes need to be explicitly instantiated only
-// once, in exactly one library.  All other string users see it via an "extern"
-// declaration.  This is precisely how GNU libstdc++ handles
-// std::basic_string<char> (string) and std::basic_string<wchar_t> (wstring).
-//
-// This also works around a Mac OS X linker bug in ld64-85.2.1 (Xcode 3.1.2),
-// in which the linker does not fully coalesce symbols when dead code
-// stripping is enabled.  This bug causes the memory errors described above
-// to occur even when a std::basic_string<> does not cross shared library
-// boundaries, such as in statically-linked executables.
-//
-// TODO(mark): File this bug with Apple and update this note with a bug number.
-
-extern template class std::
-    basic_string<base::char16, base::string16_internals::string16_char_traits>;
-
-// Specialize std::hash for base::string16. Although the style guide forbids
-// this in general, it is necessary for consistency with WCHAR_T_IS_UTF16
-// platforms, where base::string16 is a type alias for std::wstring.
-namespace std {
-template <>
-struct hash<base::string16> {
-  std::size_t operator()(const base::string16& s) const {
-    std::size_t result = 0;
-    for (base::char16 c : s)
-      result = (result * 131) + c;
-    return result;
-  }
-};
-}  // namespace std
-
-#endif  // WCHAR_T_IS_UTF32
-
 #endif  // BASE_STRINGS_STRING16_H_
diff --git a/base/strings/string_number_conversions.h b/base/strings/string_number_conversions.h
index ecf950e..8ffdd36 100644
--- a/base/strings/string_number_conversions.h
+++ b/base/strings/string_number_conversions.h
@@ -15,26 +15,6 @@
 #include "base/strings/string_piece.h"
 #include "util/build_config.h"
 
-// ----------------------------------------------------------------------------
-// IMPORTANT MESSAGE FROM YOUR SPONSOR
-//
-// This file contains no "wstring" variants. New code should use string16. If
-// you need to make old code work, use the UTF8 version and convert. Please do
-// not add wstring variants.
-//
-// Please do not add "convenience" functions for converting strings to integers
-// that return the value and ignore success/failure. That encourages people to
-// write code that doesn't properly handle the error conditions.
-//
-// DO NOT use these functions in any UI unless it's NOT localized on purpose.
-// Instead, use base::MessageFormatter for a complex message with numbers
-// (integer, float) embedded or base::Format{Number,Percent} to
-// just format a single number/percent. Note that some languages use native
-// digits instead of ASCII digits while others use a group separator or decimal
-// point different from ',' and '.'. Using these functions in the UI would lead
-// numbers to be formatted in a non-native way.
-// ----------------------------------------------------------------------------
-
 namespace base {
 
 // Number -> string conversions ------------------------------------------------
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 8e4deae..0722269 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -428,11 +428,6 @@
     HASH_STRING_PIECE(StringPiece16, sp16);
   }
 };
-struct WStringPieceHash {
-  std::size_t operator()(const WStringPiece& wsp) const {
-    HASH_STRING_PIECE(WStringPiece, wsp);
-  }
-};
 
 }  // namespace base
 
diff --git a/base/strings/string_piece_forward.h b/base/strings/string_piece_forward.h
index b50b980..86c1d5f 100644
--- a/base/strings/string_piece_forward.h
+++ b/base/strings/string_piece_forward.h
@@ -17,7 +17,6 @@
 class BasicStringPiece;
 typedef BasicStringPiece<std::string> StringPiece;
 typedef BasicStringPiece<string16> StringPiece16;
-typedef BasicStringPiece<std::wstring> WStringPiece;
 
 }  // namespace base
 
diff --git a/base/strings/string_tokenizer.h b/base/strings/string_tokenizer.h
index 451a011..9c3b5fa 100644
--- a/base/strings/string_tokenizer.h
+++ b/base/strings/string_tokenizer.h
@@ -242,7 +242,7 @@
 
 typedef StringTokenizerT<std::string, std::string::const_iterator>
     StringTokenizer;
-typedef StringTokenizerT<std::wstring, std::wstring::const_iterator>
+typedef StringTokenizerT<std::u16string, std::u16string::const_iterator>
     WStringTokenizer;
 typedef StringTokenizerT<std::string, const char*> CStringTokenizer;
 
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 9b03c26..f3e8257 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -97,54 +97,9 @@
 struct NonASCIIMask<8, char> {
   static inline uint64_t value() { return 0x8080808080808080ULL; }
 };
-#if defined(WCHAR_T_IS_UTF32)
-template <>
-struct NonASCIIMask<4, wchar_t> {
-  static inline uint32_t value() { return 0xFFFFFF80U; }
-};
-template <>
-struct NonASCIIMask<8, wchar_t> {
-  static inline uint64_t value() { return 0xFFFFFF80FFFFFF80ULL; }
-};
-#endif  // WCHAR_T_IS_UTF32
 
 }  // namespace
 
-bool IsWprintfFormatPortable(const wchar_t* format) {
-  for (const wchar_t* position = format; *position != '\0'; ++position) {
-    if (*position == '%') {
-      bool in_specification = true;
-      bool modifier_l = false;
-      while (in_specification) {
-        // Eat up characters until reaching a known specifier.
-        if (*++position == '\0') {
-          // The format string ended in the middle of a specification.  Call
-          // it portable because no unportable specifications were found.  The
-          // string is equally broken on all platforms.
-          return true;
-        }
-
-        if (*position == 'l') {
-          // 'l' is the only thing that can save the 's' and 'c' specifiers.
-          modifier_l = true;
-        } else if (((*position == 's' || *position == 'c') && !modifier_l) ||
-                   *position == 'S' || *position == 'C' || *position == 'F' ||
-                   *position == 'D' || *position == 'O' || *position == 'U') {
-          // Not portable.
-          return false;
-        }
-
-        if (wcschr(L"diouxXeEfgGaAcspn%", *position)) {
-          // Portable, keep scanning the rest of the format string.
-          in_specification = false;
-        }
-      }
-    }
-  }
-
-  return true;
-}
-
 namespace {
 
 template <typename StringType>
@@ -489,12 +444,6 @@
   return DoIsStringASCII(str.data(), str.length());
 }
 
-#if defined(WCHAR_T_IS_UTF32)
-bool IsStringASCII(WStringPiece str) {
-  return DoIsStringASCII(str.data(), str.length());
-}
-#endif
-
 bool IsStringUTF8(StringPiece str) {
   const char* src = str.data();
   int32_t src_len = static_cast<int32_t>(str.length());
@@ -623,7 +572,7 @@
   return EndsWithT<string16>(str, search_for, case_sensitivity);
 }
 
-char HexDigitToInt(wchar_t c) {
+char HexDigitToInt(char16_t c) {
   DCHECK(IsHexDigit(c));
   if (c >= '0' && c <= '9')
     return static_cast<char>(c - '0');
@@ -634,9 +583,9 @@
   return 0;
 }
 
-bool IsUnicodeWhitespace(wchar_t c) {
+bool IsUnicodeWhitespace(char16_t c) {
   // kWhitespaceWide is a NULL-terminated string
-  for (const wchar_t* cur = kWhitespaceWide; *cur; ++cur) {
+  for (const char16_t* cur = kWhitespaceUTF16; *cur; ++cur) {
     if (*cur == c)
       return true;
   }
@@ -1091,11 +1040,4 @@
 
 }  // namespace
 
-size_t strlcpy(char* dst, const char* src, size_t dst_size) {
-  return lcpyT<char>(dst, src, dst_size);
-}
-size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
-  return lcpyT<wchar_t>(dst, src, dst_size);
-}
-
 }  // namespace base
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 2d5d01c..9b3c608 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -53,38 +53,6 @@
   return result;
 }
 
-// BSD-style safe and consistent string copy functions.
-// Copies |src| to |dst|, where |dst_size| is the total allocated size of |dst|.
-// Copies at most |dst_size|-1 characters, and always NULL terminates |dst|, as
-// long as |dst_size| is not 0.  Returns the length of |src| in characters.
-// If the return value is >= dst_size, then the output was truncated.
-// NOTE: All sizes are in number of characters, NOT in bytes.
-size_t strlcpy(char* dst, const char* src, size_t dst_size);
-size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
-
-// Scan a wprintf format string to determine whether it's portable across a
-// variety of systems.  This function only checks that the conversion
-// specifiers used by the format string are supported and have the same meaning
-// on a variety of systems.  It doesn't check for other errors that might occur
-// within a format string.
-//
-// Nonportable conversion specifiers for wprintf are:
-//  - 's' and 'c' without an 'l' length modifier.  %s and %c operate on char
-//     data on all systems except Windows, which treat them as wchar_t data.
-//     Use %ls and %lc for wchar_t data instead.
-//  - 'S' and 'C', which operate on wchar_t data on all systems except Windows,
-//     which treat them as char data.  Use %ls and %lc for wchar_t data
-//     instead.
-//  - 'F', which is not identified by Windows wprintf documentation.
-//  - 'D', 'O', and 'U', which are deprecated and not available on all systems.
-//     Use %ld, %lo, and %lu instead.
-//
-// Note that there is no portable conversion specifier for char data when
-// working with wprintf.
-//
-// This function is intended to be called from base::vswprintf.
-bool IsWprintfFormatPortable(const wchar_t* format);
-
 // ASCII-specific tolower.  The standard library's tolower is locale sensitive,
 // so we don't want to use it here.
 inline char ToLowerASCII(char c) {
@@ -146,7 +114,6 @@
 // Contains the set of characters representing whitespace in the corresponding
 // encoding. Null-terminated. The ASCII versions are the whitespaces as defined
 // by HTML5, and don't include control characters.
-extern const wchar_t kWhitespaceWide[];  // Includes Unicode.
 extern const char16 kWhitespaceUTF16[];  // Includes Unicode.
 extern const char kWhitespaceASCII[];
 extern const char16 kWhitespaceASCIIAs16[];  // No unicode.
@@ -264,9 +231,6 @@
 bool IsStringUTF8(StringPiece str);
 bool IsStringASCII(StringPiece str);
 bool IsStringASCII(StringPiece16 str);
-#if defined(WCHAR_T_IS_UTF32)
-bool IsStringASCII(WStringPiece str);
-#endif
 
 // Compare the lower-case form of the given string against the given
 // previously-lower-cased ASCII string (typically a constant).
@@ -338,10 +302,10 @@
 //    'a' -> 10
 //    'B' -> 11
 // Assumes the input is a valid hex character. DCHECKs in debug builds if not.
-char HexDigitToInt(wchar_t c);
+char HexDigitToInt(char16_t c);
 
 // Returns true if it's a Unicode whitespace character.
-bool IsUnicodeWhitespace(wchar_t c);
+bool IsUnicodeWhitespace(char16_t c);
 
 // Return a byte string in human-readable format with a unit suffix. Not
 // appropriate for use in any UI; use of FormatBytes and friends in ui/base is
diff --git a/base/strings/string_util_constants.cc b/base/strings/string_util_constants.cc
index 37ff95f..ed17fcd 100644
--- a/base/strings/string_util_constants.cc
+++ b/base/strings/string_util_constants.cc
@@ -34,8 +34,6 @@
       0x3000, /* IDEOGRAPHIC SPACE */         \
       0
 
-const wchar_t kWhitespaceWide[] = {WHITESPACE_UNICODE};
-
 const char16 kWhitespaceUTF16[] = {WHITESPACE_UNICODE};
 
 const char kWhitespaceASCII[] = {0x09,  // CHARACTER TABULATION
diff --git a/base/strings/string_util_posix.h b/base/strings/string_util_posix.h
index 6868a65..83be1db 100644
--- a/base/strings/string_util_posix.h
+++ b/base/strings/string_util_posix.h
@@ -7,20 +7,12 @@
 
 #include <stdarg.h>
 #include <stddef.h>
-#include <stdio.h>
 #include <string.h>
-#include <wchar.h>
 
 #include "base/logging.h"
 
 namespace base {
 
-// Chromium code style is to not use malloc'd strings; this is only for use
-// for interaction with APIs that require it.
-inline char* strdup(const char* str) {
-  return ::strdup(str);
-}
-
 inline int vsnprintf(char* buffer,
                      size_t size,
                      const char* format,
@@ -28,14 +20,6 @@
   return ::vsnprintf(buffer, size, format, arguments);
 }
 
-inline int vswprintf(wchar_t* buffer,
-                     size_t size,
-                     const wchar_t* format,
-                     va_list arguments) {
-  DCHECK(IsWprintfFormatPortable(format));
-  return ::vswprintf(buffer, size, format, arguments);
-}
-
 }  // namespace base
 
 #endif  // BASE_STRINGS_STRING_UTIL_POSIX_H_
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h
index 8f9fa81..717a72c 100644
--- a/base/strings/string_util_win.h
+++ b/base/strings/string_util_win.h
@@ -9,18 +9,11 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
-#include <wchar.h>
 
 #include "base/logging.h"
 
 namespace base {
 
-// Chromium code style is to not use malloc'd strings; this is only for use
-// for interaction with APIs that require it.
-inline char* strdup(const char* str) {
-  return _strdup(str);
-}
-
 inline int vsnprintf(char* buffer,
                      size_t size,
                      const char* format,
@@ -31,18 +24,6 @@
   return length;
 }
 
-inline int vswprintf(wchar_t* buffer,
-                     size_t size,
-                     const wchar_t* format,
-                     va_list arguments) {
-  DCHECK(IsWprintfFormatPortable(format));
-
-  int length = _vsnwprintf_s(buffer, size, size - 1, format, arguments);
-  if (length < 0)
-    return _vscwprintf(format, arguments);
-  return length;
-}
-
 }  // namespace base
 
 #endif  // BASE_STRINGS_STRING_UTIL_WIN_H_
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc
index c7d141b..20ddfc6 100644
--- a/base/strings/stringprintf.cc
+++ b/base/strings/stringprintf.cc
@@ -32,15 +32,6 @@
   return base::vsnprintf(buffer, buf_size, format, argptr);
 }
 
-#if defined(OS_WIN)
-inline int vsnprintfT(wchar_t* buffer,
-                      size_t buf_size,
-                      const wchar_t* format,
-                      va_list argptr) {
-  return base::vswprintf(buffer, buf_size, format, argptr);
-}
-#endif
-
 // Templatized backend for StringPrintF/StringAppendF. This does not finalize
 // the va_list, the caller is expected to do that.
 template <class StringType>
@@ -122,17 +113,6 @@
   return result;
 }
 
-#if defined(OS_WIN)
-std::wstring StringPrintf(const wchar_t* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  std::wstring result;
-  StringAppendV(&result, format, ap);
-  va_end(ap);
-  return result;
-}
-#endif
-
 std::string StringPrintV(const char* format, va_list ap) {
   std::string result;
   StringAppendV(&result, format, ap);
@@ -148,19 +128,6 @@
   return *dst;
 }
 
-#if defined(OS_WIN)
-const std::wstring& SStringPrintf(std::wstring* dst,
-                                  const wchar_t* format,
-                                  ...) {
-  va_list ap;
-  va_start(ap, format);
-  dst->clear();
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-  return *dst;
-}
-#endif
-
 void StringAppendF(std::string* dst, const char* format, ...) {
   va_list ap;
   va_start(ap, format);
@@ -168,23 +135,8 @@
   va_end(ap);
 }
 
-#if defined(OS_WIN)
-void StringAppendF(std::wstring* dst, const wchar_t* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-}
-#endif
-
 void StringAppendV(std::string* dst, const char* format, va_list ap) {
   StringAppendVT(dst, format, ap);
 }
 
-#if defined(OS_WIN)
-void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) {
-  StringAppendVT(dst, format, ap);
-}
-#endif
-
 }  // namespace base
diff --git a/base/strings/stringprintf.h b/base/strings/stringprintf.h
index 8c12aca..e6e0746 100644
--- a/base/strings/stringprintf.h
+++ b/base/strings/stringprintf.h
@@ -17,10 +17,6 @@
 // Return a C++ string given printf-like input.
 std::string StringPrintf(_Printf_format_string_ const char* format, ...)
     PRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT;
-#if defined(OS_WIN)
-std::wstring StringPrintf(_Printf_format_string_ const wchar_t* format, ...)
-    WPRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT;
-#endif
 
 // Return a C++ string given vprintf-like input.
 std::string StringPrintV(const char* format, va_list ap)
@@ -30,30 +26,16 @@
 const std::string& SStringPrintf(std::string* dst,
                                  _Printf_format_string_ const char* format,
                                  ...) PRINTF_FORMAT(2, 3);
-#if defined(OS_WIN)
-const std::wstring& SStringPrintf(std::wstring* dst,
-                                  _Printf_format_string_ const wchar_t* format,
-                                  ...) WPRINTF_FORMAT(2, 3);
-#endif
 
 // Append result to a supplied string.
 void StringAppendF(std::string* dst,
                    _Printf_format_string_ const char* format,
                    ...) PRINTF_FORMAT(2, 3);
-#if defined(OS_WIN)
-void StringAppendF(std::wstring* dst,
-                   _Printf_format_string_ const wchar_t* format,
-                   ...) WPRINTF_FORMAT(2, 3);
-#endif
 
 // Lower-level routine that takes a va_list and appends to a specified
 // string.  All other routines are just convenience wrappers around it.
 void StringAppendV(std::string* dst, const char* format, va_list ap)
     PRINTF_FORMAT(2, 0);
-#if defined(OS_WIN)
-void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap)
-    WPRINTF_FORMAT(2, 0);
-#endif
 
 }  // namespace base
 
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index c962411..4e5f890 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -53,19 +53,6 @@
   return IsValidCodepoint(*code_point);
 }
 
-#if defined(WCHAR_T_IS_UTF32)
-bool ReadUnicodeCharacter(const wchar_t* src,
-                          int32_t src_len,
-                          int32_t* char_index,
-                          uint32_t* code_point) {
-  // Conversion is easy since the source is 32-bit.
-  *code_point = src[*char_index];
-
-  // Validate the value.
-  return IsValidCodepoint(*code_point);
-}
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 // WriteUnicodeCharacter -------------------------------------------------------
 
 size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output) {
@@ -120,10 +107,6 @@
 }
 
 // Instantiate versions we know callers will need.
-#if !defined(OS_WIN)
-// wchar_t and char16 are the same thing on Windows.
-template void PrepareForUTF8Output(const wchar_t*, size_t, std::string*);
-#endif
 template void PrepareForUTF8Output(const char16*, size_t, std::string*);
 
 template <typename STRING>
@@ -144,10 +127,6 @@
 }
 
 // Instantiate versions we know callers will need.
-#if !defined(OS_WIN)
-// std::wstring and string16 are the same thing on Windows.
-template void PrepareForUTF16Or32Output(const char*, size_t, std::wstring*);
-#endif
 template void PrepareForUTF16Or32Output(const char*, size_t, string16*);
 
 }  // namespace base
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h
index 6f89652..78cbde7 100644
--- a/base/strings/utf_string_conversion_utils.h
+++ b/base/strings/utf_string_conversion_utils.h
@@ -52,14 +52,6 @@
                           int32_t* char_index,
                           uint32_t* code_point);
 
-#if defined(WCHAR_T_IS_UTF32)
-// Reads UTF-32 character. The usage is the same as the 8-bit version above.
-bool ReadUnicodeCharacter(const wchar_t* src,
-                          int32_t src_len,
-                          int32_t* char_index,
-                          uint32_t* code_point);
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 // WriteUnicodeCharacter -------------------------------------------------------
 
 // Appends a UTF-8 character to the given 8-bit string.  Returns the number of
@@ -70,16 +62,6 @@
 // string.  Returns the number of 16-bit values written.
 size_t WriteUnicodeCharacter(uint32_t code_point, string16* output);
 
-#if defined(WCHAR_T_IS_UTF32)
-// Appends the given UTF-32 character to the given 32-bit string.  Returns the
-// number of 32-bit values written.
-inline size_t WriteUnicodeCharacter(uint32_t code_point, std::wstring* output) {
-  // This is the easy case, just append the character.
-  output->push_back(code_point);
-  return 1;
-}
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 // Generalized Unicode converter -----------------------------------------------
 
 // Guesses the length of the output in UTF-8 in bytes, clears that output
diff --git a/base/strings/utf_string_conversions.cc b/base/strings/utf_string_conversions.cc
index b04d54d..15f12f6 100644
--- a/base/strings/utf_string_conversions.cc
+++ b/base/strings/utf_string_conversions.cc
@@ -37,20 +37,6 @@
   static constexpr int value = 3;
 };
 
-#if defined(WCHAR_T_IS_UTF32)
-template <>
-struct SizeCoefficient<wchar_t, char> {
-  // UTF-8 uses at most 4 codeunits per character.
-  static constexpr int value = 4;
-};
-
-template <>
-struct SizeCoefficient<wchar_t, char16> {
-  // UTF-16 uses at most 2 codeunits per character.
-  static constexpr int value = 2;
-};
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 template <typename SrcChar, typename DestChar>
 constexpr int size_coefficient_v =
     SizeCoefficient<std::decay_t<SrcChar>, std::decay_t<DestChar>>::value;
@@ -67,14 +53,6 @@
   CBU16_APPEND_UNSAFE(out, *size, code_point);
 }
 
-#if defined(WCHAR_T_IS_UTF32)
-
-void UnicodeAppendUnsafe(wchar_t* out, int32_t* size, uint32_t code_point) {
-  out[(*size)++] = code_point;
-}
-
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 // DoUTFConversion ------------------------------------------------------------
 // Main driver of UTFConversion specialized for different Src encodings.
 // dest has to have enough room for the converted text.
@@ -144,31 +122,6 @@
   return success;
 }
 
-#if defined(WCHAR_T_IS_UTF32)
-
-template <typename DestChar>
-bool DoUTFConversion(const wchar_t* src,
-                     int32_t src_len,
-                     DestChar* dest,
-                     int32_t* dest_len) {
-  bool success = true;
-
-  for (int32_t i = 0; i < src_len; ++i) {
-    int32_t code_point = src[i];
-
-    if (!IsValidCodepoint(code_point)) {
-      success = false;
-      code_point = kErrorCodePoint;
-    }
-
-    UnicodeAppendUnsafe(dest, dest_len, code_point);
-  }
-
-  return success;
-}
-
-#endif  // defined(WCHAR_T_IS_UTF32)
-
 // UTFConversion --------------------------------------------------------------
 // Function template for generating all UTF conversions.
 
@@ -226,99 +179,7 @@
   return ret;
 }
 
-// UTF-16 <-> Wide -------------------------------------------------------------
-
-#if defined(WCHAR_T_IS_UTF16)
-// When wide == UTF-16 the conversions are a NOP.
-
-bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) {
-  output->assign(src, src_len);
-  return true;
-}
-
-string16 WideToUTF16(WStringPiece wide) {
-  return wide.as_string();
-}
-
-bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) {
-  output->assign(src, src_len);
-  return true;
-}
-
-std::wstring UTF16ToWide(StringPiece16 utf16) {
-  return utf16.as_string();
-}
-
-#elif defined(WCHAR_T_IS_UTF32)
-
-bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) {
-  return UTFConversion(base::WStringPiece(src, src_len), output);
-}
-
-string16 WideToUTF16(WStringPiece wide) {
-  string16 ret;
-  // Ignore the success flag of this call, it will do the best it can for
-  // invalid input, which is what we want here.
-  WideToUTF16(wide.data(), wide.length(), &ret);
-  return ret;
-}
-
-bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) {
-  return UTFConversion(StringPiece16(src, src_len), output);
-}
-
-std::wstring UTF16ToWide(StringPiece16 utf16) {
-  std::wstring ret;
-  // Ignore the success flag of this call, it will do the best it can for
-  // invalid input, which is what we want here.
-  UTF16ToWide(utf16.data(), utf16.length(), &ret);
-  return ret;
-}
-
-#endif  // defined(WCHAR_T_IS_UTF32)
-
-// UTF-8 <-> Wide --------------------------------------------------------------
-
-// UTF8ToWide is the same code, regardless of whether wide is 16 or 32 bits
-
-bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output) {
-  return UTFConversion(StringPiece(src, src_len), output);
-}
-
-std::wstring UTF8ToWide(StringPiece utf8) {
-  std::wstring ret;
-  // Ignore the success flag of this call, it will do the best it can for
-  // invalid input, which is what we want here.
-  UTF8ToWide(utf8.data(), utf8.length(), &ret);
-  return ret;
-}
-
-#if defined(WCHAR_T_IS_UTF16)
-// Easy case since we can use the "utf" versions we already wrote above.
-
-bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) {
-  return UTF16ToUTF8(src, src_len, output);
-}
-
-std::string WideToUTF8(WStringPiece wide) {
-  return UTF16ToUTF8(wide);
-}
-
-#elif defined(WCHAR_T_IS_UTF32)
-
-bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) {
-  return UTFConversion(WStringPiece(src, src_len), output);
-}
-
-std::string WideToUTF8(WStringPiece wide) {
-  std::string ret;
-  // Ignore the success flag of this call, it will do the best it can for
-  // invalid input, which is what we want here.
-  WideToUTF8(wide.data(), wide.length(), &ret);
-  return ret;
-}
-
-#endif  // defined(WCHAR_T_IS_UTF32)
+// ASCII <-> UTF-16 -----------------------------------------------------------
 
 string16 ASCIIToUTF16(StringPiece ascii) {
   DCHECK(IsStringASCII(ascii)) << ascii;
diff --git a/base/strings/utf_string_conversions.h b/base/strings/utf_string_conversions.h
index 704943e..c4c2b11 100644
--- a/base/strings/utf_string_conversions.h
+++ b/base/strings/utf_string_conversions.h
@@ -14,22 +14,6 @@
 
 namespace base {
 
-// These convert between UTF-8, -16, and -32 strings. They are potentially slow,
-// so avoid unnecessary conversions. The low-level versions return a boolean
-// indicating whether the conversion was 100% valid. In this case, it will still
-// do the best it can and put the result in the output buffer. The versions that
-// return strings ignore this error and just return the best conversion
-// possible.
-bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output);
-std::string WideToUTF8(WStringPiece wide);
-bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output);
-std::wstring UTF8ToWide(StringPiece utf8);
-
-bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output);
-string16 WideToUTF16(WStringPiece wide);
-bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output);
-std::wstring UTF16ToWide(StringPiece16 utf16);
-
 bool UTF8ToUTF16(const char* src, size_t src_len, string16* output);
 string16 UTF8ToUTF16(StringPiece utf8);
 bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output);
diff --git a/base/win/registry.cc b/base/win/registry.cc
index e07820b..2ea2de3 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string_util.h"
+#include "base/win/win_util.h"
 
 namespace base {
 namespace win {
@@ -22,11 +23,11 @@
 // name size, such that a buffer with this size should read any name.
 const DWORD MAX_REGISTRY_NAME_SIZE = 16384;
 
-// Registry values are read as BYTE* but can have wchar_t* data whose last
-// wchar_t is truncated. This function converts the reported |byte_size| to
-// a size in wchar_t that can store a truncated wchar_t if necessary.
+// Registry values are read as BYTE* but can have char16_t* data whose last
+// char16_t is truncated. This function converts the reported |byte_size| to
+// a size in char16_t that can store a truncated char16_t if necessary.
 inline DWORD to_wchar_size(DWORD byte_size) {
-  return (byte_size + sizeof(wchar_t) - 1) / sizeof(wchar_t);
+  return (byte_size + sizeof(char16_t) - 1) / sizeof(char16_t);
 }
 
 // Mask to pull WOW64 access flags out of REGSAM access.
@@ -40,7 +41,7 @@
 
 RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {}
 
-RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
+RegKey::RegKey(HKEY rootkey, const char16_t* subkey, REGSAM access)
     : key_(NULL), wow64access_(0) {
   if (rootkey) {
     if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
@@ -57,20 +58,20 @@
   Close();
 }
 
-LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
+LONG RegKey::Create(HKEY rootkey, const char16_t* subkey, REGSAM access) {
   DWORD disposition_value;
   return CreateWithDisposition(rootkey, subkey, &disposition_value, access);
 }
 
 LONG RegKey::CreateWithDisposition(HKEY rootkey,
-                                   const wchar_t* subkey,
+                                   const char16_t* subkey,
                                    DWORD* disposition,
                                    REGSAM access) {
   DCHECK(rootkey && subkey && access && disposition);
   HKEY subhkey = NULL;
-  LONG result =
-      RegCreateKeyEx(rootkey, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, access,
-                     NULL, &subhkey, disposition);
+  LONG result = RegCreateKeyEx(rootkey, ToWCharT(subkey), 0, NULL,
+                               REG_OPTION_NON_VOLATILE, access, NULL, &subhkey,
+                               disposition);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subhkey;
@@ -80,7 +81,7 @@
   return result;
 }
 
-LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) {
+LONG RegKey::CreateKey(const char16_t* name, REGSAM access) {
   DCHECK(name && access);
   // After the application has accessed an alternate registry view using one of
   // the [KEY_WOW64_32KEY / KEY_WOW64_64KEY] flags, all subsequent operations
@@ -92,8 +93,9 @@
     return ERROR_INVALID_PARAMETER;
   }
   HKEY subkey = NULL;
-  LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
-                               access, NULL, &subkey, NULL);
+  LONG result =
+      RegCreateKeyEx(key_, ToWCharT(name), 0, NULL, REG_OPTION_NON_VOLATILE,
+                     access, NULL, &subkey, NULL);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subkey;
@@ -103,11 +105,11 @@
   return result;
 }
 
-LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
+LONG RegKey::Open(HKEY rootkey, const char16_t* subkey, REGSAM access) {
   DCHECK(rootkey && subkey && access);
   HKEY subhkey = NULL;
 
-  LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &subhkey);
+  LONG result = RegOpenKeyEx(rootkey, ToWCharT(subkey), 0, access, &subhkey);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subhkey;
@@ -117,7 +119,7 @@
   return result;
 }
 
-LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) {
+LONG RegKey::OpenKey(const char16_t* relative_key_name, REGSAM access) {
   DCHECK(relative_key_name && access);
   // After the application has accessed an alternate registry view using one of
   // the [KEY_WOW64_32KEY / KEY_WOW64_64KEY] flags, all subsequent operations
@@ -129,7 +131,8 @@
     return ERROR_INVALID_PARAMETER;
   }
   HKEY subkey = NULL;
-  LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey);
+  LONG result =
+      RegOpenKeyEx(key_, ToWCharT(relative_key_name), 0, access, &subkey);
 
   // We have to close the current opened key before replacing it with the new
   // one.
@@ -164,8 +167,9 @@
   return key;
 }
 
-bool RegKey::HasValue(const wchar_t* name) const {
-  return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
+bool RegKey::HasValue(const char16_t* name) const {
+  return RegQueryValueEx(key_, ToWCharT(name), 0, NULL, NULL, NULL) ==
+         ERROR_SUCCESS;
 }
 
 DWORD RegKey::GetValueCount() const {
@@ -175,39 +179,40 @@
   return (result == ERROR_SUCCESS) ? count : 0;
 }
 
-LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
-  wchar_t buf[256];
+LONG RegKey::GetValueNameAt(int index, std::u16string* name) const {
+  char16_t buf[256];
   DWORD bufsize = arraysize(buf);
-  LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL);
+  LONG r = ::RegEnumValue(key_, index, ToWCharT(buf), &bufsize, NULL, NULL,
+                          NULL, NULL);
   if (r == ERROR_SUCCESS)
     *name = buf;
 
   return r;
 }
 
-LONG RegKey::DeleteKey(const wchar_t* name) {
+LONG RegKey::DeleteKey(const char16_t* name) {
   DCHECK(key_);
   DCHECK(name);
   HKEY subkey = NULL;
 
   // Verify the key exists before attempting delete to replicate previous
   // behavior.
-  LONG result =
-      RegOpenKeyEx(key_, name, 0, READ_CONTROL | wow64access_, &subkey);
+  LONG result = RegOpenKeyEx(key_, ToWCharT(name), 0,
+                             READ_CONTROL | wow64access_, &subkey);
   if (result != ERROR_SUCCESS)
     return result;
   RegCloseKey(subkey);
 
-  return RegDelRecurse(key_, std::wstring(name), wow64access_);
+  return RegDelRecurse(key_, std::u16string(name), wow64access_);
 }
 
-LONG RegKey::DeleteEmptyKey(const wchar_t* name) {
+LONG RegKey::DeleteEmptyKey(const char16_t* name) {
   DCHECK(key_);
   DCHECK(name);
 
   HKEY target_key = NULL;
-  LONG result =
-      RegOpenKeyEx(key_, name, 0, KEY_READ | wow64access_, &target_key);
+  LONG result = RegOpenKeyEx(key_, ToWCharT(name), 0, KEY_READ | wow64access_,
+                             &target_key);
 
   if (result != ERROR_SUCCESS)
     return result;
@@ -227,13 +232,13 @@
   return ERROR_DIR_NOT_EMPTY;
 }
 
-LONG RegKey::DeleteValue(const wchar_t* value_name) {
+LONG RegKey::DeleteValue(const char16_t* value_name) {
   DCHECK(key_);
-  LONG result = RegDeleteValue(key_, value_name);
+  LONG result = RegDeleteValue(key_, ToWCharT(value_name));
   return result;
 }
 
-LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const {
+LONG RegKey::ReadValueDW(const char16_t* name, DWORD* out_value) const {
   DCHECK(out_value);
   DWORD type = REG_DWORD;
   DWORD size = sizeof(DWORD);
@@ -249,7 +254,7 @@
   return result;
 }
 
-LONG RegKey::ReadInt64(const wchar_t* name, int64_t* out_value) const {
+LONG RegKey::ReadInt64(const char16_t* name, int64_t* out_value) const {
   DCHECK(out_value);
   DWORD type = REG_QWORD;
   int64_t local_value = 0;
@@ -266,20 +271,21 @@
   return result;
 }
 
-LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const {
+LONG RegKey::ReadValue(const char16_t* name, std::u16string* out_value) const {
   DCHECK(out_value);
   const size_t kMaxStringLength = 1024;  // This is after expansion.
   // Use the one of the other forms of ReadValue if 1024 is too small for you.
-  wchar_t raw_value[kMaxStringLength];
+  char16_t raw_value[kMaxStringLength];
   DWORD type = REG_SZ, size = sizeof(raw_value);
   LONG result = ReadValue(name, raw_value, &size, &type);
   if (result == ERROR_SUCCESS) {
     if (type == REG_SZ) {
       *out_value = raw_value;
     } else if (type == REG_EXPAND_SZ) {
-      wchar_t expanded[kMaxStringLength];
-      size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength);
-      // Success: returns the number of wchar_t's copied
+      char16_t expanded[kMaxStringLength];
+      size = ExpandEnvironmentStrings(ToWCharT(raw_value), ToWCharT(expanded),
+                                      kMaxStringLength);
+      // Success: returns the number of char16_t's copied
       // Fail: buffer too small, returns the size required
       // Fail: other, returns 0
       if (size == 0 || size > kMaxStringLength) {
@@ -296,17 +302,17 @@
   return result;
 }
 
-LONG RegKey::ReadValue(const wchar_t* name,
+LONG RegKey::ReadValue(const char16_t* name,
                        void* data,
                        DWORD* dsize,
                        DWORD* dtype) const {
-  LONG result = RegQueryValueEx(key_, name, 0, dtype,
+  LONG result = RegQueryValueEx(key_, ToWCharT(name), 0, dtype,
                                 reinterpret_cast<LPBYTE>(data), dsize);
   return result;
 }
 
-LONG RegKey::ReadValues(const wchar_t* name,
-                        std::vector<std::wstring>* values) {
+LONG RegKey::ReadValues(const char16_t* name,
+                        std::vector<std::u16string>* values) {
   values->clear();
 
   DWORD type = REG_MULTI_SZ;
@@ -318,7 +324,7 @@
   if (type != REG_MULTI_SZ)
     return ERROR_CANTREAD;
 
-  std::vector<wchar_t> buffer(size / sizeof(wchar_t));
+  std::vector<char16_t> buffer(size / sizeof(char16_t));
   result = ReadValue(name, &buffer[0], &size, NULL);
   if (result != ERROR_SUCCESS || size == 0)
     return result;
@@ -326,42 +332,43 @@
   // Parse the double-null-terminated list of strings.
   // Note: This code is paranoid to not read outside of |buf|, in the case where
   // it may not be properly terminated.
-  const wchar_t* entry = &buffer[0];
-  const wchar_t* buffer_end = entry + (size / sizeof(wchar_t));
+  const char16_t* entry = &buffer[0];
+  const char16_t* buffer_end = entry + (size / sizeof(char16_t));
   while (entry < buffer_end && entry[0] != '\0') {
-    const wchar_t* entry_end = std::find(entry, buffer_end, L'\0');
-    values->push_back(std::wstring(entry, entry_end));
+    const char16_t* entry_end = std::find(entry, buffer_end, L'\0');
+    values->push_back(std::u16string(entry, entry_end));
     entry = entry_end + 1;
   }
   return 0;
 }
 
-LONG RegKey::WriteValue(const wchar_t* name, DWORD in_value) {
+LONG RegKey::WriteValue(const char16_t* name, DWORD in_value) {
   return WriteValue(name, &in_value, static_cast<DWORD>(sizeof(in_value)),
                     REG_DWORD);
 }
 
-LONG RegKey::WriteValue(const wchar_t* name, const wchar_t* in_value) {
+LONG RegKey::WriteValue(const char16_t* name, const char16_t* in_value) {
   return WriteValue(
       name, in_value,
-      static_cast<DWORD>(sizeof(*in_value) * (wcslen(in_value) + 1)), REG_SZ);
+      static_cast<DWORD>(sizeof(*in_value) * (wcslen(ToWCharT(in_value)) + 1)),
+      REG_SZ);
 }
 
-LONG RegKey::WriteValue(const wchar_t* name,
+LONG RegKey::WriteValue(const char16_t* name,
                         const void* data,
                         DWORD dsize,
                         DWORD dtype) {
   DCHECK(data || !dsize);
 
   LONG result =
-      RegSetValueEx(key_, name, 0, dtype,
+      RegSetValueEx(key_, ToWCharT(name), 0, dtype,
                     reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
   return result;
 }
 
 // static
 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey,
-                                   const wchar_t* lpSubKey,
+                                   const char16_t* lpSubKey,
                                    REGSAM samDesired,
                                    DWORD Reserved) {
   typedef LSTATUS(WINAPI * RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD);
@@ -371,15 +378,16 @@
           GetProcAddress(GetModuleHandleA("advapi32.dll"), "RegDeleteKeyExW"));
 
   if (reg_delete_key_ex_func)
-    return reg_delete_key_ex_func(hKey, lpSubKey, samDesired, Reserved);
+    return reg_delete_key_ex_func(hKey, ToWCharT(lpSubKey), samDesired,
+                                  Reserved);
 
   // Windows XP does not support RegDeleteKeyEx, so fallback to RegDeleteKey.
-  return RegDeleteKey(hKey, lpSubKey);
+  return RegDeleteKey(hKey, ToWCharT(lpSubKey));
 }
 
 // static
 LONG RegKey::RegDelRecurse(HKEY root_key,
-                           const std::wstring& name,
+                           const std::u16string& name,
                            REGSAM access) {
   // First, see if the key can be deleted without having to recurse.
   LONG result = RegDeleteKeyExWrapper(root_key, name.c_str(), access, 0);
@@ -387,7 +395,7 @@
     return result;
 
   HKEY target_key = NULL;
-  result = RegOpenKeyEx(root_key, name.c_str(), 0,
+  result = RegOpenKeyEx(root_key, ToWCharT(&name), 0,
                         KEY_ENUMERATE_SUB_KEYS | access, &target_key);
 
   if (result == ERROR_FILE_NOT_FOUND)
@@ -395,22 +403,22 @@
   if (result != ERROR_SUCCESS)
     return result;
 
-  std::wstring subkey_name(name);
+  std::u16string subkey_name(name);
 
   // Check for an ending slash and add one if it is missing.
-  if (!name.empty() && subkey_name[name.length() - 1] != L'\\')
-    subkey_name += L"\\";
+  if (!name.empty() && subkey_name[name.length() - 1] != '\\')
+    subkey_name += u"\\";
 
   // Enumerate the keys
   result = ERROR_SUCCESS;
   const DWORD kMaxKeyNameLength = MAX_PATH;
   const size_t base_key_length = subkey_name.length();
-  std::wstring key_name;
+  std::u16string key_name;
   while (result == ERROR_SUCCESS) {
     DWORD key_size = kMaxKeyNameLength;
-    result =
-        RegEnumKeyEx(target_key, 0, WriteInto(&key_name, kMaxKeyNameLength),
-                     &key_size, NULL, NULL, NULL, NULL);
+    result = RegEnumKeyEx(target_key, 0,
+                          ToWCharT(WriteInto(&key_name, kMaxKeyNameLength)),
+                          &key_size, NULL, NULL, NULL, NULL);
 
     if (result != ERROR_SUCCESS)
       break;
@@ -434,24 +442,24 @@
 // RegistryValueIterator ------------------------------------------------------
 
 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
-                                             const wchar_t* folder_key,
+                                             const char16_t* folder_key,
                                              REGSAM wow64access)
     : name_(MAX_PATH, L'\0'), value_(MAX_PATH, L'\0') {
   Initialize(root_key, folder_key, wow64access);
 }
 
 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
-                                             const wchar_t* folder_key)
+                                             const char16_t* folder_key)
     : name_(MAX_PATH, L'\0'), value_(MAX_PATH, L'\0') {
   Initialize(root_key, folder_key, 0);
 }
 
 void RegistryValueIterator::Initialize(HKEY root_key,
-                                       const wchar_t* folder_key,
+                                       const char16_t* folder_key,
                                        REGSAM wow64access) {
   DCHECK_EQ(wow64access & ~kWow64AccessMask, static_cast<REGSAM>(0));
-  LONG result =
-      RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
+  LONG result = RegOpenKeyEx(root_key, ToWCharT(folder_key), 0,
+                             KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
     key_ = NULL;
   } else {
@@ -499,10 +507,10 @@
     DWORD capacity = static_cast<DWORD>(name_.capacity());
     DWORD name_size = capacity;
     // |value_size_| is in bytes. Reserve the last character for a NUL.
-    value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
+    value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(char16_t));
     LONG result = ::RegEnumValue(
-        key_, index_, WriteInto(&name_, name_size), &name_size, NULL, &type_,
-        reinterpret_cast<BYTE*>(value_.data()), &value_size_);
+        key_, index_, ToWCharT(WriteInto(&name_, name_size)), &name_size, NULL,
+        &type_, reinterpret_cast<BYTE*>(value_.data()), &value_size_);
 
     if (result == ERROR_MORE_DATA) {
       // Registry key names are limited to 255 characters and fit within
@@ -514,11 +522,11 @@
       DWORD value_size_in_wchars = to_wchar_size(value_size_);
       if (value_size_in_wchars + 1 > value_.size())
         value_.resize(value_size_in_wchars + 1, L'\0');
-      value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
+      value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(char16_t));
       name_size = name_size == capacity ? MAX_REGISTRY_NAME_SIZE : capacity;
       result = ::RegEnumValue(
-          key_, index_, WriteInto(&name_, name_size), &name_size, NULL, &type_,
-          reinterpret_cast<BYTE*>(value_.data()), &value_size_);
+          key_, index_, ToWCharT(WriteInto(&name_, name_size)), &name_size,
+          NULL, &type_, reinterpret_cast<BYTE*>(value_.data()), &value_size_);
     }
 
     if (result == ERROR_SUCCESS) {
@@ -537,12 +545,12 @@
 // RegistryKeyIterator --------------------------------------------------------
 
 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
-                                         const wchar_t* folder_key) {
+                                         const char16_t* folder_key) {
   Initialize(root_key, folder_key, 0);
 }
 
 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
-                                         const wchar_t* folder_key,
+                                         const char16_t* folder_key,
                                          REGSAM wow64access) {
   Initialize(root_key, folder_key, wow64access);
 }
@@ -575,8 +583,8 @@
   if (Valid()) {
     DWORD ncount = arraysize(name_);
     FILETIME written;
-    LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, NULL,
-                            &written);
+    LONG r = ::RegEnumKeyEx(key_, index_, ToWCharT(name_), &ncount, NULL, NULL,
+                            NULL, &written);
     if (ERROR_SUCCESS == r)
       return true;
   }
@@ -586,11 +594,11 @@
 }
 
 void RegistryKeyIterator::Initialize(HKEY root_key,
-                                     const wchar_t* folder_key,
+                                     const char16_t* folder_key,
                                      REGSAM wow64access) {
   DCHECK_EQ(wow64access & ~kWow64AccessMask, static_cast<REGSAM>(0));
-  LONG result =
-      RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
+  LONG result = RegOpenKeyEx(root_key, ToWCharT(folder_key), 0,
+                             KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
     key_ = NULL;
   } else {
diff --git a/base/win/registry.h b/base/win/registry.h
index e2e0d30..1fb2388 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -29,24 +29,24 @@
  public:
   RegKey();
   explicit RegKey(HKEY key);
-  RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access);
+  RegKey(HKEY rootkey, const char16_t* subkey, REGSAM access);
   ~RegKey();
 
-  LONG Create(HKEY rootkey, const wchar_t* subkey, REGSAM access);
+  LONG Create(HKEY rootkey, const char16_t* subkey, REGSAM access);
 
   LONG CreateWithDisposition(HKEY rootkey,
-                             const wchar_t* subkey,
+                             const char16_t* subkey,
                              DWORD* disposition,
                              REGSAM access);
 
   // Creates a subkey or open it if it already exists.
-  LONG CreateKey(const wchar_t* name, REGSAM access);
+  LONG CreateKey(const char16_t* name, REGSAM access);
 
   // Opens an existing reg key.
-  LONG Open(HKEY rootkey, const wchar_t* subkey, REGSAM access);
+  LONG Open(HKEY rootkey, const char16_t* subkey, REGSAM access);
 
   // Opens an existing reg key, given the relative key name.
-  LONG OpenKey(const wchar_t* relative_key_name, REGSAM access);
+  LONG OpenKey(const char16_t* relative_key_name, REGSAM access);
 
   // Closes this reg key.
   void Close();
@@ -59,51 +59,51 @@
 
   // Returns false if this key does not have the specified value, or if an error
   // occurrs while attempting to access it.
-  bool HasValue(const wchar_t* value_name) const;
+  bool HasValue(const char16_t* value_name) const;
 
   // Returns the number of values for this key, or 0 if the number cannot be
   // determined.
   DWORD GetValueCount() const;
 
   // Determines the nth value's name.
-  LONG GetValueNameAt(int index, std::wstring* name) const;
+  LONG GetValueNameAt(int index, std::u16string* name) const;
 
   // True while the key is valid.
   bool Valid() const { return key_ != NULL; }
 
   // Kills a key and everything that lives below it; please be careful when
   // using it.
-  LONG DeleteKey(const wchar_t* name);
+  LONG DeleteKey(const char16_t* name);
 
   // Deletes an empty subkey.  If the subkey has subkeys or values then this
   // will fail.
-  LONG DeleteEmptyKey(const wchar_t* name);
+  LONG DeleteEmptyKey(const char16_t* name);
 
   // Deletes a single value within the key.
-  LONG DeleteValue(const wchar_t* name);
+  LONG DeleteValue(const char16_t* name);
 
   // Getters:
 
   // Reads a REG_DWORD (uint32_t) into |out_value|. If |name| is null or empty,
   // reads the key's default value, if any.
-  LONG ReadValueDW(const wchar_t* name, DWORD* out_value) const;
+  LONG ReadValueDW(const char16_t* name, DWORD* out_value) const;
 
   // Reads a REG_QWORD (int64_t) into |out_value|. If |name| is null or empty,
   // reads the key's default value, if any.
-  LONG ReadInt64(const wchar_t* name, int64_t* out_value) const;
+  LONG ReadInt64(const char16_t* name, int64_t* out_value) const;
 
   // Reads a string into |out_value|. If |name| is null or empty, reads
   // the key's default value, if any.
-  LONG ReadValue(const wchar_t* name, std::wstring* out_value) const;
+  LONG ReadValue(const char16_t* name, std::u16string* out_value) const;
 
   // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears
   // |values| initially and adds further strings to the list. Returns
   // ERROR_CANTREAD if type is not REG_MULTI_SZ.
-  LONG ReadValues(const wchar_t* name, std::vector<std::wstring>* values);
+  LONG ReadValues(const char16_t* name, std::vector<std::u16string>* values);
 
   // Reads raw data into |data|. If |name| is null or empty, reads the key's
   // default value, if any.
-  LONG ReadValue(const wchar_t* name,
+  LONG ReadValue(const char16_t* name,
                  void* data,
                  DWORD* dsize,
                  DWORD* dtype) const;
@@ -111,13 +111,13 @@
   // Setters:
 
   // Sets an int32_t value.
-  LONG WriteValue(const wchar_t* name, DWORD in_value);
+  LONG WriteValue(const char16_t* name, DWORD in_value);
 
   // Sets a string value.
-  LONG WriteValue(const wchar_t* name, const wchar_t* in_value);
+  LONG WriteValue(const char16_t* name, const char16_t* in_value);
 
   // Sets raw data, including type.
-  LONG WriteValue(const wchar_t* name,
+  LONG WriteValue(const char16_t* name,
                   const void* data,
                   DWORD dsize,
                   DWORD dtype);
@@ -128,13 +128,13 @@
   // Calls RegDeleteKeyEx on supported platforms, alternatively falls back to
   // RegDeleteKey.
   static LONG RegDeleteKeyExWrapper(HKEY hKey,
-                                    const wchar_t* lpSubKey,
+                                    const char16_t* lpSubKey,
                                     REGSAM samDesired,
                                     DWORD Reserved);
 
   // Recursively deletes a key and all of its subkeys.
   static LONG RegDelRecurse(HKEY root_key,
-                            const std::wstring& name,
+                            const std::u16string& name,
                             REGSAM access);
 
   HKEY key_;  // The registry key being iterated.
@@ -147,7 +147,7 @@
 class RegistryValueIterator {
  public:
   // Constructs a Registry Value Iterator with default WOW64 access.
-  RegistryValueIterator(HKEY root_key, const wchar_t* folder_key);
+  RegistryValueIterator(HKEY root_key, const char16_t* folder_key);
 
   // Constructs a Registry Key Iterator with specific WOW64 access, one of
   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0.
@@ -155,7 +155,7 @@
   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE).
   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx.
   RegistryValueIterator(HKEY root_key,
-                        const wchar_t* folder_key,
+                        const char16_t* folder_key,
                         REGSAM wow64access);
 
   ~RegistryValueIterator();
@@ -168,8 +168,8 @@
   // Advances to the next registry entry.
   void operator++();
 
-  const wchar_t* Name() const { return name_.c_str(); }
-  const wchar_t* Value() const { return value_.data(); }
+  const char16_t* Name() const { return name_.c_str(); }
+  const char16_t* Value() const { return value_.data(); }
   // ValueSize() is in bytes.
   DWORD ValueSize() const { return value_size_; }
   DWORD Type() const { return type_; }
@@ -180,7 +180,9 @@
   // Reads in the current values.
   bool Read();
 
-  void Initialize(HKEY root_key, const wchar_t* folder_key, REGSAM wow64access);
+  void Initialize(HKEY root_key,
+                  const char16_t* folder_key,
+                  REGSAM wow64access);
 
   // The registry key being iterated.
   HKEY key_;
@@ -189,8 +191,8 @@
   int index_;
 
   // Current values.
-  std::wstring name_;
-  std::vector<wchar_t> value_;
+  std::u16string name_;
+  std::vector<char16_t> value_;
   DWORD value_size_;
   DWORD type_;
 
@@ -200,7 +202,7 @@
 class RegistryKeyIterator {
  public:
   // Constructs a Registry Key Iterator with default WOW64 access.
-  RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key);
+  RegistryKeyIterator(HKEY root_key, const char16_t* folder_key);
 
   // Constructs a Registry Value Iterator with specific WOW64 access, one of
   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0.
@@ -208,7 +210,7 @@
   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE).
   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx.
   RegistryKeyIterator(HKEY root_key,
-                      const wchar_t* folder_key,
+                      const char16_t* folder_key,
                       REGSAM wow64access);
 
   ~RegistryKeyIterator();
@@ -221,7 +223,7 @@
   // Advances to the next entry in the folder.
   void operator++();
 
-  const wchar_t* Name() const { return name_; }
+  const char16_t* Name() const { return name_; }
 
   int Index() const { return index_; }
 
@@ -229,7 +231,9 @@
   // Reads in the current values.
   bool Read();
 
-  void Initialize(HKEY root_key, const wchar_t* folder_key, REGSAM wow64access);
+  void Initialize(HKEY root_key,
+                  const char16_t* folder_key,
+                  REGSAM wow64access);
 
   // The registry key being iterated.
   HKEY key_;
@@ -237,7 +241,7 @@
   // Current index of the iteration.
   int index_;
 
-  wchar_t name_[MAX_PATH];
+  char16_t name_[MAX_PATH];
 
   DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator);
 };
diff --git a/base/win/win_util.h b/base/win/win_util.h
new file mode 100644
index 0000000..49eac8a
--- /dev/null
+++ b/base/win/win_util.h
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.

+// Use of this source code is governed by a BSD-style license that can be

+// found in the LICENSE file.

+

+#ifndef BASE_WIN_WIN_UTIL_H_

+#define BASE_WIN_WIN_UTIL_H_

+

+#include <string>

+#include <string_view>

+

+namespace base {

+

+// Windows API calls take wchar_t but on that platform wchar_t should be the

+// same as a char16_t.

+inline const wchar_t* ToWCharT(const std::u16string* s) {

+  static_assert(sizeof(std::u16string::value_type) == sizeof(wchar_t));

+  return reinterpret_cast<const wchar_t*>(s->c_str());

+}

+

+inline const wchar_t* ToWCharT(const char16_t* s) {

+  return reinterpret_cast<const wchar_t*>(s);

+}

+

+inline wchar_t* ToWCharT(char16_t* s) {

+  return reinterpret_cast<wchar_t*>(s);

+}

+

+}  // namespace base

+

+#endif  // BASE_WIN_WIN_UTIL_H_

diff --git a/build/gen.py b/build/gen.py
index 4c3f716..3d9406c 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -655,7 +655,6 @@
         'base/files/file_util_posix.cc',
         'base/posix/file_descriptor_shuffle.cc',
         'base/posix/safe_strerror.cc',
-        'base/strings/string16.cc',
     ])
 
   if platform.is_windows():
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc
index 9957508..096ba8f 100644
--- a/tools/gn/command_args.cc
+++ b/tools/gn/command_args.cc
@@ -288,7 +288,7 @@
   memset(&info, 0, sizeof(info));
   info.cbSize = sizeof(info);
   info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_CLASSNAME;
-  info.lpFile = file_to_edit.value().c_str();
+  info.lpFile = reinterpret_cast<LPCWSTR>(file_to_edit.value().c_str());
   info.nShow = SW_SHOW;
   info.lpClass = L".txt";
   if (!::ShellExecuteEx(&info)) {
diff --git a/tools/gn/exec_process.cc b/tools/gn/exec_process.cc
index 6c13558..2496405 100644
--- a/tools/gn/exec_process.cc
+++ b/tools/gn/exec_process.cc
@@ -18,6 +18,7 @@
 
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_process_information.h"
+#include "base/win/win_util.h"
 #else
 #include <errno.h>
 #include <fcntl.h>
@@ -97,11 +98,11 @@
 
   // Create the child process.
   PROCESS_INFORMATION temp_process_info = {};
-  if (!CreateProcess(nullptr, &cmdline_writable[0], nullptr, nullptr,
-                     TRUE,  // Handles are inherited.
-                     NORMAL_PRIORITY_CLASS, nullptr,
-                     startup_dir.value().c_str(), &start_info,
-                     &temp_process_info)) {
+  if (!CreateProcess(
+          nullptr, base::ToWCharT(&cmdline_writable[0]), nullptr, nullptr,
+          TRUE,  // Handles are inherited.
+          NORMAL_PRIORITY_CLASS, nullptr, base::ToWCharT(&startup_dir.value()),
+          &start_info, &temp_process_info)) {
     return false;
   }
   base::win::ScopedProcessInformation proc_info(temp_process_info);
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index c378233..727e2f3 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -159,8 +159,10 @@
   // Note: The documentation for CompareString says it runs fastest on
   // null-terminated strings with -1 passed for the length, so we do that here.
   // There should not be embedded nulls in filesystem strings.
-  return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE, a.c_str(),
-                         -1, b.c_str(), -1) == CSTR_EQUAL;
+  return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE,
+                         reinterpret_cast<LPCWSTR>(a.c_str()), -1,
+                         reinterpret_cast<LPCWSTR>(b.c_str()),
+                         -1) == CSTR_EQUAL;
 #else
   // Assume case-sensitive filesystems on non-Windows.
   return a == b;
@@ -214,7 +216,7 @@
 
 std::string FilePathToUTF8(const base::FilePath::StringType& str) {
 #if defined(OS_WIN)
-  return base::WideToUTF8(str);
+  return base::UTF16ToUTF8(str);
 #else
   return str;
 #endif
@@ -222,7 +224,7 @@
 
 base::FilePath UTF8ToFilePath(const base::StringPiece& sp) {
 #if defined(OS_WIN)
-  return base::FilePath(base::UTF8ToWide(sp));
+  return base::FilePath(base::UTF8ToUTF16(sp));
 #else
   return base::FilePath(sp.as_string());
 #endif
@@ -977,9 +979,9 @@
   // version opens with FILE_SHARE_READ (normally not what you want when
   // replacing the entire contents of the file) which lets us continue even if
   // another program has the file open for reading. See http://crbug.com/468437
-  base::win::ScopedHandle file(::CreateFile(file_path.value().c_str(),
-                                            GENERIC_WRITE, FILE_SHARE_READ,
-                                            NULL, CREATE_ALWAYS, 0, NULL));
+  base::win::ScopedHandle file(::CreateFile(
+      reinterpret_cast<LPCWSTR>(file_path.value().c_str()), GENERIC_WRITE,
+      FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL));
   if (file.IsValid()) {
     DWORD written;
     BOOL result = ::WriteFile(file.Get(), data.c_str(), size, &written, NULL);
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc
index 433ea36..32b30f6 100644
--- a/tools/gn/filesystem_utils_unittest.cc
+++ b/tools/gn/filesystem_utils_unittest.cc
@@ -177,31 +177,31 @@
 TEST(FilesystemUtils, MakeAbsoluteFilePathRelativeIfPossible) {
 #if defined(OS_WIN)
   EXPECT_EQ(
-      base::FilePath(L"out\\Debug"),
+      base::FilePath(u"out\\Debug"),
       MakeAbsoluteFilePathRelativeIfPossible(
-          base::FilePath(L"C:\\src"), base::FilePath(L"C:\\src\\out\\Debug")));
-  EXPECT_EQ(base::FilePath(L".\\gn"),
+          base::FilePath(u"C:\\src"), base::FilePath(u"C:\\src\\out\\Debug")));
+  EXPECT_EQ(base::FilePath(u".\\gn"),
             MakeAbsoluteFilePathRelativeIfPossible(
-                base::FilePath(L"C:\\src\\out\\Debug"),
-                base::FilePath(L"C:\\src\\out\\Debug\\gn")));
+                base::FilePath(u"C:\\src\\out\\Debug"),
+                base::FilePath(u"C:\\src\\out\\Debug\\gn")));
   EXPECT_EQ(
-      base::FilePath(L"..\\.."),
+      base::FilePath(u"..\\.."),
       MakeAbsoluteFilePathRelativeIfPossible(
-          base::FilePath(L"C:\\src\\out\\Debug"), base::FilePath(L"C:\\src")));
+          base::FilePath(u"C:\\src\\out\\Debug"), base::FilePath(u"C:\\src")));
   EXPECT_EQ(
-      base::FilePath(L"..\\.."),
+      base::FilePath(u"..\\.."),
       MakeAbsoluteFilePathRelativeIfPossible(
-          base::FilePath(L"C:\\src\\out\\Debug"), base::FilePath(L"C:/src")));
-  EXPECT_EQ(base::FilePath(L"."),
-            MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(L"C:\\src"),
-                                                   base::FilePath(L"C:\\src")));
-  EXPECT_EQ(base::FilePath(L"..\\..\\..\\u\\v\\w"),
+          base::FilePath(u"C:\\src\\out\\Debug"), base::FilePath(u"C:/src")));
+  EXPECT_EQ(base::FilePath(u"."),
+            MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(u"C:\\src"),
+                                                   base::FilePath(u"C:\\src")));
+  EXPECT_EQ(base::FilePath(u"..\\..\\..\\u\\v\\w"),
             MakeAbsoluteFilePathRelativeIfPossible(
-                base::FilePath(L"C:\\a\\b\\c\\x\\y\\z"),
-                base::FilePath(L"C:\\a\\b\\c\\u\\v\\w")));
-  EXPECT_EQ(base::FilePath(L"D:\\bar"),
-            MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(L"C:\\foo"),
-                                                   base::FilePath(L"D:\\bar")));
+                base::FilePath(u"C:\\a\\b\\c\\x\\y\\z"),
+                base::FilePath(u"C:\\a\\b\\c\\u\\v\\w")));
+  EXPECT_EQ(base::FilePath(u"D:\\bar"),
+            MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(u"C:\\foo"),
+                                                   base::FilePath(u"D:\\bar")));
 #else
   EXPECT_EQ(base::FilePath("out/Debug"),
             MakeAbsoluteFilePathRelativeIfPossible(
@@ -559,42 +559,42 @@
 
 TEST(FilesystemUtils, SourceDirForPath) {
 #if defined(OS_WIN)
-  base::FilePath root(L"C:\\source\\foo\\");
+  base::FilePath root(u"C:\\source\\foo\\");
   EXPECT_EQ("/C:/foo/bar/",
-            SourceDirForPath(root, base::FilePath(L"C:\\foo\\bar")).value());
-  EXPECT_EQ("/", SourceDirForPath(root, base::FilePath(L"/")).value());
+            SourceDirForPath(root, base::FilePath(u"C:\\foo\\bar")).value());
+  EXPECT_EQ("/", SourceDirForPath(root, base::FilePath(u"/")).value());
   EXPECT_EQ("//",
-            SourceDirForPath(root, base::FilePath(L"C:\\source\\foo")).value());
+            SourceDirForPath(root, base::FilePath(u"C:\\source\\foo")).value());
   EXPECT_EQ("//bar/",
-            SourceDirForPath(root, base::FilePath(L"C:\\source\\foo\\bar\\"))
+            SourceDirForPath(root, base::FilePath(u"C:\\source\\foo\\bar\\"))
                 .value());
   EXPECT_EQ("//bar/baz/",
-            SourceDirForPath(root, base::FilePath(L"C:\\source\\foo\\bar\\baz"))
+            SourceDirForPath(root, base::FilePath(u"C:\\source\\foo\\bar\\baz"))
                 .value());
 
   // Should be case-and-slash-insensitive.
   EXPECT_EQ(
       "//baR/",
-      SourceDirForPath(root, base::FilePath(L"c:/SOURCE\\Foo/baR/")).value());
+      SourceDirForPath(root, base::FilePath(u"c:/SOURCE\\Foo/baR/")).value());
 
   // Some "weird" Windows paths.
   EXPECT_EQ("/foo/bar/",
-            SourceDirForPath(root, base::FilePath(L"/foo/bar/")).value());
+            SourceDirForPath(root, base::FilePath(u"/foo/bar/")).value());
   EXPECT_EQ("/C:/foo/bar/",
-            SourceDirForPath(root, base::FilePath(L"C:foo/bar/")).value());
+            SourceDirForPath(root, base::FilePath(u"C:foo/bar/")).value());
 
   // Also allow absolute GN-style Windows paths.
   EXPECT_EQ("/C:/foo/bar/",
-            SourceDirForPath(root, base::FilePath(L"/C:/foo/bar")).value());
+            SourceDirForPath(root, base::FilePath(u"/C:/foo/bar")).value());
   EXPECT_EQ(
       "//bar/",
-      SourceDirForPath(root, base::FilePath(L"/C:/source/foo/bar")).value());
+      SourceDirForPath(root, base::FilePath(u"/C:/source/foo/bar")).value());
 
   // Empty source dir.
   base::FilePath empty;
   EXPECT_EQ(
       "/C:/source/foo/",
-      SourceDirForPath(empty, base::FilePath(L"C:\\source\\foo")).value());
+      SourceDirForPath(empty, base::FilePath(u"C:\\source\\foo")).value());
 #else
   base::FilePath root("/source/foo/");
   EXPECT_EQ("/foo/bar/",
diff --git a/tools/gn/function_rebase_path_unittest.cc b/tools/gn/function_rebase_path_unittest.cc
index fdd09dc..1bd9b86 100644
--- a/tools/gn/function_rebase_path_unittest.cc
+++ b/tools/gn/function_rebase_path_unittest.cc
@@ -59,7 +59,7 @@
 
 // Test system path output.
 #if defined(OS_WIN)
-  setup.build_settings()->SetRootPath(base::FilePath(L"C:/path/to/src"));
+  setup.build_settings()->SetRootPath(base::FilePath(u"C:/path/to/src"));
   EXPECT_EQ("C:/path/to/src", RebaseOne(scope, ".", "", "//"));
   EXPECT_EQ("C:/path/to/src/", RebaseOne(scope, "//", "", "//"));
   EXPECT_EQ("C:/path/to/src/foo", RebaseOne(scope, "foo", "", "//"));
@@ -98,7 +98,7 @@
 
 #if defined(OS_WIN)
   setup.build_settings()->SetBuildDir(SourceDir("C:/ssd/out/Debug"));
-  setup.build_settings()->SetRootPath(base::FilePath(L"C:/hdd/src"));
+  setup.build_settings()->SetRootPath(base::FilePath(u"C:/hdd/src"));
 
   // Test system absolute to-dir.
   EXPECT_EQ("../../ssd/out/Debug",
diff --git a/tools/gn/gn_main.cc b/tools/gn/gn_main.cc
index a61a752..8b9f499 100644
--- a/tools/gn/gn_main.cc
+++ b/tools/gn/gn_main.cc
@@ -25,7 +25,7 @@
 #if defined(OS_WIN)
   std::vector<std::string> out_args;
   for (const auto& arg : in_args)
-    out_args.push_back(base::WideToUTF8(arg));
+    out_args.push_back(base::UTF16ToUTF8(arg));
   return out_args;
 #else
   return in_args;
diff --git a/tools/gn/label.h b/tools/gn/label.h
index 6606a6b..44f6e40 100644
--- a/tools/gn/label.h
+++ b/tools/gn/label.h
@@ -5,6 +5,8 @@
 #ifndef TOOLS_GN_LABEL_H_
 #define TOOLS_GN_LABEL_H_
 
+#include <tuple>
+
 #include <stddef.h>
 
 #include "tools/gn/source_dir.h"
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc
index 3127c9a..c5cd90a 100644
--- a/tools/gn/ninja_build_writer.cc
+++ b/tools/gn/ninja_build_writer.cc
@@ -47,7 +47,7 @@
   const Target* last_seen;
 };
 
-} // namespace
+}  // namespace
 
 base::CommandLine GetSelfInvocationCommandLine(
     const BuildSettings* build_settings) {
@@ -119,10 +119,9 @@
 namespace {
 
 std::string GetSelfInvocationCommand(const BuildSettings* build_settings) {
-  base::CommandLine cmdline = GetSelfInvocationCommandLine(
-      build_settings);
+  base::CommandLine cmdline = GetSelfInvocationCommandLine(build_settings);
 #if defined(OS_WIN)
-  return base::WideToUTF8(cmdline.GetCommandLineString());
+  return base::UTF16ToUTF8(cmdline.GetCommandLineString());
 #else
   return cmdline.GetCommandLineString();
 #endif
@@ -247,8 +246,8 @@
   std::stringstream file;
   std::stringstream depfile;
   NinjaBuildWriter gen(build_settings, used_toolchains, all_targets,
-                       default_toolchain, default_toolchain_targets,
-                       file, depfile);
+                       default_toolchain, default_toolchain_targets, file,
+                       depfile);
   if (!gen.Run(err))
     return false;
 
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index ef26431..1b2ad55 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -40,6 +40,7 @@
 #include <windows.h>
 
 #include "base/win/scoped_process_information.h"
+#include "base/win/win_util.h"
 #endif
 
 const char kDotfile_Help[] =
@@ -192,19 +193,20 @@
 
 #if defined(OS_WIN)
 
-std::wstring SysMultiByteToWide(base::StringPiece mb) {
+std::u16string SysMultiByteTo16(base::StringPiece mb) {
   if (mb.empty())
-    return std::wstring();
+    return std::u16string();
 
   int mb_length = static_cast<int>(mb.length());
   // Compute the length of the buffer.
   int charcount = MultiByteToWideChar(CP_ACP, 0, mb.data(), mb_length, NULL, 0);
   if (charcount == 0)
-    return std::wstring();
+    return std::u16string();
 
-  std::wstring wide;
+  std::u16string wide;
   wide.resize(charcount);
-  MultiByteToWideChar(CP_ACP, 0, mb.data(), mb_length, &wide[0], charcount);
+  MultiByteToWideChar(CP_ACP, 0, mb.data(), mb_length, base::ToWCharT(&wide[0]),
+                      charcount);
 
   return wide;
 }
@@ -220,9 +222,9 @@
   // quote the first argument in addition (to allow for spaces in the Python
   // path, you need *another* set of quotes around that, likewise, we need
   // two quotes at the end.
-  base::string16 command = L"cmd.exe /c \"\"";
+  base::string16 command = u"cmd.exe /c \"\"";
   command.append(bat_path.value());
-  command.append(L"\" -c \"import sys; print sys.executable\"\"");
+  command.append(u"\" -c \"import sys; print sys.executable\"\"");
 
   std::string python_path;
   std::string std_err;
@@ -234,7 +236,7 @@
     base::TrimWhitespaceASCII(python_path, base::TRIM_ALL, &python_path);
 
     // Python uses the system multibyte code page for sys.executable.
-    base::FilePath exe_path(SysMultiByteToWide(python_path));
+    base::FilePath exe_path(SysMultiByteTo16(python_path));
 
     // Check for reasonable output, cmd may have output an error message.
     if (base::PathExists(exe_path))
@@ -243,12 +245,12 @@
   return base::FilePath();
 }
 
-const base::char16 kPythonExeName[] = L"python.exe";
-const base::char16 kPythonBatName[] = L"python.bat";
+const base::char16 kPythonExeName[] = u"python.exe";
+const base::char16 kPythonBatName[] = u"python.bat";
 
 base::FilePath FindWindowsPython() {
   base::char16 current_directory[MAX_PATH];
-  ::GetCurrentDirectory(MAX_PATH, current_directory);
+  ::GetCurrentDirectory(MAX_PATH, reinterpret_cast<LPWSTR>(current_directory));
 
   // First search for python.exe in the current directory.
   base::FilePath cur_dir_candidate_exe =
@@ -257,18 +259,20 @@
     return cur_dir_candidate_exe;
 
   // Get the path.
-  const base::char16 kPathEnvVarName[] = L"Path";
-  DWORD path_length = ::GetEnvironmentVariable(kPathEnvVarName, nullptr, 0);
+  const base::char16 kPathEnvVarName[] = u"Path";
+  DWORD path_length = ::GetEnvironmentVariable(
+      reinterpret_cast<LPCWSTR>(kPathEnvVarName), nullptr, 0);
   if (path_length == 0)
     return base::FilePath();
   std::unique_ptr<base::char16[]> full_path(new base::char16[path_length]);
-  DWORD actual_path_length =
-      ::GetEnvironmentVariable(kPathEnvVarName, full_path.get(), path_length);
+  DWORD actual_path_length = ::GetEnvironmentVariable(
+      reinterpret_cast<LPCWSTR>(kPathEnvVarName),
+      reinterpret_cast<LPWSTR>(full_path.get()), path_length);
   CHECK_EQ(path_length, actual_path_length + 1);
 
   // Search for python.exe in the path.
   for (const auto& component : base::SplitStringPiece(
-           base::StringPiece16(full_path.get(), path_length), L";",
+           base::StringPiece16(full_path.get(), path_length), u";",
            base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
     base::FilePath candidate_exe =
         base::FilePath(component).Append(kPythonExeName);
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc
index 5f4380c..9d9aa21 100644
--- a/tools/gn/visual_studio_writer.cc
+++ b/tools/gn/visual_studio_writer.cc
@@ -99,8 +99,8 @@
 
 #if defined(OS_WIN)
   const base::char16* const subkeys[] = {
-      L"SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
-      L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows Kits\\Installed Roots"};
+      u"SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
+      u"SOFTWARE\\Wow6432Node\\Microsoft\\Windows Kits\\Installed Roots"};
 
   base::string16 value_name =
       base::ASCIIToUTF16("KitsRoot") + base::ASCIIToUTF16(kWindowsKitsVersion);
diff --git a/util/build_config.h b/util/build_config.h
index addd7cf..f98f044 100644
--- a/util/build_config.h
+++ b/util/build_config.h
@@ -5,7 +5,6 @@
 // This file adds defines about the platform we're currently building on.
 //  Operating System:
 //    OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX) /
-//    OS_NACL (NACL_SFI or NACL_NONSFI) / OS_NACL_SFI / OS_NACL_NONSFI
 //    OS_CHROMEOS is set by the build system
 //  Compiler:
 //    COMPILER_MSVC / COMPILER_GCC
@@ -16,19 +15,7 @@
 #ifndef BUILD_BUILD_CONFIG_H_
 #define BUILD_BUILD_CONFIG_H_
 
-// A set of macros to use for platform detection.
-#if defined(__native_client__)
-// __native_client__ must be first, so that other OS_ defines are not set.
-#define OS_NACL 1
-// OS_NACL comes in two sandboxing technology flavors, SFI or Non-SFI.
-// PNaCl toolchain defines __native_client_nonsfi__ macro in Non-SFI build
-// mode, while it does not in SFI build mode.
-#if defined(__native_client_nonsfi__)
-#define OS_NACL_NONSFI
-#else
-#define OS_NACL_SFI
-#endif
-#elif defined(ANDROID)
+#if defined(ANDROID)
 #define OS_ANDROID 1
 #elif defined(__APPLE__)
 // only include TargetConditions after testing ANDROID as some android builds
@@ -81,8 +68,8 @@
 // more specific macro.
 #if defined(OS_AIX) || defined(OS_ANDROID) || defined(OS_ASMJS) ||    \
     defined(OS_FREEBSD) || defined(OS_LINUX) || defined(OS_MACOSX) || \
-    defined(OS_NACL) || defined(OS_NETBSD) || defined(OS_OPENBSD) ||  \
-    defined(OS_QNX) || defined(OS_SOLARIS)
+    defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_QNX) ||   \
+    defined(OS_SOLARIS)
 #define OS_POSIX 1
 #endif
 
@@ -176,21 +163,4 @@
 #error Please add support for your architecture in build_config.h
 #endif
 
-// Type detection for wchar_t.
-#if defined(OS_WIN)
-#define WCHAR_T_IS_UTF16
-#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \
-    (__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff)
-#define WCHAR_T_IS_UTF32
-#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \
-    (__WCHAR_MAX__ == 0x7fff || __WCHAR_MAX__ == 0xffff)
-// On Posix, we'll detect short wchar_t, but projects aren't guaranteed to
-// compile in this mode (in particular, Chrome doesn't). This is intended for
-// other projects using base who manage their own dependencies and make sure
-// short wchar works for them.
-#define WCHAR_T_IS_UTF16
-#else
-#error Please add support for your compiler in build_config.h
-#endif
-
 #endif  // BUILD_BUILD_CONFIG_H_
diff --git a/util/exe_path.cc b/util/exe_path.cc
index 3c9c9de..4d487fa 100644
--- a/util/exe_path.cc
+++ b/util/exe_path.cc
@@ -13,6 +13,8 @@
 #include <mach-o/dyld.h>
 #elif defined(OS_WIN)
 #include <windows.h>
+
+#include "base/win/win_util.h"
 #elif defined(OS_FREEBSD)
 #include <limits.h>
 #include <sys/sysctl.h>
@@ -42,9 +44,9 @@
 #elif defined(OS_WIN)
 
 base::FilePath GetExePath() {
-  wchar_t system_buffer[MAX_PATH];
+  char16_t system_buffer[MAX_PATH];
   system_buffer[0] = 0;
-  if (GetModuleFileName(NULL, system_buffer, MAX_PATH) == 0) {
+  if (GetModuleFileName(NULL, base::ToWCharT(system_buffer), MAX_PATH) == 0) {
     return base::FilePath();
   }
   return base::FilePath(system_buffer);
@@ -53,7 +55,7 @@
 #elif defined(OS_FREEBSD)
 
 base::FilePath GetExePath() {
-  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
   char buf[PATH_MAX];
   size_t buf_size = PATH_MAX;
   if (sysctl(mib, 4, buf, &buf_size, nullptr, 0) == -1) {