Skip to content

Commit

Permalink
Properly handle short file names on the command line in Windows
Browse files Browse the repository at this point in the history
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

llvm-svn: 272967
  • Loading branch information
amccarth-google committed Jun 16, 2016
1 parent 886e061 commit 205bb61
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions llvm/lib/Support/Windows/Process.inc
Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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 *>,
Expand All @@ -238,7 +258,12 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
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;
Expand Down

0 comments on commit 205bb61

Please sign in to comment.