Index: lldb/test/Shell/Driver/TestNoUseColor.test =================================================================== --- lldb/test/Shell/Driver/TestNoUseColor.test +++ lldb/test/Shell/Driver/TestNoUseColor.test @@ -1,4 +1,4 @@ -# RUN: %lldb --no-use-color -s %s | FileCheck %s +# RUN: %lldb --no-use-colors -s %s | FileCheck %s settings show use-color # CHECK: use-color (boolean) = false q Index: lldb/test/Shell/Driver/TestPositionalArgs.test =================================================================== --- /dev/null +++ lldb/test/Shell/Driver/TestPositionalArgs.test @@ -0,0 +1,24 @@ +RUN: echo "int main() { return 0; }" | %clang_host -x c - -o %t.foo + +RUN: %lldb -x -b %t.foo -- bar baz quux | FileCheck %s --check-prefix=FOO +RUN: %lldb -x -b %t.foo bar -- baz quux | FileCheck %s --check-prefix=FOO +RUN: %lldb -x -b %t.foo bar baz -- quux | FileCheck %s --check-prefix=FOO +RUN: %lldb -x -b %t.foo bar baz quux | FileCheck %s --check-prefix=FOO +RUN: not %lldb -x -b %t.foo bar baz quux -o 'bogus' 2>&1 | FileCheck %s --check-prefix=FOO --check-prefix LLDB-BOGUS +RUN: %lldb -x -b --unknown %t.foo bar baz quux 2>&1 | FileCheck %s --check-prefix LLDB-UNKNOWN --check-prefix FOO + +LLDB-UNKNOWN: warning: ignoring unknown option: --unknown +FOO: Current executable set to {{.*}}foo +FOO: target.run-args "bar" "baz" "quux" +LLDB-BOGUS: error: 'bogus' is not a valid command. + +RUN: %lldb -x -b %t.foo bar baz quux -- -o 'bogus' 2>&1 | FileCheck %s --check-prefix INFERIOR-BOGUS + +INFERIOR-BOGUS: Current executable set to {{.*}}foo +INFERIOR-BOGUS: target.run-args "bar" "baz" "quux" "-o" "bogus" + +RUN: %lldb -x -b %t.foo bar baz quux --unknown 2>&1 | FileCheck %s --check-prefix INFERIOR-UNKNOWN +RUN: %lldb -x -b %t.foo bar baz quux -- --unknown 2>&1 | FileCheck %s --check-prefix INFERIOR-UNKNOWN + +INFERIOR-UNKNOWN: Current executable set to {{.*}}foo +INFERIOR-UNKNOWN: target.run-args "bar" "baz" "quux" "--unknown" Index: lldb/tools/driver/Driver.cpp =================================================================== --- lldb/tools/driver/Driver.cpp +++ lldb/tools/driver/Driver.cpp @@ -364,8 +364,24 @@ // If the option data args array is empty that means the file was not // specified with -f and we need to get it from the input args. if (m_option_data.m_args.empty()) { - if (auto *arg = args.getLastArgNoClaim(OPT_INPUT)) { - m_option_data.m_args.push_back(arg->getAsString((args))); + // Find the first input argument. + unsigned first_input_arg = std::numeric_limits::max(); + for (auto *arg : args.filtered(OPT_INPUT)) { + first_input_arg = arg->getIndex(); + break; + } + + // Iterate over all the positional, unknown and remaining arguments. The + // order will match how they were specified on the command line. + for (auto *arg : args.filtered(OPT_INPUT, OPT_UNKNOWN)) { + // Any argument with an index smaller than the first input argument + // cannot be an argument to the inferior. + if (arg->getIndex() >= first_input_arg) { + // Claim the argument so we don't report it as unknown. + arg->claim(); + // Add it to the argument list. + m_option_data.m_args.push_back(arg->getAsString((args))); + } } } @@ -856,11 +872,6 @@ return 0; } - for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { - WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() - << '\n'; - } - if (auto exit_code = InitializeReproducer(input_args)) { return *exit_code; } @@ -892,6 +903,13 @@ bool exiting = false; SBError error(driver.ProcessArgs(input_args, exiting)); + + for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { + if (!arg->isClaimed()) + WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() + << '\n'; + } + if (error.Fail()) { exit_code = 1; if (const char *error_cstr = error.GetCString())