summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian McCarthy <amccarth@google.com>2016-06-20 17:51:27 +0000
committerAdrian McCarthy <amccarth@google.com>2016-06-20 17:51:27 +0000
commitf833141187d68950e3e244b07bb206fc9a1417cc (patch)
treef772e05b329b3775df806c0a0fa0372caac55d7e
parenta038240660ff33c452a7e95a8dd33d0a376f1c35 (diff)
downloadbcm5719-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.inc36
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;
OpenPOWER on IntegriCloud