diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Driver/Arg.cpp | 20 | ||||
-rw-r--r-- | lib/Driver/ArgList.cpp | 15 | ||||
-rw-r--r-- | lib/Driver/CC1AsOptions.cpp | 14 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/DriverOptions.cpp | 14 | ||||
-rw-r--r-- | lib/Driver/OptTable.cpp | 70 | ||||
-rw-r--r-- | lib/Driver/Option.cpp | 45 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 6 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 4 |
9 files changed, 137 insertions, 53 deletions
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp index b156d7cf71..2431051e9d 100644 --- a/lib/Driver/Arg.cpp +++ b/lib/Driver/Arg.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "clang/Driver/Arg.h" +#include "clang/Basic/LLVM.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/Option.h" #include "llvm/ADT/SmallString.h" @@ -15,22 +16,23 @@ #include "llvm/Support/raw_ostream.h" using namespace clang::driver; +using clang::StringRef; -Arg::Arg(const Option _Opt, unsigned _Index, const Arg *_BaseArg) - : Opt(_Opt), BaseArg(_BaseArg), Index(_Index), +Arg::Arg(const Option _Opt, StringRef S, unsigned _Index, const Arg *_BaseArg) + : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index), Claimed(false), OwnsValues(false) { } -Arg::Arg(const Option _Opt, unsigned _Index, +Arg::Arg(const Option _Opt, StringRef S, unsigned _Index, const char *Value0, const Arg *_BaseArg) - : Opt(_Opt), BaseArg(_BaseArg), Index(_Index), + : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index), Claimed(false), OwnsValues(false) { Values.push_back(Value0); } -Arg::Arg(const Option _Opt, unsigned _Index, +Arg::Arg(const Option _Opt, StringRef S, unsigned _Index, const char *Value0, const char *Value1, const Arg *_BaseArg) - : Opt(_Opt), BaseArg(_BaseArg), Index(_Index), + : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index), Claimed(false), OwnsValues(false) { Values.push_back(Value0); Values.push_back(Value1); @@ -96,7 +98,7 @@ void Arg::render(const ArgList &Args, ArgStringList &Output) const { case Option::RenderCommaJoinedStyle: { SmallString<256> Res; llvm::raw_svector_ostream OS(Res); - OS << getOption().getName(); + OS << getSpelling(); for (unsigned i = 0, e = getNumValues(); i != e; ++i) { if (i) OS << ','; OS << getValue(Args, i); @@ -107,13 +109,13 @@ void Arg::render(const ArgList &Args, ArgStringList &Output) const { case Option::RenderJoinedStyle: Output.push_back(Args.GetOrMakeJoinedArgString( - getIndex(), getOption().getName(), getValue(Args, 0))); + getIndex(), getSpelling(), getValue(Args, 0))); for (unsigned i = 1, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); break; case Option::RenderSeparateStyle: - Output.push_back(getOption().getName().data()); + Output.push_back(Args.MakeArgString(getSpelling())); for (unsigned i = 0, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); break; diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp index 3b824f7c81..28d6b1e023 100644 --- a/lib/Driver/ArgList.cpp +++ b/lib/Driver/ArgList.cpp @@ -363,7 +363,9 @@ const char *DerivedArgList::MakeArgString(StringRef Str) const { } Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const { - Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt.getName()), BaseArg); + Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) + + Twine(Opt.getName())), + BaseArgs.MakeIndex(Opt.getName()), BaseArg); SynthesizedArgs.push_back(A); return A; } @@ -371,7 +373,9 @@ Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const { Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt, StringRef Value) const { unsigned Index = BaseArgs.MakeIndex(Value); - Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg); + Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) + + Twine(Opt.getName())), + Index, BaseArgs.getArgString(Index), BaseArg); SynthesizedArgs.push_back(A); return A; } @@ -379,7 +383,9 @@ Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt, Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt, StringRef Value) const { unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value); - Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg); + Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) + + Twine(Opt.getName())), + Index, BaseArgs.getArgString(Index + 1), BaseArg); SynthesizedArgs.push_back(A); return A; } @@ -387,7 +393,8 @@ Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt, Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt, StringRef Value) const { unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str()); - Arg *A = new Arg(Opt, Index, + Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) + + Twine(Opt.getName())), Index, BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg); SynthesizedArgs.push_back(A); diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp index cc7c7a4fef..4f89b73a46 100644 --- a/lib/Driver/CC1AsOptions.cpp +++ b/lib/Driver/CC1AsOptions.cpp @@ -15,11 +15,19 @@ using namespace clang::driver; using namespace clang::driver::options; using namespace clang::driver::cc1asoptions; +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) +#include "clang/Driver/CC1AsOptions.inc" +#undef OPTION +#undef PREFIX + static const OptTable::Info CC1AsInfoTable[] = { -#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define PREFIX(NAME, VALUE) +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ HELPTEXT, METAVAR) \ - { NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, FLAGS, \ - OPT_##GROUP, OPT_##ALIAS }, + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \ + FLAGS, OPT_##GROUP, OPT_##ALIAS }, #include "clang/Driver/CC1AsOptions.inc" }; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 59cebf58c1..31492a7b6d 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -608,7 +608,7 @@ void Driver::PrintOptions(const ArgList &Args) const { it != ie; ++it, ++i) { Arg *A = *it; llvm::errs() << "Option " << i << " - " - << "Name: \"" << A->getOption().getName() << "\", " + << "Name: \"" << A->getOption().getPrefixedName() << "\", " << "Values: {"; for (unsigned j = 0; j < A->getNumValues(); ++j) { if (j) diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp index f9d36cfb5e..3925b8aa35 100644 --- a/lib/Driver/DriverOptions.cpp +++ b/lib/Driver/DriverOptions.cpp @@ -14,11 +14,19 @@ using namespace clang::driver; using namespace clang::driver::options; +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) +#include "clang/Driver/Options.inc" +#undef OPTION +#undef PREFIX + static const OptTable::Info InfoTable[] = { -#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define PREFIX(NAME, VALUE) +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ HELPTEXT, METAVAR) \ - { NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, FLAGS, \ - OPT_##GROUP, OPT_##ALIAS }, + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \ + FLAGS, OPT_##GROUP, OPT_##ALIAS }, #include "clang/Driver/Options.inc" }; diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index a1c5ecd8e6..db59298743 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -55,6 +55,13 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { if (int N = StrCmpOptionName(A.Name, B.Name)) return N == -1; + for (const char * const *APre = A.Prefixes, + * const *BPre = B.Prefixes; + *APre != 0 && *BPre != 0; ++APre, ++BPre) { + if (int N = StrCmpOptionName(*APre, *BPre)) + return N == -1; + } + // Names are the same, check that classes are in order; exactly one // should be joined, and it should succeed the other. assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) && @@ -123,6 +130,26 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos) } } #endif + + // Build prefixes. + for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) { + if (const char *const *P = getInfo(i).Prefixes) { + for (; *P != 0; ++P) { + PrefixesUnion.insert(*P); + } + } + } + + // Build prefix chars. + for (llvm::StringSet<>::const_iterator I = PrefixesUnion.begin(), + E = PrefixesUnion.end(); I != E; ++I) { + StringRef Prefix = I->getKey(); + for (StringRef::const_iterator C = Prefix.begin(), CE = Prefix.end(); + C != CE; ++C) + if (std::find(PrefixChars.begin(), PrefixChars.end(), *C) + == PrefixChars.end()) + PrefixChars.push_back(*C); + } } OptTable::~OptTable() { @@ -140,19 +167,41 @@ bool OptTable::isOptionHelpHidden(OptSpecifier id) const { return getInfo(id).Flags & options::HelpHidden; } +static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) { + if (Arg == "-") + return true; + for (llvm::StringSet<>::const_iterator I = Prefixes.begin(), + E = Prefixes.end(); I != E; ++I) + if (Arg.startswith(I->getKey())) + return false; + return true; +} + +/// \returns Matched size. 0 means no match. +static unsigned matchOption(const OptTable::Info *I, StringRef Str) { + for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) { + StringRef Prefix(*Pre); + if (Str.startswith(Prefix) && Str.substr(Prefix.size()).startswith(I->Name)) + return Prefix.size() + StringRef(I->Name).size(); + } + return 0; +} + 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 Arg(getOption(TheInputOptionID), Index++, Str); + // Anything that doesn't start with PrefixesUnion is an input, as is '-' + // itself. + if (isInput(PrefixesUnion, Str)) + return new Arg(getOption(TheInputOptionID), Str, Index++, Str); const Info *Start = OptionInfos + FirstSearchableIndex; const Info *End = OptionInfos + getNumOptions(); + StringRef Name = StringRef(Str).ltrim(PrefixChars); // Search for the first next option which could be a prefix. - Start = std::lower_bound(Start, End, Str); + Start = std::lower_bound(Start, End, Name.data()); // Options are stored in sorted order, with '\0' at the end of the // alphabet. Since the only options which can accept a string must @@ -162,17 +211,17 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const { // FIXME: This is searching much more than necessary, but I am // blanking on the simplest way to make it fast. We can solve this // problem when we move to TableGen. - StringRef StrRef(Str); for (; Start != End; ++Start) { + unsigned ArgSize = 0; // Scan for first option which is a proper prefix. for (; Start != End; ++Start) - if (StrRef.startswith(Start->Name)) + if ((ArgSize = matchOption(Start, Str))) break; if (Start == End) break; // See if this option matches. - if (Arg *A = getOption(Start - OptionInfos + 1).accept(Args, Index)) + if (Arg *A = Option(Start, this).accept(Args, Index, ArgSize)) return A; // Otherwise, see if this argument was missing values. @@ -180,7 +229,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const { return 0; } - return new Arg(getOption(TheUnknownOptionID), Index++, Str); + return new Arg(getOption(TheUnknownOptionID), Str, Index++, Str); } InputArgList *OptTable::ParseArgs(const char* const *ArgBegin, @@ -220,10 +269,11 @@ InputArgList *OptTable::ParseArgs(const char* const *ArgBegin, } static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { - std::string Name = Opts.getOptionName(Id); + const Option O = Opts.getOption(Id); + std::string Name = O.getPrefixedName(); // Add metavar, if used. - switch (Opts.getOptionKind(Id)) { + switch (O.getKind()) { case Option::GroupClass: case Option::InputClass: case Option::UnknownClass: llvm_unreachable("Invalid option with help text."); diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp index e9440c5242..a22cb15e2e 100644 --- a/lib/Driver/Option.cpp +++ b/lib/Driver/Option.cpp @@ -48,6 +48,12 @@ void Option::dump() const { #undef P } + llvm::errs() << " Prefixes:["; + for (const char * const *Pre = Info->Prefixes; *Pre != 0; ++Pre) { + llvm::errs() << '"' << *Pre << (*(Pre + 1) == 0 ? "\"" : "\", "); + } + llvm::errs() << ']'; + llvm::errs() << " Name:\"" << getName() << '"'; const Option Group = getGroup(); @@ -84,21 +90,24 @@ bool Option::matches(OptSpecifier Opt) const { return false; } -Arg *Option::accept(const ArgList &Args, unsigned &Index) const { +Arg *Option::accept(const ArgList &Args, + unsigned &Index, + unsigned ArgSize) const { + StringRef Spelling(Args.getArgString(Index), ArgSize); switch (getKind()) { case FlagClass: - if (getName().size() != strlen(Args.getArgString(Index))) + if (ArgSize != strlen(Args.getArgString(Index))) return 0; - return new Arg(getUnaliasedOption(), Index++); + return new Arg(getUnaliasedOption(), Spelling, Index++); case JoinedClass: { - const char *Value = Args.getArgString(Index) + getName().size(); - return new Arg(getUnaliasedOption(), Index++, Value); + const char *Value = Args.getArgString(Index) + ArgSize; + return new Arg(getUnaliasedOption(), Spelling, Index++, Value); } case CommaJoinedClass: { // Always matches. - const char *Str = Args.getArgString(Index) + getName().size(); - Arg *A = new Arg(getUnaliasedOption(), Index++); + const char *Str = Args.getArgString(Index) + ArgSize; + Arg *A = new Arg(getUnaliasedOption(), Spelling, Index++); // Parse out the comma separated values. const char *Prev = Str; @@ -126,26 +135,26 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const { case SeparateClass: // Matches iff this is an exact match. // FIXME: Avoid strlen. - if (getName().size() != strlen(Args.getArgString(Index))) + if (ArgSize != strlen(Args.getArgString(Index))) return 0; Index += 2; if (Index > Args.getNumInputArgStrings()) return 0; - return new Arg(getUnaliasedOption(), + return new Arg(getUnaliasedOption(), Spelling, Index - 2, Args.getArgString(Index - 1)); case MultiArgClass: { // Matches iff this is an exact match. // FIXME: Avoid strlen. - if (getName().size() != strlen(Args.getArgString(Index))) + if (ArgSize != strlen(Args.getArgString(Index))) return 0; Index += 1 + getNumArgs(); if (Index > Args.getNumInputArgStrings()) return 0; - Arg *A = new Arg(getUnaliasedOption(), Index - 1 - getNumArgs(), + Arg *A = new Arg(getUnaliasedOption(), Spelling, Index - 1 - getNumArgs(), Args.getArgString(Index - getNumArgs())); for (unsigned i = 1; i != getNumArgs(); ++i) A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i)); @@ -154,9 +163,9 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const { case JoinedOrSeparateClass: { // If this is not an exact match, it is a joined arg. // FIXME: Avoid strlen. - if (getName().size() != strlen(Args.getArgString(Index))) { - const char *Value = Args.getArgString(Index) + getName().size(); - return new Arg(*this, Index++, Value); + if (ArgSize != strlen(Args.getArgString(Index))) { + const char *Value = Args.getArgString(Index) + ArgSize; + return new Arg(*this, Spelling, Index++, Value); } // Otherwise it must be separate. @@ -164,7 +173,7 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const { if (Index > Args.getNumInputArgStrings()) return 0; - return new Arg(getUnaliasedOption(), + return new Arg(getUnaliasedOption(), Spelling, Index - 2, Args.getArgString(Index - 1)); } case JoinedAndSeparateClass: @@ -173,9 +182,9 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const { if (Index > Args.getNumInputArgStrings()) return 0; - return new Arg(getUnaliasedOption(), Index - 2, - Args.getArgString(Index-2)+getName().size(), - Args.getArgString(Index-1)); + return new Arg(getUnaliasedOption(), Spelling, Index - 2, + Args.getArgString(Index - 2) + ArgSize, + Args.getArgString(Index - 1)); default: llvm_unreachable("Invalid option kind!"); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 7848b488d3..54ec0cb1a9 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1175,8 +1175,8 @@ void Clang::AddX86TargetArgs(const ArgList &Args, (*it)->claim(); // Skip over "-m". - assert(Name.startswith("-m") && "Invalid feature name."); - Name = Name.substr(2); + assert(Name.startswith("m") && "Invalid feature name."); + Name = Name.substr(1); bool IsNegative = Name.startswith("no-"); if (IsNegative) @@ -2283,7 +2283,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fbounds-checking=1"); } - if (Args.hasArg(options::OPT__relocatable_pch)) + if (Args.hasArg(options::OPT_relocatable_pch)) CmdArgs.push_back("-relocatable-pch"); if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 4f0cfa8001..1de547d9b4 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1001,10 +1001,10 @@ static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) { for (arg_iterator I = Args.filtered_begin(OPT_W_Group), E = Args.filtered_end(); I != E; ++I) { Arg *A = *I; - // If the argument is a pure flag, add its name (minus the "-W" at the beginning) + // If the argument is a pure flag, add its name (minus the "W" at the beginning) // to the warning list. Else, add its value (for the OPT_W case). if (A->getOption().getKind() == Option::FlagClass) { - Warnings.push_back(A->getOption().getName().substr(2)); + Warnings.push_back(A->getOption().getName().substr(1)); } else { for (unsigned Idx = 0, End = A->getNumValues(); Idx < End; ++Idx) { |