Index: llvm/trunk/include/llvm/Support/InitLLVM.h =================================================================== --- llvm/trunk/include/llvm/Support/InitLLVM.h +++ llvm/trunk/include/llvm/Support/InitLLVM.h @@ -37,7 +37,7 @@ ~InitLLVM(); private: - SpecificBumpPtrAllocator Alloc; + BumpPtrAllocator Alloc; SmallVector Args; PrettyStackTraceProgram StackPrinter; }; Index: llvm/trunk/include/llvm/Support/Process.h =================================================================== --- llvm/trunk/include/llvm/Support/Process.h +++ llvm/trunk/include/llvm/Support/Process.h @@ -90,14 +90,6 @@ static Optional FindInEnvPath(StringRef EnvName, StringRef FileName); - /// This function returns a SmallVector containing the arguments passed from - /// the operating system to the program. This function expects to be handed - /// the vector passed in from main. - static std::error_code - GetArgumentVector(SmallVectorImpl &Args, - ArrayRef ArgsFromMain, - SpecificBumpPtrAllocator &ArgAllocator); - // This functions ensures that the standard file descriptors (input, output, // and error) are properly mapped to a file descriptor before we use any of // them. This should only be called by standalone programs, library Index: llvm/trunk/lib/Support/InitLLVM.cpp =================================================================== --- llvm/trunk/lib/Support/InitLLVM.cpp +++ llvm/trunk/lib/Support/InitLLVM.cpp @@ -15,7 +15,12 @@ #include "llvm/Support/Signals.h" #include +#ifdef _WIN32 +#include "Windows/WindowsSupport.h" +#endif + using namespace llvm; +using namespace llvm::sys; InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) { sys::PrintStackTraceOnErrorSignal(Argv[0]); @@ -33,11 +38,10 @@ std::string Banner = std::string(Argv[0]) + ": "; ExitOnError ExitOnErr(Banner); - ExitOnErr(errorCodeToError( - sys::Process::GetArgumentVector(Args, makeArrayRef(Argv, Argc), Alloc))); + ExitOnErr(errorCodeToError(windows::GetCommandLineArguments(Args, Alloc))); - // GetArgumentVector doesn't terminate the vector with a nullptr. - // Do it to make it compatible with the real argv. + // GetCommandLineArguments doesn't terminate the vector with a + // nullptr. Do it to make it compatible with the real argv. Args.push_back(nullptr); Argc = Args.size() - 1; Index: llvm/trunk/lib/Support/Unix/Process.inc =================================================================== --- llvm/trunk/lib/Support/Unix/Process.inc +++ llvm/trunk/lib/Support/Unix/Process.inc @@ -172,15 +172,6 @@ return std::string(Val); } -std::error_code -Process::GetArgumentVector(SmallVectorImpl &ArgsOut, - ArrayRef ArgsIn, - SpecificBumpPtrAllocator &) { - ArgsOut.append(ArgsIn.begin(), ArgsIn.end()); - - return std::error_code(); -} - namespace { class FDCloser { public: Index: llvm/trunk/lib/Support/Windows/Process.inc =================================================================== --- llvm/trunk/lib/Support/Windows/Process.inc +++ llvm/trunk/lib/Support/Windows/Process.inc @@ -139,39 +139,38 @@ return std::string(Res.data()); } -static void AllocateAndPush(const SmallVectorImpl &S, - SmallVectorImpl &Vector, - SpecificBumpPtrAllocator &Allocator) { - char *Buffer = Allocator.Allocate(S.size() + 1); - ::memcpy(Buffer, S.data(), S.size()); - Buffer[S.size()] = '\0'; - Vector.push_back(Buffer); +static const char *AllocateString(const SmallVectorImpl &S, + BumpPtrAllocator &Alloc) { + char *Buf = reinterpret_cast(Alloc.Allocate(S.size() + 1, 1)); + ::memcpy(Buf, S.data(), S.size()); + Buf[S.size()] = '\0'; + return Buf; } /// Convert Arg from UTF-16 to UTF-8 and push it onto Args. -static std::error_code -ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl &Args, - SpecificBumpPtrAllocator &Allocator) { +static std::error_code ConvertAndPushArg(const wchar_t *Arg, + SmallVectorImpl &Args, + BumpPtrAllocator &Alloc) { SmallVector ArgString; if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString)) return ec; - AllocateAndPush(ArgString, Args, Allocator); + Args.push_back(AllocateString(ArgString, Alloc)); return std::error_code(); } /// \brief Perform wildcard expansion of Arg, or just push it into Args if it /// doesn't have wildcards or doesn't match any files. -static std::error_code -WildcardExpand(const wchar_t *Arg, SmallVectorImpl &Args, - SpecificBumpPtrAllocator &Allocator) { +static std::error_code WildcardExpand(const wchar_t *Arg, + SmallVectorImpl &Args, + BumpPtrAllocator &Alloc) { if (!wcspbrk(Arg, L"*?")) { // Arg does not contain any wildcard characters. This is the common case. - return ConvertAndPushArg(Arg, Args, Allocator); + return ConvertAndPushArg(Arg, Args, Alloc); } if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) { // Don't wildcard expand /?. Always treat it as an option. - return ConvertAndPushArg(Arg, Args, Allocator); + return ConvertAndPushArg(Arg, Args, Alloc); } // Extract any directory part of the argument. @@ -188,7 +187,7 @@ WIN32_FIND_DATAW FileData; HANDLE FindHandle = FindFirstFileW(Arg, &FileData); if (FindHandle == INVALID_HANDLE_VALUE) { - return ConvertAndPushArg(Arg, Args, Allocator); + return ConvertAndPushArg(Arg, Args, Alloc); } std::error_code ec; @@ -201,7 +200,7 @@ // Append FileName to Dir, and remove it afterwards. llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size())); - AllocateAndPush(Dir, Args, Allocator); + Args.push_back(AllocateString(Dir, Alloc)); Dir.resize(DirSize); } while (FindNextFileW(FindHandle, &FileData)); @@ -209,9 +208,9 @@ return ec; } -static std::error_code -ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl &Args, - SpecificBumpPtrAllocator &Allocator) { +static std::error_code ExpandShortFileName(const wchar_t *Arg, + SmallVectorImpl &Args, + BumpPtrAllocator &Alloc) { SmallVector LongPath; DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity()); if (Length == 0) @@ -223,13 +222,12 @@ return mapWindowsError(ERROR_INSUFFICIENT_BUFFER); } LongPath.set_size(Length); - return ConvertAndPushArg(LongPath.data(), Args, Allocator); + return ConvertAndPushArg(LongPath.data(), Args, Alloc); } std::error_code -Process::GetArgumentVector(SmallVectorImpl &Args, - ArrayRef, - SpecificBumpPtrAllocator &ArgAllocator) { +windows::GetCommandLineArguments(SmallVectorImpl &Args, + BumpPtrAllocator &Alloc) { int ArgCount; wchar_t **UnicodeCommandLine = CommandLineToArgvW(GetCommandLineW(), &ArgCount); @@ -249,10 +247,10 @@ // If the first argument is a shortened (8.3) name (which is possible even // if we got the module name), the driver will have trouble distinguishing it // (e.g., clang.exe v. clang++.exe), so expand it now. - ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator); + ec = ExpandShortFileName(UnicodeCommandLine[0], Args, Alloc); for (int i = 1; i < ArgCount && !ec; ++i) { - ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); + ec = WildcardExpand(UnicodeCommandLine[i], Args, Alloc); if (ec) break; } Index: llvm/trunk/lib/Support/Windows/WindowsSupport.h =================================================================== --- llvm/trunk/lib/Support/Windows/WindowsSupport.h +++ llvm/trunk/lib/Support/Windows/WindowsSupport.h @@ -261,6 +261,12 @@ /// Convert from UTF16 to the current code page used in the system std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, SmallVectorImpl &utf8); + +// Returns command line arguments. Unlike arguments given to main(), +// this function guarantees that the returned arguments are encoded in +// UTF-8 regardless of the current code page setting. +std::error_code GetCommandLineArguments(SmallVectorImpl &Args, + BumpPtrAllocator &Alloc); } // end namespace windows } // end namespace sys } // end namespace llvm.