diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-03-22 23:26:43 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-03-22 23:26:43 +0000 |
commit | b0c4df5c4df69a003f26b378eb95961bc7c486e5 (patch) | |
tree | 2366feb7fa7499a78e8a7244b6670a36077068f7 /lib/Driver | |
parent | 5fdeae17da443c50c62f602733d06193a71b170f (diff) |
Driver: Implement 'missing argument' error.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/ArgList.cpp | 4 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 23 | ||||
-rw-r--r-- | lib/Driver/OptTable.cpp | 13 | ||||
-rw-r--r-- | lib/Driver/Option.cpp | 28 |
4 files changed, 46 insertions, 22 deletions
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp index 30da136e04..7653daf7ee 100644 --- a/lib/Driver/ArgList.cpp +++ b/lib/Driver/ArgList.cpp @@ -13,7 +13,9 @@ using namespace clang::driver; -ArgList::ArgList(const char **ArgBegin, const char **ArgEnd) { +ArgList::ArgList(const char **ArgBegin, const char **ArgEnd) + : NumInputArgStrings(ArgEnd - ArgBegin) +{ ArgStrings.append(ArgBegin, ArgEnd); } diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 40c6e50063..db084262e9 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -72,18 +72,23 @@ ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) { } unsigned Prev = Index; - Arg *A = getOpts().ParseOneArg(*Args, Index, End); - if (A) { - if (A->getOption().isUnsupported()) { - Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args); - continue; - } + Arg *A = getOpts().ParseOneArg(*Args, Index); + assert(Index > Prev && "Parser failed to consume argument."); - Args->append(A); + // Check for missing argument error. + if (!A) { + assert(Index >= End && "Unexpected parser error."); + Diag(clang::diag::err_drv_missing_argument) + << Args->getArgString(Prev) + << (Index - Prev - 1); + break; } - assert(Index > Prev && "Parser failed to consume argument."); - (void) Prev; + if (A->getOption().isUnsupported()) { + Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args); + continue; + } + Args->append(A); } return Args; diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index 7b7e2a7bbc..07e3511719 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -128,21 +128,28 @@ Option *OptTable::constructOption(options::ID id) const { return Opt; } -Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, - unsigned IndexEnd) const { +Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const { + unsigned Prev = Index; const char *Str = Args.getArgString(Index); // Anything that doesn't start with '-' is an input, as is '-' itself. if (Str[0] != '-' || Str[1] == '\0') return new PositionalArg(getOption(OPT_INPUT), Index++); + // FIXME: Make this fast, and avoid looking through option + // groups. Maybe we should declare them separately? for (unsigned j = OPT_UNKNOWN + 1; j < LastOption; ++j) { const char *OptName = getOptionName((options::ID) j); // Arguments are only accepted by options which prefix them. - if (memcmp(Str, OptName, strlen(OptName)) == 0) + if (memcmp(Str, OptName, strlen(OptName)) == 0) { if (Arg *A = getOption((options::ID) j)->accept(Args, Index)) return A; + + // Otherwise, see if this argument was missing values. + if (Prev != Index) + return 0; + } } return new PositionalArg(getOption(OPT_UNKNOWN), Index++); diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp index 12d501b3cb..dc681c7295 100644 --- a/lib/Driver/Option.cpp +++ b/lib/Driver/Option.cpp @@ -108,7 +108,7 @@ OptionGroup::OptionGroup(options::ID ID, const char *Name, } Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const { - assert(0 && "FIXME"); + assert(0 && "accept() should never be called on an OptionGroup"); return 0; } @@ -117,7 +117,7 @@ InputOption::InputOption() } Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const { - assert(0 && "FIXME"); + assert(0 && "accept() should never be called on an InputOption"); return 0; } @@ -126,7 +126,7 @@ UnknownOption::UnknownOption() } Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const { - assert(0 && "FIXME"); + assert(0 && "accept() should never be called on an UnknownOption"); return 0; } @@ -181,8 +181,10 @@ Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const { if (strlen(getName()) != strlen(Args.getArgString(Index))) return 0; - // FIXME: Missing argument error. Index += 2; + if (Index > Args.getNumInputArgStrings()) + return 0; + return new SeparateArg(this, Index - 2, 1); } @@ -199,8 +201,10 @@ Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const { if (strlen(getName()) != strlen(Args.getArgString(Index))) return 0; - // FIXME: Missing argument error. Index += 1 + NumArgs; + if (Index > Args.getNumInputArgStrings()) + return 0; + return new SeparateArg(this, Index - 1 - NumArgs, NumArgs); } @@ -210,15 +214,18 @@ JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID, const char *Name, : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) { } -Arg *JoinedOrSeparateOption::accept(const ArgList &Args, unsigned &Index) const { +Arg *JoinedOrSeparateOption::accept(const ArgList &Args, + unsigned &Index) const { // If this is not an exact match, it is a joined arg. // FIXME: Avoid strlen. if (strlen(getName()) != strlen(Args.getArgString(Index))) return new JoinedArg(this, Index++); // Otherwise it must be separate. - // FIXME: Missing argument error. Index += 2; + if (Index > Args.getNumInputArgStrings()) + return 0; + return new SeparateArg(this, Index - 2, 1); } @@ -229,11 +236,14 @@ JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID, : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) { } -Arg *JoinedAndSeparateOption::accept(const ArgList &Args, unsigned &Index) const { +Arg *JoinedAndSeparateOption::accept(const ArgList &Args, + unsigned &Index) const { // Always matches. - // FIXME: Missing argument error. Index += 2; + if (Index > Args.getNumInputArgStrings()) + return 0; + return new JoinedAndSeparateArg(this, Index - 2); } |