aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r--llvm/lib/Support/CommandLine.cpp67
-rw-r--r--llvm/lib/Support/Host.cpp6
-rw-r--r--llvm/lib/Support/Windows/Process.inc5
3 files changed, 63 insertions, 15 deletions
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 4c92502..3e5fff9 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -918,21 +918,34 @@ static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) {
return I - 1;
}
-// Windows treats whitespace, double quotes, and backslashes specially.
+// Windows treats whitespace, double quotes, and backslashes specially, except
+// when parsing the first token of a full command line, in which case
+// backslashes are not special.
static bool isWindowsSpecialChar(char C) {
return isWhitespaceOrNull(C) || C == '\\' || C == '\"';
}
+static bool isWindowsSpecialCharInCommandName(char C) {
+ return isWhitespaceOrNull(C) || C == '\"';
+}
// Windows tokenization implementation. The implementation is designed to be
// inlined and specialized for the two user entry points.
-static inline void
-tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
- function_ref<void(StringRef)> AddToken,
- bool AlwaysCopy, function_ref<void()> MarkEOL) {
+static inline void tokenizeWindowsCommandLineImpl(
+ StringRef Src, StringSaver &Saver, function_ref<void(StringRef)> AddToken,
+ bool AlwaysCopy, function_ref<void()> MarkEOL, bool InitialCommandName) {
SmallString<128> Token;
+ // Sometimes, this function will be handling a full command line including an
+ // executable pathname at the start. In that situation, the initial pathname
+ // needs different handling from the following arguments, because when
+ // CreateProcess or cmd.exe scans the pathname, it doesn't treat \ as
+ // escaping the quote character, whereas when libc scans the rest of the
+ // command line, it does.
+ bool CommandName = InitialCommandName;
+
// Try to do as much work inside the state machine as possible.
enum { INIT, UNQUOTED, QUOTED } State = INIT;
+
for (size_t I = 0, E = Src.size(); I < E; ++I) {
switch (State) {
case INIT: {
@@ -947,19 +960,29 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
if (I >= E)
break;
size_t Start = I;
- while (I < E && !isWindowsSpecialChar(Src[I]))
- ++I;
+ if (CommandName) {
+ while (I < E && !isWindowsSpecialCharInCommandName(Src[I]))
+ ++I;
+ } else {
+ while (I < E && !isWindowsSpecialChar(Src[I]))
+ ++I;
+ }
StringRef NormalChars = Src.slice(Start, I);
if (I >= E || isWhitespaceOrNull(Src[I])) {
// No special characters: slice out the substring and start the next
// token. Copy the string if the caller asks us to.
AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);
- if (I < E && Src[I] == '\n')
+ if (I < E && Src[I] == '\n') {
MarkEOL();
+ CommandName = InitialCommandName;
+ } else {
+ CommandName = false;
+ }
} else if (Src[I] == '\"') {
Token += NormalChars;
State = QUOTED;
} else if (Src[I] == '\\') {
+ assert(!CommandName && "or else we'd have treated it as a normal char");
Token += NormalChars;
I = parseBackslash(Src, I, Token);
State = UNQUOTED;
@@ -976,12 +999,16 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
// token.
AddToken(Saver.save(Token.str()));
Token.clear();
- if (Src[I] == '\n')
+ if (Src[I] == '\n') {
+ CommandName = InitialCommandName;
MarkEOL();
+ } else {
+ CommandName = false;
+ }
State = INIT;
} else if (Src[I] == '\"') {
State = QUOTED;
- } else if (Src[I] == '\\') {
+ } else if (Src[I] == '\\' && !CommandName) {
I = parseBackslash(Src, I, Token);
} else {
Token.push_back(Src[I]);
@@ -999,7 +1026,7 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
// Otherwise, end the quoted portion and return to the unquoted state.
State = UNQUOTED;
}
- } else if (Src[I] == '\\') {
+ } else if (Src[I] == '\\' && !CommandName) {
I = parseBackslash(Src, I, Token);
} else {
Token.push_back(Src[I]);
@@ -1008,7 +1035,7 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
}
}
- if (State == UNQUOTED)
+ if (State != INIT)
AddToken(Saver.save(Token.str()));
}
@@ -1021,7 +1048,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,
NewArgv.push_back(nullptr);
};
tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,
- /*AlwaysCopy=*/true, OnEOL);
+ /*AlwaysCopy=*/true, OnEOL, false);
}
void cl::TokenizeWindowsCommandLineNoCopy(StringRef Src, StringSaver &Saver,
@@ -1029,7 +1056,19 @@ void cl::TokenizeWindowsCommandLineNoCopy(StringRef Src, StringSaver &Saver,
auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok); };
auto OnEOL = []() {};
tokenizeWindowsCommandLineImpl(Src, Saver, AddToken, /*AlwaysCopy=*/false,
- OnEOL);
+ OnEOL, false);
+}
+
+void cl::TokenizeWindowsCommandLineFull(StringRef Src, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs) {
+ auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };
+ auto OnEOL = [&]() {
+ if (MarkEOLs)
+ NewArgv.push_back(nullptr);
+ };
+ tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,
+ /*AlwaysCopy=*/true, OnEOL, true);
}
void cl::tokenizeConfigFile(StringRef Source, StringSaver &Saver,
diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp
index 98272bb..976599f 100644
--- a/llvm/lib/Support/Host.cpp
+++ b/llvm/lib/Support/Host.cpp
@@ -296,6 +296,12 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
}
}
+ if (Implementer == "0xc0") { // Ampere Computing
+ return StringSwitch<const char *>(Part)
+ .Case("0xac3", "ampere1")
+ .Default("generic");
+ }
+
return "generic";
}
diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc
index dfaab16..e415674 100644
--- a/llvm/lib/Support/Windows/Process.inc
+++ b/llvm/lib/Support/Windows/Process.inc
@@ -247,7 +247,7 @@ windows::GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
SmallVector<const char *, 20> TmpArgs;
StringSaver Saver(Alloc);
- cl::TokenizeWindowsCommandLine(Cmd, Saver, TmpArgs, /*MarkEOLs=*/false);
+ cl::TokenizeWindowsCommandLineFull(Cmd, Saver, TmpArgs, /*MarkEOLs=*/false);
for (const char *Arg : TmpArgs) {
EC = WildcardExpand(Arg, Args, Saver);
@@ -255,6 +255,9 @@ windows::GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
return EC;
}
+ if (Args.size() == 0)
+ return std::make_error_code(std::errc::invalid_argument);
+
SmallVector<char, MAX_PATH> Arg0(Args[0], Args[0] + strlen(Args[0]));
SmallVector<char, MAX_PATH> Filename;
sys::path::remove_filename(Arg0);