Rename sys::Process::GetArgumentVector -> sys::windows::GetCommandLineArguments

GetArgumentVector (or GetCommandLineArguments) is very Windows-specific.
I think it doesn't make much sense to provide that function from sys::Process.

I also made a change so that the function takes a BumpPtrAllocator
instead of a SpecificBumpPtrAllocator. The latter is the class to call
dtors, but since char * is trivially destructible, we should use the
former class.

Differential Revision: https://reviews.llvm.org/D45641

llvm-svn: 330216
This commit is contained in:
Rui Ueyama 2018-04-17 21:09:16 +00:00
parent 4576dc06be
commit e6ac9f5ec3
6 changed files with 40 additions and 49 deletions

View File

@ -37,7 +37,7 @@ public:
~InitLLVM(); ~InitLLVM();
private: private:
SpecificBumpPtrAllocator<char> Alloc; BumpPtrAllocator Alloc;
SmallVector<const char *, 0> Args; SmallVector<const char *, 0> Args;
PrettyStackTraceProgram StackPrinter; PrettyStackTraceProgram StackPrinter;
}; };

View File

@ -90,14 +90,6 @@ public:
static Optional<std::string> FindInEnvPath(StringRef EnvName, static Optional<std::string> FindInEnvPath(StringRef EnvName,
StringRef FileName); 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<const char *> &Args,
ArrayRef<const char *> ArgsFromMain,
SpecificBumpPtrAllocator<char> &ArgAllocator);
// This functions ensures that the standard file descriptors (input, output, // This functions ensures that the standard file descriptors (input, output,
// and error) are properly mapped to a file descriptor before we use any of // and error) are properly mapped to a file descriptor before we use any of
// them. This should only be called by standalone programs, library // them. This should only be called by standalone programs, library

View File

@ -15,7 +15,12 @@
#include "llvm/Support/Signals.h" #include "llvm/Support/Signals.h"
#include <string> #include <string>
#ifdef _WIN32
#include "Windows/WindowsSupport.h"
#endif
using namespace llvm; using namespace llvm;
using namespace llvm::sys;
InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) { InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) {
sys::PrintStackTraceOnErrorSignal(Argv[0]); sys::PrintStackTraceOnErrorSignal(Argv[0]);
@ -33,11 +38,10 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) {
std::string Banner = std::string(Argv[0]) + ": "; std::string Banner = std::string(Argv[0]) + ": ";
ExitOnError ExitOnErr(Banner); ExitOnError ExitOnErr(Banner);
ExitOnErr(errorCodeToError( ExitOnErr(errorCodeToError(windows::GetCommandLineArguments(Args, Alloc)));
sys::Process::GetArgumentVector(Args, makeArrayRef(Argv, Argc), Alloc)));
// GetArgumentVector doesn't terminate the vector with a nullptr. // GetCommandLineArguments doesn't terminate the vector with a
// Do it to make it compatible with the real argv. // nullptr. Do it to make it compatible with the real argv.
Args.push_back(nullptr); Args.push_back(nullptr);
Argc = Args.size() - 1; Argc = Args.size() - 1;

View File

@ -172,15 +172,6 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
return std::string(Val); return std::string(Val);
} }
std::error_code
Process::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut,
ArrayRef<const char *> ArgsIn,
SpecificBumpPtrAllocator<char> &) {
ArgsOut.append(ArgsIn.begin(), ArgsIn.end());
return std::error_code();
}
namespace { namespace {
class FDCloser { class FDCloser {
public: public:

View File

@ -139,39 +139,38 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
return std::string(Res.data()); return std::string(Res.data());
} }
static void AllocateAndPush(const SmallVectorImpl<char> &S, static const char *AllocateString(const SmallVectorImpl<char> &S,
SmallVectorImpl<const char *> &Vector, BumpPtrAllocator &Alloc) {
SpecificBumpPtrAllocator<char> &Allocator) { char *Buf = reinterpret_cast<char *>(Alloc.Allocate(S.size() + 1, 1));
char *Buffer = Allocator.Allocate(S.size() + 1); ::memcpy(Buf, S.data(), S.size());
::memcpy(Buffer, S.data(), S.size()); Buf[S.size()] = '\0';
Buffer[S.size()] = '\0'; return Buf;
Vector.push_back(Buffer);
} }
/// Convert Arg from UTF-16 to UTF-8 and push it onto Args. /// Convert Arg from UTF-16 to UTF-8 and push it onto Args.
static std::error_code static std::error_code ConvertAndPushArg(const wchar_t *Arg,
ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, SmallVectorImpl<const char *> &Args,
SpecificBumpPtrAllocator<char> &Allocator) { BumpPtrAllocator &Alloc) {
SmallVector<char, MAX_PATH> ArgString; SmallVector<char, MAX_PATH> ArgString;
if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString)) if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString))
return ec; return ec;
AllocateAndPush(ArgString, Args, Allocator); Args.push_back(AllocateString(ArgString, Alloc));
return std::error_code(); return std::error_code();
} }
/// \brief Perform wildcard expansion of Arg, or just push it into Args if it /// \brief Perform wildcard expansion of Arg, or just push it into Args if it
/// doesn't have wildcards or doesn't match any files. /// doesn't have wildcards or doesn't match any files.
static std::error_code static std::error_code WildcardExpand(const wchar_t *Arg,
WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, SmallVectorImpl<const char *> &Args,
SpecificBumpPtrAllocator<char> &Allocator) { BumpPtrAllocator &Alloc) {
if (!wcspbrk(Arg, L"*?")) { if (!wcspbrk(Arg, L"*?")) {
// Arg does not contain any wildcard characters. This is the common case. // 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) { if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) {
// Don't wildcard expand /?. Always treat it as an option. // 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. // Extract any directory part of the argument.
@ -188,7 +187,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
WIN32_FIND_DATAW FileData; WIN32_FIND_DATAW FileData;
HANDLE FindHandle = FindFirstFileW(Arg, &FileData); HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
if (FindHandle == INVALID_HANDLE_VALUE) { if (FindHandle == INVALID_HANDLE_VALUE) {
return ConvertAndPushArg(Arg, Args, Allocator); return ConvertAndPushArg(Arg, Args, Alloc);
} }
std::error_code ec; std::error_code ec;
@ -201,7 +200,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
// Append FileName to Dir, and remove it afterwards. // Append FileName to Dir, and remove it afterwards.
llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size())); llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
AllocateAndPush(Dir, Args, Allocator); Args.push_back(AllocateString(Dir, Alloc));
Dir.resize(DirSize); Dir.resize(DirSize);
} while (FindNextFileW(FindHandle, &FileData)); } while (FindNextFileW(FindHandle, &FileData));
@ -209,9 +208,9 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
return ec; return ec;
} }
static std::error_code static std::error_code ExpandShortFileName(const wchar_t *Arg,
ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, SmallVectorImpl<const char *> &Args,
SpecificBumpPtrAllocator<char> &Allocator) { BumpPtrAllocator &Alloc) {
SmallVector<wchar_t, MAX_PATH> LongPath; SmallVector<wchar_t, MAX_PATH> LongPath;
DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity()); DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
if (Length == 0) if (Length == 0)
@ -223,13 +222,12 @@ ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
return mapWindowsError(ERROR_INSUFFICIENT_BUFFER); return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
} }
LongPath.set_size(Length); LongPath.set_size(Length);
return ConvertAndPushArg(LongPath.data(), Args, Allocator); return ConvertAndPushArg(LongPath.data(), Args, Alloc);
} }
std::error_code std::error_code
Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, windows::GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
ArrayRef<const char *>, BumpPtrAllocator &Alloc) {
SpecificBumpPtrAllocator<char> &ArgAllocator) {
int ArgCount; int ArgCount;
wchar_t **UnicodeCommandLine = wchar_t **UnicodeCommandLine =
CommandLineToArgvW(GetCommandLineW(), &ArgCount); CommandLineToArgvW(GetCommandLineW(), &ArgCount);
@ -249,10 +247,10 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
// If the first argument is a shortened (8.3) name (which is possible even // 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 // if we got the module name), the driver will have trouble distinguishing it
// (e.g., clang.exe v. clang++.exe), so expand it now. // (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) { for (int i = 1; i < ArgCount && !ec; ++i) {
ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); ec = WildcardExpand(UnicodeCommandLine[i], Args, Alloc);
if (ec) if (ec)
break; break;
} }

View File

@ -261,6 +261,12 @@ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
/// Convert from UTF16 to the current code page used in the system /// Convert from UTF16 to the current code page used in the system
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
SmallVectorImpl<char> &utf8); SmallVectorImpl<char> &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<const char *> &Args,
BumpPtrAllocator &Alloc);
} // end namespace windows } // end namespace windows
} // end namespace sys } // end namespace sys
} // end namespace llvm. } // end namespace llvm.