[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