diff options
author | Adrian McCarthy <amccarth@google.com> | 2016-06-20 17:51:27 +0000 |
---|---|---|
committer | Adrian McCarthy <amccarth@google.com> | 2016-06-20 17:51:27 +0000 |
commit | f833141187d68950e3e244b07bb206fc9a1417cc (patch) | |
tree | f772e05b329b3775df806c0a0fa0372caac55d7e | |
parent | a038240660ff33c452a7e95a8dd33d0a376f1c35 (diff) | |
download | bcm5719-llvm-f833141187d68950e3e244b07bb206fc9a1417cc.tar.gz bcm5719-llvm-f833141187d68950e3e244b07bb206fc9a1417cc.zip |
Properly handle short file names on the command line in Windows [TAKE 2]
Trying to expand short names with a relative path doesn't work, so this
first gets the module name to get a full path (which can still have short
names).
llvm-svn: 273171
-rw-r--r-- | llvm/lib/Support/Windows/Process.inc | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc index 3aef79fee84..b012991c2a5 100644 --- a/llvm/lib/Support/Windows/Process.inc +++ b/llvm/lib/Support/Windows/Process.inc @@ -201,6 +201,9 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, const int DirSize = Dir.size(); // Search for matching files. + // FIXME: This assumes the wildcard is only in the file name and not in the + // directory portion of the file path. For example, it doesn't handle + // "*\foo.c" nor "s?c\bar.cpp". WIN32_FIND_DATAW FileData; HANDLE FindHandle = FindFirstFileW(Arg, &FileData); if (FindHandle == INVALID_HANDLE_VALUE) { @@ -215,7 +218,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, if (ec) break; - // Push the filename onto Dir, and remove it afterwards. + // Append FileName to Dir, and remove it afterwards. llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size())); AllocateAndPush(Dir, Args, Allocator); Dir.resize(DirSize); @@ -225,6 +228,23 @@ 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()); + if (Length == 0) + return mapWindowsError(GetLastError()); + if (Length > LongPath.capacity()) { + // 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 Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, ArrayRef<const char *>, @@ -238,7 +258,19 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, Args.reserve(ArgCount); std::error_code ec; - for (int i = 0; i < ArgCount; ++i) { + // 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); + + for (int i = 1; i < ArgCount && !ec; ++i) { ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); if (ec) break; |