diff options
Diffstat (limited to 'contrib/llvm/lib/Support/Windows/Process.inc')
| -rw-r--r-- | contrib/llvm/lib/Support/Windows/Process.inc | 120 | 
1 files changed, 61 insertions, 59 deletions
| diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc index 3fe9f89f1ef5..30126568769c 100644 --- a/contrib/llvm/lib/Support/Windows/Process.inc +++ b/contrib/llvm/lib/Support/Windows/Process.inc @@ -12,6 +12,7 @@  //===----------------------------------------------------------------------===//  #include "llvm/Support/Allocator.h" +#include "llvm/Support/ConvertUTF.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/WindowsError.h"  #include <malloc.h> @@ -24,14 +25,7 @@  #include <psapi.h>  #include <shellapi.h> -#ifdef __MINGW32__ - #if (HAVE_LIBPSAPI != 1) -  #error "libpsapi.a should be present" - #endif - #if (HAVE_LIBSHELL32 != 1) -  #error "libshell32.a should be present" - #endif -#else +#if !defined(__MINGW32__)   #pragma comment(lib, "psapi.lib")   #pragma comment(lib, "shell32.lib")  #endif @@ -146,39 +140,38 @@ Optional<std::string> Process::GetEnv(StringRef Name) {    return std::string(Res.data());  } -static void AllocateAndPush(const SmallVectorImpl<char> &S, -                            SmallVectorImpl<const char *> &Vector, -                            SpecificBumpPtrAllocator<char> &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<char> &S, +                                  BumpPtrAllocator &Alloc) { +  char *Buf = reinterpret_cast<char *>(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<const char *> &Args, -                  SpecificBumpPtrAllocator<char> &Allocator) { +static std::error_code ConvertAndPushArg(const wchar_t *Arg, +                                         SmallVectorImpl<const char *> &Args, +                                         BumpPtrAllocator &Alloc) {    SmallVector<char, MAX_PATH> 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 +/// 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<const char *> &Args, -               SpecificBumpPtrAllocator<char> &Allocator) { +static std::error_code WildcardExpand(const wchar_t *Arg, +                                      SmallVectorImpl<const char *> &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. @@ -195,7 +188,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,    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; @@ -208,7 +201,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,      // 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)); @@ -216,56 +209,65 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,    return ec;  } -static std::error_code -ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, -                    SpecificBumpPtrAllocator<char> &Allocator) { -  SmallVector<wchar_t, MAX_PATH> LongPath; -  DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity()); +static std::error_code GetExecutableName(SmallVectorImpl<char> &Filename) { +  // The first argument may contain just the name of the executable (e.g., +  // "clang") rather than the full path, so swap it with the full path. +  wchar_t ModuleName[MAX_PATH]; +  size_t Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH); +  if (Length == 0 || Length == MAX_PATH) { +    return mapWindowsError(GetLastError()); +  } + +  // 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. +  Length = GetLongPathNameW(ModuleName, ModuleName, MAX_PATH);    if (Length == 0)      return mapWindowsError(GetLastError()); -  if (Length > LongPath.capacity()) { +  if (Length > MAX_PATH) {      // We're not going to try to deal with paths longer than MAX_PATH, so we'll      // treat this as an error.  GetLastError() returns ERROR_SUCCESS, which      // isn't useful, so we'll hardcode an appropriate error value.      return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);    } -  LongPath.set_size(Length); -  return ConvertAndPushArg(LongPath.data(), Args, Allocator); + +  std::error_code EC = windows::UTF16ToUTF8(ModuleName, Length, Filename); +  if (EC) +    return EC; + +  StringRef Base = sys::path::filename(Filename.data()); +  Filename.assign(Base.begin(), Base.end()); +  return std::error_code();  }  std::error_code -Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, -                           ArrayRef<const char *>, -                           SpecificBumpPtrAllocator<char> &ArgAllocator) { +windows::GetCommandLineArguments(SmallVectorImpl<const char *> &Args, +                                 BumpPtrAllocator &Alloc) {    int ArgCount; -  wchar_t **UnicodeCommandLine = -      CommandLineToArgvW(GetCommandLineW(), &ArgCount); +  std::unique_ptr<wchar_t *[], decltype(&LocalFree)> UnicodeCommandLine{ +    CommandLineToArgvW(GetCommandLineW(), &ArgCount), &LocalFree};    if (!UnicodeCommandLine)      return mapWindowsError(::GetLastError()); -  Args.reserve(ArgCount); -  std::error_code ec; +  std::error_code EC; -  // The first argument may contain just the name of the executable (e.g., -  // "clang") rather than the full path, so swap it with the full path. -  wchar_t ModuleName[MAX_PATH]; -  int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH); -  if (0 < Length && Length < MAX_PATH) -    UnicodeCommandLine[0] = ModuleName; - -  // 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); +  Args.reserve(ArgCount); -  for (int i = 1; i < ArgCount && !ec; ++i) { -    ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); -    if (ec) -      break; +  for (int I = 0; I < ArgCount; ++I) { +    EC = WildcardExpand(UnicodeCommandLine[I], Args, Alloc); +    if (EC) +      return EC;    } -  LocalFree(UnicodeCommandLine); -  return ec; +  SmallVector<char, MAX_PATH> Arg0(Args[0], Args[0] + strlen(Args[0])); +  SmallVector<char, MAX_PATH> Filename; +  sys::path::remove_filename(Arg0); +  EC = GetExecutableName(Filename); +  if (EC) +    return EC; +  sys::path::append(Arg0, Filename); +  Args[0] = AllocateString(Arg0, Alloc); +  return std::error_code();  }  std::error_code Process::FixupStandardFileDescriptors() { | 
