[llvm] r272967 - Properly handle short file names on the command line in Windows
Adrian McCarthy via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 16 15:07:56 PDT 2016
Author: amccarth
Date: Thu Jun 16 17:07:55 2016
New Revision: 272967
URL: http://llvm.org/viewvc/llvm-project?rev=272967&view=rev
Log:
Properly handle short file names on the command line in Windows
Some build systems use the short (8.3) file names on Windows, especially if the path has spaces in it. The shortening made it impossible for clang to distinguish between clang.exe, clang++.exe, and clang-cl.exe. So this expands short names in the first argument and does wildcard expansion for the rest.
Differential Revision: http://reviews.llvm.org/D21420
Modified:
llvm/trunk/lib/Support/Windows/Process.inc
Modified: llvm/trunk/lib/Support/Windows/Process.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=272967&r1=272966&r2=272967&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/Process.inc (original)
+++ llvm/trunk/lib/Support/Windows/Process.inc Thu Jun 16 17:07:55 2016
@@ -201,6 +201,9 @@ WildcardExpand(const wchar_t *Arg, Small
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, Small
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, Small
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,12 @@ Process::GetArgumentVector(SmallVectorIm
Args.reserve(ArgCount);
std::error_code ec;
- for (int i = 0; i < ArgCount; ++i) {
+ // If the first argument is a shortenedd (8.3) name, the driver will have
+ // trouble distinguishing it (e.g., clang.exe v. clang++.exe), so make sure
+ // it's a full name.
+ ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator);
+
+ for (int i = 1; i < ArgCount && !ec; ++i) {
ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
if (ec)
break;
More information about the llvm-commits
mailing list